@elastic/eui 112.2.0-snapshot.1770205951498 → 112.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/components/flyout/index.js +4 -1
- package/es/components/flyout/manager/flyout_managed.js +31 -11
- package/es/components/flyout/manager/index.js +2 -0
- package/es/components/flyout/manager/store.js +31 -0
- package/es/components/form/file_picker/file_picker.js +1 -1
- package/eui.d.ts +47 -34
- package/lib/components/flyout/index.js +6 -0
- package/lib/components/flyout/manager/flyout_managed.js +30 -10
- package/lib/components/flyout/manager/index.js +7 -0
- package/lib/components/flyout/manager/store.js +30 -0
- package/lib/components/form/file_picker/file_picker.js +1 -1
- package/optimize/es/components/flyout/index.js +4 -1
- package/optimize/es/components/flyout/manager/flyout_managed.js +31 -11
- package/optimize/es/components/flyout/manager/index.js +2 -0
- package/optimize/es/components/flyout/manager/store.js +31 -0
- package/optimize/es/components/form/file_picker/file_picker.js +1 -1
- package/optimize/lib/components/flyout/index.js +6 -0
- package/optimize/lib/components/flyout/manager/flyout_managed.js +30 -10
- package/optimize/lib/components/flyout/manager/index.js +7 -0
- package/optimize/lib/components/flyout/manager/store.js +30 -0
- package/optimize/lib/components/form/file_picker/file_picker.js +1 -1
- package/package.json +2 -3
- package/test-env/components/flyout/index.js +6 -0
- package/test-env/components/flyout/manager/flyout_managed.js +30 -10
- package/test-env/components/flyout/manager/index.js +7 -0
- package/test-env/components/flyout/manager/store.js +30 -0
- package/test-env/components/form/file_picker/file_picker.js +1 -1
|
@@ -16,4 +16,7 @@ export { EuiFlyoutMenu } from './flyout_menu';
|
|
|
16
16
|
|
|
17
17
|
// Hooks for using Manager-based flyouts
|
|
18
18
|
export { useIsInManagedFlyout, useHasActiveSession } from './manager';
|
|
19
|
-
export { useIsInsideParentFlyout } from './flyout_parent_context';
|
|
19
|
+
export { useIsInsideParentFlyout } from './flyout_parent_context';
|
|
20
|
+
|
|
21
|
+
// Flyout manager store (for cross-root state synchronization)
|
|
22
|
+
export { getFlyoutManagerStore } from './manager';
|
|
@@ -22,8 +22,9 @@ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t =
|
|
|
22
22
|
* Side Public License, v 1.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import React, { useEffect, useMemo, useRef, useState, forwardRef } from 'react';
|
|
25
|
+
import React, { useEffect, useLayoutEffect, useMemo, useRef, useState, forwardRef } from 'react';
|
|
26
26
|
import PropTypes from "prop-types";
|
|
27
|
+
import { flushSync } from 'react-dom';
|
|
27
28
|
import { useCombinedRefs, useEuiMemoizedStyles } from '../../../services';
|
|
28
29
|
import { useEuiI18n } from '../../i18n';
|
|
29
30
|
import { useResizeObserver } from '../../observer/resize_observer';
|
|
@@ -135,11 +136,25 @@ export var EuiManagedFlyout = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
135
136
|
// Track if flyout was ever registered to avoid false positives on initial mount
|
|
136
137
|
var wasRegisteredRef = useRef(false);
|
|
137
138
|
|
|
138
|
-
//
|
|
139
|
+
// Track flyoutExistsInManager in a ref to avoid dependency loop
|
|
140
|
+
// The cleanup function needs the current value but shouldn't cause re-runs
|
|
141
|
+
var flyoutExistsInManagerRef = useRef(flyoutExistsInManager);
|
|
142
|
+
|
|
143
|
+
// Update ref when flyoutExistsInManager changes
|
|
139
144
|
useEffect(function () {
|
|
145
|
+
flyoutExistsInManagerRef.current = flyoutExistsInManager;
|
|
146
|
+
}, [flyoutExistsInManager]);
|
|
147
|
+
|
|
148
|
+
// Register with flyout manager context when open, remove when closed
|
|
149
|
+
// Using useLayoutEffect to run synchronously before DOM updates
|
|
150
|
+
useLayoutEffect(function () {
|
|
140
151
|
addFlyout(flyoutId, title, level, size);
|
|
141
152
|
return function () {
|
|
142
|
-
closeFlyout
|
|
153
|
+
// Only call closeFlyout if it wasn't already called via onClose
|
|
154
|
+
// This prevents duplicate removal when using Escape/X button
|
|
155
|
+
if (flyoutExistsInManagerRef.current) {
|
|
156
|
+
closeFlyout(flyoutId);
|
|
157
|
+
}
|
|
143
158
|
|
|
144
159
|
// Reset navigation tracking when explicitly closed via isOpen=false
|
|
145
160
|
wasRegisteredRef.current = false;
|
|
@@ -175,12 +190,6 @@ export var EuiManagedFlyout = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
175
190
|
onActiveCallbackRef.current();
|
|
176
191
|
}
|
|
177
192
|
}, [currentSession, flyoutId, level]);
|
|
178
|
-
useEffect(function () {
|
|
179
|
-
return function () {
|
|
180
|
-
// Only remove from manager on component unmount, don't trigger close callback
|
|
181
|
-
closeFlyout(flyoutId);
|
|
182
|
-
};
|
|
183
|
-
}, [closeFlyout, flyoutId]);
|
|
184
193
|
|
|
185
194
|
// Track width changes for flyouts
|
|
186
195
|
var _useResizeObserver = useResizeObserver(isActive ? flyoutRef : null, 'width'),
|
|
@@ -188,8 +197,19 @@ export var EuiManagedFlyout = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
188
197
|
|
|
189
198
|
// Pass the stabilized onClose callback to the flyout menu context
|
|
190
199
|
var onClose = function onClose(e) {
|
|
191
|
-
|
|
192
|
-
|
|
200
|
+
// CRITICAL: Update manager state FIRST before allowing React to unmount
|
|
201
|
+
// This prevents race conditions during portal → inline DOM transitions
|
|
202
|
+
// and ensures cascade close logic runs before DOM cleanup begins
|
|
203
|
+
// Using flushSync to force synchronous state update completion
|
|
204
|
+
flushSync(function () {
|
|
205
|
+
closeFlyout(flyoutId);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// trigger parent callback, unmounts the component
|
|
209
|
+
if (onCloseCallbackRef.current) {
|
|
210
|
+
var event = e || new MouseEvent('click');
|
|
211
|
+
onCloseCallbackRef.current(event);
|
|
212
|
+
}
|
|
193
213
|
};
|
|
194
214
|
|
|
195
215
|
// Update width in manager state when it changes
|
|
@@ -14,6 +14,8 @@ export { addFlyout as addFlyoutAction, closeFlyout as closeFlyoutAction, setActi
|
|
|
14
14
|
/** Reducer and default state for the flyout manager. */
|
|
15
15
|
export { flyoutManagerReducer, initialState } from './reducer';
|
|
16
16
|
|
|
17
|
+
/** Flyout manager store singleton and types. */
|
|
18
|
+
export { getFlyoutManagerStore } from './store';
|
|
17
19
|
/** Provider component exposing the Flyout Manager API via context. */
|
|
18
20
|
export { EuiFlyoutManager } from './provider';
|
|
19
21
|
|
|
@@ -8,10 +8,16 @@
|
|
|
8
8
|
|
|
9
9
|
import { addFlyout as addFlyoutAction, closeFlyout as closeFlyoutAction, setActiveFlyout as setActiveFlyoutAction, setFlyoutWidth as setFlyoutWidthAction, setPushPadding as setPushPaddingAction, goBack as goBackAction, goToFlyout as goToFlyoutAction, addUnmanagedFlyout as addUnmanagedFlyoutAction, closeUnmanagedFlyout as closeUnmanagedFlyoutAction } from './actions';
|
|
10
10
|
import { flyoutManagerReducer, initialState } from './reducer';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Events emitted by the flyout manager store for external consumers.
|
|
14
|
+
*/
|
|
15
|
+
|
|
11
16
|
function createStore() {
|
|
12
17
|
var initial = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
|
|
13
18
|
var currentState = initial;
|
|
14
19
|
var listeners = new Set();
|
|
20
|
+
var eventListeners = new Set();
|
|
15
21
|
var getState = function getState() {
|
|
16
22
|
return currentState;
|
|
17
23
|
};
|
|
@@ -21,6 +27,17 @@ function createStore() {
|
|
|
21
27
|
listeners.delete(listener);
|
|
22
28
|
};
|
|
23
29
|
};
|
|
30
|
+
var subscribeToEvents = function subscribeToEvents(listener) {
|
|
31
|
+
eventListeners.add(listener);
|
|
32
|
+
return function () {
|
|
33
|
+
eventListeners.delete(listener);
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
var emitEvent = function emitEvent(event) {
|
|
37
|
+
eventListeners.forEach(function (listener) {
|
|
38
|
+
listener(event);
|
|
39
|
+
});
|
|
40
|
+
};
|
|
24
41
|
|
|
25
42
|
// The onClick handlers won't execute until after store is fully assigned.
|
|
26
43
|
// eslint-disable-next-line prefer-const -- Forward declaration requires 'let' not 'const'
|
|
@@ -49,6 +66,19 @@ function createStore() {
|
|
|
49
66
|
// This ensures stable references and avoids stale closures
|
|
50
67
|
if (nextState.sessions !== previousSessions) {
|
|
51
68
|
store.historyItems = computeHistoryItems();
|
|
69
|
+
|
|
70
|
+
// Detect removed sessions and emit CLOSE_SESSION events
|
|
71
|
+
var nextSessionIds = new Set(nextState.sessions.map(function (s) {
|
|
72
|
+
return s.mainFlyoutId;
|
|
73
|
+
}));
|
|
74
|
+
previousSessions.forEach(function (session) {
|
|
75
|
+
if (!nextSessionIds.has(session.mainFlyoutId)) {
|
|
76
|
+
emitEvent({
|
|
77
|
+
type: 'CLOSE_SESSION',
|
|
78
|
+
session: session
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
});
|
|
52
82
|
}
|
|
53
83
|
listeners.forEach(function (l) {
|
|
54
84
|
l();
|
|
@@ -58,6 +88,7 @@ function createStore() {
|
|
|
58
88
|
store = {
|
|
59
89
|
getState: getState,
|
|
60
90
|
subscribe: subscribe,
|
|
91
|
+
subscribeToEvents: subscribeToEvents,
|
|
61
92
|
dispatch: dispatch,
|
|
62
93
|
addFlyout: function addFlyout(flyoutId, title, level, size) {
|
|
63
94
|
return dispatch(addFlyoutAction(flyoutId, title, level, size));
|
|
@@ -214,7 +214,7 @@ export var EuiFilePickerClass = /*#__PURE__*/function (_Component) {
|
|
|
214
214
|
css: iconStyles,
|
|
215
215
|
className: "euiFilePicker__icon",
|
|
216
216
|
color: iconColor,
|
|
217
|
-
type: isInvalid ? 'alert' : disabled ? 'minusInCircle' : '
|
|
217
|
+
type: isInvalid ? 'alert' : disabled ? 'minusInCircle' : 'upload',
|
|
218
218
|
size: normalFormControl ? 'm' : 'l',
|
|
219
219
|
"aria-hidden": "true"
|
|
220
220
|
}), ___EmotionJSX("span", {
|
package/eui.d.ts
CHANGED
|
@@ -12278,6 +12278,49 @@ declare module '@elastic/eui/src/components/flyout/manager/reducer' {
|
|
|
12278
12278
|
*/
|
|
12279
12279
|
export function flyoutManagerReducer(state: EuiFlyoutManagerState | undefined, action: Action): EuiFlyoutManagerState;
|
|
12280
12280
|
|
|
12281
|
+
}
|
|
12282
|
+
declare module '@elastic/eui/src/components/flyout/manager/store' {
|
|
12283
|
+
import type { EuiFlyoutLevel, EuiFlyoutManagerState, FlyoutSession } from '@elastic/eui/src/components/flyout/manager/types';
|
|
12284
|
+
import type { Action } from '@elastic/eui/src/components/flyout/manager/actions';
|
|
12285
|
+
type Listener = () => void;
|
|
12286
|
+
/**
|
|
12287
|
+
* Events emitted by the flyout manager store for external consumers.
|
|
12288
|
+
*/
|
|
12289
|
+
export type FlyoutManagerEvent = {
|
|
12290
|
+
type: 'CLOSE_SESSION';
|
|
12291
|
+
session: FlyoutSession;
|
|
12292
|
+
};
|
|
12293
|
+
type EventListener = (event: FlyoutManagerEvent) => void;
|
|
12294
|
+
export interface FlyoutManagerStore {
|
|
12295
|
+
getState: () => EuiFlyoutManagerState;
|
|
12296
|
+
subscribe: (listener: Listener) => () => void;
|
|
12297
|
+
subscribeToEvents: (listener: EventListener) => () => void;
|
|
12298
|
+
dispatch: (action: Action) => void;
|
|
12299
|
+
addFlyout: (flyoutId: string, title: string, level?: EuiFlyoutLevel, size?: string) => void;
|
|
12300
|
+
closeFlyout: (flyoutId: string) => void;
|
|
12301
|
+
setActiveFlyout: (flyoutId: string | null) => void;
|
|
12302
|
+
setFlyoutWidth: (flyoutId: string, width: number) => void;
|
|
12303
|
+
setPushPadding: (side: 'left' | 'right', width: number) => void;
|
|
12304
|
+
goBack: () => void;
|
|
12305
|
+
goToFlyout: (flyoutId: string) => void;
|
|
12306
|
+
addUnmanagedFlyout: (flyoutId: string) => void;
|
|
12307
|
+
closeUnmanagedFlyout: (flyoutId: string) => void;
|
|
12308
|
+
historyItems: Array<{
|
|
12309
|
+
title: string;
|
|
12310
|
+
onClick: () => void;
|
|
12311
|
+
}>;
|
|
12312
|
+
}
|
|
12313
|
+
/**
|
|
12314
|
+
* Returns a singleton store instance shared across all React roots within the same JS context.
|
|
12315
|
+
* Uses module-level singleton to ensure deduplication even if modules are loaded twice.
|
|
12316
|
+
*/
|
|
12317
|
+
export function getFlyoutManagerStore(): FlyoutManagerStore;
|
|
12318
|
+
/**
|
|
12319
|
+
* For testing purposes - allows resetting the store
|
|
12320
|
+
*/
|
|
12321
|
+
export function _resetFlyoutManagerStore(): void;
|
|
12322
|
+
export {};
|
|
12323
|
+
|
|
12281
12324
|
}
|
|
12282
12325
|
declare module '@elastic/eui/src/components/flyout/manager/selectors' {
|
|
12283
12326
|
export const useSession: (flyoutId?: string | null) => import ("@elastic/eui/src/components/flyout/manager/types").FlyoutSession | null;
|
|
@@ -12352,40 +12395,6 @@ declare module '@elastic/eui/src/components/flyout/manager/layout_mode' {
|
|
|
12352
12395
|
/** Current layout mode for managed flyouts (`side-by-side` or `stacked`). */
|
|
12353
12396
|
export const useFlyoutLayoutMode: () => EuiFlyoutLayoutMode;
|
|
12354
12397
|
|
|
12355
|
-
}
|
|
12356
|
-
declare module '@elastic/eui/src/components/flyout/manager/store' {
|
|
12357
|
-
import type { EuiFlyoutLevel, EuiFlyoutManagerState } from '@elastic/eui/src/components/flyout/manager/types';
|
|
12358
|
-
import type { Action } from '@elastic/eui/src/components/flyout/manager/actions';
|
|
12359
|
-
type Listener = () => void;
|
|
12360
|
-
export interface FlyoutManagerStore {
|
|
12361
|
-
getState: () => EuiFlyoutManagerState;
|
|
12362
|
-
subscribe: (listener: Listener) => () => void;
|
|
12363
|
-
dispatch: (action: Action) => void;
|
|
12364
|
-
addFlyout: (flyoutId: string, title: string, level?: EuiFlyoutLevel, size?: string) => void;
|
|
12365
|
-
closeFlyout: (flyoutId: string) => void;
|
|
12366
|
-
setActiveFlyout: (flyoutId: string | null) => void;
|
|
12367
|
-
setFlyoutWidth: (flyoutId: string, width: number) => void;
|
|
12368
|
-
setPushPadding: (side: 'left' | 'right', width: number) => void;
|
|
12369
|
-
goBack: () => void;
|
|
12370
|
-
goToFlyout: (flyoutId: string) => void;
|
|
12371
|
-
addUnmanagedFlyout: (flyoutId: string) => void;
|
|
12372
|
-
closeUnmanagedFlyout: (flyoutId: string) => void;
|
|
12373
|
-
historyItems: Array<{
|
|
12374
|
-
title: string;
|
|
12375
|
-
onClick: () => void;
|
|
12376
|
-
}>;
|
|
12377
|
-
}
|
|
12378
|
-
/**
|
|
12379
|
-
* Returns a singleton store instance shared across all React roots within the same JS context.
|
|
12380
|
-
* Uses module-level singleton to ensure deduplication even if modules are loaded twice.
|
|
12381
|
-
*/
|
|
12382
|
-
export function getFlyoutManagerStore(): FlyoutManagerStore;
|
|
12383
|
-
/**
|
|
12384
|
-
* For testing purposes - allows resetting the store
|
|
12385
|
-
*/
|
|
12386
|
-
export function _resetFlyoutManagerStore(): void;
|
|
12387
|
-
export {};
|
|
12388
|
-
|
|
12389
12398
|
}
|
|
12390
12399
|
declare module '@elastic/eui/src/components/flyout/manager/provider' {
|
|
12391
12400
|
import React from 'react';
|
|
@@ -13103,6 +13112,9 @@ declare module '@elastic/eui/src/components/flyout/manager' {
|
|
|
13103
13112
|
export { addFlyout as addFlyoutAction, closeFlyout as closeFlyoutAction, setActiveFlyout as setActiveFlyoutAction, setFlyoutWidth as setFlyoutWidthAction, setPushPadding as setPushPaddingAction, setActivityStage as setActivityStageAction, } from '@elastic/eui/src/components/flyout/manager/actions';
|
|
13104
13113
|
/** Reducer and default state for the flyout manager. */
|
|
13105
13114
|
export { flyoutManagerReducer, initialState } from '@elastic/eui/src/components/flyout/manager/reducer';
|
|
13115
|
+
/** Flyout manager store singleton and types. */
|
|
13116
|
+
export { getFlyoutManagerStore, type FlyoutManagerStore, type FlyoutManagerEvent, } from '@elastic/eui/src/components/flyout/manager/store';
|
|
13117
|
+
export type { EuiFlyoutManagerState, FlyoutSession } from '@elastic/eui/src/components/flyout/manager/types';
|
|
13106
13118
|
/** Provider component exposing the Flyout Manager API via context. */
|
|
13107
13119
|
export { EuiFlyoutManager } from '@elastic/eui/src/components/flyout/manager/provider';
|
|
13108
13120
|
/**
|
|
@@ -14197,6 +14209,7 @@ declare module '@elastic/eui/src/components/flyout' {
|
|
|
14197
14209
|
export { EuiFlyoutMenu } from '@elastic/eui/src/components/flyout/flyout_menu';
|
|
14198
14210
|
export { useIsInManagedFlyout, useHasActiveSession } from '@elastic/eui/src/components/flyout/manager';
|
|
14199
14211
|
export { useIsInsideParentFlyout } from '@elastic/eui/src/components/flyout/flyout_parent_context';
|
|
14212
|
+
export { getFlyoutManagerStore, type FlyoutManagerStore, type FlyoutManagerEvent, type EuiFlyoutManagerState, type FlyoutSession, } from '@elastic/eui/src/components/flyout/manager';
|
|
14200
14213
|
|
|
14201
14214
|
}
|
|
14202
14215
|
declare module '@elastic/eui/src/components/provider/component_defaults/component_defaults' {
|
|
@@ -51,6 +51,12 @@ Object.defineProperty(exports, "euiFlyoutSlideInRight", {
|
|
|
51
51
|
return _flyout2.euiFlyoutSlideInRight;
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
|
+
Object.defineProperty(exports, "getFlyoutManagerStore", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function get() {
|
|
57
|
+
return _manager.getFlyoutManagerStore;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
54
60
|
Object.defineProperty(exports, "useHasActiveSession", {
|
|
55
61
|
enumerable: true,
|
|
56
62
|
get: function get() {
|
|
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.EuiManagedFlyout = void 0;
|
|
8
8
|
var _react = _interopRequireWildcard(require("react"));
|
|
9
9
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
10
|
+
var _reactDom = require("react-dom");
|
|
10
11
|
var _services = require("../../../services");
|
|
11
12
|
var _i18n = require("../../i18n");
|
|
12
13
|
var _resize_observer = require("../../observer/resize_observer");
|
|
@@ -142,11 +143,25 @@ var EuiManagedFlyout = exports.EuiManagedFlyout = /*#__PURE__*/(0, _react.forwar
|
|
|
142
143
|
// Track if flyout was ever registered to avoid false positives on initial mount
|
|
143
144
|
var wasRegisteredRef = (0, _react.useRef)(false);
|
|
144
145
|
|
|
145
|
-
//
|
|
146
|
+
// Track flyoutExistsInManager in a ref to avoid dependency loop
|
|
147
|
+
// The cleanup function needs the current value but shouldn't cause re-runs
|
|
148
|
+
var flyoutExistsInManagerRef = (0, _react.useRef)(flyoutExistsInManager);
|
|
149
|
+
|
|
150
|
+
// Update ref when flyoutExistsInManager changes
|
|
146
151
|
(0, _react.useEffect)(function () {
|
|
152
|
+
flyoutExistsInManagerRef.current = flyoutExistsInManager;
|
|
153
|
+
}, [flyoutExistsInManager]);
|
|
154
|
+
|
|
155
|
+
// Register with flyout manager context when open, remove when closed
|
|
156
|
+
// Using useLayoutEffect to run synchronously before DOM updates
|
|
157
|
+
(0, _react.useLayoutEffect)(function () {
|
|
147
158
|
addFlyout(flyoutId, title, level, size);
|
|
148
159
|
return function () {
|
|
149
|
-
closeFlyout
|
|
160
|
+
// Only call closeFlyout if it wasn't already called via onClose
|
|
161
|
+
// This prevents duplicate removal when using Escape/X button
|
|
162
|
+
if (flyoutExistsInManagerRef.current) {
|
|
163
|
+
closeFlyout(flyoutId);
|
|
164
|
+
}
|
|
150
165
|
|
|
151
166
|
// Reset navigation tracking when explicitly closed via isOpen=false
|
|
152
167
|
wasRegisteredRef.current = false;
|
|
@@ -182,12 +197,6 @@ var EuiManagedFlyout = exports.EuiManagedFlyout = /*#__PURE__*/(0, _react.forwar
|
|
|
182
197
|
onActiveCallbackRef.current();
|
|
183
198
|
}
|
|
184
199
|
}, [currentSession, flyoutId, level]);
|
|
185
|
-
(0, _react.useEffect)(function () {
|
|
186
|
-
return function () {
|
|
187
|
-
// Only remove from manager on component unmount, don't trigger close callback
|
|
188
|
-
closeFlyout(flyoutId);
|
|
189
|
-
};
|
|
190
|
-
}, [closeFlyout, flyoutId]);
|
|
191
200
|
|
|
192
201
|
// Track width changes for flyouts
|
|
193
202
|
var _useResizeObserver = (0, _resize_observer.useResizeObserver)(isActive ? flyoutRef : null, 'width'),
|
|
@@ -195,8 +204,19 @@ var EuiManagedFlyout = exports.EuiManagedFlyout = /*#__PURE__*/(0, _react.forwar
|
|
|
195
204
|
|
|
196
205
|
// Pass the stabilized onClose callback to the flyout menu context
|
|
197
206
|
var onClose = function onClose(e) {
|
|
198
|
-
|
|
199
|
-
|
|
207
|
+
// CRITICAL: Update manager state FIRST before allowing React to unmount
|
|
208
|
+
// This prevents race conditions during portal → inline DOM transitions
|
|
209
|
+
// and ensures cascade close logic runs before DOM cleanup begins
|
|
210
|
+
// Using flushSync to force synchronous state update completion
|
|
211
|
+
(0, _reactDom.flushSync)(function () {
|
|
212
|
+
closeFlyout(flyoutId);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// trigger parent callback, unmounts the component
|
|
216
|
+
if (onCloseCallbackRef.current) {
|
|
217
|
+
var event = e || new MouseEvent('click');
|
|
218
|
+
onCloseCallbackRef.current(event);
|
|
219
|
+
}
|
|
200
220
|
};
|
|
201
221
|
|
|
202
222
|
// Update width in manager state when it changes
|
|
@@ -39,6 +39,12 @@ Object.defineProperty(exports, "flyoutManagerReducer", {
|
|
|
39
39
|
return _reducer.flyoutManagerReducer;
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
|
+
Object.defineProperty(exports, "getFlyoutManagerStore", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function get() {
|
|
45
|
+
return _store.getFlyoutManagerStore;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
42
48
|
Object.defineProperty(exports, "getWidthFromSize", {
|
|
43
49
|
enumerable: true,
|
|
44
50
|
get: function get() {
|
|
@@ -161,6 +167,7 @@ Object.defineProperty(exports, "usePushPaddingOffsets", {
|
|
|
161
167
|
});
|
|
162
168
|
var _actions = require("./actions");
|
|
163
169
|
var _reducer = require("./reducer");
|
|
170
|
+
var _store = require("./store");
|
|
164
171
|
var _provider = require("./provider");
|
|
165
172
|
var _hooks = require("./hooks");
|
|
166
173
|
var _flyout_child = require("./flyout_child");
|
|
@@ -15,10 +15,15 @@ var _reducer = require("./reducer");
|
|
|
15
15
|
* Side Public License, v 1.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Events emitted by the flyout manager store for external consumers.
|
|
20
|
+
*/
|
|
21
|
+
|
|
18
22
|
function createStore() {
|
|
19
23
|
var initial = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _reducer.initialState;
|
|
20
24
|
var currentState = initial;
|
|
21
25
|
var listeners = new Set();
|
|
26
|
+
var eventListeners = new Set();
|
|
22
27
|
var getState = function getState() {
|
|
23
28
|
return currentState;
|
|
24
29
|
};
|
|
@@ -28,6 +33,17 @@ function createStore() {
|
|
|
28
33
|
listeners.delete(listener);
|
|
29
34
|
};
|
|
30
35
|
};
|
|
36
|
+
var subscribeToEvents = function subscribeToEvents(listener) {
|
|
37
|
+
eventListeners.add(listener);
|
|
38
|
+
return function () {
|
|
39
|
+
eventListeners.delete(listener);
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
var emitEvent = function emitEvent(event) {
|
|
43
|
+
eventListeners.forEach(function (listener) {
|
|
44
|
+
listener(event);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
31
47
|
|
|
32
48
|
// The onClick handlers won't execute until after store is fully assigned.
|
|
33
49
|
// eslint-disable-next-line prefer-const -- Forward declaration requires 'let' not 'const'
|
|
@@ -56,6 +72,19 @@ function createStore() {
|
|
|
56
72
|
// This ensures stable references and avoids stale closures
|
|
57
73
|
if (nextState.sessions !== previousSessions) {
|
|
58
74
|
store.historyItems = computeHistoryItems();
|
|
75
|
+
|
|
76
|
+
// Detect removed sessions and emit CLOSE_SESSION events
|
|
77
|
+
var nextSessionIds = new Set(nextState.sessions.map(function (s) {
|
|
78
|
+
return s.mainFlyoutId;
|
|
79
|
+
}));
|
|
80
|
+
previousSessions.forEach(function (session) {
|
|
81
|
+
if (!nextSessionIds.has(session.mainFlyoutId)) {
|
|
82
|
+
emitEvent({
|
|
83
|
+
type: 'CLOSE_SESSION',
|
|
84
|
+
session: session
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
});
|
|
59
88
|
}
|
|
60
89
|
listeners.forEach(function (l) {
|
|
61
90
|
l();
|
|
@@ -65,6 +94,7 @@ function createStore() {
|
|
|
65
94
|
store = {
|
|
66
95
|
getState: getState,
|
|
67
96
|
subscribe: subscribe,
|
|
97
|
+
subscribeToEvents: subscribeToEvents,
|
|
68
98
|
dispatch: dispatch,
|
|
69
99
|
addFlyout: function addFlyout(flyoutId, title, level, size) {
|
|
70
100
|
return dispatch((0, _actions.addFlyout)(flyoutId, title, level, size));
|
|
@@ -221,7 +221,7 @@ var EuiFilePickerClass = exports.EuiFilePickerClass = /*#__PURE__*/function (_Co
|
|
|
221
221
|
css: iconStyles,
|
|
222
222
|
className: "euiFilePicker__icon",
|
|
223
223
|
color: iconColor,
|
|
224
|
-
type: isInvalid ? 'alert' : disabled ? 'minusInCircle' : '
|
|
224
|
+
type: isInvalid ? 'alert' : disabled ? 'minusInCircle' : 'upload',
|
|
225
225
|
size: normalFormControl ? 'm' : 'l',
|
|
226
226
|
"aria-hidden": "true"
|
|
227
227
|
}), (0, _react2.jsx)("span", {
|
|
@@ -16,4 +16,7 @@ export { EuiFlyoutMenu } from './flyout_menu';
|
|
|
16
16
|
|
|
17
17
|
// Hooks for using Manager-based flyouts
|
|
18
18
|
export { useIsInManagedFlyout, useHasActiveSession } from './manager';
|
|
19
|
-
export { useIsInsideParentFlyout } from './flyout_parent_context';
|
|
19
|
+
export { useIsInsideParentFlyout } from './flyout_parent_context';
|
|
20
|
+
|
|
21
|
+
// Flyout manager store (for cross-root state synchronization)
|
|
22
|
+
export { getFlyoutManagerStore } from './manager';
|
|
@@ -13,7 +13,8 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
13
13
|
* Side Public License, v 1.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import React, { useEffect, useMemo, useRef, useState, forwardRef } from 'react';
|
|
16
|
+
import React, { useEffect, useLayoutEffect, useMemo, useRef, useState, forwardRef } from 'react';
|
|
17
|
+
import { flushSync } from 'react-dom';
|
|
17
18
|
import { useCombinedRefs, useEuiMemoizedStyles } from '../../../services';
|
|
18
19
|
import { useEuiI18n } from '../../i18n';
|
|
19
20
|
import { useResizeObserver } from '../../observer/resize_observer';
|
|
@@ -125,11 +126,25 @@ export var EuiManagedFlyout = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
125
126
|
// Track if flyout was ever registered to avoid false positives on initial mount
|
|
126
127
|
var wasRegisteredRef = useRef(false);
|
|
127
128
|
|
|
128
|
-
//
|
|
129
|
+
// Track flyoutExistsInManager in a ref to avoid dependency loop
|
|
130
|
+
// The cleanup function needs the current value but shouldn't cause re-runs
|
|
131
|
+
var flyoutExistsInManagerRef = useRef(flyoutExistsInManager);
|
|
132
|
+
|
|
133
|
+
// Update ref when flyoutExistsInManager changes
|
|
129
134
|
useEffect(function () {
|
|
135
|
+
flyoutExistsInManagerRef.current = flyoutExistsInManager;
|
|
136
|
+
}, [flyoutExistsInManager]);
|
|
137
|
+
|
|
138
|
+
// Register with flyout manager context when open, remove when closed
|
|
139
|
+
// Using useLayoutEffect to run synchronously before DOM updates
|
|
140
|
+
useLayoutEffect(function () {
|
|
130
141
|
addFlyout(flyoutId, title, level, size);
|
|
131
142
|
return function () {
|
|
132
|
-
closeFlyout
|
|
143
|
+
// Only call closeFlyout if it wasn't already called via onClose
|
|
144
|
+
// This prevents duplicate removal when using Escape/X button
|
|
145
|
+
if (flyoutExistsInManagerRef.current) {
|
|
146
|
+
closeFlyout(flyoutId);
|
|
147
|
+
}
|
|
133
148
|
|
|
134
149
|
// Reset navigation tracking when explicitly closed via isOpen=false
|
|
135
150
|
wasRegisteredRef.current = false;
|
|
@@ -165,12 +180,6 @@ export var EuiManagedFlyout = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
165
180
|
onActiveCallbackRef.current();
|
|
166
181
|
}
|
|
167
182
|
}, [currentSession, flyoutId, level]);
|
|
168
|
-
useEffect(function () {
|
|
169
|
-
return function () {
|
|
170
|
-
// Only remove from manager on component unmount, don't trigger close callback
|
|
171
|
-
closeFlyout(flyoutId);
|
|
172
|
-
};
|
|
173
|
-
}, [closeFlyout, flyoutId]);
|
|
174
183
|
|
|
175
184
|
// Track width changes for flyouts
|
|
176
185
|
var _useResizeObserver = useResizeObserver(isActive ? flyoutRef : null, 'width'),
|
|
@@ -178,8 +187,19 @@ export var EuiManagedFlyout = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
178
187
|
|
|
179
188
|
// Pass the stabilized onClose callback to the flyout menu context
|
|
180
189
|
var onClose = function onClose(e) {
|
|
181
|
-
|
|
182
|
-
|
|
190
|
+
// CRITICAL: Update manager state FIRST before allowing React to unmount
|
|
191
|
+
// This prevents race conditions during portal → inline DOM transitions
|
|
192
|
+
// and ensures cascade close logic runs before DOM cleanup begins
|
|
193
|
+
// Using flushSync to force synchronous state update completion
|
|
194
|
+
flushSync(function () {
|
|
195
|
+
closeFlyout(flyoutId);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// trigger parent callback, unmounts the component
|
|
199
|
+
if (onCloseCallbackRef.current) {
|
|
200
|
+
var event = e || new MouseEvent('click');
|
|
201
|
+
onCloseCallbackRef.current(event);
|
|
202
|
+
}
|
|
183
203
|
};
|
|
184
204
|
|
|
185
205
|
// Update width in manager state when it changes
|
|
@@ -14,6 +14,8 @@ export { addFlyout as addFlyoutAction, closeFlyout as closeFlyoutAction, setActi
|
|
|
14
14
|
/** Reducer and default state for the flyout manager. */
|
|
15
15
|
export { flyoutManagerReducer, initialState } from './reducer';
|
|
16
16
|
|
|
17
|
+
/** Flyout manager store singleton and types. */
|
|
18
|
+
export { getFlyoutManagerStore } from './store';
|
|
17
19
|
/** Provider component exposing the Flyout Manager API via context. */
|
|
18
20
|
export { EuiFlyoutManager } from './provider';
|
|
19
21
|
|
|
@@ -8,10 +8,16 @@
|
|
|
8
8
|
|
|
9
9
|
import { addFlyout as addFlyoutAction, closeFlyout as closeFlyoutAction, setActiveFlyout as setActiveFlyoutAction, setFlyoutWidth as setFlyoutWidthAction, setPushPadding as setPushPaddingAction, goBack as goBackAction, goToFlyout as goToFlyoutAction, addUnmanagedFlyout as addUnmanagedFlyoutAction, closeUnmanagedFlyout as closeUnmanagedFlyoutAction } from './actions';
|
|
10
10
|
import { flyoutManagerReducer, initialState } from './reducer';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Events emitted by the flyout manager store for external consumers.
|
|
14
|
+
*/
|
|
15
|
+
|
|
11
16
|
function createStore() {
|
|
12
17
|
var initial = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
|
|
13
18
|
var currentState = initial;
|
|
14
19
|
var listeners = new Set();
|
|
20
|
+
var eventListeners = new Set();
|
|
15
21
|
var getState = function getState() {
|
|
16
22
|
return currentState;
|
|
17
23
|
};
|
|
@@ -21,6 +27,17 @@ function createStore() {
|
|
|
21
27
|
listeners.delete(listener);
|
|
22
28
|
};
|
|
23
29
|
};
|
|
30
|
+
var subscribeToEvents = function subscribeToEvents(listener) {
|
|
31
|
+
eventListeners.add(listener);
|
|
32
|
+
return function () {
|
|
33
|
+
eventListeners.delete(listener);
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
var emitEvent = function emitEvent(event) {
|
|
37
|
+
eventListeners.forEach(function (listener) {
|
|
38
|
+
listener(event);
|
|
39
|
+
});
|
|
40
|
+
};
|
|
24
41
|
|
|
25
42
|
// The onClick handlers won't execute until after store is fully assigned.
|
|
26
43
|
// eslint-disable-next-line prefer-const -- Forward declaration requires 'let' not 'const'
|
|
@@ -49,6 +66,19 @@ function createStore() {
|
|
|
49
66
|
// This ensures stable references and avoids stale closures
|
|
50
67
|
if (nextState.sessions !== previousSessions) {
|
|
51
68
|
store.historyItems = computeHistoryItems();
|
|
69
|
+
|
|
70
|
+
// Detect removed sessions and emit CLOSE_SESSION events
|
|
71
|
+
var nextSessionIds = new Set(nextState.sessions.map(function (s) {
|
|
72
|
+
return s.mainFlyoutId;
|
|
73
|
+
}));
|
|
74
|
+
previousSessions.forEach(function (session) {
|
|
75
|
+
if (!nextSessionIds.has(session.mainFlyoutId)) {
|
|
76
|
+
emitEvent({
|
|
77
|
+
type: 'CLOSE_SESSION',
|
|
78
|
+
session: session
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
});
|
|
52
82
|
}
|
|
53
83
|
listeners.forEach(function (l) {
|
|
54
84
|
l();
|
|
@@ -58,6 +88,7 @@ function createStore() {
|
|
|
58
88
|
store = {
|
|
59
89
|
getState: getState,
|
|
60
90
|
subscribe: subscribe,
|
|
91
|
+
subscribeToEvents: subscribeToEvents,
|
|
61
92
|
dispatch: dispatch,
|
|
62
93
|
addFlyout: function addFlyout(flyoutId, title, level, size) {
|
|
63
94
|
return dispatch(addFlyoutAction(flyoutId, title, level, size));
|
|
@@ -201,7 +201,7 @@ export var EuiFilePickerClass = /*#__PURE__*/function (_Component) {
|
|
|
201
201
|
css: iconStyles,
|
|
202
202
|
className: "euiFilePicker__icon",
|
|
203
203
|
color: iconColor,
|
|
204
|
-
type: isInvalid ? 'alert' : disabled ? 'minusInCircle' : '
|
|
204
|
+
type: isInvalid ? 'alert' : disabled ? 'minusInCircle' : 'upload',
|
|
205
205
|
size: normalFormControl ? 'm' : 'l',
|
|
206
206
|
"aria-hidden": "true"
|
|
207
207
|
}), ___EmotionJSX("span", {
|
|
@@ -51,6 +51,12 @@ Object.defineProperty(exports, "euiFlyoutSlideInRight", {
|
|
|
51
51
|
return _flyout2.euiFlyoutSlideInRight;
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
|
+
Object.defineProperty(exports, "getFlyoutManagerStore", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function get() {
|
|
57
|
+
return _manager.getFlyoutManagerStore;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
54
60
|
Object.defineProperty(exports, "useHasActiveSession", {
|
|
55
61
|
enumerable: true,
|
|
56
62
|
get: function get() {
|
|
@@ -11,6 +11,7 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
|
|
|
11
11
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
12
12
|
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
13
13
|
var _react = _interopRequireWildcard(require("react"));
|
|
14
|
+
var _reactDom = require("react-dom");
|
|
14
15
|
var _services = require("../../../services");
|
|
15
16
|
var _i18n = require("../../i18n");
|
|
16
17
|
var _resize_observer = require("../../observer/resize_observer");
|
|
@@ -133,11 +134,25 @@ var EuiManagedFlyout = exports.EuiManagedFlyout = /*#__PURE__*/(0, _react.forwar
|
|
|
133
134
|
// Track if flyout was ever registered to avoid false positives on initial mount
|
|
134
135
|
var wasRegisteredRef = (0, _react.useRef)(false);
|
|
135
136
|
|
|
136
|
-
//
|
|
137
|
+
// Track flyoutExistsInManager in a ref to avoid dependency loop
|
|
138
|
+
// The cleanup function needs the current value but shouldn't cause re-runs
|
|
139
|
+
var flyoutExistsInManagerRef = (0, _react.useRef)(flyoutExistsInManager);
|
|
140
|
+
|
|
141
|
+
// Update ref when flyoutExistsInManager changes
|
|
137
142
|
(0, _react.useEffect)(function () {
|
|
143
|
+
flyoutExistsInManagerRef.current = flyoutExistsInManager;
|
|
144
|
+
}, [flyoutExistsInManager]);
|
|
145
|
+
|
|
146
|
+
// Register with flyout manager context when open, remove when closed
|
|
147
|
+
// Using useLayoutEffect to run synchronously before DOM updates
|
|
148
|
+
(0, _react.useLayoutEffect)(function () {
|
|
138
149
|
addFlyout(flyoutId, title, level, size);
|
|
139
150
|
return function () {
|
|
140
|
-
closeFlyout
|
|
151
|
+
// Only call closeFlyout if it wasn't already called via onClose
|
|
152
|
+
// This prevents duplicate removal when using Escape/X button
|
|
153
|
+
if (flyoutExistsInManagerRef.current) {
|
|
154
|
+
closeFlyout(flyoutId);
|
|
155
|
+
}
|
|
141
156
|
|
|
142
157
|
// Reset navigation tracking when explicitly closed via isOpen=false
|
|
143
158
|
wasRegisteredRef.current = false;
|
|
@@ -173,12 +188,6 @@ var EuiManagedFlyout = exports.EuiManagedFlyout = /*#__PURE__*/(0, _react.forwar
|
|
|
173
188
|
onActiveCallbackRef.current();
|
|
174
189
|
}
|
|
175
190
|
}, [currentSession, flyoutId, level]);
|
|
176
|
-
(0, _react.useEffect)(function () {
|
|
177
|
-
return function () {
|
|
178
|
-
// Only remove from manager on component unmount, don't trigger close callback
|
|
179
|
-
closeFlyout(flyoutId);
|
|
180
|
-
};
|
|
181
|
-
}, [closeFlyout, flyoutId]);
|
|
182
191
|
|
|
183
192
|
// Track width changes for flyouts
|
|
184
193
|
var _useResizeObserver = (0, _resize_observer.useResizeObserver)(isActive ? flyoutRef : null, 'width'),
|
|
@@ -186,8 +195,19 @@ var EuiManagedFlyout = exports.EuiManagedFlyout = /*#__PURE__*/(0, _react.forwar
|
|
|
186
195
|
|
|
187
196
|
// Pass the stabilized onClose callback to the flyout menu context
|
|
188
197
|
var onClose = function onClose(e) {
|
|
189
|
-
|
|
190
|
-
|
|
198
|
+
// CRITICAL: Update manager state FIRST before allowing React to unmount
|
|
199
|
+
// This prevents race conditions during portal → inline DOM transitions
|
|
200
|
+
// and ensures cascade close logic runs before DOM cleanup begins
|
|
201
|
+
// Using flushSync to force synchronous state update completion
|
|
202
|
+
(0, _reactDom.flushSync)(function () {
|
|
203
|
+
closeFlyout(flyoutId);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// trigger parent callback, unmounts the component
|
|
207
|
+
if (onCloseCallbackRef.current) {
|
|
208
|
+
var event = e || new MouseEvent('click');
|
|
209
|
+
onCloseCallbackRef.current(event);
|
|
210
|
+
}
|
|
191
211
|
};
|
|
192
212
|
|
|
193
213
|
// Update width in manager state when it changes
|
|
@@ -39,6 +39,12 @@ Object.defineProperty(exports, "flyoutManagerReducer", {
|
|
|
39
39
|
return _reducer.flyoutManagerReducer;
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
|
+
Object.defineProperty(exports, "getFlyoutManagerStore", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function get() {
|
|
45
|
+
return _store.getFlyoutManagerStore;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
42
48
|
Object.defineProperty(exports, "getWidthFromSize", {
|
|
43
49
|
enumerable: true,
|
|
44
50
|
get: function get() {
|
|
@@ -161,6 +167,7 @@ Object.defineProperty(exports, "usePushPaddingOffsets", {
|
|
|
161
167
|
});
|
|
162
168
|
var _actions = require("./actions");
|
|
163
169
|
var _reducer = require("./reducer");
|
|
170
|
+
var _store = require("./store");
|
|
164
171
|
var _provider = require("./provider");
|
|
165
172
|
var _hooks = require("./hooks");
|
|
166
173
|
var _flyout_child = require("./flyout_child");
|
|
@@ -15,10 +15,15 @@ var _reducer = require("./reducer");
|
|
|
15
15
|
* Side Public License, v 1.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Events emitted by the flyout manager store for external consumers.
|
|
20
|
+
*/
|
|
21
|
+
|
|
18
22
|
function createStore() {
|
|
19
23
|
var initial = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _reducer.initialState;
|
|
20
24
|
var currentState = initial;
|
|
21
25
|
var listeners = new Set();
|
|
26
|
+
var eventListeners = new Set();
|
|
22
27
|
var getState = function getState() {
|
|
23
28
|
return currentState;
|
|
24
29
|
};
|
|
@@ -28,6 +33,17 @@ function createStore() {
|
|
|
28
33
|
listeners.delete(listener);
|
|
29
34
|
};
|
|
30
35
|
};
|
|
36
|
+
var subscribeToEvents = function subscribeToEvents(listener) {
|
|
37
|
+
eventListeners.add(listener);
|
|
38
|
+
return function () {
|
|
39
|
+
eventListeners.delete(listener);
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
var emitEvent = function emitEvent(event) {
|
|
43
|
+
eventListeners.forEach(function (listener) {
|
|
44
|
+
listener(event);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
31
47
|
|
|
32
48
|
// The onClick handlers won't execute until after store is fully assigned.
|
|
33
49
|
// eslint-disable-next-line prefer-const -- Forward declaration requires 'let' not 'const'
|
|
@@ -56,6 +72,19 @@ function createStore() {
|
|
|
56
72
|
// This ensures stable references and avoids stale closures
|
|
57
73
|
if (nextState.sessions !== previousSessions) {
|
|
58
74
|
store.historyItems = computeHistoryItems();
|
|
75
|
+
|
|
76
|
+
// Detect removed sessions and emit CLOSE_SESSION events
|
|
77
|
+
var nextSessionIds = new Set(nextState.sessions.map(function (s) {
|
|
78
|
+
return s.mainFlyoutId;
|
|
79
|
+
}));
|
|
80
|
+
previousSessions.forEach(function (session) {
|
|
81
|
+
if (!nextSessionIds.has(session.mainFlyoutId)) {
|
|
82
|
+
emitEvent({
|
|
83
|
+
type: 'CLOSE_SESSION',
|
|
84
|
+
session: session
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
});
|
|
59
88
|
}
|
|
60
89
|
listeners.forEach(function (l) {
|
|
61
90
|
l();
|
|
@@ -65,6 +94,7 @@ function createStore() {
|
|
|
65
94
|
store = {
|
|
66
95
|
getState: getState,
|
|
67
96
|
subscribe: subscribe,
|
|
97
|
+
subscribeToEvents: subscribeToEvents,
|
|
68
98
|
dispatch: dispatch,
|
|
69
99
|
addFlyout: function addFlyout(flyoutId, title, level, size) {
|
|
70
100
|
return dispatch((0, _actions.addFlyout)(flyoutId, title, level, size));
|
|
@@ -209,7 +209,7 @@ var EuiFilePickerClass = exports.EuiFilePickerClass = /*#__PURE__*/function (_Co
|
|
|
209
209
|
css: iconStyles,
|
|
210
210
|
className: "euiFilePicker__icon",
|
|
211
211
|
color: iconColor,
|
|
212
|
-
type: isInvalid ? 'alert' : disabled ? 'minusInCircle' : '
|
|
212
|
+
type: isInvalid ? 'alert' : disabled ? 'minusInCircle' : 'upload',
|
|
213
213
|
size: normalFormControl ? 'm' : 'l',
|
|
214
214
|
"aria-hidden": "true"
|
|
215
215
|
}), (0, _react2.jsx)("span", {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elastic/eui",
|
|
3
3
|
"description": "Elastic UI Component Library",
|
|
4
|
-
"version": "112.
|
|
4
|
+
"version": "112.3.0",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"main": "lib",
|
|
7
7
|
"module": "es",
|
|
@@ -281,6 +281,5 @@
|
|
|
281
281
|
],
|
|
282
282
|
"installConfig": {
|
|
283
283
|
"hoistingLimits": "workspaces"
|
|
284
|
-
}
|
|
285
|
-
"stableVersion": "112.2.0"
|
|
284
|
+
}
|
|
286
285
|
}
|
|
@@ -51,6 +51,12 @@ Object.defineProperty(exports, "euiFlyoutSlideInRight", {
|
|
|
51
51
|
return _flyout2.euiFlyoutSlideInRight;
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
|
+
Object.defineProperty(exports, "getFlyoutManagerStore", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function get() {
|
|
57
|
+
return _manager.getFlyoutManagerStore;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
54
60
|
Object.defineProperty(exports, "useHasActiveSession", {
|
|
55
61
|
enumerable: true,
|
|
56
62
|
get: function get() {
|
|
@@ -12,6 +12,7 @@ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/sli
|
|
|
12
12
|
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
13
13
|
var _react = _interopRequireWildcard(require("react"));
|
|
14
14
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
15
|
+
var _reactDom = require("react-dom");
|
|
15
16
|
var _services = require("../../../services");
|
|
16
17
|
var _i18n = require("../../i18n");
|
|
17
18
|
var _resize_observer = require("../../observer/resize_observer");
|
|
@@ -134,11 +135,25 @@ var EuiManagedFlyout = exports.EuiManagedFlyout = /*#__PURE__*/(0, _react.forwar
|
|
|
134
135
|
// Track if flyout was ever registered to avoid false positives on initial mount
|
|
135
136
|
var wasRegisteredRef = (0, _react.useRef)(false);
|
|
136
137
|
|
|
137
|
-
//
|
|
138
|
+
// Track flyoutExistsInManager in a ref to avoid dependency loop
|
|
139
|
+
// The cleanup function needs the current value but shouldn't cause re-runs
|
|
140
|
+
var flyoutExistsInManagerRef = (0, _react.useRef)(flyoutExistsInManager);
|
|
141
|
+
|
|
142
|
+
// Update ref when flyoutExistsInManager changes
|
|
138
143
|
(0, _react.useEffect)(function () {
|
|
144
|
+
flyoutExistsInManagerRef.current = flyoutExistsInManager;
|
|
145
|
+
}, [flyoutExistsInManager]);
|
|
146
|
+
|
|
147
|
+
// Register with flyout manager context when open, remove when closed
|
|
148
|
+
// Using useLayoutEffect to run synchronously before DOM updates
|
|
149
|
+
(0, _react.useLayoutEffect)(function () {
|
|
139
150
|
addFlyout(flyoutId, title, level, size);
|
|
140
151
|
return function () {
|
|
141
|
-
closeFlyout
|
|
152
|
+
// Only call closeFlyout if it wasn't already called via onClose
|
|
153
|
+
// This prevents duplicate removal when using Escape/X button
|
|
154
|
+
if (flyoutExistsInManagerRef.current) {
|
|
155
|
+
closeFlyout(flyoutId);
|
|
156
|
+
}
|
|
142
157
|
|
|
143
158
|
// Reset navigation tracking when explicitly closed via isOpen=false
|
|
144
159
|
wasRegisteredRef.current = false;
|
|
@@ -174,12 +189,6 @@ var EuiManagedFlyout = exports.EuiManagedFlyout = /*#__PURE__*/(0, _react.forwar
|
|
|
174
189
|
onActiveCallbackRef.current();
|
|
175
190
|
}
|
|
176
191
|
}, [currentSession, flyoutId, level]);
|
|
177
|
-
(0, _react.useEffect)(function () {
|
|
178
|
-
return function () {
|
|
179
|
-
// Only remove from manager on component unmount, don't trigger close callback
|
|
180
|
-
closeFlyout(flyoutId);
|
|
181
|
-
};
|
|
182
|
-
}, [closeFlyout, flyoutId]);
|
|
183
192
|
|
|
184
193
|
// Track width changes for flyouts
|
|
185
194
|
var _useResizeObserver = (0, _resize_observer.useResizeObserver)(isActive ? flyoutRef : null, 'width'),
|
|
@@ -187,8 +196,19 @@ var EuiManagedFlyout = exports.EuiManagedFlyout = /*#__PURE__*/(0, _react.forwar
|
|
|
187
196
|
|
|
188
197
|
// Pass the stabilized onClose callback to the flyout menu context
|
|
189
198
|
var onClose = function onClose(e) {
|
|
190
|
-
|
|
191
|
-
|
|
199
|
+
// CRITICAL: Update manager state FIRST before allowing React to unmount
|
|
200
|
+
// This prevents race conditions during portal → inline DOM transitions
|
|
201
|
+
// and ensures cascade close logic runs before DOM cleanup begins
|
|
202
|
+
// Using flushSync to force synchronous state update completion
|
|
203
|
+
(0, _reactDom.flushSync)(function () {
|
|
204
|
+
closeFlyout(flyoutId);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// trigger parent callback, unmounts the component
|
|
208
|
+
if (onCloseCallbackRef.current) {
|
|
209
|
+
var event = e || new MouseEvent('click');
|
|
210
|
+
onCloseCallbackRef.current(event);
|
|
211
|
+
}
|
|
192
212
|
};
|
|
193
213
|
|
|
194
214
|
// Update width in manager state when it changes
|
|
@@ -39,6 +39,12 @@ Object.defineProperty(exports, "flyoutManagerReducer", {
|
|
|
39
39
|
return _reducer.flyoutManagerReducer;
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
|
+
Object.defineProperty(exports, "getFlyoutManagerStore", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function get() {
|
|
45
|
+
return _store.getFlyoutManagerStore;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
42
48
|
Object.defineProperty(exports, "getWidthFromSize", {
|
|
43
49
|
enumerable: true,
|
|
44
50
|
get: function get() {
|
|
@@ -161,6 +167,7 @@ Object.defineProperty(exports, "usePushPaddingOffsets", {
|
|
|
161
167
|
});
|
|
162
168
|
var _actions = require("./actions");
|
|
163
169
|
var _reducer = require("./reducer");
|
|
170
|
+
var _store = require("./store");
|
|
164
171
|
var _provider = require("./provider");
|
|
165
172
|
var _hooks = require("./hooks");
|
|
166
173
|
var _flyout_child = require("./flyout_child");
|
|
@@ -15,10 +15,15 @@ var _reducer = require("./reducer");
|
|
|
15
15
|
* Side Public License, v 1.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Events emitted by the flyout manager store for external consumers.
|
|
20
|
+
*/
|
|
21
|
+
|
|
18
22
|
function createStore() {
|
|
19
23
|
var initial = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _reducer.initialState;
|
|
20
24
|
var currentState = initial;
|
|
21
25
|
var listeners = new Set();
|
|
26
|
+
var eventListeners = new Set();
|
|
22
27
|
var getState = function getState() {
|
|
23
28
|
return currentState;
|
|
24
29
|
};
|
|
@@ -28,6 +33,17 @@ function createStore() {
|
|
|
28
33
|
listeners.delete(listener);
|
|
29
34
|
};
|
|
30
35
|
};
|
|
36
|
+
var subscribeToEvents = function subscribeToEvents(listener) {
|
|
37
|
+
eventListeners.add(listener);
|
|
38
|
+
return function () {
|
|
39
|
+
eventListeners.delete(listener);
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
var emitEvent = function emitEvent(event) {
|
|
43
|
+
eventListeners.forEach(function (listener) {
|
|
44
|
+
listener(event);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
31
47
|
|
|
32
48
|
// The onClick handlers won't execute until after store is fully assigned.
|
|
33
49
|
// eslint-disable-next-line prefer-const -- Forward declaration requires 'let' not 'const'
|
|
@@ -56,6 +72,19 @@ function createStore() {
|
|
|
56
72
|
// This ensures stable references and avoids stale closures
|
|
57
73
|
if (nextState.sessions !== previousSessions) {
|
|
58
74
|
store.historyItems = computeHistoryItems();
|
|
75
|
+
|
|
76
|
+
// Detect removed sessions and emit CLOSE_SESSION events
|
|
77
|
+
var nextSessionIds = new Set(nextState.sessions.map(function (s) {
|
|
78
|
+
return s.mainFlyoutId;
|
|
79
|
+
}));
|
|
80
|
+
previousSessions.forEach(function (session) {
|
|
81
|
+
if (!nextSessionIds.has(session.mainFlyoutId)) {
|
|
82
|
+
emitEvent({
|
|
83
|
+
type: 'CLOSE_SESSION',
|
|
84
|
+
session: session
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
});
|
|
59
88
|
}
|
|
60
89
|
listeners.forEach(function (l) {
|
|
61
90
|
l();
|
|
@@ -65,6 +94,7 @@ function createStore() {
|
|
|
65
94
|
store = {
|
|
66
95
|
getState: getState,
|
|
67
96
|
subscribe: subscribe,
|
|
97
|
+
subscribeToEvents: subscribeToEvents,
|
|
68
98
|
dispatch: dispatch,
|
|
69
99
|
addFlyout: function addFlyout(flyoutId, title, level, size) {
|
|
70
100
|
return dispatch((0, _actions.addFlyout)(flyoutId, title, level, size));
|
|
@@ -210,7 +210,7 @@ var EuiFilePickerClass = exports.EuiFilePickerClass = /*#__PURE__*/function (_Co
|
|
|
210
210
|
css: iconStyles,
|
|
211
211
|
className: "euiFilePicker__icon",
|
|
212
212
|
color: iconColor,
|
|
213
|
-
type: isInvalid ? 'alert' : disabled ? 'minusInCircle' : '
|
|
213
|
+
type: isInvalid ? 'alert' : disabled ? 'minusInCircle' : 'upload',
|
|
214
214
|
size: normalFormControl ? 'm' : 'l',
|
|
215
215
|
"aria-hidden": "true"
|
|
216
216
|
}), (0, _react2.jsx)("span", {
|