@instructure/ui-drilldown 8.21.1-snapshot.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/LICENSE.md +27 -0
  3. package/README.md +30 -0
  4. package/es/Drilldown/DrilldownGroup/index.js +56 -0
  5. package/es/Drilldown/DrilldownGroup/props.js +42 -0
  6. package/es/Drilldown/DrilldownLocator.js +144 -0
  7. package/es/Drilldown/DrilldownOption/index.js +59 -0
  8. package/es/Drilldown/DrilldownOption/props.js +46 -0
  9. package/es/Drilldown/DrilldownPage/index.js +56 -0
  10. package/es/Drilldown/DrilldownPage/props.js +41 -0
  11. package/es/Drilldown/DrilldownSeparator/index.js +52 -0
  12. package/es/Drilldown/DrilldownSeparator/props.js +30 -0
  13. package/es/Drilldown/__examples__/Drilldown.examples.js +299 -0
  14. package/es/Drilldown/index.js +1241 -0
  15. package/es/Drilldown/locator.js +26 -0
  16. package/es/Drilldown/props.js +67 -0
  17. package/es/Drilldown/styles.js +82 -0
  18. package/es/Drilldown/theme.js +43 -0
  19. package/es/index.js +24 -0
  20. package/lib/Drilldown/DrilldownGroup/index.js +42 -0
  21. package/lib/Drilldown/DrilldownGroup/props.js +56 -0
  22. package/lib/Drilldown/DrilldownLocator.js +157 -0
  23. package/lib/Drilldown/DrilldownOption/index.js +45 -0
  24. package/lib/Drilldown/DrilldownOption/props.js +57 -0
  25. package/lib/Drilldown/DrilldownPage/index.js +66 -0
  26. package/lib/Drilldown/DrilldownPage/props.js +56 -0
  27. package/lib/Drilldown/DrilldownSeparator/index.js +38 -0
  28. package/lib/Drilldown/DrilldownSeparator/props.js +41 -0
  29. package/lib/Drilldown/__examples__/Drilldown.examples.js +289 -0
  30. package/lib/Drilldown/index.js +1253 -0
  31. package/lib/Drilldown/locator.js +40 -0
  32. package/lib/Drilldown/props.js +83 -0
  33. package/lib/Drilldown/styles.js +90 -0
  34. package/lib/Drilldown/theme.js +51 -0
  35. package/lib/index.js +13 -0
  36. package/lib/package.json +1 -0
  37. package/package.json +58 -0
  38. package/src/Drilldown/DrilldownGroup/index.tsx +64 -0
  39. package/src/Drilldown/DrilldownGroup/props.ts +149 -0
  40. package/src/Drilldown/DrilldownLocator.ts +101 -0
  41. package/src/Drilldown/DrilldownOption/index.tsx +68 -0
  42. package/src/Drilldown/DrilldownOption/props.ts +224 -0
  43. package/src/Drilldown/DrilldownPage/index.tsx +58 -0
  44. package/src/Drilldown/DrilldownPage/props.ts +129 -0
  45. package/src/Drilldown/DrilldownSeparator/index.tsx +60 -0
  46. package/src/Drilldown/DrilldownSeparator/props.ts +65 -0
  47. package/src/Drilldown/README.md +1515 -0
  48. package/src/Drilldown/__examples__/Drilldown.examples.tsx +318 -0
  49. package/src/Drilldown/index.tsx +1492 -0
  50. package/src/Drilldown/locator.ts +28 -0
  51. package/src/Drilldown/props.ts +378 -0
  52. package/src/Drilldown/styles.ts +95 -0
  53. package/src/Drilldown/theme.ts +47 -0
  54. package/src/index.ts +26 -0
  55. package/tsconfig.build.json +30 -0
  56. package/tsconfig.build.tsbuildinfo +1 -0
  57. package/tsconfig.json +4 -0
  58. package/types/Drilldown/DrilldownGroup/index.d.ts +59 -0
  59. package/types/Drilldown/DrilldownGroup/index.d.ts.map +1 -0
  60. package/types/Drilldown/DrilldownGroup/props.d.ts +65 -0
  61. package/types/Drilldown/DrilldownGroup/props.d.ts.map +1 -0
  62. package/types/Drilldown/DrilldownLocator.d.ts +652 -0
  63. package/types/Drilldown/DrilldownLocator.d.ts.map +1 -0
  64. package/types/Drilldown/DrilldownOption/index.d.ts +134 -0
  65. package/types/Drilldown/DrilldownOption/index.d.ts.map +1 -0
  66. package/types/Drilldown/DrilldownOption/props.d.ts +116 -0
  67. package/types/Drilldown/DrilldownOption/props.d.ts.map +1 -0
  68. package/types/Drilldown/DrilldownPage/index.d.ts +45 -0
  69. package/types/Drilldown/DrilldownPage/index.d.ts.map +1 -0
  70. package/types/Drilldown/DrilldownPage/props.d.ts +51 -0
  71. package/types/Drilldown/DrilldownPage/props.d.ts.map +1 -0
  72. package/types/Drilldown/DrilldownSeparator/index.d.ts +27 -0
  73. package/types/Drilldown/DrilldownSeparator/index.d.ts.map +1 -0
  74. package/types/Drilldown/DrilldownSeparator/props.d.ts +18 -0
  75. package/types/Drilldown/DrilldownSeparator/props.d.ts.map +1 -0
  76. package/types/Drilldown/__examples__/Drilldown.examples.d.ts +5 -0
  77. package/types/Drilldown/__examples__/Drilldown.examples.d.ts.map +1 -0
  78. package/types/Drilldown/index.d.ts +246 -0
  79. package/types/Drilldown/index.d.ts.map +1 -0
  80. package/types/Drilldown/locator.d.ts +4 -0
  81. package/types/Drilldown/locator.d.ts.map +1 -0
  82. package/types/Drilldown/props.d.ts +189 -0
  83. package/types/Drilldown/props.d.ts.map +1 -0
  84. package/types/Drilldown/styles.d.ts +15 -0
  85. package/types/Drilldown/styles.d.ts.map +1 -0
  86. package/types/Drilldown/theme.d.ts +10 -0
  87. package/types/Drilldown/theme.d.ts.map +1 -0
  88. package/types/index.d.ts +3 -0
  89. package/types/index.d.ts.map +1 -0
@@ -0,0 +1,1241 @@
1
+ import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
2
+ const _excluded = ["groupProps"],
3
+ _excluded2 = ["groupProps"],
4
+ _excluded3 = ["id", "themeOverride"];
5
+
6
+ var _dec, _dec2, _dec3, _class, _class2, _temp, _IconArrowOpenEndSoli, _IconArrowOpenStartSo, _Options$Separator, _Options$Separator2;
7
+
8
+ /*
9
+ * The MIT License (MIT)
10
+ *
11
+ * Copyright (c) 2015 - present Instructure, Inc.
12
+ *
13
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ * of this software and associated documentation files (the "Software"), to deal
15
+ * in the Software without restriction, including without limitation the rights
16
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ * copies of the Software, and to permit persons to whom the Software is
18
+ * furnished to do so, subject to the following conditions:
19
+ *
20
+ * The above copyright notice and this permission notice shall be included in all
21
+ * copies or substantial portions of the Software.
22
+ *
23
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ * SOFTWARE.
30
+ */
31
+
32
+ /** @jsx jsx */
33
+
34
+ /** @jsxFrag React.Fragment */
35
+ import React, { Component } from 'react';
36
+ import { warn, error } from '@instructure/console';
37
+ import { testable } from '@instructure/ui-testable';
38
+ import { contains, containsActiveElement } from '@instructure/ui-dom-utils';
39
+ import { callRenderProp, matchComponentTypes, omitProps, safeCloneElement, withDeterministicId } from '@instructure/ui-react-utils';
40
+ import { View } from '@instructure/ui-view';
41
+ import { Options } from '@instructure/ui-options';
42
+ import { Popover } from '@instructure/ui-popover';
43
+ import { Selectable } from '@instructure/ui-selectable';
44
+ import { IconArrowOpenStartSolid, IconArrowOpenEndSolid, IconCheckSolid } from '@instructure/ui-icons';
45
+ import { withStyle, jsx } from '@instructure/emotion';
46
+ import { DrilldownSeparator } from './DrilldownSeparator';
47
+ import { DrilldownOption } from './DrilldownOption';
48
+ import { DrilldownGroup } from './DrilldownGroup';
49
+ import { DrilldownPage } from './DrilldownPage';
50
+ import generateStyle from './styles';
51
+ import generateComponentTheme from './theme';
52
+ import { propTypes, allowedProps } from './props';
53
+
54
+ /**
55
+ ---
56
+ category: components
57
+ experimental: true
58
+ ---
59
+ @tsProps
60
+ **/
61
+ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, generateComponentTheme), _dec3 = testable(), _dec(_class = _dec2(_class = _dec3(_class = (_temp = _class2 = class Drilldown extends Component {
62
+ // Array of visited page ids in "breadcrumbs" fashion
63
+ // Map of the active options on the page (includes header options too)
64
+ // Map of the selected options in groups (grouped by group id)
65
+ constructor(props) {
66
+ super(props);
67
+ this._drilldownRef = null;
68
+ this._popover = null;
69
+ this._trigger = null;
70
+ this._containerElement = null;
71
+ this._id = void 0;
72
+ this._triggerId = void 0;
73
+ this._headerBackId = void 0;
74
+ this._headerTitleId = void 0;
75
+ this._headerTitleLabelId = void 0;
76
+ this._headerActionId = void 0;
77
+ this._pageHistory = void 0;
78
+ this._activeOptionsMap = {};
79
+ this._selectedGroupOptionsMap = {};
80
+ this.ref = null;
81
+
82
+ this.handleRef = el => {
83
+ // ref and elementRef have to be set together for the same element
84
+ const elementRef = this.props.elementRef;
85
+ this.ref = el;
86
+
87
+ if (typeof elementRef === 'function') {
88
+ elementRef(el);
89
+ }
90
+ };
91
+
92
+ this.handleDrilldownRef = el => {
93
+ const drilldownRef = this.props.drilldownRef;
94
+ this._drilldownRef = el;
95
+
96
+ if (typeof drilldownRef === 'function') {
97
+ drilldownRef(el);
98
+ } // setting ref for "non-popover" version, the drilldown itself
99
+ // (if a trigger is provided, the Popover sets the ref)
100
+
101
+
102
+ if (!this.props.trigger) {
103
+ this.handleRef(el);
104
+ }
105
+ };
106
+
107
+ this.show = event => {
108
+ if (this._popover) {
109
+ this._popover.show(event);
110
+
111
+ this.setState({
112
+ isShowingPopover: true
113
+ });
114
+ }
115
+ };
116
+
117
+ this.hide = event => {
118
+ if (this._popover) {
119
+ this._popover.hide(event);
120
+
121
+ this.setState({
122
+ isShowingPopover: false
123
+ });
124
+ this.reset();
125
+ }
126
+ };
127
+
128
+ this.handleOptionHighlight = (_event, _ref) => {
129
+ let id = _ref.id,
130
+ direction = _ref.direction;
131
+ const rotateFocus = this.props.rotateFocus;
132
+ const highlightedOptionId = this.state.highlightedOptionId; // if id exists, use that, or calculate from direction
133
+
134
+ let highlightId = this.getPageChildById(id) ? id : void 0;
135
+
136
+ if (!highlightId) {
137
+ if (!highlightedOptionId) {
138
+ // nothing highlighted yet, highlight first option
139
+ highlightId = this.activeOptionIds[0];
140
+ } else if (direction) {
141
+ // if it has direction, find next id based on it
142
+ const index = this.activeOptionIds.indexOf(highlightedOptionId);
143
+ const newIndex = index + direction;
144
+ highlightId = index > -1 ? this.activeOptionIds[newIndex] : void 0;
145
+
146
+ if (rotateFocus) {
147
+ const lastOptionsIndex = this.activeOptionIds.length - 1;
148
+
149
+ if (newIndex < 0) {
150
+ highlightId = this.activeOptionIds[lastOptionsIndex];
151
+ }
152
+
153
+ if (newIndex > lastOptionsIndex) {
154
+ highlightId = this.activeOptionIds[0];
155
+ }
156
+ }
157
+ }
158
+ }
159
+
160
+ if (highlightId) {
161
+ // only highlight if id exists as a valid option
162
+ this.setState({
163
+ highlightedOptionId: highlightId
164
+ }, () => {
165
+ this.focusOption(highlightId);
166
+ });
167
+ }
168
+ };
169
+
170
+ this.goToPage = newPageId => {
171
+ var _this$pageMap;
172
+
173
+ if (!newPageId) {
174
+ warn(false, `Cannot go to page because there was no page id provided.`);
175
+ return void 0;
176
+ } // TS complains that it cannot be true, but since it is an exposed method,
177
+ // it is better if we provide a warning for this case too
178
+
179
+
180
+ if (typeof newPageId !== 'string') {
181
+ warn(false, `Cannot go to page because parameter newPageId has to be string (valid page id). Current newPageId is "${typeof newPageId}".`);
182
+ return void 0;
183
+ }
184
+
185
+ if (!((_this$pageMap = this.pageMap) !== null && _this$pageMap !== void 0 && _this$pageMap[newPageId])) {
186
+ warn(false, `Cannot go to page because page with id: "${newPageId}" doesn't exist.`);
187
+ return void 0;
188
+ } // the last page id in the history is the current one,
189
+ // it will become the "prevPage"
190
+
191
+
192
+ const prevPageId = this._pageHistory[this._pageHistory.length - 1];
193
+
194
+ const idxInHistory = this._pageHistory.indexOf(newPageId);
195
+
196
+ if (idxInHistory < 0) {
197
+ // if it is not in the page history, we have to add it
198
+ this._pageHistory.push(newPageId);
199
+ } else {
200
+ // if it was already in the history, we go back to that page,
201
+ // and clear the rest from the history
202
+ this._pageHistory.splice(idxInHistory + 1, this._pageHistory.length - 1);
203
+ }
204
+
205
+ this.setState({
206
+ activePageId: newPageId,
207
+ highlightedOptionId: void 0
208
+ });
209
+ return {
210
+ prevPageId,
211
+ newPageId
212
+ };
213
+ };
214
+
215
+ this.goToPreviousPage = () => {
216
+ if (!this.previousPage) {
217
+ warn(false, `There is no previous page to go to. The current page history is: [${this._pageHistory.join(', ')}].`);
218
+ return void 0;
219
+ } // If there is a previous page, goToPage will succeed and return the data
220
+
221
+
222
+ const _ref2 = this.goToPage(this.previousPage.id),
223
+ newPageId = _ref2.newPageId,
224
+ prevPageId = _ref2.prevPageId;
225
+
226
+ return {
227
+ newPageId,
228
+ prevPageId
229
+ };
230
+ };
231
+
232
+ this.handleBackButtonClick = () => {
233
+ const _ref3 = this.currentPage,
234
+ onBackButtonClicked = _ref3.onBackButtonClicked; // we only display the back button when there is a page to go back to
235
+
236
+ const _ref4 = this.goToPreviousPage(),
237
+ newPageId = _ref4.newPageId,
238
+ prevPageId = _ref4.prevPageId;
239
+
240
+ if (typeof onBackButtonClicked === 'function') {
241
+ onBackButtonClicked(newPageId, prevPageId);
242
+ }
243
+ };
244
+
245
+ this.handleOptionSelect = (event, _ref5) => {
246
+ let id = _ref5.id;
247
+ const selectedOption = this.getPageChildById(id);
248
+
249
+ if (!id || !selectedOption || selectedOption.props.disabled || event.target.getAttribute('disabled') || event.target.getAttribute('aria-disabled')) {
250
+ event.preventDefault();
251
+ event.stopPropagation();
252
+ return;
253
+ }
254
+
255
+ const _this$props = this.props,
256
+ shouldHideOnSelect = _this$props.shouldHideOnSelect,
257
+ onSelect = _this$props.onSelect;
258
+
259
+ const groupProps = selectedOption.groupProps,
260
+ selectedOptionChild = _objectWithoutProperties(selectedOption, _excluded);
261
+
262
+ const _selectedOptionChild$ = selectedOptionChild.props,
263
+ subPageId = _selectedOptionChild$.subPageId,
264
+ href = _selectedOptionChild$.href,
265
+ value = _selectedOptionChild$.value,
266
+ onOptionClick = _selectedOptionChild$.onOptionClick;
267
+
268
+ if (typeof onOptionClick === 'function') {
269
+ onOptionClick(event, {
270
+ optionId: id,
271
+ drilldown: this,
272
+ ...this.exposedNavigationProps
273
+ });
274
+ }
275
+
276
+ if (subPageId) {
277
+ this.goToPage(subPageId);
278
+ }
279
+
280
+ if (href) {
281
+ var _this$_drilldownRef;
282
+
283
+ const optionEl = (_this$_drilldownRef = this._drilldownRef) === null || _this$_drilldownRef === void 0 ? void 0 : _this$_drilldownRef.querySelector(`#${id}`);
284
+ const isLink = optionEl.tagName.toLowerCase() === 'a'; // we need this check because in some cases
285
+ // we ignore href prop in renderOption()
286
+
287
+ if (isLink && optionEl !== null && optionEl !== void 0 && optionEl.href) {
288
+ optionEl.click();
289
+ }
290
+ }
291
+
292
+ if (groupProps !== null && groupProps !== void 0 && groupProps.selectableType) {
293
+ this.handleGroupOptionSelected(event, selectedOption);
294
+ } else {
295
+ if (typeof onSelect === 'function') {
296
+ onSelect(event, {
297
+ value,
298
+ isSelected: true,
299
+ selectedOption: selectedOptionChild,
300
+ drilldown: this
301
+ });
302
+ }
303
+ } // should prevent closing on page navigation
304
+
305
+
306
+ if (shouldHideOnSelect && !subPageId && id !== this._headerBackId) {
307
+ this.hide(event);
308
+ }
309
+ };
310
+
311
+ this.handleKeyDown = event => {
312
+ const id = event.target.id;
313
+ const option = this.getPageChildById(id); // On Space...
314
+
315
+ if ([' ', 'space', 'Space'].includes(event.key)) {
316
+ // we need to preventDefault so the page doesn't scroll on Space
317
+ event.preventDefault();
318
+ event.stopPropagation(); // for options, Space it has to work as Enter (get selected)
319
+
320
+ if (option) {
321
+ this.handleOptionSelect(event, {
322
+ id
323
+ });
324
+ }
325
+ } // On Right arrow...
326
+
327
+
328
+ if (event.key === 'ArrowRight') {
329
+ // if the option has subpage, we open it
330
+ if (option !== null && option !== void 0 && option.props.subPageId) {
331
+ this.handleOptionSelect(event, {
332
+ id
333
+ });
334
+ }
335
+ } // On Left arrow...
336
+
337
+
338
+ if (event.key === 'ArrowLeft') {
339
+ var _this$_popover;
340
+
341
+ // if it is possible, we go a level up in the history
342
+ if (this._pageHistory.length > 1) {
343
+ this.goToPreviousPage();
344
+ } // if on root page and popover is open, we close it
345
+
346
+
347
+ if (this.isOnRootPage && (_this$_popover = this._popover) !== null && _this$_popover !== void 0 && _this$_popover.shown) {
348
+ this._popover.hide(event);
349
+ }
350
+ }
351
+ };
352
+
353
+ this.handleToggle = (event, shown) => {
354
+ const onToggle = this.props.onToggle;
355
+ this.setState({
356
+ isShowingPopover: shown
357
+ });
358
+
359
+ if (typeof onToggle === 'function') {
360
+ onToggle(event, {
361
+ shown,
362
+ drilldown: this,
363
+ ...this.exposedNavigationProps
364
+ });
365
+ }
366
+ };
367
+
368
+ this.state = {
369
+ isShowingPopover: props.trigger ? !!props.show : false,
370
+ activePageId: props.rootPageId,
371
+ highlightedOptionId: void 0,
372
+ lastSelectedId: void 0
373
+ };
374
+ this._pageHistory = [props.rootPageId];
375
+ this.setDefaultSelected();
376
+ this._id = props.id || props.deterministicId();
377
+ this._triggerId = props.deterministicId('Drilldown-Trigger');
378
+ this._headerBackId = props.deterministicId('DrilldownHeader-Back');
379
+ this._headerTitleId = props.deterministicId('DrilldownHeader-Title');
380
+ this._headerTitleLabelId = props.deterministicId('DrilldownHeader-Title-Label');
381
+ this._headerActionId = props.deterministicId('DrilldownHeader-Action');
382
+ }
383
+
384
+ componentDidMount() {
385
+ var _this$props$makeStyle, _this$props2;
386
+
387
+ (_this$props$makeStyle = (_this$props2 = this.props).makeStyles) === null || _this$props$makeStyle === void 0 ? void 0 : _this$props$makeStyle.call(_this$props2, this.makeStylesVariables);
388
+ }
389
+
390
+ componentDidUpdate(_prevProps, prevState) {
391
+ var _this$props$makeStyle2, _this$props3;
392
+
393
+ (_this$props$makeStyle2 = (_this$props3 = this.props).makeStyles) === null || _this$props$makeStyle2 === void 0 ? void 0 : _this$props$makeStyle2.call(_this$props3, this.makeStylesVariables);
394
+
395
+ if (prevState.activePageId !== this.state.activePageId) {
396
+ // on page change with mouse navigation, some option can get rendered
397
+ // under the cursor and get focused, so we need to wait a tick to see
398
+ // if anything gets focused, otherwise we focus the whole drilldown
399
+ setTimeout(() => {
400
+ if (!this.focused()) {
401
+ this.focus();
402
+ }
403
+ }, 0);
404
+ } // if the current page was removed
405
+
406
+
407
+ if (!this.currentPage) {
408
+ if (this.previousPage) {
409
+ this.goToPreviousPage();
410
+ } else {
411
+ this.goToPage(this.props.rootPageId);
412
+ }
413
+ }
414
+
415
+ if (this.state.highlightedOptionId && !this.getPageChildById(this.state.highlightedOptionId)) {
416
+ this.setState({
417
+ highlightedOptionId: void 0
418
+ });
419
+ }
420
+ }
421
+
422
+ get makeStylesVariables() {
423
+ return {
424
+ hasHighlightedOption: !!this.state.highlightedOptionId
425
+ };
426
+ }
427
+
428
+ get activeOptionIds() {
429
+ return Object.keys(this._activeOptionsMap);
430
+ }
431
+
432
+ get activeOptions() {
433
+ return Object.values(this._activeOptionsMap);
434
+ }
435
+
436
+ get pages() {
437
+ const children = this.props.children;
438
+ return React.Children.toArray(children || []);
439
+ }
440
+
441
+ get pageMap() {
442
+ const children = this.props.children;
443
+
444
+ if (!children) {
445
+ return void 0;
446
+ }
447
+
448
+ const map = {};
449
+ this.pages.forEach(page => {
450
+ const props = page.props;
451
+ const children = props.children;
452
+ map[props.id] = { ...props,
453
+ children: React.Children.toArray(children || [])
454
+ };
455
+ });
456
+ return map;
457
+ }
458
+
459
+ get isOnRootPage() {
460
+ return this.state.activePageId === this.props.rootPageId;
461
+ }
462
+
463
+ get currentPage() {
464
+ return this.getPageById(this.state.activePageId);
465
+ }
466
+
467
+ get previousPage() {
468
+ const previousPageId = this._pageHistory[this._pageHistory.length - 2];
469
+ return this.getPageById(previousPageId);
470
+ } // Returns the navigation methods and the page history.
471
+ // These are used in some callbacks to expose the navigation logic.
472
+
473
+
474
+ get exposedNavigationProps() {
475
+ const goToPage = this.goToPage,
476
+ goToPreviousPage = this.goToPreviousPage; // we make a copy of the array so the original history
477
+ // cannot be modified from the outside
478
+
479
+ const pageHistory = [...this._pageHistory];
480
+ return {
481
+ pageHistory,
482
+ goToPage,
483
+ goToPreviousPage
484
+ };
485
+ }
486
+
487
+ get currentPageAriaLabel() {
488
+ var _this$currentPage;
489
+
490
+ // return, if explicitly set
491
+ if (this.props['aria-labelledby']) {
492
+ return this.props['aria-labelledby'];
493
+ } // if it has title, point to the title label content
494
+
495
+
496
+ if ((_this$currentPage = this.currentPage) !== null && _this$currentPage !== void 0 && _this$currentPage.renderTitle) {
497
+ return this._headerTitleLabelId;
498
+ } // if root page has no title, try the trigger, if exists
499
+
500
+
501
+ if (this.isOnRootPage && this.props.trigger) {
502
+ return this._triggerId;
503
+ }
504
+
505
+ return void 0;
506
+ }
507
+
508
+ getChildrenArray(children) {
509
+ if (!children) {
510
+ return [];
511
+ }
512
+
513
+ return Array.isArray(children) ? children : [children];
514
+ }
515
+
516
+ getPageById(id) {
517
+ return this.pageMap && id ? this.pageMap[id] : void 0;
518
+ }
519
+
520
+ getPageChildById(id) {
521
+ return id ? this._activeOptionsMap[id] : void 0;
522
+ }
523
+
524
+ setDefaultSelected() {
525
+ this.pages.forEach(page => {
526
+ const children = page.props.children;
527
+ this.getChildrenArray(children).forEach(child => {
528
+ if (matchComponentTypes(child, [DrilldownGroup])) {
529
+ var _this$getChildrenArra;
530
+
531
+ const _child$props = child.props,
532
+ groupId = _child$props.id,
533
+ selectableType = _child$props.selectableType,
534
+ _child$props$defaultS = _child$props.defaultSelected,
535
+ groupDefaultSelected = _child$props$defaultS === void 0 ? [] : _child$props$defaultS,
536
+ groupChildren = _child$props.children;
537
+
538
+ if (!selectableType) {
539
+ return;
540
+ }
541
+
542
+ if (selectableType === 'single' && groupDefaultSelected.length > 1) {
543
+ error(false, `Radio type selectable groups can have only one item selected! Group with id "${groupId}" cannot select multiple items: [${groupDefaultSelected.join(', ')}]!`);
544
+ return;
545
+ }
546
+
547
+ this._selectedGroupOptionsMap[groupId] = new Map();
548
+ (_this$getChildrenArra = this.getChildrenArray(groupChildren)) === null || _this$getChildrenArra === void 0 ? void 0 : _this$getChildrenArra.forEach(groupChild => {
549
+ if (matchComponentTypes(groupChild, [DrilldownOption])) {
550
+ const _groupChild$props = groupChild.props,
551
+ optionId = _groupChild$props.id,
552
+ optionValue = _groupChild$props.value,
553
+ optionDefaultSelected = _groupChild$props.defaultSelected; // if explicitly set to false, it should override the group's
554
+
555
+ if (optionDefaultSelected === false) {
556
+ return;
557
+ }
558
+
559
+ const isGroupDefaultSelected = typeof optionValue !== 'undefined' && groupDefaultSelected.filter(value => typeof value !== 'undefined').includes(optionValue);
560
+
561
+ if (optionDefaultSelected || isGroupDefaultSelected) {
562
+ this._selectedGroupOptionsMap[groupId].set(optionId, optionValue);
563
+ }
564
+ }
565
+ });
566
+ }
567
+ });
568
+ });
569
+ }
570
+
571
+ get selectedGroupOptionIdsArray() {
572
+ return Object.values(this._selectedGroupOptionsMap).map(groupIdMap => Array.from(groupIdMap.keys())).flat();
573
+ }
574
+
575
+ get headerChildren() {
576
+ const currentPage = this.currentPage;
577
+ const _this$props4 = this.props,
578
+ styles = _this$props4.styles,
579
+ deterministicId = _this$props4.deterministicId;
580
+ const headerChildren = [];
581
+
582
+ if (!currentPage) {
583
+ return headerChildren;
584
+ }
585
+
586
+ const children = currentPage.children,
587
+ renderBackButtonLabel = currentPage.renderBackButtonLabel,
588
+ renderTitle = currentPage.renderTitle,
589
+ renderActionLabel = currentPage.renderActionLabel,
590
+ onHeaderActionClicked = currentPage.onHeaderActionClicked,
591
+ withoutHeaderSeparator = currentPage.withoutHeaderSeparator; // Back navigation option
592
+
593
+ if (this.previousPage) {
594
+ const prevPageTitle = callRenderProp(this.previousPage.renderTitle);
595
+ const backButtonLabel = callRenderProp(renderBackButtonLabel, prevPageTitle);
596
+ headerChildren.push(jsx(DrilldownOption, {
597
+ id: this._headerBackId,
598
+ onOptionClick: this.handleBackButtonClick
599
+ }, jsx("div", {
600
+ css: styles === null || styles === void 0 ? void 0 : styles.headerBack,
601
+ role: "presentation"
602
+ }, backButtonLabel)));
603
+ } // Header title
604
+
605
+
606
+ if (renderTitle) {
607
+ const title = callRenderProp(renderTitle);
608
+
609
+ if (title) {
610
+ headerChildren.push(jsx(DrilldownOption, {
611
+ id: this._headerTitleId,
612
+ role: "presentation",
613
+ "aria-hidden": "true"
614
+ }, jsx("div", {
615
+ css: styles === null || styles === void 0 ? void 0 : styles.headerTitle,
616
+ id: this._headerTitleLabelId
617
+ }, title)));
618
+ }
619
+ } // Action label
620
+
621
+
622
+ if (renderActionLabel) {
623
+ const actionLabel = callRenderProp(renderActionLabel);
624
+
625
+ if (actionLabel) {
626
+ headerChildren.push(jsx(DrilldownOption, {
627
+ id: this._headerActionId,
628
+ themeOverride: {
629
+ color: styles === null || styles === void 0 ? void 0 : styles.headerActionColor
630
+ },
631
+ onOptionClick: event => {
632
+ if (typeof onHeaderActionClicked === 'function') {
633
+ onHeaderActionClicked(event);
634
+ }
635
+ }
636
+ }, actionLabel));
637
+ }
638
+ } // header separator
639
+
640
+
641
+ if (headerChildren.length > 0 && children.length > 0 && !withoutHeaderSeparator) {
642
+ headerChildren.push(jsx(DrilldownSeparator, {
643
+ id: deterministicId('DrilldownHeader-Separator')
644
+ }));
645
+ }
646
+
647
+ return headerChildren;
648
+ }
649
+
650
+ get shown() {
651
+ return this.props.trigger ? this.state.isShowingPopover : true;
652
+ }
653
+
654
+ reset() {
655
+ this._activeOptionsMap = {};
656
+ this.setState({
657
+ highlightedOptionId: void 0
658
+ });
659
+ }
660
+
661
+ focus() {
662
+ if (this.shown) {
663
+ var _this$_drilldownRef2, _this$_drilldownRef3;
664
+
665
+ error(!!((_this$_drilldownRef2 = this._drilldownRef) !== null && _this$_drilldownRef2 !== void 0 && _this$_drilldownRef2.focus), '[Drilldown] Could not focus the drilldown.');
666
+ (_this$_drilldownRef3 = this._drilldownRef) === null || _this$_drilldownRef3 === void 0 ? void 0 : _this$_drilldownRef3.focus();
667
+ } else {
668
+ var _this$_trigger;
669
+
670
+ error(!!((_this$_trigger = this._trigger) !== null && _this$_trigger !== void 0 && _this$_trigger.focus), '[Drilldown] Could not focus the trigger.');
671
+
672
+ this._trigger.focus();
673
+ }
674
+ }
675
+
676
+ focused() {
677
+ if (this.shown) {
678
+ return containsActiveElement(this._drilldownRef);
679
+ } else {
680
+ return containsActiveElement(this._trigger);
681
+ }
682
+ }
683
+
684
+ focusOption(id) {
685
+ const container = this._containerElement;
686
+ const optionElement = container === null || container === void 0 ? void 0 : container.querySelector(`[id="${id}"]`);
687
+ optionElement === null || optionElement === void 0 ? void 0 : optionElement.focus();
688
+ }
689
+
690
+ handleGroupOptionSelected(event, selectedOption) {
691
+ const _selectedOption$props = selectedOption.props,
692
+ optionId = _selectedOption$props.id,
693
+ value = _selectedOption$props.value;
694
+ const _ref6 = selectedOption.groupProps,
695
+ groupId = _ref6.id,
696
+ selectableType = _ref6.selectableType,
697
+ groupOnSelect = _ref6.onSelect;
698
+ const onSelect = this.props.onSelect;
699
+
700
+ if (this._selectedGroupOptionsMap[groupId].has(optionId)) {
701
+ // toggle off, if already selected
702
+ this._selectedGroupOptionsMap[groupId].delete(optionId);
703
+ } else {
704
+ if (selectableType === 'multiple') {
705
+ // "checkbox"
706
+ this._selectedGroupOptionsMap[groupId].set(optionId, value);
707
+ } else if (selectableType === 'single') {
708
+ // "radio"
709
+ this._selectedGroupOptionsMap[groupId] = new Map();
710
+
711
+ this._selectedGroupOptionsMap[groupId].set(optionId, value);
712
+ }
713
+ } // needed for rerender
714
+
715
+
716
+ this.setState({
717
+ lastSelectedId: optionId
718
+ });
719
+
720
+ const groupProps = selectedOption.groupProps,
721
+ option = _objectWithoutProperties(selectedOption, _excluded2);
722
+
723
+ const selectedOptionValuesInGroup = Array.from(this._selectedGroupOptionsMap[groupId].values());
724
+
725
+ if (typeof groupOnSelect === 'function') {
726
+ groupOnSelect(event, {
727
+ value: selectedOptionValuesInGroup,
728
+ isSelected: this._selectedGroupOptionsMap[groupId].has(optionId),
729
+ selectedOption: option,
730
+ drilldown: this
731
+ });
732
+ }
733
+
734
+ if (typeof onSelect === 'function') {
735
+ onSelect(event, {
736
+ value: selectedOptionValuesInGroup,
737
+ isSelected: this._selectedGroupOptionsMap[groupId].has(optionId),
738
+ selectedOption: option,
739
+ drilldown: this
740
+ });
741
+ }
742
+ }
743
+
744
+ renderList(getOptionProps, getDisabledOptionProps) {
745
+ const currentPage = this.currentPage,
746
+ headerChildren = this.headerChildren;
747
+
748
+ if (!currentPage) {
749
+ return null;
750
+ }
751
+
752
+ const pageChildren = [...headerChildren, ...currentPage.children]; // for tracking if the last item was a Separator or not
753
+
754
+ let lastItemWasSeparator = false;
755
+ return pageChildren.map((child, index) => {
756
+ /**
757
+ * --- RENDER GROUP ---
758
+ */
759
+ if (matchComponentTypes(child, [DrilldownGroup])) {
760
+ const isFirstChild = index === 0;
761
+ const isLastChild = index === pageChildren.length - 1;
762
+ const afterSeparator = lastItemWasSeparator;
763
+ const needsFirstSeparator = !child.props.withoutSeparators && !isFirstChild && !afterSeparator;
764
+ const needsLastSeparator = !child.props.withoutSeparators && !isLastChild;
765
+ lastItemWasSeparator = needsLastSeparator;
766
+ return this.renderGroup(child, getOptionProps, getDisabledOptionProps, // for rendering separators appropriately
767
+ needsFirstSeparator, needsLastSeparator);
768
+ /**
769
+ * --- RENDER SEPARATOR ---
770
+ */
771
+ } else if (matchComponentTypes(child, [DrilldownSeparator])) {
772
+ // if the last item was separator, we don't want to duplicate it
773
+ if (lastItemWasSeparator) {
774
+ return null;
775
+ }
776
+
777
+ lastItemWasSeparator = true;
778
+ return this.renderSeparator(child);
779
+ /**
780
+ * --- RENDER OPTION ---
781
+ */
782
+ } else if (matchComponentTypes(child, [DrilldownOption])) {
783
+ lastItemWasSeparator = false;
784
+ return this.renderOption(child, getOptionProps, getDisabledOptionProps);
785
+ } else {
786
+ return null;
787
+ }
788
+ });
789
+ }
790
+
791
+ renderSeparator(separator) {
792
+ const _separator$props = separator.props,
793
+ id = _separator$props.id,
794
+ themeOverride = _separator$props.themeOverride,
795
+ props = _objectWithoutProperties(_separator$props, _excluded3);
796
+
797
+ return jsx(Options.Separator, Object.assign({}, props, {
798
+ id: id,
799
+ key: id,
800
+ role: "separator" // we pass the themeOverride to Options.Separator
801
+ ,
802
+ themeOverride: themeOverride
803
+ }));
804
+ }
805
+
806
+ renderOption(option, getOptionProps, getDisabledOptionProps, groupProps) {
807
+ var _this$currentPage2, _optionProps$renderBe, _optionProps$renderBe2, _optionProps$renderAf, _optionProps$renderAf2;
808
+
809
+ const styles = this.props.styles;
810
+ let isSelected = false;
811
+ const _option$props = option.props,
812
+ id = _option$props.id,
813
+ children = _option$props.children,
814
+ href = _option$props.href,
815
+ as = _option$props.as,
816
+ role = _option$props.role,
817
+ subPageId = _option$props.subPageId,
818
+ disabled = _option$props.disabled,
819
+ renderLabelInfo = _option$props.renderLabelInfo,
820
+ renderBeforeLabel = _option$props.renderBeforeLabel,
821
+ renderAfterLabel = _option$props.renderAfterLabel,
822
+ beforeLabelContentVAlign = _option$props.beforeLabelContentVAlign,
823
+ afterLabelContentVAlign = _option$props.afterLabelContentVAlign,
824
+ description = _option$props.description,
825
+ descriptionRole = _option$props.descriptionRole,
826
+ elementRef = _option$props.elementRef,
827
+ themeOverride = _option$props.themeOverride;
828
+
829
+ if (!id) {
830
+ warn(false, `Drilldown.Option without id won't be rendered. It is needed to internally track the options.`);
831
+ return null;
832
+ }
833
+
834
+ if (this.getPageChildById(id)) {
835
+ warn(false, `Duplicate id: "${id}"! Make sure all options have unique ids, otherwise they won't be rendered.`);
836
+ return null;
837
+ } // Props passed to the Option.Item
838
+
839
+
840
+ let optionProps = { // passthrough props
841
+ ...omitProps(option.props, [...DrilldownOption.allowedProps, ...Options.Item.allowedProps]),
842
+ // props from selectable
843
+ ...getOptionProps({
844
+ id,
845
+ // aria-selected is only valid for these roles, otherwise we need to unset it
846
+ ...(role && !['gridcell', 'option', 'row', 'tab', 'columnheader', 'rowheader', 'treeitem'].includes(role) && {
847
+ 'aria-selected': void 0
848
+ })
849
+ }),
850
+ // we pass the themeOverride to Options.Item
851
+ themeOverride,
852
+ // directly passed props
853
+ renderBeforeLabel,
854
+ renderAfterLabel,
855
+ beforeLabelContentVAlign,
856
+ afterLabelContentVAlign,
857
+ description,
858
+ descriptionRole,
859
+ as,
860
+ role,
861
+ elementRef,
862
+ variant: 'default',
863
+ tabIndex: -1
864
+ }; // extra data we need track on the option,
865
+ // but don't want to expose as props
866
+
867
+ const optionData = {
868
+ groupProps: groupProps
869
+ };
870
+ const isOptionDisabled = id !== this._headerBackId && ( // Back nav is never disabled
871
+ this.props.disabled || ((_this$currentPage2 = this.currentPage) === null || _this$currentPage2 === void 0 ? void 0 : _this$currentPage2.disabled) || (groupProps === null || groupProps === void 0 ? void 0 : groupProps.disabled) || disabled); // display option as disabled
872
+
873
+ if (isOptionDisabled) {
874
+ optionProps.variant = 'disabled';
875
+ optionProps = { ...optionProps,
876
+ ...getDisabledOptionProps()
877
+ };
878
+ } // track as valid active option if not the title
879
+
880
+
881
+ if (id !== this._headerTitleId) {
882
+ this._activeOptionsMap[id] = { ...option,
883
+ ...optionData
884
+ };
885
+ }
886
+
887
+ const customRole = role !== DrilldownOption.defaultProps.role ? role : void 0; // BEFORE/AFTER elements:
888
+ // we set a few manually on Options.Item,
889
+ // the rest are passed directly
890
+
891
+ if (subPageId) {
892
+ optionProps.renderAfterLabel = _IconArrowOpenEndSoli || (_IconArrowOpenEndSoli = jsx(IconArrowOpenEndSolid, null));
893
+ optionProps['aria-haspopup'] = true;
894
+ optionProps.role = customRole || 'button';
895
+ warn(!renderAfterLabel, `The prop "renderAfterLabel" is reserved on item with id: "${id}". When it has "subPageId" provided, a navigation arrow will render after the label.`);
896
+ }
897
+
898
+ if (id === this._headerBackId) {
899
+ optionProps.renderBeforeLabel = _IconArrowOpenStartSo || (_IconArrowOpenStartSo = jsx(IconArrowOpenStartSolid, null));
900
+ }
901
+
902
+ if (groupProps !== null && groupProps !== void 0 && groupProps.selectableType) {
903
+ isSelected = this._selectedGroupOptionsMap[groupProps.id].has(id);
904
+ optionProps['aria-checked'] = isSelected;
905
+ optionProps.renderBeforeLabel = jsx(IconCheckSolid, {
906
+ style: {
907
+ opacity: isSelected ? 1 : 0
908
+ }
909
+ });
910
+ warn(!renderBeforeLabel, `The prop "renderBeforeLabel" is reserved on item with id: "${id}". When this option is a selectable member of a Drilldown.Group, selection indicator will render before the label.`); // setting aria roles and attributes for selectable group items
911
+
912
+ if (groupProps.selectableType === 'single') {
913
+ optionProps.role = customRole || 'menuitemradio';
914
+ }
915
+
916
+ if (groupProps.selectableType === 'multiple') {
917
+ optionProps.role = customRole || 'menuitemcheckbox';
918
+ }
919
+ } // display option as highlighted
920
+
921
+
922
+ if (id === this.state.highlightedOptionId) {
923
+ optionProps.variant = 'highlighted';
924
+
925
+ if (isOptionDisabled) {
926
+ optionProps.variant = 'highlighted-disabled';
927
+ }
928
+ }
929
+
930
+ if (href) {
931
+ if (subPageId) {
932
+ warn(false, `Drilldown.Option with id "${id}" has subPageId, so it will ignore the "href" property.`);
933
+ } else if (groupProps !== null && groupProps !== void 0 && groupProps.selectableType) {
934
+ warn(false, `Drilldown.Option with id "${id}" is in a selectable group, so it will ignore the "href" property.`);
935
+ } else {
936
+ optionProps.href = href;
937
+ }
938
+ }
939
+
940
+ const optionLabel = callRenderProp(children, {
941
+ id,
942
+ variant: optionProps.variant,
943
+ isSelected
944
+ });
945
+
946
+ if (!optionLabel) {
947
+ warn(false, `There are no "children" prop provided for option with id: "${id}", so it won't be rendered.`);
948
+ return null;
949
+ }
950
+
951
+ const renderLabelProps = {
952
+ variant: optionProps.variant,
953
+ vAlign: afterLabelContentVAlign,
954
+ as,
955
+ role: optionProps.role,
956
+ isSelected
957
+ }; // we need to bind our own option props the render functions
958
+
959
+ if (typeof optionProps.renderBeforeLabel === 'function' && !((_optionProps$renderBe = optionProps.renderBeforeLabel) !== null && _optionProps$renderBe !== void 0 && (_optionProps$renderBe2 = _optionProps$renderBe.prototype) !== null && _optionProps$renderBe2 !== void 0 && _optionProps$renderBe2.isReactComponent)) {
960
+ optionProps.renderBeforeLabel = optionProps.renderBeforeLabel.bind(null, renderLabelProps);
961
+ }
962
+
963
+ if (typeof optionProps.renderAfterLabel === 'function' && !((_optionProps$renderAf = optionProps.renderAfterLabel) !== null && _optionProps$renderAf !== void 0 && (_optionProps$renderAf2 = _optionProps$renderAf.prototype) !== null && _optionProps$renderAf2 !== void 0 && _optionProps$renderAf2.isReactComponent)) {
964
+ optionProps.renderAfterLabel = optionProps.renderAfterLabel.bind(null, renderLabelProps);
965
+ }
966
+
967
+ const labelInfo = renderLabelInfo && callRenderProp(renderLabelInfo, renderLabelProps);
968
+ const vAlignMap = {
969
+ start: 'flex-start',
970
+ center: 'center',
971
+ end: 'flex-end'
972
+ };
973
+ const labelAriaId = `${id}__label`;
974
+ const infoAriaId = `${id}__info`;
975
+ const labelledby = option.props['aria-labelledby'] || labelAriaId;
976
+ const describedby = option.props['aria-describedby'] || (labelInfo ? infoAriaId : void 0);
977
+ return jsx(Options.Item, Object.assign({}, optionProps, {
978
+ key: id,
979
+ "aria-labelledby": labelledby,
980
+ "aria-describedby": describedby
981
+ }), jsx("div", {
982
+ css: styles === null || styles === void 0 ? void 0 : styles.optionContainer,
983
+ role: "none"
984
+ }, jsx("span", {
985
+ css: styles === null || styles === void 0 ? void 0 : styles.optionContent,
986
+ role: "none",
987
+ id: labelAriaId
988
+ }, optionLabel), labelInfo ? jsx("span", {
989
+ css: styles === null || styles === void 0 ? void 0 : styles.optionLabelInfo,
990
+ role: "presentation",
991
+ style: {
992
+ alignSelf: vAlignMap[afterLabelContentVAlign]
993
+ }
994
+ }, jsx("span", {
995
+ role: "note",
996
+ id: infoAriaId
997
+ }, labelInfo)) : null));
998
+ }
999
+
1000
+ renderGroup(group, getOptionProps, getDisabledOptionProps, needsFirstSeparator, needsLastSeparator) {
1001
+ const _group$props = group.props,
1002
+ id = _group$props.id,
1003
+ children = _group$props.children,
1004
+ renderGroupTitle = _group$props.renderGroupTitle,
1005
+ themeOverride = _group$props.themeOverride,
1006
+ selectableType = _group$props.selectableType,
1007
+ role = _group$props.role,
1008
+ as = _group$props.as,
1009
+ elementRef = _group$props.elementRef;
1010
+
1011
+ if (!children) {
1012
+ return null;
1013
+ }
1014
+
1015
+ const groupChildren = []; // add a separator above
1016
+
1017
+ if (needsFirstSeparator) {
1018
+ groupChildren.push(_Options$Separator || (_Options$Separator = jsx(Options.Separator, null)));
1019
+ }
1020
+
1021
+ if (selectableType && !this._selectedGroupOptionsMap[id]) {
1022
+ this._selectedGroupOptionsMap[id] = new Map();
1023
+ } // create a sublist as a group
1024
+ // (a wrapping list item will be created by Options)
1025
+
1026
+
1027
+ groupChildren.push(jsx(Options, {
1028
+ id: id,
1029
+ key: id,
1030
+ role: role,
1031
+ as: as || this.props.as,
1032
+ renderLabel: renderGroupTitle,
1033
+ elementRef: elementRef // we pass the themeOverride to Options
1034
+ ,
1035
+ themeOverride: themeOverride
1036
+ }, this.getChildrenArray(children).map(child => {
1037
+ if (matchComponentTypes(child, [DrilldownSeparator])) {
1038
+ return this.renderSeparator(child);
1039
+ } else if (matchComponentTypes(child, [DrilldownOption])) {
1040
+ return this.renderOption(child, getOptionProps, getDisabledOptionProps, group.props);
1041
+ } else {
1042
+ return null;
1043
+ }
1044
+ }))); // add a separator below
1045
+
1046
+ if (needsLastSeparator) {
1047
+ groupChildren.push(_Options$Separator2 || (_Options$Separator2 = jsx(Options.Separator, null)));
1048
+ }
1049
+
1050
+ return groupChildren;
1051
+ }
1052
+
1053
+ renderPage() {
1054
+ const _this$props5 = this.props,
1055
+ styles = _this$props5.styles,
1056
+ overflowY = _this$props5.overflowY,
1057
+ overflowX = _this$props5.overflowX,
1058
+ height = _this$props5.height,
1059
+ width = _this$props5.width,
1060
+ maxHeight = _this$props5.maxHeight,
1061
+ maxWidth = _this$props5.maxWidth,
1062
+ role = _this$props5.role,
1063
+ as = _this$props5.as,
1064
+ label = _this$props5.label;
1065
+
1066
+ if (!this.currentPage) {
1067
+ return null;
1068
+ }
1069
+
1070
+ return jsx(Selectable, {
1071
+ isShowingOptions: this.shown,
1072
+ highlightedOptionId: this.state.highlightedOptionId,
1073
+ selectedOptionId: this.selectedGroupOptionIdsArray,
1074
+ onRequestShowOptions: this.show,
1075
+ onRequestHideOptions: this.hide,
1076
+ onRequestSelectOption: this.handleOptionSelect,
1077
+ onRequestHighlightOption: this.handleOptionHighlight,
1078
+ onRequestHighlightFirstOption: event => {
1079
+ const firstOptionId = this.activeOptionIds[0];
1080
+ this.handleOptionHighlight(event, {
1081
+ id: firstOptionId
1082
+ });
1083
+ },
1084
+ onRequestHighlightLastOption: event => {
1085
+ const lastOptionId = this.activeOptionIds[this.activeOptionIds.length - 1];
1086
+ this.handleOptionHighlight(event, {
1087
+ id: lastOptionId
1088
+ });
1089
+ }
1090
+ }, _ref7 => {
1091
+ let getTriggerProps = _ref7.getTriggerProps,
1092
+ getListProps = _ref7.getListProps,
1093
+ getOptionProps = _ref7.getOptionProps,
1094
+ getDisabledOptionProps = _ref7.getDisabledOptionProps;
1095
+ return jsx(View, Object.assign({
1096
+ as: "div",
1097
+ elementRef: this.handleDrilldownRef,
1098
+ tabIndex: 0,
1099
+ css: styles === null || styles === void 0 ? void 0 : styles.drilldown,
1100
+ position: "relative",
1101
+ borderRadius: "small",
1102
+ width: width,
1103
+ maxWidth: maxWidth,
1104
+ role: role,
1105
+ "aria-label": label,
1106
+ "aria-labelledby": this.currentPageAriaLabel
1107
+ }, getTriggerProps({
1108
+ id: this._id,
1109
+ // We need to override these aria attributes added by Selectable,
1110
+ // since Drilldown is not a combobox and has no popup
1111
+ 'aria-haspopup': false,
1112
+ 'aria-expanded': void 0,
1113
+ onKeyDown: this.handleKeyDown,
1114
+ onBlur: event => {
1115
+ const target = event.currentTarget;
1116
+ const related = event.relatedTarget;
1117
+ const containsRelated = contains(target, related);
1118
+
1119
+ if (!related || related === this._drilldownRef || related !== target && !containsRelated) {
1120
+ this.setState({
1121
+ highlightedOptionId: void 0
1122
+ });
1123
+ }
1124
+ },
1125
+ onMouseLeave: () => {
1126
+ this.setState({
1127
+ highlightedOptionId: void 0
1128
+ });
1129
+ }
1130
+ })), jsx(View, {
1131
+ as: "div",
1132
+ overflowY: overflowY,
1133
+ overflowX: overflowX,
1134
+ height: height,
1135
+ width: width,
1136
+ maxHeight: maxHeight,
1137
+ maxWidth: maxWidth,
1138
+ css: styles === null || styles === void 0 ? void 0 : styles.container,
1139
+ borderRadius: "small",
1140
+ role: "presentation",
1141
+ elementRef: element => {
1142
+ this._containerElement = element;
1143
+ }
1144
+ }, jsx(Options, Object.assign({}, getListProps(), {
1145
+ role: "presentation",
1146
+ as: as
1147
+ }), this.renderList(getOptionProps, getDisabledOptionProps))));
1148
+ });
1149
+ }
1150
+
1151
+ render() {
1152
+ // clear temporary option store
1153
+ this._activeOptionsMap = {};
1154
+ const _this$props6 = this.props,
1155
+ show = _this$props6.show,
1156
+ defaultShow = _this$props6.defaultShow,
1157
+ placement = _this$props6.placement,
1158
+ withArrow = _this$props6.withArrow,
1159
+ shouldContainFocus = _this$props6.shouldContainFocus,
1160
+ shouldReturnFocus = _this$props6.shouldReturnFocus,
1161
+ trigger = _this$props6.trigger,
1162
+ mountNode = _this$props6.mountNode,
1163
+ constrain = _this$props6.constrain,
1164
+ positionTarget = _this$props6.positionTarget,
1165
+ popoverRef = _this$props6.popoverRef,
1166
+ disabled = _this$props6.disabled,
1167
+ onDismiss = _this$props6.onDismiss,
1168
+ onFocus = _this$props6.onFocus,
1169
+ onMouseOver = _this$props6.onMouseOver,
1170
+ offsetX = _this$props6.offsetX,
1171
+ offsetY = _this$props6.offsetY;
1172
+ return trigger ? jsx(Popover, {
1173
+ isShowingContent: show,
1174
+ defaultIsShowingContent: defaultShow,
1175
+ shouldCloseOnDocumentClick: true,
1176
+ onHideContent: (event, _ref8) => {
1177
+ let documentClick = _ref8.documentClick;
1178
+
1179
+ if (typeof onDismiss === 'function') {
1180
+ onDismiss(event, documentClick);
1181
+ }
1182
+
1183
+ this.reset();
1184
+ this.handleToggle(event, false);
1185
+ },
1186
+ onShowContent: event => this.handleToggle(event, true),
1187
+ mountNode: mountNode,
1188
+ placement: placement,
1189
+ withArrow: withArrow,
1190
+ positionTarget: positionTarget,
1191
+ constrain: constrain,
1192
+ shouldContainFocus: shouldContainFocus,
1193
+ shouldReturnFocus: shouldReturnFocus,
1194
+ id: this._id,
1195
+ on: ['click'],
1196
+ onFocus: onFocus,
1197
+ onMouseOver: onMouseOver,
1198
+ offsetX: offsetX,
1199
+ offsetY: offsetY,
1200
+ elementRef: element => {
1201
+ // setting ref for "Popover" version, the popover root
1202
+ // (if there is no trigger, we set it in handleDrilldownRef)
1203
+ this.handleRef(element);
1204
+ },
1205
+ ref: el => {
1206
+ this._popover = el;
1207
+
1208
+ if (typeof popoverRef === 'function') {
1209
+ popoverRef(el);
1210
+ }
1211
+ },
1212
+ renderTrigger: safeCloneElement(trigger, {
1213
+ ref: el => {
1214
+ this._trigger = el;
1215
+ },
1216
+ 'aria-haspopup': this.props.role,
1217
+ id: this._triggerId,
1218
+ disabled: !!(trigger.props.disabled || disabled),
1219
+ 'aria-disabled': trigger.props.disabled || disabled ? 'true' : void 0
1220
+ })
1221
+ }, this.renderPage()) : this.renderPage();
1222
+ }
1223
+
1224
+ }, _class2.displayName = "Drilldown", _class2.componentId = 'Drilldown', _class2.propTypes = propTypes, _class2.allowedProps = allowedProps, _class2.defaultProps = {
1225
+ disabled: false,
1226
+ rotateFocus: true,
1227
+ as: 'ul',
1228
+ role: 'menu',
1229
+ overflowX: 'auto',
1230
+ overflowY: 'auto',
1231
+ placement: 'bottom center',
1232
+ defaultShow: false,
1233
+ shouldHideOnSelect: true,
1234
+ shouldContainFocus: false,
1235
+ shouldReturnFocus: true,
1236
+ withArrow: true,
1237
+ offsetX: 0,
1238
+ offsetY: 0
1239
+ }, _class2.Group = DrilldownGroup, _class2.Option = DrilldownOption, _class2.Page = DrilldownPage, _class2.Separator = DrilldownSeparator, _temp)) || _class) || _class) || _class);
1240
+ export default Drilldown;
1241
+ export { Drilldown };