baseui 0.0.0-next-887e00c → 0.0.0-next-1598215

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.
@@ -43,8 +43,6 @@ export default function MaybeChildMenu(props) {
43
43
  overrides: mergeOverrides({
44
44
  Body: {
45
45
  props: {
46
- // Adds mouseleave to popover body so that child menu closes when user mouses out.
47
- onMouseLeave: props.resetParentMenu,
48
46
  // Trap tabbing when focused on a child menu. Popover mounts the element at the end of
49
47
  // the html body by default. If a user was to tab to the next element it would navigate
50
48
  // to elements not within the immediate area surrounding the menu.
@@ -12,6 +12,8 @@ export const NestedMenuContext = /*#__PURE__*/React.createContext({
12
12
  removeMenuFromNesting: () => {},
13
13
  getParentMenu: () => {},
14
14
  getChildMenu: () => {},
15
+ nestedMenuHoverIndex: -1,
16
+ isNestedMenuVisible: () => false,
15
17
  mountRef: {
16
18
  current: null
17
19
  }
@@ -30,16 +32,43 @@ export default class NestedMenus extends React.Component {
30
32
  super(...args);
31
33
 
32
34
  _defineProperty(this, "state", {
33
- menus: []
35
+ menus: [],
36
+ nestedMenuHoverIndex: -1
34
37
  });
35
38
 
36
39
  _defineProperty(this, "mountRef", /*#__PURE__*/React.createRef());
37
40
 
41
+ _defineProperty(this, "mouseLeaveTimeoueId", null);
42
+
43
+ _defineProperty(this, "handleMenuMouseLeave", event => {
44
+ this.mouseLeaveTimeoueId = setTimeout(() => {
45
+ this.setState({
46
+ nestedMenuHoverIndex: -1
47
+ });
48
+ }, 200);
49
+ });
50
+
51
+ _defineProperty(this, "handleMenuMouseEnter", event => {
52
+ if (typeof document !== 'undefined') {
53
+ clearTimeout(this.mouseLeaveTimeoueId);
54
+ const index = this.state.menus.findIndex(m => {
55
+ return m.current && event.currentTarget instanceof Node && m.current.contains(event.currentTarget);
56
+ });
57
+ this.setState({
58
+ nestedMenuHoverIndex: index
59
+ });
60
+ }
61
+ });
62
+
38
63
  _defineProperty(this, "addMenuToNesting", ref => {
39
64
  // check offsetHeight to determine if component is visible in the dom (0 means hidden)
40
65
  // we need to do this so that when we renderAll, the hidden seo-only child-menus don't
41
66
  // register themselves which would break the nesting logic
42
- if (ref.current && ref.current.offsetHeight) {
67
+ const element = ref.current;
68
+
69
+ if (element && element.offsetHeight) {
70
+ element.addEventListener('mouseenter', this.handleMenuMouseEnter);
71
+ element.addEventListener('mouseleave', this.handleMenuMouseLeave);
43
72
  this.setState(state => {
44
73
  return {
45
74
  menus: [...state.menus, ref]
@@ -50,7 +79,17 @@ export default class NestedMenus extends React.Component {
50
79
 
51
80
  _defineProperty(this, "removeMenuFromNesting", ref => {
52
81
  this.setState(state => {
53
- const nextMenus = state.menus.filter(r => r.current).filter(r => !isSame(r.current, ref.current));
82
+ for (const r of this.state.menus) {
83
+ if (r.current && isSame(r.current, ref.current)) {
84
+ const element = r.current;
85
+ element.removeEventListener('mouseenter', this.handleMenuMouseEnter);
86
+ element.removeEventListener('mouseleave', this.handleMenuMouseLeave);
87
+ }
88
+ }
89
+
90
+ const nextMenus = state.menus.filter(r => {
91
+ return r.current && !isSame(r.current, ref.current);
92
+ });
54
93
  return {
55
94
  menus: nextMenus
56
95
  };
@@ -70,6 +109,11 @@ export default class NestedMenus extends React.Component {
70
109
  const index = this.findMenuIndexByRef(ref) + 1;
71
110
  return this.state.menus[index];
72
111
  });
112
+
113
+ _defineProperty(this, "isNestedMenuVisible", ref => {
114
+ const index = this.findMenuIndexByRef(ref);
115
+ return index <= this.state.nestedMenuHoverIndex;
116
+ });
73
117
  }
74
118
 
75
119
  render() {
@@ -79,6 +123,8 @@ export default class NestedMenus extends React.Component {
79
123
  removeMenuFromNesting: this.removeMenuFromNesting,
80
124
  getParentMenu: this.getParentMenu,
81
125
  getChildMenu: this.getChildMenu,
126
+ isNestedMenuVisible: this.isNestedMenuVisible,
127
+ nestedMenuHoverIndex: this.state.nestedMenuHoverIndex,
82
128
  mountRef: this.mountRef
83
129
  }
84
130
  }, /*#__PURE__*/React.createElement(React.Fragment, null, this.props.children, /*#__PURE__*/React.createElement("span", {
@@ -34,6 +34,8 @@ const DEFAULT_PROPS = {
34
34
  removeMenuFromNesting: () => {},
35
35
  getParentMenu: () => {},
36
36
  getChildMenu: () => {},
37
+ nestedMenuHoverIndex: -1,
38
+ isNestedMenuVisible: () => false,
37
39
  forceHighlight: false
38
40
  };
39
41
 
@@ -223,16 +225,7 @@ class MenuStatefulContainerInner extends React.Component {
223
225
  });
224
226
  });
225
227
 
226
- _defineProperty(this, "handleMouseLeave", () => {
227
- const rootRef = this.props.rootRef ? this.props.rootRef : this.rootRef;
228
- const childMenu = this.props.getChildMenu && this.props.getChildMenu(rootRef);
229
-
230
- if (!this.props.forceHighlight && !childMenu) {
231
- this.internalSetState(STATE_CHANGE_TYPES.mouseLeave, {
232
- highlightedIndex: -1
233
- });
234
- }
235
- });
228
+ _defineProperty(this, "handleMouseLeave", event => {});
236
229
 
237
230
  _defineProperty(this, "getRequiredItemProps", (item, index) => {
238
231
  let itemRef = this.refList[index];
@@ -339,10 +332,12 @@ class MenuStatefulContainerInner extends React.Component {
339
332
  if (this.keyboardControlNode) this.keyboardControlNode.removeEventListener('keydown', this.onKeyDown);
340
333
  }
341
334
 
342
- this.props.removeMenuFromNesting && this.props.removeMenuFromNesting(rootRef);
335
+ if (this.props.removeMenuFromNesting) {
336
+ this.props.removeMenuFromNesting(rootRef);
337
+ }
343
338
  }
344
339
 
345
- componentDidUpdate(_, prevState) {
340
+ componentDidUpdate(prevProps, prevState) {
346
341
  if (typeof document !== 'undefined') {
347
342
  if (!prevState.isFocused && this.state.isFocused) {
348
343
  if (this.keyboardControlNode) this.keyboardControlNode.addEventListener('keydown', this.onKeyDown);
@@ -368,6 +363,12 @@ class MenuStatefulContainerInner extends React.Component {
368
363
  highlightedIndex: 0
369
364
  });
370
365
  }
366
+
367
+ if (this.props.isNestedMenuVisible && this.props.nestedMenuHoverIndex !== prevProps.nestedMenuHoverIndex && !this.props.isNestedMenuVisible(this.rootRef) && !this.props.forceHighlight) {
368
+ this.setState({
369
+ highlightedIndex: -1
370
+ });
371
+ }
371
372
  } // One array to hold all of list item refs
372
373
 
373
374
 
@@ -736,7 +736,7 @@ class Select extends React.Component {
736
736
  "aria-required": this.props.required || null,
737
737
  onFocus: this.handleInputFocus,
738
738
  tabIndex: 0
739
- }, sharedProps, inputContainerProps), /*#__PURE__*/React.createElement("input", {
739
+ }, sharedProps, inputContainerProps), /*#__PURE__*/React.createElement("input", _extends({
740
740
  "aria-hidden": true,
741
741
  id: this.props.id || null,
742
742
  ref: this.handleInputRef,
@@ -748,7 +748,7 @@ class Select extends React.Component {
748
748
  padding: 0
749
749
  },
750
750
  tabIndex: -1
751
- }));
751
+ }, overrides.Input ? overrides.Input.props ? overrides.Input.props : {} : {})));
752
752
  }
753
753
 
754
754
  return /*#__PURE__*/React.createElement(InputContainer, _extends({}, sharedProps, inputContainerProps), /*#__PURE__*/React.createElement(AutosizeInput, _extends({
@@ -59,8 +59,6 @@ export default function MaybeChildMenu(props) {
59
59
  overrides: mergeOverrides({
60
60
  Body: {
61
61
  props: {
62
- // Adds mouseleave to popover body so that child menu closes when user mouses out.
63
- onMouseLeave: props.resetParentMenu,
64
62
  // Trap tabbing when focused on a child menu. Popover mounts the element at the end of
65
63
  // the html body by default. If a user was to tab to the next element it would navigate
66
64
  // to elements not within the immediate area surrounding the menu.
@@ -1,5 +1,7 @@
1
1
  function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
2
2
 
3
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
4
+
3
5
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
4
6
 
5
7
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -46,6 +48,10 @@ export var NestedMenuContext = /*#__PURE__*/React.createContext({
46
48
  removeMenuFromNesting: function removeMenuFromNesting() {},
47
49
  getParentMenu: function getParentMenu() {},
48
50
  getChildMenu: function getChildMenu() {},
51
+ nestedMenuHoverIndex: -1,
52
+ isNestedMenuVisible: function isNestedMenuVisible() {
53
+ return false;
54
+ },
49
55
  mountRef: {
50
56
  current: null
51
57
  }
@@ -76,16 +82,46 @@ var NestedMenus = /*#__PURE__*/function (_React$Component) {
76
82
  _this = _super.call.apply(_super, [this].concat(args));
77
83
 
78
84
  _defineProperty(_assertThisInitialized(_this), "state", {
79
- menus: []
85
+ menus: [],
86
+ nestedMenuHoverIndex: -1
80
87
  });
81
88
 
82
89
  _defineProperty(_assertThisInitialized(_this), "mountRef", /*#__PURE__*/React.createRef());
83
90
 
91
+ _defineProperty(_assertThisInitialized(_this), "mouseLeaveTimeoueId", null);
92
+
93
+ _defineProperty(_assertThisInitialized(_this), "handleMenuMouseLeave", function (event) {
94
+ _this.mouseLeaveTimeoueId = setTimeout(function () {
95
+ _this.setState({
96
+ nestedMenuHoverIndex: -1
97
+ });
98
+ }, 200);
99
+ });
100
+
101
+ _defineProperty(_assertThisInitialized(_this), "handleMenuMouseEnter", function (event) {
102
+ if (typeof document !== 'undefined') {
103
+ clearTimeout(_this.mouseLeaveTimeoueId);
104
+
105
+ var index = _this.state.menus.findIndex(function (m) {
106
+ return m.current && event.currentTarget instanceof Node && m.current.contains(event.currentTarget);
107
+ });
108
+
109
+ _this.setState({
110
+ nestedMenuHoverIndex: index
111
+ });
112
+ }
113
+ });
114
+
84
115
  _defineProperty(_assertThisInitialized(_this), "addMenuToNesting", function (ref) {
85
116
  // check offsetHeight to determine if component is visible in the dom (0 means hidden)
86
117
  // we need to do this so that when we renderAll, the hidden seo-only child-menus don't
87
118
  // register themselves which would break the nesting logic
88
- if (ref.current && ref.current.offsetHeight) {
119
+ var element = ref.current;
120
+
121
+ if (element && element.offsetHeight) {
122
+ element.addEventListener('mouseenter', _this.handleMenuMouseEnter);
123
+ element.addEventListener('mouseleave', _this.handleMenuMouseLeave);
124
+
89
125
  _this.setState(function (state) {
90
126
  return {
91
127
  menus: [].concat(_toConsumableArray(state.menus), [ref])
@@ -96,10 +132,27 @@ var NestedMenus = /*#__PURE__*/function (_React$Component) {
96
132
 
97
133
  _defineProperty(_assertThisInitialized(_this), "removeMenuFromNesting", function (ref) {
98
134
  _this.setState(function (state) {
135
+ var _iterator = _createForOfIteratorHelper(_this.state.menus),
136
+ _step;
137
+
138
+ try {
139
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
140
+ var r = _step.value;
141
+
142
+ if (r.current && isSame(r.current, ref.current)) {
143
+ var element = r.current;
144
+ element.removeEventListener('mouseenter', _this.handleMenuMouseEnter);
145
+ element.removeEventListener('mouseleave', _this.handleMenuMouseLeave);
146
+ }
147
+ }
148
+ } catch (err) {
149
+ _iterator.e(err);
150
+ } finally {
151
+ _iterator.f();
152
+ }
153
+
99
154
  var nextMenus = state.menus.filter(function (r) {
100
- return r.current;
101
- }).filter(function (r) {
102
- return !isSame(r.current, ref.current);
155
+ return r.current && !isSame(r.current, ref.current);
103
156
  });
104
157
  return {
105
158
  menus: nextMenus
@@ -123,6 +176,12 @@ var NestedMenus = /*#__PURE__*/function (_React$Component) {
123
176
  return _this.state.menus[index];
124
177
  });
125
178
 
179
+ _defineProperty(_assertThisInitialized(_this), "isNestedMenuVisible", function (ref) {
180
+ var index = _this.findMenuIndexByRef(ref);
181
+
182
+ return index <= _this.state.nestedMenuHoverIndex;
183
+ });
184
+
126
185
  return _this;
127
186
  }
128
187
 
@@ -135,6 +194,8 @@ var NestedMenus = /*#__PURE__*/function (_React$Component) {
135
194
  removeMenuFromNesting: this.removeMenuFromNesting,
136
195
  getParentMenu: this.getParentMenu,
137
196
  getChildMenu: this.getChildMenu,
197
+ isNestedMenuVisible: this.isNestedMenuVisible,
198
+ nestedMenuHoverIndex: this.state.nestedMenuHoverIndex,
138
199
  mountRef: this.mountRef
139
200
  }
140
201
  }, /*#__PURE__*/React.createElement(React.Fragment, null, this.props.children, /*#__PURE__*/React.createElement("span", {
@@ -70,6 +70,10 @@ var DEFAULT_PROPS = {
70
70
  removeMenuFromNesting: function removeMenuFromNesting() {},
71
71
  getParentMenu: function getParentMenu() {},
72
72
  getChildMenu: function getChildMenu() {},
73
+ nestedMenuHoverIndex: -1,
74
+ isNestedMenuVisible: function isNestedMenuVisible() {
75
+ return false;
76
+ },
73
77
  forceHighlight: false
74
78
  };
75
79
 
@@ -276,17 +280,7 @@ var MenuStatefulContainerInner = /*#__PURE__*/function (_React$Component) {
276
280
  });
277
281
  });
278
282
 
279
- _defineProperty(_assertThisInitialized(_this), "handleMouseLeave", function () {
280
- var rootRef = _this.props.rootRef ? _this.props.rootRef : _this.rootRef;
281
-
282
- var childMenu = _this.props.getChildMenu && _this.props.getChildMenu(rootRef);
283
-
284
- if (!_this.props.forceHighlight && !childMenu) {
285
- _this.internalSetState(STATE_CHANGE_TYPES.mouseLeave, {
286
- highlightedIndex: -1
287
- });
288
- }
289
- });
283
+ _defineProperty(_assertThisInitialized(_this), "handleMouseLeave", function (event) {});
290
284
 
291
285
  _defineProperty(_assertThisInitialized(_this), "getRequiredItemProps", function (item, index) {
292
286
  var itemRef = _this.refList[index];
@@ -397,11 +391,13 @@ var MenuStatefulContainerInner = /*#__PURE__*/function (_React$Component) {
397
391
  if (this.keyboardControlNode) this.keyboardControlNode.removeEventListener('keydown', this.onKeyDown);
398
392
  }
399
393
 
400
- this.props.removeMenuFromNesting && this.props.removeMenuFromNesting(rootRef);
394
+ if (this.props.removeMenuFromNesting) {
395
+ this.props.removeMenuFromNesting(rootRef);
396
+ }
401
397
  }
402
398
  }, {
403
399
  key: "componentDidUpdate",
404
- value: function componentDidUpdate(_, prevState) {
400
+ value: function componentDidUpdate(prevProps, prevState) {
405
401
  if (typeof document !== 'undefined') {
406
402
  if (!prevState.isFocused && this.state.isFocused) {
407
403
  if (this.keyboardControlNode) this.keyboardControlNode.addEventListener('keydown', this.onKeyDown);
@@ -427,6 +423,12 @@ var MenuStatefulContainerInner = /*#__PURE__*/function (_React$Component) {
427
423
  highlightedIndex: 0
428
424
  });
429
425
  }
426
+
427
+ if (this.props.isNestedMenuVisible && this.props.nestedMenuHoverIndex !== prevProps.nestedMenuHoverIndex && !this.props.isNestedMenuVisible(this.rootRef) && !this.props.forceHighlight) {
428
+ this.setState({
429
+ highlightedIndex: -1
430
+ });
431
+ }
430
432
  } // One array to hold all of list item refs
431
433
 
432
434
  }, {
@@ -859,7 +859,7 @@ var Select = /*#__PURE__*/function (_React$Component) {
859
859
  "aria-required": this.props.required || null,
860
860
  onFocus: this.handleInputFocus,
861
861
  tabIndex: 0
862
- }, sharedProps, inputContainerProps), /*#__PURE__*/React.createElement("input", {
862
+ }, sharedProps, inputContainerProps), /*#__PURE__*/React.createElement("input", _extends({
863
863
  "aria-hidden": true,
864
864
  id: this.props.id || null,
865
865
  ref: this.handleInputRef,
@@ -871,7 +871,7 @@ var Select = /*#__PURE__*/function (_React$Component) {
871
871
  padding: 0
872
872
  },
873
873
  tabIndex: -1
874
- }));
874
+ }, overrides.Input ? overrides.Input.props ? overrides.Input.props : {} : {})));
875
875
  }
876
876
 
877
877
  return /*#__PURE__*/React.createElement(InputContainer, _extends({}, sharedProps, inputContainerProps), /*#__PURE__*/React.createElement(AutosizeInput, _extends({
package/menu/index.d.ts CHANGED
@@ -69,7 +69,6 @@ export interface RenderItemProps {
69
69
  id?: string;
70
70
  isFocused?: boolean;
71
71
  isHighlighted?: boolean;
72
- resetMenu?: () => any;
73
72
  }
74
73
 
75
74
  export type OnItemSelect = (args: {
@@ -108,6 +107,8 @@ export interface StatefulContainerProps {
108
107
  removeMenuFromNesting?: (ref: React.Ref<HTMLElement>) => void;
109
108
  getParentMenu?: (ref: React.Ref<HTMLElement>) => void;
110
109
  getChildMenu?: (ref: React.Ref<HTMLElement>) => void;
110
+ nestedMenuHoverIndex?: nubmer;
111
+ isNestedMenuVisible?: (ref: React.Ref<HTMLElement>) => boolean;
111
112
  }
112
113
  export interface StatefulContainerState {
113
114
  activedescendantId?: string;
@@ -131,7 +132,6 @@ export interface OptionListProps extends BaseMenuPropsT {
131
132
  ChildMenuPopover?: Override<any>;
132
133
  };
133
134
  renderHrefAsAnchor?: boolean;
134
- resetMenu?: () => void;
135
135
  $isHighlighted?: boolean;
136
136
  $isFocused?: boolean;
137
137
  renderAll?: boolean;
@@ -148,7 +148,11 @@ export interface OptionProfileProps extends BaseMenuPropsT {
148
148
  getChildMenu?: (item: any) => React.ReactNode;
149
149
  getProfileItemLabels: (
150
150
  item: any,
151
- ) => {title?: string; subtitle?: string; body?: string};
151
+ ) => {
152
+ title?: string;
153
+ subtitle?: string;
154
+ body?: string;
155
+ };
152
156
  getProfileItemImg: (item: any) => string | React.ComponentType<any>;
153
157
  getProfileItemImgText: (item: any) => string;
154
158
  overrides?: {
@@ -161,7 +165,6 @@ export interface OptionProfileProps extends BaseMenuPropsT {
161
165
  ProfileBody?: Override<any>;
162
166
  ChildMenuPopover?: Override<any>;
163
167
  };
164
- resetMenu?: () => void;
165
168
  $isHighlighted?: boolean;
166
169
  }
167
170
  export const OptionProfile: React.FC<OptionProfileProps>;
@@ -200,6 +203,8 @@ export class NestedMenus extends React.Component<
200
203
  findMenuIndexByRef(ref: React.Ref<HTMLElement>): number;
201
204
  getParentMenu(ref: React.Ref<HTMLElement>): React.Ref<HTMLElement>;
202
205
  getChildMenu(ref: React.Ref<HTMLElement>): React.Ref<HTMLElement>;
206
+ nestedMenuHoverIndex: number;
207
+ isNestedMenuVisible(ref: React.Ref<HTMLElement>): boolean;
203
208
  }
204
209
 
205
210
  export const StyledEmptyState: StyletronComponent<any>;
@@ -70,8 +70,6 @@ function MaybeChildMenu(props) {
70
70
  overrides: (0, _overrides.mergeOverrides)({
71
71
  Body: {
72
72
  props: {
73
- // Adds mouseleave to popover body so that child menu closes when user mouses out.
74
- onMouseLeave: props.resetParentMenu,
75
73
  // Trap tabbing when focused on a child menu. Popover mounts the element at the end of
76
74
  // the html body by default. If a user was to tab to the next element it would navigate
77
75
  // to elements not within the immediate area surrounding the menu.
@@ -64,8 +64,6 @@ export default function MaybeChildMenu(props: PropsT) {
64
64
  {
65
65
  Body: {
66
66
  props: {
67
- // Adds mouseleave to popover body so that child menu closes when user mouses out.
68
- onMouseLeave: props.resetParentMenu,
69
67
  // Trap tabbing when focused on a child menu. Popover mounts the element at the end of
70
68
  // the html body by default. If a user was to tab to the next element it would navigate
71
69
  // to elements not within the immediate area surrounding the menu.
@@ -13,6 +13,8 @@ function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return
13
13
 
14
14
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
15
15
 
16
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
17
+
16
18
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
17
19
 
18
20
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -52,6 +54,10 @@ var NestedMenuContext = /*#__PURE__*/React.createContext({
52
54
  removeMenuFromNesting: function removeMenuFromNesting() {},
53
55
  getParentMenu: function getParentMenu() {},
54
56
  getChildMenu: function getChildMenu() {},
57
+ nestedMenuHoverIndex: -1,
58
+ isNestedMenuVisible: function isNestedMenuVisible() {
59
+ return false;
60
+ },
55
61
  mountRef: {
56
62
  current: null
57
63
  }
@@ -83,16 +89,46 @@ var NestedMenus = /*#__PURE__*/function (_React$Component) {
83
89
  _this = _super.call.apply(_super, [this].concat(args));
84
90
 
85
91
  _defineProperty(_assertThisInitialized(_this), "state", {
86
- menus: []
92
+ menus: [],
93
+ nestedMenuHoverIndex: -1
87
94
  });
88
95
 
89
96
  _defineProperty(_assertThisInitialized(_this), "mountRef", /*#__PURE__*/React.createRef());
90
97
 
98
+ _defineProperty(_assertThisInitialized(_this), "mouseLeaveTimeoueId", null);
99
+
100
+ _defineProperty(_assertThisInitialized(_this), "handleMenuMouseLeave", function (event) {
101
+ _this.mouseLeaveTimeoueId = setTimeout(function () {
102
+ _this.setState({
103
+ nestedMenuHoverIndex: -1
104
+ });
105
+ }, 200);
106
+ });
107
+
108
+ _defineProperty(_assertThisInitialized(_this), "handleMenuMouseEnter", function (event) {
109
+ if (typeof document !== 'undefined') {
110
+ clearTimeout(_this.mouseLeaveTimeoueId);
111
+
112
+ var index = _this.state.menus.findIndex(function (m) {
113
+ return m.current && event.currentTarget instanceof Node && m.current.contains(event.currentTarget);
114
+ });
115
+
116
+ _this.setState({
117
+ nestedMenuHoverIndex: index
118
+ });
119
+ }
120
+ });
121
+
91
122
  _defineProperty(_assertThisInitialized(_this), "addMenuToNesting", function (ref) {
92
123
  // check offsetHeight to determine if component is visible in the dom (0 means hidden)
93
124
  // we need to do this so that when we renderAll, the hidden seo-only child-menus don't
94
125
  // register themselves which would break the nesting logic
95
- if (ref.current && ref.current.offsetHeight) {
126
+ var element = ref.current;
127
+
128
+ if (element && element.offsetHeight) {
129
+ element.addEventListener('mouseenter', _this.handleMenuMouseEnter);
130
+ element.addEventListener('mouseleave', _this.handleMenuMouseLeave);
131
+
96
132
  _this.setState(function (state) {
97
133
  return {
98
134
  menus: [].concat(_toConsumableArray(state.menus), [ref])
@@ -103,10 +139,27 @@ var NestedMenus = /*#__PURE__*/function (_React$Component) {
103
139
 
104
140
  _defineProperty(_assertThisInitialized(_this), "removeMenuFromNesting", function (ref) {
105
141
  _this.setState(function (state) {
142
+ var _iterator = _createForOfIteratorHelper(_this.state.menus),
143
+ _step;
144
+
145
+ try {
146
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
147
+ var r = _step.value;
148
+
149
+ if (r.current && isSame(r.current, ref.current)) {
150
+ var element = r.current;
151
+ element.removeEventListener('mouseenter', _this.handleMenuMouseEnter);
152
+ element.removeEventListener('mouseleave', _this.handleMenuMouseLeave);
153
+ }
154
+ }
155
+ } catch (err) {
156
+ _iterator.e(err);
157
+ } finally {
158
+ _iterator.f();
159
+ }
160
+
106
161
  var nextMenus = state.menus.filter(function (r) {
107
- return r.current;
108
- }).filter(function (r) {
109
- return !isSame(r.current, ref.current);
162
+ return r.current && !isSame(r.current, ref.current);
110
163
  });
111
164
  return {
112
165
  menus: nextMenus
@@ -130,6 +183,12 @@ var NestedMenus = /*#__PURE__*/function (_React$Component) {
130
183
  return _this.state.menus[index];
131
184
  });
132
185
 
186
+ _defineProperty(_assertThisInitialized(_this), "isNestedMenuVisible", function (ref) {
187
+ var index = _this.findMenuIndexByRef(ref);
188
+
189
+ return index <= _this.state.nestedMenuHoverIndex;
190
+ });
191
+
133
192
  return _this;
134
193
  }
135
194
 
@@ -142,6 +201,8 @@ var NestedMenus = /*#__PURE__*/function (_React$Component) {
142
201
  removeMenuFromNesting: this.removeMenuFromNesting,
143
202
  getParentMenu: this.getParentMenu,
144
203
  getChildMenu: this.getChildMenu,
204
+ isNestedMenuVisible: this.isNestedMenuVisible,
205
+ nestedMenuHoverIndex: this.state.nestedMenuHoverIndex,
145
206
  mountRef: this.mountRef
146
207
  }
147
208
  }, /*#__PURE__*/React.createElement(React.Fragment, null, this.props.children, /*#__PURE__*/React.createElement("span", {
@@ -12,6 +12,7 @@ import * as React from 'react';
12
12
  import type {NestedMenuRefT, NestedMenuContextT} from './types.js';
13
13
 
14
14
  type StateT = {
15
+ nestedMenuHoverIndex: number,
15
16
  menus: NestedMenuRefT[],
16
17
  };
17
18
  type PropsT = {
@@ -24,6 +25,8 @@ export const NestedMenuContext: React.Context<NestedMenuContextT> = React.create
24
25
  removeMenuFromNesting: () => {},
25
26
  getParentMenu: () => {},
26
27
  getChildMenu: () => {},
28
+ nestedMenuHoverIndex: -1,
29
+ isNestedMenuVisible: () => false,
27
30
  mountRef: {current: null},
28
31
  },
29
32
  );
@@ -37,14 +40,40 @@ function isSame(a: ?HTMLElement, b: ?HTMLElement) {
37
40
  }
38
41
 
39
42
  export default class NestedMenus extends React.Component<PropsT, StateT> {
40
- state = {menus: []};
43
+ state = {menus: [], nestedMenuHoverIndex: -1};
41
44
  mountRef = (React.createRef(): {current: HTMLElement | null});
45
+ mouseLeaveTimeoueId = null;
46
+
47
+ handleMenuMouseLeave = (event: MouseEvent) => {
48
+ this.mouseLeaveTimeoueId = setTimeout(() => {
49
+ this.setState({nestedMenuHoverIndex: -1});
50
+ }, 200);
51
+ };
52
+
53
+ handleMenuMouseEnter = (event: MouseEvent) => {
54
+ if (__BROWSER__) {
55
+ clearTimeout(this.mouseLeaveTimeoueId);
56
+ const index = this.state.menus.findIndex(m => {
57
+ return (
58
+ m.current &&
59
+ event.currentTarget instanceof Node &&
60
+ m.current.contains(event.currentTarget)
61
+ );
62
+ });
63
+
64
+ this.setState({nestedMenuHoverIndex: index});
65
+ }
66
+ };
42
67
 
43
68
  addMenuToNesting = (ref: NestedMenuRefT) => {
44
69
  // check offsetHeight to determine if component is visible in the dom (0 means hidden)
45
70
  // we need to do this so that when we renderAll, the hidden seo-only child-menus don't
46
71
  // register themselves which would break the nesting logic
47
- if (ref.current && ref.current.offsetHeight) {
72
+ const element = ref.current;
73
+ if (element && element.offsetHeight) {
74
+ element.addEventListener('mouseenter', this.handleMenuMouseEnter);
75
+ element.addEventListener('mouseleave', this.handleMenuMouseLeave);
76
+
48
77
  this.setState(state => {
49
78
  return {menus: [...state.menus, ref]};
50
79
  });
@@ -53,9 +82,18 @@ export default class NestedMenus extends React.Component<PropsT, StateT> {
53
82
 
54
83
  removeMenuFromNesting = (ref: NestedMenuRefT) => {
55
84
  this.setState(state => {
56
- const nextMenus = state.menus
57
- .filter(r => r.current)
58
- .filter(r => !isSame(r.current, ref.current));
85
+ for (const r of this.state.menus) {
86
+ if (r.current && isSame(r.current, ref.current)) {
87
+ const element = r.current;
88
+ element.removeEventListener('mouseenter', this.handleMenuMouseEnter);
89
+ element.removeEventListener('mouseleave', this.handleMenuMouseLeave);
90
+ }
91
+ }
92
+
93
+ const nextMenus = state.menus.filter(r => {
94
+ return r.current && !isSame(r.current, ref.current);
95
+ });
96
+
59
97
  return {menus: nextMenus};
60
98
  });
61
99
  };
@@ -74,6 +112,11 @@ export default class NestedMenus extends React.Component<PropsT, StateT> {
74
112
  return this.state.menus[index];
75
113
  };
76
114
 
115
+ isNestedMenuVisible = (ref: NestedMenuRefT): boolean => {
116
+ const index = this.findMenuIndexByRef(ref);
117
+ return index <= this.state.nestedMenuHoverIndex;
118
+ };
119
+
77
120
  render() {
78
121
  return (
79
122
  <NestedMenuContext.Provider
@@ -82,6 +125,8 @@ export default class NestedMenus extends React.Component<PropsT, StateT> {
82
125
  removeMenuFromNesting: this.removeMenuFromNesting,
83
126
  getParentMenu: this.getParentMenu,
84
127
  getChildMenu: this.getChildMenu,
128
+ isNestedMenuVisible: this.isNestedMenuVisible,
129
+ nestedMenuHoverIndex: this.state.nestedMenuHoverIndex,
85
130
  mountRef: this.mountRef,
86
131
  }}
87
132
  >
@@ -77,6 +77,10 @@ var DEFAULT_PROPS = {
77
77
  removeMenuFromNesting: function removeMenuFromNesting() {},
78
78
  getParentMenu: function getParentMenu() {},
79
79
  getChildMenu: function getChildMenu() {},
80
+ nestedMenuHoverIndex: -1,
81
+ isNestedMenuVisible: function isNestedMenuVisible() {
82
+ return false;
83
+ },
80
84
  forceHighlight: false
81
85
  };
82
86
 
@@ -283,17 +287,7 @@ var MenuStatefulContainerInner = /*#__PURE__*/function (_React$Component) {
283
287
  });
284
288
  });
285
289
 
286
- _defineProperty(_assertThisInitialized(_this), "handleMouseLeave", function () {
287
- var rootRef = _this.props.rootRef ? _this.props.rootRef : _this.rootRef;
288
-
289
- var childMenu = _this.props.getChildMenu && _this.props.getChildMenu(rootRef);
290
-
291
- if (!_this.props.forceHighlight && !childMenu) {
292
- _this.internalSetState(_constants.STATE_CHANGE_TYPES.mouseLeave, {
293
- highlightedIndex: -1
294
- });
295
- }
296
- });
290
+ _defineProperty(_assertThisInitialized(_this), "handleMouseLeave", function (event) {});
297
291
 
298
292
  _defineProperty(_assertThisInitialized(_this), "getRequiredItemProps", function (item, index) {
299
293
  var itemRef = _this.refList[index];
@@ -404,11 +398,13 @@ var MenuStatefulContainerInner = /*#__PURE__*/function (_React$Component) {
404
398
  if (this.keyboardControlNode) this.keyboardControlNode.removeEventListener('keydown', this.onKeyDown);
405
399
  }
406
400
 
407
- this.props.removeMenuFromNesting && this.props.removeMenuFromNesting(rootRef);
401
+ if (this.props.removeMenuFromNesting) {
402
+ this.props.removeMenuFromNesting(rootRef);
403
+ }
408
404
  }
409
405
  }, {
410
406
  key: "componentDidUpdate",
411
- value: function componentDidUpdate(_, prevState) {
407
+ value: function componentDidUpdate(prevProps, prevState) {
412
408
  if (typeof document !== 'undefined') {
413
409
  if (!prevState.isFocused && this.state.isFocused) {
414
410
  if (this.keyboardControlNode) this.keyboardControlNode.addEventListener('keydown', this.onKeyDown);
@@ -434,6 +430,12 @@ var MenuStatefulContainerInner = /*#__PURE__*/function (_React$Component) {
434
430
  highlightedIndex: 0
435
431
  });
436
432
  }
433
+
434
+ if (this.props.isNestedMenuVisible && this.props.nestedMenuHoverIndex !== prevProps.nestedMenuHoverIndex && !this.props.isNestedMenuVisible(this.rootRef) && !this.props.forceHighlight) {
435
+ this.setState({
436
+ highlightedIndex: -1
437
+ });
438
+ }
437
439
  } // One array to hold all of list item refs
438
440
 
439
441
  }, {
@@ -37,6 +37,8 @@ const DEFAULT_PROPS = {
37
37
  removeMenuFromNesting: () => {},
38
38
  getParentMenu: () => {},
39
39
  getChildMenu: () => {},
40
+ nestedMenuHoverIndex: -1,
41
+ isNestedMenuVisible: () => false,
40
42
  forceHighlight: false,
41
43
  };
42
44
 
@@ -99,11 +101,16 @@ class MenuStatefulContainerInner extends React.Component<
99
101
  if (this.keyboardControlNode)
100
102
  this.keyboardControlNode.removeEventListener('keydown', this.onKeyDown);
101
103
  }
102
- this.props.removeMenuFromNesting &&
104
+
105
+ if (this.props.removeMenuFromNesting) {
103
106
  this.props.removeMenuFromNesting(rootRef);
107
+ }
104
108
  }
105
109
 
106
- componentDidUpdate(_: mixed, prevState: StatefulContainerStateT) {
110
+ componentDidUpdate(
111
+ prevProps: StatefulContainerPropsT,
112
+ prevState: StatefulContainerStateT,
113
+ ) {
107
114
  if (__BROWSER__) {
108
115
  if (!prevState.isFocused && this.state.isFocused) {
109
116
  if (this.keyboardControlNode)
@@ -135,6 +142,15 @@ class MenuStatefulContainerInner extends React.Component<
135
142
  highlightedIndex: 0,
136
143
  });
137
144
  }
145
+
146
+ if (
147
+ this.props.isNestedMenuVisible &&
148
+ this.props.nestedMenuHoverIndex !== prevProps.nestedMenuHoverIndex &&
149
+ !this.props.isNestedMenuVisible(this.rootRef) &&
150
+ !this.props.forceHighlight
151
+ ) {
152
+ this.setState({highlightedIndex: -1});
153
+ }
138
154
  }
139
155
 
140
156
  // One array to hold all of list item refs
@@ -342,17 +358,7 @@ class MenuStatefulContainerInner extends React.Component<
342
358
  });
343
359
  };
344
360
 
345
- handleMouseLeave = () => {
346
- const rootRef = this.props.rootRef ? this.props.rootRef : this.rootRef;
347
- const childMenu =
348
- this.props.getChildMenu && this.props.getChildMenu(rootRef);
349
-
350
- if (!this.props.forceHighlight && !childMenu) {
351
- this.internalSetState(STATE_CHANGE_TYPES.mouseLeave, {
352
- highlightedIndex: -1,
353
- });
354
- }
355
- };
361
+ handleMouseLeave = (event: SyntheticMouseEvent<HTMLElement>) => {};
356
362
 
357
363
  getRequiredItemProps: GetRequiredItemPropsFnT = (item, index) => {
358
364
  let itemRef = this.refList[index];
@@ -136,6 +136,8 @@ export type StatefulContainerPropsT = {
136
136
  getChildMenu?: (ref: {current: HTMLElement | null}) => ?{
137
137
  current: HTMLElement | null,
138
138
  },
139
+ nestedMenuHoverIndex?: number,
140
+ isNestedMenuVisible?: (ref: {current: HTMLElement | null}) => boolean,
139
141
  forceHighlight: boolean,
140
142
  };
141
143
 
@@ -171,7 +173,7 @@ export type SharedStatelessPropsT = {
171
173
  ariaLabel?: string,
172
174
  getRequiredItemProps?: GetRequiredItemPropsFnT,
173
175
  isFocused?: boolean,
174
- handleMouseLeave?: () => mixed,
176
+ handleMouseLeave?: (event: SyntheticMouseEvent<HTMLElement>) => mixed,
175
177
  /** Index of highlighted menu item. */
176
178
  highlightedIndex?: number,
177
179
  /** List of menu items. */
@@ -215,6 +217,8 @@ export type StatefulMenuPropsT = {
215
217
  getChildMenu?: (ref: {current: HTMLElement | null}) => ?{
216
218
  current: HTMLElement | null,
217
219
  },
220
+ nestedMenuHoverIndex?: number,
221
+ isNestedMenuVisible?: (ref: {current: HTMLElement | null}) => boolean,
218
222
  } & MenuPropsT;
219
223
 
220
224
  export type StatefulMenuProfilePropsT = StatefulContainerPropsT &
@@ -300,6 +304,8 @@ export type NestedMenuContextT = {|
300
304
  removeMenuFromNesting: (ref: NestedMenuRefT) => void,
301
305
  getParentMenu: (ref: NestedMenuRefT) => ?NestedMenuRefT,
302
306
  getChildMenu: (ref: NestedMenuRefT) => ?NestedMenuRefT,
307
+ nestedMenuHoverIndex: number,
308
+ isNestedMenuVisible: (ref: NestedMenuRefT) => boolean,
303
309
  mountRef: NestedMenuRefT,
304
310
  |};
305
311
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baseui",
3
- "version": "0.0.0-next-887e00c",
3
+ "version": "0.0.0-next-1598215",
4
4
  "description": "A React Component library implementing the Base design language",
5
5
  "keywords": [
6
6
  "react",
@@ -880,7 +880,7 @@ var Select = /*#__PURE__*/function (_React$Component) {
880
880
  "aria-required": this.props.required || null,
881
881
  onFocus: this.handleInputFocus,
882
882
  tabIndex: 0
883
- }, sharedProps, inputContainerProps), /*#__PURE__*/React.createElement("input", {
883
+ }, sharedProps, inputContainerProps), /*#__PURE__*/React.createElement("input", _extends({
884
884
  "aria-hidden": true,
885
885
  id: this.props.id || null,
886
886
  ref: this.handleInputRef,
@@ -892,7 +892,7 @@ var Select = /*#__PURE__*/function (_React$Component) {
892
892
  padding: 0
893
893
  },
894
894
  tabIndex: -1
895
- }));
895
+ }, overrides.Input ? overrides.Input.props ? overrides.Input.props : {} : {})));
896
896
  }
897
897
 
898
898
  return /*#__PURE__*/React.createElement(InputContainer, _extends({}, sharedProps, inputContainerProps), /*#__PURE__*/React.createElement(_autosizeInput.default, _extends({
@@ -730,6 +730,11 @@ class Select extends React.Component<PropsT, SelectStateT> {
730
730
  padding: 0,
731
731
  }}
732
732
  tabIndex={-1}
733
+ {...(overrides.Input
734
+ ? overrides.Input.props
735
+ ? overrides.Input.props
736
+ : {}
737
+ : {})}
733
738
  />
734
739
  </InputContainer>
735
740
  );