@nebula.js/stardust 4.0.0-alpha.5 → 4.0.0-alpha.7

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/core/esm/dev.js CHANGED
@@ -1,14 +1,14 @@
1
1
  /*
2
- * @nebula.js/stardust v4.0.0-alpha.5
2
+ * @nebula.js/stardust v4.0.0-alpha.7
3
3
  * Copyright (c) 2023 QlikTech International AB
4
4
  * Released under the MIT license.
5
5
  */
6
6
 
7
7
  import * as React from 'react';
8
- import React__default, { useState as useState$1, useEffect as useEffect$1, forwardRef, useMemo as useMemo$1, useImperativeHandle as useImperativeHandle$1, useReducer, useCallback, useLayoutEffect as useLayoutEffect$1, PureComponent, useRef, createElement, useContext } from 'react';
8
+ import React__default, { useState as useState$1, useEffect as useEffect$1, forwardRef, useMemo as useMemo$1, useImperativeHandle as useImperativeHandle$1, useReducer, useCallback, useLayoutEffect as useLayoutEffect$1, PureComponent, useRef, useContext, createElement } from 'react';
9
9
  import ReactDOM from 'react-dom';
10
10
  import { CacheProvider, ThemeContext as ThemeContext$2 } from '@emotion/react';
11
- import { Checkbox, Radio, Typography, FormControlLabel, Box, Grid, Tooltip, Paper, IconButton, Popover, MenuList, MenuItem, ListItemIcon, Divider, InputAdornment, OutlinedInput, Badge, List, ListItem, Button, Icon, CircularProgress } from '@mui/material';
11
+ import { Checkbox, Radio, Typography, FormControlLabel, Box, Grid, Tooltip, Paper, IconButton, styled as styled$4, Popover, MenuList, MenuItem, ListItemIcon, Divider, InputAdornment, OutlinedInput, Badge, List, ListItem, Button, Icon, CircularProgress } from '@mui/material';
12
12
  import styled$3 from '@emotion/styled';
13
13
 
14
14
  function getAugmentedNamespace(n) {
@@ -1496,7 +1496,7 @@ var Selection_SelectPossible = {
1496
1496
  var SelectionToolbar_ClickToUnlock = {
1497
1497
  id: "SelectionToolbar.ClickToUnlock",
1498
1498
  locale: {
1499
- "de-DE": "Klicken zum Freigeben",
1499
+ "de-DE": "Zum Entsperren klicken",
1500
1500
  "en-US": "Click to unlock",
1501
1501
  "es-ES": "Haga clic para desbloquearla",
1502
1502
  "fr-FR": "Cliquez pour déverrouiller",
@@ -8064,7 +8064,7 @@ function create$3(definition) {
8064
8064
  return cache[key];
8065
8065
  }
8066
8066
 
8067
- const NEBULA_VERSION_HASH = "6643" ;
8067
+ const NEBULA_VERSION_HASH = "a704" ;
8068
8068
  ClassNameGenerator$1.configure(componentName => {
8069
8069
  return "njs-".concat(NEBULA_VERSION_HASH, "-").concat(componentName.replace('Mui', ''));
8070
8070
  });
@@ -8272,7 +8272,7 @@ function boot(_ref2) {
8272
8272
  const appRef = React__default.createRef();
8273
8273
  const element = document.createElement('div');
8274
8274
  element.style.display = 'none';
8275
- element.setAttribute('data-nebulajs-version', "4.0.0-alpha.5" );
8275
+ element.setAttribute('data-nebulajs-version', "4.0.0-alpha.7" );
8276
8276
  element.setAttribute('data-app-id', app.id);
8277
8277
  document.body.appendChild(element);
8278
8278
  const root = client.createRoot(element);
@@ -9071,7 +9071,7 @@ function fillRange(elementNbrs, elemNumbersOrdered) {
9071
9071
  return elemNumbersOrdered.slice(min, max + 1);
9072
9072
  }
9073
9073
 
9074
- const getKeyAsToggleSelected = event => !(event.metaKey || event.ctrlKey);
9074
+ const getKeyAsToggleSelected = event => !(event !== null && event !== void 0 && event.metaKey || event !== null && event !== void 0 && event.ctrlKey);
9075
9075
  function useSelectionsInteractions(_ref) {
9076
9076
  let {
9077
9077
  selectionState,
@@ -9112,6 +9112,11 @@ function useSelectionsInteractions(_ref) {
9112
9112
  const selectManually = function () {
9113
9113
  let elementIds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
9114
9114
  let additive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
9115
+ let event = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
9116
+ const toggle = !selectionState.isSingleSelect && getKeyAsToggleSelected(event === null || event === void 0 ? void 0 : event.nativeEvent);
9117
+ if (!toggle) {
9118
+ selectionState.clearItemStates(true);
9119
+ }
9115
9120
  const elemNumbers = [];
9116
9121
  selectionState.updateItems(elementIds, additive, elemNumbers);
9117
9122
  selectionState.setSelectableValuesUpdating();
@@ -9119,7 +9124,7 @@ function useSelectionsInteractions(_ref) {
9119
9124
  selections,
9120
9125
  elemNumbers: additive ? elemNumbers : elementIds,
9121
9126
  isSingleSelect: selectionState.isSingleSelect,
9122
- toggle: !selectionState.isSingleSelect
9127
+ toggle
9123
9128
  });
9124
9129
  };
9125
9130
  const handleSingleSelectKey = (event, target) => {
@@ -9343,6 +9348,84 @@ const KEYS = Object.freeze({
9343
9348
  isArrow: key => key === KEYS.ARROW_UP || key === KEYS.ARROW_DOWN || key === KEYS.ARROW_LEFT || key === KEYS.ARROW_RIGHT
9344
9349
  });
9345
9350
 
9351
+ function removeInnnerTabStops(container) {
9352
+ container === null || container === void 0 ? void 0 : container.querySelectorAll('[tabIndex="0"]').forEach(elm => {
9353
+ elm.setAttribute('tabIndex', -1);
9354
+ });
9355
+ }
9356
+ function removeLastFocused(container) {
9357
+ container === null || container === void 0 ? void 0 : container.querySelectorAll('.last-focused').forEach(elm => {
9358
+ elm.classList.remove('last-focused');
9359
+ });
9360
+ }
9361
+ function getVizCell(container) {
9362
+ return (container === null || container === void 0 ? void 0 : container.closest('.njs-cell')) || (container === null || container === void 0 ? void 0 : container.closest('.qv-gridcell'));
9363
+ }
9364
+
9365
+ // Emulate the keyboard hook, until we support it in the Listbox.
9366
+ function useTempKeyboard(_ref) {
9367
+ let {
9368
+ containerRef,
9369
+ enabled
9370
+ } = _ref;
9371
+ const [keyboardActive, setKeyboardActive] = useState$1(false);
9372
+ const innerTabStops = !enabled || keyboardActive;
9373
+ const keyboard = {
9374
+ enabled,
9375
+ active: keyboardActive,
9376
+ innerTabStops,
9377
+ // does keyboard permit inner tab stops
9378
+ outerTabStops: !innerTabStops,
9379
+ // does keyboard permit outer tab stops
9380
+ blur: resetFocus => {
9381
+ var _containerRef$current;
9382
+ if (!enabled) {
9383
+ return;
9384
+ }
9385
+ setKeyboardActive(false);
9386
+ const vizCell = getVizCell(containerRef.current) || ((_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.parentElement);
9387
+ removeInnnerTabStops(containerRef.current);
9388
+ removeLastFocused(containerRef.current);
9389
+ if (resetFocus && vizCell) {
9390
+ // Move focus to the viz's cell.
9391
+ vizCell.setAttribute('tabIndex', 0);
9392
+ vizCell.focus();
9393
+ }
9394
+ },
9395
+ focus: () => {
9396
+ if (!enabled) {
9397
+ return;
9398
+ }
9399
+ setKeyboardActive(true);
9400
+ const c = containerRef.current;
9401
+ const searchField = c === null || c === void 0 ? void 0 : c.querySelector('.search input');
9402
+ const lastSelectedRow = c === null || c === void 0 ? void 0 : c.querySelector('.value.last-focused');
9403
+ const fieldElement = c === null || c === void 0 ? void 0 : c.querySelector('.value.selector, .value, .ActionsToolbar-item button');
9404
+ const elementToFocus = searchField || lastSelectedRow || fieldElement;
9405
+ elementToFocus === null || elementToFocus === void 0 ? void 0 : elementToFocus.setAttribute('tabIndex', 0);
9406
+ elementToFocus === null || elementToFocus === void 0 ? void 0 : elementToFocus.focus();
9407
+ },
9408
+ focusSelection: () => {
9409
+ const confirmButton = document.querySelector('.actions-toolbar-default-actions .actions-toolbar-confirm');
9410
+ confirmButton === null || confirmButton === void 0 ? void 0 : confirmButton.setAttribute('tabIndex', 0);
9411
+ confirmButton === null || confirmButton === void 0 ? void 0 : confirmButton.focus();
9412
+ }
9413
+ };
9414
+ return keyboard;
9415
+ }
9416
+
9417
+ const getElementIndex = currentTarget => +currentTarget.getAttribute('data-n');
9418
+ const focusSearch = container => {
9419
+ const searchField = container === null || container === void 0 ? void 0 : container.querySelector('.search input');
9420
+ searchField === null || searchField === void 0 ? void 0 : searchField.focus();
9421
+ return searchField;
9422
+ };
9423
+ const focusRow = container => {
9424
+ const row = container === null || container === void 0 ? void 0 : container.querySelector('.value.last-focused, .value.selector, .value');
9425
+ row === null || row === void 0 ? void 0 : row.setAttribute('tabIndex', 0);
9426
+ row === null || row === void 0 ? void 0 : row.focus();
9427
+ return row;
9428
+ };
9346
9429
  function getFieldKeyboardNavigation(_ref) {
9347
9430
  let {
9348
9431
  select,
@@ -9351,7 +9434,9 @@ function getFieldKeyboardNavigation(_ref) {
9351
9434
  confirm,
9352
9435
  cancel,
9353
9436
  setScrollPosition,
9354
- focusListItems
9437
+ focusListItems,
9438
+ keyboard,
9439
+ isModal
9355
9440
  } = _ref;
9356
9441
  const getElement = function (elm) {
9357
9442
  let next = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@@ -9364,49 +9449,86 @@ function getFieldKeyboardNavigation(_ref) {
9364
9449
  };
9365
9450
  const handleKeyDown = event => {
9366
9451
  let elementToFocus;
9452
+ const {
9453
+ currentTarget,
9454
+ nativeEvent
9455
+ } = event;
9367
9456
  const {
9368
9457
  keyCode,
9369
9458
  shiftKey = false,
9370
9459
  ctrlKey = false,
9371
9460
  metaKey = false
9372
- } = event.nativeEvent;
9461
+ } = nativeEvent;
9373
9462
  switch (keyCode) {
9463
+ case KEYS.TAB:
9464
+ {
9465
+ // Try to focus search field, otherwise confirm button.
9466
+ const container = currentTarget.closest('.listbox-container');
9467
+ const inSelection = isModal();
9468
+
9469
+ // TODO: use a store to keep track of this row.
9470
+ currentTarget.classList.add('last-focused'); // so that we can go back here when we tab back
9471
+
9472
+ if (shiftKey) {
9473
+ if (!focusSearch(container)) {
9474
+ if (inSelection) {
9475
+ keyboard.focusSelection();
9476
+ } else {
9477
+ keyboard.blur(true);
9478
+ }
9479
+ }
9480
+ break;
9481
+ }
9482
+
9483
+ // Without shift key
9484
+ if (inSelection) {
9485
+ keyboard.focusSelection();
9486
+ } else {
9487
+ currentTarget.blur();
9488
+ keyboard.blur();
9489
+ }
9490
+ break;
9491
+ }
9374
9492
  case KEYS.SHIFT:
9375
9493
  // This is to ensure we include the first value when starting a range selection.
9376
9494
  setStartedRange(true);
9377
9495
  break;
9378
9496
  case KEYS.SPACE:
9379
- select([+event.currentTarget.getAttribute('data-n')]);
9497
+ select([getElementIndex(currentTarget)], false, event);
9380
9498
  break;
9381
9499
  case KEYS.ARROW_DOWN:
9382
9500
  case KEYS.ARROW_RIGHT:
9383
- elementToFocus = getElement(event.currentTarget, true);
9501
+ elementToFocus = getElement(currentTarget, true);
9384
9502
  if (shiftKey && elementToFocus) {
9385
9503
  if (startedRange) {
9386
- select([+event.currentTarget.getAttribute('data-n')], true);
9504
+ select([getElementIndex(currentTarget)], true);
9387
9505
  setStartedRange(false);
9388
9506
  }
9389
- select([+elementToFocus.getAttribute('data-n')], true);
9507
+ select([getElementIndex(elementToFocus)], true);
9390
9508
  }
9391
9509
  break;
9392
9510
  case KEYS.ARROW_UP:
9393
9511
  case KEYS.ARROW_LEFT:
9394
- elementToFocus = getElement(event.currentTarget, false);
9512
+ elementToFocus = getElement(currentTarget, false);
9395
9513
  if (shiftKey && elementToFocus) {
9396
9514
  if (startedRange) {
9397
- select([+event.currentTarget.getAttribute('data-n')], true);
9515
+ select([getElementIndex(currentTarget)], true);
9398
9516
  setStartedRange(false);
9399
9517
  }
9400
- select([+elementToFocus.getAttribute('data-n')], true);
9518
+ select([getElementIndex(elementToFocus)], true);
9401
9519
  }
9402
9520
  break;
9403
9521
  case KEYS.ENTER:
9404
9522
  confirm();
9405
9523
  break;
9406
9524
  case KEYS.ESCAPE:
9407
- cancel();
9408
- return;
9409
- // let it propagate to top-level
9525
+ if (isModal()) {
9526
+ cancel();
9527
+ } else {
9528
+ return; // propagate to other Esc handler
9529
+ }
9530
+
9531
+ break;
9410
9532
  case KEYS.HOME:
9411
9533
  focusListItems.setFirst(true);
9412
9534
  if (ctrlKey) {
@@ -9450,39 +9572,41 @@ function getFieldKeyboardNavigation(_ref) {
9450
9572
  }
9451
9573
  function getListboxInlineKeyboardNavigation(_ref2) {
9452
9574
  let {
9453
- setKeyboardActive,
9575
+ keyboard,
9454
9576
  hovering,
9455
9577
  setHovering,
9456
9578
  updateKeyScroll,
9457
9579
  containerRef,
9458
9580
  currentScrollIndex,
9459
- app,
9460
- appSelections,
9581
+ isModal,
9461
9582
  constraints
9462
9583
  } = _ref2;
9463
- const focusInsideListbox = element => {
9464
- const fieldElement = element.querySelector('.search input, .value.selector, .value, .ActionsToolbar-item button');
9465
- setKeyboardActive(true);
9466
- if (fieldElement) {
9467
- fieldElement.focus();
9468
- }
9469
- };
9470
- const changeFocus = event => {
9471
- var _event$target;
9472
- if ((_event$target = event.target) !== null && _event$target !== void 0 && _event$target.classList.contains('listbox-container')) {
9473
- // Focus currently on a listbox
9474
- // Esc on a list box should move the focus to its parent, i.e. a filter pane if any
9475
- setKeyboardActive(false);
9584
+ const blur = event => {
9585
+ const {
9586
+ currentTarget,
9587
+ target
9588
+ } = event;
9589
+ const isFocusedOnListbox = target.classList.contains('listbox-container');
9590
+ const container = currentTarget.closest('.listbox-container');
9591
+ const vizCell = getVizCell(container);
9592
+ const isSingleListbox = (vizCell === null || vizCell === void 0 ? void 0 : vizCell.querySelectorAll('.listbox-container').length) === 1;
9593
+ if (isFocusedOnListbox || isSingleListbox) {
9594
+ // Move the focus from listbox container to the viz container.
9595
+ keyboard.blur(true);
9476
9596
  } else {
9477
- var _event$target2, _event$target3, _event$currentTarget, _event$currentTarget2;
9478
- // Focus currently on a row
9479
- // Esc on a row should move the focus to its parent, i.e. a listbox
9480
- // First unfocus the row
9481
- (_event$target2 = event.target) === null || _event$target2 === void 0 ? void 0 : _event$target2.setAttribute('tabIndex', '-1');
9482
- (_event$target3 = event.target) === null || _event$target3 === void 0 ? void 0 : _event$target3.blur();
9483
- // Then focus the listbox
9484
- (_event$currentTarget = event.currentTarget) === null || _event$currentTarget === void 0 ? void 0 : _event$currentTarget.setAttribute('tabIndex', '0');
9485
- (_event$currentTarget2 = event.currentTarget) === null || _event$currentTarget2 === void 0 ? void 0 : _event$currentTarget2.focus();
9597
+ // More than one listbox: Move focus from row to listbox container.
9598
+
9599
+ // 1. Remove last-focused class from row siblings.
9600
+ removeLastFocused(containerRef.current);
9601
+
9602
+ // 2. Add last-focused class so we can re-focus it later.
9603
+ currentTarget.classList.add('last-focused');
9604
+
9605
+ // 3. Blur row and focus the listbox container.
9606
+ keyboard.blur();
9607
+ const c = currentTarget.closest('.listbox-container');
9608
+ c.setAttribute('tabIndex', 0);
9609
+ c === null || c === void 0 ? void 0 : c.focus();
9486
9610
  }
9487
9611
  };
9488
9612
  const updateKeyScrollOnHover = newState => {
@@ -9496,65 +9620,84 @@ function getListboxInlineKeyboardNavigation(_ref2) {
9496
9620
  ctrlKey = false,
9497
9621
  shiftKey = false
9498
9622
  } = event.nativeEvent;
9623
+ const prevent = () => {
9624
+ event.stopPropagation();
9625
+ event.preventDefault();
9626
+ };
9499
9627
  switch (keyCode) {
9500
- // case KEYS.TAB: TODO: Focus confirm button using keyboard.focusSelection when we can access the useKeyboard hook.
9501
- case KEYS.ENTER:
9502
- case KEYS.SPACE:
9503
- if (!event.target.classList.contains('listbox-container')) {
9504
- return; // don't mess with keydown handlers within the listbox
9505
- }
9506
-
9507
- focusInsideListbox(event.currentTarget);
9508
- break;
9509
- case KEYS.ESCAPE:
9510
- changeFocus(event);
9511
- break;
9512
- case KEYS.ARROW_UP:
9513
- updateKeyScrollOnHover({
9514
- up: 1
9515
- });
9516
- break;
9517
- case KEYS.ARROW_DOWN:
9518
- updateKeyScrollOnHover({
9519
- down: 1
9520
- });
9521
- break;
9522
- case KEYS.ARROW_LEFT:
9523
- case KEYS.ARROW_RIGHT:
9524
- return;
9525
- // let it propagate to top-level
9526
9628
  case KEYS.PAGE_UP:
9527
9629
  updateKeyScrollOnHover({
9528
9630
  up: currentScrollIndex.stop - currentScrollIndex.start
9529
9631
  });
9632
+ prevent();
9530
9633
  break;
9531
9634
  case KEYS.PAGE_DOWN:
9532
9635
  updateKeyScrollOnHover({
9533
9636
  down: currentScrollIndex.stop - currentScrollIndex.start
9534
9637
  });
9638
+ prevent();
9535
9639
  break;
9536
9640
  case KEYS.HOME:
9537
9641
  updateKeyScrollOnHover({
9538
9642
  scrollPosition: ctrlKey && shiftKey ? 'overflowStart' : 'start'
9539
9643
  });
9644
+ prevent();
9540
9645
  break;
9541
9646
  case KEYS.END:
9542
9647
  updateKeyScrollOnHover({
9543
9648
  scrollPosition: ctrlKey && shiftKey ? 'overflowEnd' : 'end'
9544
9649
  });
9650
+ prevent();
9651
+ break;
9652
+ case KEYS.ARROW_UP:
9653
+ updateKeyScrollOnHover({
9654
+ up: 1
9655
+ });
9656
+ prevent();
9657
+ break;
9658
+ case KEYS.ARROW_DOWN:
9659
+ updateKeyScrollOnHover({
9660
+ down: 1
9661
+ });
9662
+ prevent();
9545
9663
  break;
9546
- default:
9547
- return;
9548
9664
  }
9665
+ if (!keyboard.enabled) {
9666
+ // Other keys should not be handled unless keyboard is enabled.
9667
+ return undefined;
9668
+ }
9669
+ const container = event.currentTarget.closest('.listbox-container');
9670
+ switch (keyCode) {
9671
+ case KEYS.TAB:
9672
+ if (shiftKey) {
9673
+ focusRow(container) || focusSearch(container);
9674
+ } else {
9675
+ focusSearch(container) || focusRow(container);
9676
+ }
9677
+ prevent();
9678
+ break;
9679
+ case KEYS.ENTER:
9680
+ case KEYS.SPACE:
9681
+ if (!event.target.classList.contains('listbox-container')) {
9682
+ return undefined; // don't mess with keydown handlers within the listbox (e.g. row seletion)
9683
+ }
9549
9684
 
9550
- // Note: We should not stop propagation here as it will block the containing app
9551
- // from handling keydown events.
9552
- event.preventDefault();
9685
+ keyboard.focus();
9686
+ prevent();
9687
+ break;
9688
+ case KEYS.ESCAPE:
9689
+ blur(event);
9690
+ prevent();
9691
+ break;
9692
+ case KEYS.ARROW_LEFT:
9693
+ case KEYS.ARROW_RIGHT:
9694
+ return undefined;
9695
+ }
9696
+ return undefined;
9553
9697
  };
9554
9698
  const focusOnHoverDisabled = () => {
9555
- var _app$isInModalSelecti, _app$isInModalSelecti2;
9556
9699
  const selectNotAllowed = (constraints === null || constraints === void 0 ? void 0 : constraints.select) || (constraints === null || constraints === void 0 ? void 0 : constraints.active);
9557
- const appInModal = (_app$isInModalSelecti = (_app$isInModalSelecti2 = app.isInModalSelection) === null || _app$isInModalSelecti2 === void 0 ? void 0 : _app$isInModalSelecti2.call(app)) !== null && _app$isInModalSelecti !== void 0 ? _app$isInModalSelecti : appSelections.isInModal();
9700
+ const appInModal = isModal();
9558
9701
  return selectNotAllowed || appInModal;
9559
9702
  };
9560
9703
  const handleOnMouseEnter = () => {
@@ -9759,15 +9902,10 @@ const RowColRoot = styled$1('div', {
9759
9902
  ["& .".concat(rowColClasses.labelDense)]: {
9760
9903
  fontSize: 12
9761
9904
  },
9762
- // Highlight is added to labelText spans, which are created as siblings to original labelText,
9905
+ // Highlight is added to labelText spans, which are created as children to original labelText,
9763
9906
  // when a search string is matched.
9764
9907
  ["& .".concat(rowColClasses.highlighted)]: {
9765
- overflow: 'visible',
9766
- width: '100%',
9767
- '& > span': {
9768
- width: '100%',
9769
- backgroundColor: '#FFC72A'
9770
- }
9908
+ backgroundColor: '#FFC72A'
9771
9909
  },
9772
9910
  // Checkbox and label container.
9773
9911
  ["& .".concat(rowColClasses.checkboxLabel)]: {
@@ -9787,12 +9925,6 @@ const RowColRoot = styled$1('div', {
9787
9925
  paddingRight: '2px'
9788
9926
  })
9789
9927
  },
9790
- ["& .".concat(rowColClasses.checkboxLabel, " .").concat(rowColClasses.labelText)]: {
9791
- width: 'auto'
9792
- },
9793
- ["& .".concat(rowColClasses.checkboxLabel, " .").concat(rowColClasses.labelText, ".").concat(rowColClasses.highlighted)]: {
9794
- width: 'auto'
9795
- },
9796
9928
  // The icons container holding tick and lock, shown inside fields.
9797
9929
  ["& .".concat(rowColClasses.icon)]: {
9798
9930
  display: 'flex',
@@ -10027,7 +10159,6 @@ function ValueField(_ref) {
10027
10159
  let {
10028
10160
  label,
10029
10161
  color,
10030
- highlighted = false,
10031
10162
  dense,
10032
10163
  showGray = true,
10033
10164
  checkboxes,
@@ -10037,14 +10168,14 @@ function ValueField(_ref) {
10037
10168
  return /*#__PURE__*/React__default.createElement(Typography, {
10038
10169
  component: "span",
10039
10170
  variant: "body2",
10040
- className: joinClassNames([rowColClasses.labelText, highlighted && rowColClasses.highlighted, dense && rowColClasses.labelDense, showGray && excludedOrAlternative({
10171
+ className: joinClassNames([rowColClasses.labelText, dense && rowColClasses.labelDense, showGray && excludedOrAlternative({
10041
10172
  cell,
10042
10173
  checkboxes
10043
10174
  }) && rowColClasses.excludedTextWithCheckbox]),
10044
10175
  color: color,
10045
- align: valueTextAlign
10176
+ align: valueTextAlign,
10177
+ dir: "auto"
10046
10178
  }, /*#__PURE__*/React__default.createElement("span", {
10047
- dir: "auto",
10048
10179
  style: {
10049
10180
  whiteSpace: 'pre'
10050
10181
  }
@@ -10055,7 +10186,6 @@ function LabelTag(_ref) {
10055
10186
  let {
10056
10187
  label,
10057
10188
  color,
10058
- highlighted,
10059
10189
  dense,
10060
10190
  showGray,
10061
10191
  checkboxes,
@@ -10066,7 +10196,6 @@ function LabelTag(_ref) {
10066
10196
  return /*#__PURE__*/React__default.createElement(ValueField, {
10067
10197
  label: label,
10068
10198
  color: color,
10069
- highlighted: highlighted,
10070
10199
  dense: dense,
10071
10200
  showGray: showGray,
10072
10201
  checkboxes: checkboxes,
@@ -10089,7 +10218,6 @@ function CheckboxField(_ref) {
10089
10218
  isGridCol,
10090
10219
  showGray,
10091
10220
  isSingleSelect,
10092
- highlighted,
10093
10221
  checkboxes,
10094
10222
  valueTextAlign
10095
10223
  } = _ref;
@@ -10117,7 +10245,6 @@ function CheckboxField(_ref) {
10117
10245
  label: /*#__PURE__*/React__default.createElement(LabelTag, {
10118
10246
  label: label,
10119
10247
  color: color,
10120
- highlighted: highlighted,
10121
10248
  dense: dense,
10122
10249
  showGray: showGray,
10123
10250
  checkboxes: checkboxes,
@@ -10133,23 +10260,21 @@ function LabelsWithRanges(_ref) {
10133
10260
  labels,
10134
10261
  dense,
10135
10262
  showGray,
10136
- checkboxes,
10137
- textDirection
10263
+ checkboxes
10138
10264
  } = _ref;
10139
- return /*#__PURE__*/React__default.createElement("div", {
10140
- dir: textDirection
10141
- }, labels.map((_ref2, index) => {
10265
+ const text = labels.map((_ref2, index) => {
10142
10266
  let [label, highlighted] = _ref2;
10143
- const key = "".concat(index);
10144
- return /*#__PURE__*/React__default.createElement(ValueField, {
10145
- label: label,
10146
- key: key,
10147
- highlighted: highlighted,
10148
- dense: dense,
10149
- showGray: showGray,
10150
- checkboxes: checkboxes
10151
- });
10152
- }));
10267
+ return /*#__PURE__*/React__default.createElement("span", {
10268
+ id: index,
10269
+ className: highlighted ? rowColClasses.highlighted : ''
10270
+ }, label);
10271
+ });
10272
+ return /*#__PURE__*/React__default.createElement(ValueField, {
10273
+ label: text,
10274
+ dense: dense,
10275
+ showGray: showGray,
10276
+ checkboxes: checkboxes
10277
+ });
10153
10278
  }
10154
10279
  function FieldWithRanges(_ref3) {
10155
10280
  let {
@@ -10164,15 +10289,13 @@ function FieldWithRanges(_ref3) {
10164
10289
  cell,
10165
10290
  isGridCol,
10166
10291
  isSingleSelect,
10167
- valueTextAlign,
10168
- textDirection
10292
+ valueTextAlign
10169
10293
  } = _ref3;
10170
10294
  const LWR = /*#__PURE__*/React__default.createElement(LabelsWithRanges, {
10171
10295
  labels: labels,
10172
10296
  dense: dense,
10173
10297
  showGray: showGray,
10174
- checkboxes: checkboxes,
10175
- textDirection: textDirection
10298
+ checkboxes: checkboxes
10176
10299
  });
10177
10300
  return checkboxes ? /*#__PURE__*/React__default.createElement(CheckboxField, {
10178
10301
  onChange: onChange,
@@ -10202,7 +10325,6 @@ function Field(_ref) {
10202
10325
  isGridCol,
10203
10326
  showGray,
10204
10327
  isSingleSelect,
10205
- highlighted,
10206
10328
  checkboxes,
10207
10329
  valueTextAlign
10208
10330
  } = _ref;
@@ -10217,13 +10339,11 @@ function Field(_ref) {
10217
10339
  isGridCol: isGridCol,
10218
10340
  showGray: showGray,
10219
10341
  isSingleSelect: isSingleSelect,
10220
- highlighted: highlighted,
10221
10342
  checkboxes: checkboxes,
10222
10343
  valueTextAlign: valueTextAlign
10223
10344
  }) : /*#__PURE__*/React__default.createElement(ValueField, {
10224
10345
  label: label,
10225
10346
  color: color,
10226
- highlighted: false,
10227
10347
  dense: dense,
10228
10348
  showGray: true,
10229
10349
  checkboxes: checkboxes,
@@ -10265,13 +10385,15 @@ function Frequency(_ref) {
10265
10385
  dense,
10266
10386
  showGray
10267
10387
  } = _ref;
10388
+ const frequencyText = getFrequencyText(cell === null || cell === void 0 ? void 0 : cell.qFrequency);
10268
10389
  return /*#__PURE__*/React__default.createElement(Grid, {
10269
10390
  item: true,
10270
10391
  style: {
10271
10392
  display: 'flex',
10272
10393
  alignItems: 'center'
10273
10394
  },
10274
- className: rowColClasses.frequencyCount
10395
+ className: rowColClasses.frequencyCount,
10396
+ "aria-label": frequencyText
10275
10397
  }, /*#__PURE__*/React__default.createElement(Typography, {
10276
10398
  noWrap: true,
10277
10399
  color: "inherit",
@@ -10280,7 +10402,7 @@ function Frequency(_ref) {
10280
10402
  cell,
10281
10403
  checkboxes
10282
10404
  }) && rowColClasses.excludedTextWithCheckbox])
10283
- }, getFrequencyText(cell === null || cell === void 0 ? void 0 : cell.qFrequency)));
10405
+ }, frequencyText));
10284
10406
  }
10285
10407
 
10286
10408
  function getGridItemSizes(_ref) {
@@ -10317,7 +10439,7 @@ function getGridItemSizes(_ref) {
10317
10439
  }
10318
10440
 
10319
10441
  const ItemGrid = styled$1(Grid, {
10320
- shouldForwardProp: prop => !['dataLayout', 'layoutOrder', 'itemPadding', 'checkboxes'].includes(prop)
10442
+ shouldForwardProp: prop => !['dataLayout', 'layoutOrder', 'itemPadding', 'cellPaddingRight'].includes(prop)
10321
10443
  })(_ref => {
10322
10444
  let {
10323
10445
  dataLayout,
@@ -10352,54 +10474,78 @@ function getCellFromPages(_ref) {
10352
10474
  return c;
10353
10475
  }
10354
10476
 
10355
- // Source: https://en.wikipedia.org/wiki/Bi-directional_text and http://www.unicode.org/Public/6.0.0/ucd/UnicodeData.txt
10356
- // 3 types of strong direction characters: L (strong left-to-right), R(strong right-to-left, Hebrew) and AL(strong right-to-left, Arabic language)
10357
- const rangesOfLChars = '[\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u02BB-\u02C1\u02D0-\u02D1\u02E0-\u02E4\u02EE\u0370-\u0373\u0376-\u037D\u0386\u0388-\u03F5\u03F7-\u0482\u048A-\u0589\u0903-\u0939\u093B\u093D-\u0940\u0949-\u094C\u094E-\u0950\u0958-\u0961\u0964-\u097F\u0982-\u09B9\u09BD-\u09C0\u09C7-\u09CC\u09CE-\u09E1\u09E6-\u09F1\u09F4-\u09FA\u0A03-\u0A39\u0A3E-\u0A40\u0A59-\u0A6F\u0A72-\u0A74\u0A83-\u0AB9\u0ABD-\u0AC0\u0AC9-\u0ACC\u0AD0-\u0AE1\u0AE6-\u0AEF\u0B02-\u0B39\u0B3D-\u0B3E\u0B40\u0B47-\u0B4C\u0B57-\u0B61\u0B66-\u0B77\u0B83-\u0BBF\u0BC1-\u0BCC\u0BD0-\u0BF2\u0C01-\u0C3D\u0C41-\u0C44\u0C58-\u0C61\u0C66-\u0C6F\u0C7F-\u0CB9\u0CBD-\u0CCB\u0CD5-\u0CE1\u0CE6-\u0D40\u0D46-\u0D4C\u0D4E-\u0D61\u0D66-\u0DC6\u0DCF-\u0DD1\u0DD8-\u0E30\u0E32-\u0E33\u0E40-\u0E46\u0E4F-\u0EB0\u0EB2-\u0EB3\u0EBD-\u0EC6\u0ED0-\u0F17\u0F1A-\u0F34\u0F36\u0F38\u0F3E-\u0F6C\u0F7F\u0F85\u0F88-\u0F8C\u0FBE-\u0FC5\u0FC7-\u102C\u1031\u1038\u103B-\u103C\u103F-\u1057\u105A-\u105D\u1061-\u1070\u1075-\u1081\u1083-\u1084\u1087-\u108C\u108E-\u109C\u109E-\u135A\u1360-\u138F\u13A0-\u13F4\u1401-\u167F\u1681-\u169A\u16A0-\u1711\u1720-\u1731\u1735-\u1751\u1760-\u1770\u1780-\u17B6\u17BE-\u17C5\u17C7-\u17C8\u17D4-\u17DA\u17DC\u17E0-\u17E9\u1810-\u18A8\u18AA-\u191C\u1923-\u1926\u1929-\u1931\u1933-\u1938\u1946-\u19DA\u1A00-\u1A16\u1A19-\u1A55\u1A57\u1A61\u1A63-\u1A64\u1A6D-\u1A72\u1A80-\u1AAD\u1B04-\u1B33\u1B35\u1B3B\u1B3D-\u1B41\u1B43-\u1B6A\u1B74-\u1B7C\u1B82-\u1BA1\u1BA6-\u1BA7\u1BAA-\u1BE5\u1BE7\u1BEA-\u1BEC\u1BEE\u1BF2-\u1C2B\u1C34-\u1C35\u1C3B-\u1C7F\u1CD3\u1CE1\u1CE9-\u1CEC\u1CEE-\u1DBF\u1E00-\u1FBC\u1FBE\u1FC2-\u1FCC\u1FD0-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FFC\u200E\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E-\u214F\u2160-\u2188\u2336-\u237A\u2395\u249C-\u24E9\u26AC\u2800-\u28FF\u2C00-\u2CE4\u2CEB-\u2CEE\u2D00-\u2D70\u2D80-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u31BA\u31F0-\u321C\u3220-\u324F\u3260-\u327B\u327F-\u32B0\u32C0-\u32CB\u32D0-\u3376\u337B-\u33DD\u33E0-\u33FE\u3400-\u4DB5\u4E00-\uA48C\uA4D0-\uA60C\uA610-\uA66E\uA680-\uA6EF\uA6F2-\uA6F7\uA722-\uA787\uA789-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA824\uA827\uA830-\uA837\uA840-\uA873\uA880-\uA8C3\uA8CE-\uA8D9\uA8F2-\uA925\uA92E-\uA946\uA952-\uA97C\uA983-\uA9B2\uA9B4-\uA9B5\uA9BA-\uA9BB\uA9BD-\uAA28\uAA2F-\uAA30\uAA33-\uAA34\uAA40-\uAA42\uAA44-\uAA4B\uAA4D-\uAAAF\uAAB1\uAAB5-\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2-\uABE4\uABE6-\uABE7\uABE9-\uABEC\uABF0-\uFB17\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFDC]';
10358
- const rangesOfRChars = '[\u05BE\u05C0\u05C3\u05C6\u05D0-\u05F4\u07C0-\u07EA\u07F4-\u07F5\u07FA-\u0815\u081A\u0824\u0828\u0830-\u0858\u085E\u200F\uFB1D\uFB1F-\uFB28\uFB2A-\uFB4F]';
10359
- const rangesOfALChars = '[\u0608\u060B\u060D\u061B-\u064A\u066D-\u066F\u0671-\u06D5\u06E5-\u06E6\u06EE-\u06EF\u06FA-\u070D\u0710\u0712-\u072F\u074D-\u07A5\u07B1\uFB50-\uFD3D\uFD50-\uFDFC\uFE70-\uFEFC]';
10360
- const rangesOfNChars = '[\u0009-\u000D\u001C-\u0022\u0026-\u002A\u003B-\u0040\u005B-\u0060\u007B-\u007E\u0085\u00A1\u00A6-\u00A9\u00AB-\u00AC\u00AE-\u00AF\u00B4\u00B6-\u00B8\u00BB-\u00BF\u00D7\u00F7\u02B9-\u02BA\u02C2-\u02CF\u02D2-\u02DF\u02E5-\u02ED\u02EF-\u02FF\u0374-\u0375\u037E-\u0385\u0387\u03F6\u058A\u0606-\u0607\u060E-\u060F\u06DE\u06E9\u07F6-\u07F9\u0BF3-\u0BF8\u0BFA\u0C78-\u0C7E\u0F3A-\u0F3D\u1390-\u1399\u1400\u1680\u169B-\u169C\u17F0-\u180A\u180E\u1940-\u1945\u19DE-\u19FF\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD-\u200A\u2010-\u2029\u2035-\u2043\u2045-\u205F\u207C-\u207E\u208C-\u208E\u2100-\u2101\u2103-\u2106\u2108-\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u213A-\u213B\u2140-\u2144\u214A-\u214D\u2150-\u215F\u2189-\u2211\u2214-\u2335\u237B-\u2394\u2396-\u2487\u24EA-\u26AB\u26AD-\u27FF\u2900-\u2B59\u2CE5-\u2CEA\u2CF9-\u2CFF\u2E00-\u3004\u3008-\u3020\u3030\u3036-\u3037\u303D-\u303F\u309B-\u309C\u30A0\u30FB\u31C0-\u31E3\u321D-\u321E\u3250-\u325F\u327C-\u327E\u32B1-\u32BF\u32CC-\u32CF\u3377-\u337A\u33DE-\u33DF\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA60D-\uA60F\uA673\uA67E-\uA67F\uA700-\uA721\uA788\uA828-\uA82B\uA874-\uA877\uFD3E-\uFD3F\uFDFD\uFE10-\uFE19\uFE30-\uFE4F\uFE51\uFE54\uFE56-\uFE5E\uFE60-\uFE61\uFE64-\uFE68\uFE6B\uFF01-\uFF02\uFF06-\uFF0A\uFF1B-\uFF20\uFF3B-\uFF40\uFF5B-\uFF65\uFFE2-\uFFE4\uFFE8-\uFFFD]';
10361
- // eslint-disable-next-line no-misleading-character-class
10362
- const rangesOfLRgExp = new RegExp(rangesOfLChars);
10363
- const rangesOfRRgExp = new RegExp(rangesOfRChars);
10364
- const rangesOfALRgExp = new RegExp(rangesOfALChars);
10365
- const rangesOfNRgExp = new RegExp(rangesOfNChars);
10366
- const
10367
- // left-to-right marker
10368
- lrm = String.fromCharCode(8206); // right-to-left marker
10369
-
10370
- const rlm = String.fromCharCode(8207);
10371
- function isLtrChar(c) {
10372
- return rangesOfLRgExp.test(c);
10373
- }
10374
- function isRtlChar(c) {
10375
- return rangesOfRRgExp.test(c) || rangesOfALRgExp.test(c);
10376
- }
10377
- function isNeutralChar(c) {
10378
- return rangesOfNRgExp.test(c);
10379
- }
10380
- function detectTextDirection(s) {
10381
- const n = s ? s.length : 0;
10382
- let i;
10383
- let c;
10384
- for (i = 0; i < n; i++) {
10385
- c = s[i];
10386
- if (isLtrChar(c)) {
10387
- return 'ltr';
10388
- }
10389
- if (isRtlChar(c)) {
10390
- return 'rtl';
10391
- }
10477
+ /* eslint-disable import/prefer-default-export */
10478
+ const LOC_STATES = {
10479
+ S: 'Object.Listbox.Selected',
10480
+ A: 'Object.Listbox.Alternative',
10481
+ O: 'Object.Listbox.Optional',
10482
+ XS: 'Object.Listbox.SelectedExcluded',
10483
+ L: 'Object.Listbox.Locked',
10484
+ X: 'Object.Listbox.Excluded',
10485
+ XL: 'Object.Listbox.ExcludedLock'
10486
+ };
10487
+ function getValueLabel(_ref) {
10488
+ let {
10489
+ translator,
10490
+ label,
10491
+ qState,
10492
+ isSelected,
10493
+ currentIndex,
10494
+ maxIndex,
10495
+ showSearch
10496
+ } = _ref;
10497
+ const stateTranslation = LOC_STATES[qState];
10498
+ const state = translator.get(stateTranslation);
10499
+ const srStringArr = [];
10500
+ if (isSelected) {
10501
+ const navTranslation = showSearch ? 'Listbox.ScreenReader.SearchThenSelectionsMenu.WithAccSelMenu' : 'Listbox.ScreenReader.SelectionMenu.WithAccSelMenu';
10502
+ const nav = translator.get(navTranslation);
10503
+ srStringArr.push(nav);
10392
10504
  }
10393
- return 'ltr';
10505
+ const valueString = "".concat(label, " ").concat(state);
10506
+ const indexString = translator.get('CurrentSelections.Of', [currentIndex + 1, maxIndex + 1]); // E.g. 3 of 20
10507
+ srStringArr.unshift(valueString, indexString);
10508
+ const srString = srStringArr.join('. ').trim();
10509
+ return srString;
10510
+ }
10511
+
10512
+ /**
10513
+ * Announces the selection state.
10514
+ *
10515
+ * @ignore
10516
+ * @param {Layout} object
10517
+ * @returns {Element} An (invisible) component.
10518
+ */
10519
+ function ScreenReaderForSelections(_ref2) {
10520
+ var _layout$qListObject;
10521
+ let {
10522
+ layout
10523
+ } = _ref2;
10524
+ const {
10525
+ translator
10526
+ } = useContext(InstanceContext);
10527
+ const {
10528
+ qStateCounts: s = {}
10529
+ } = (layout === null || layout === void 0 ? void 0 : (_layout$qListObject = layout.qListObject) === null || _layout$qListObject === void 0 ? void 0 : _layout$qListObject.qDimensionInfo) || {};
10530
+ const count = s.qSelected + s.qSelectedExcluded + s.qLocked + s.qLockedExcluded;
10531
+ let t;
10532
+ switch (count) {
10533
+ case 0:
10534
+ t = 'ScreenReader.ZeroSelected';
10535
+ break;
10536
+ case 1:
10537
+ t = 'ScreenReader.OneSelected';
10538
+ break;
10539
+ default:
10540
+ t = 'ScreenReader.ManySelected';
10541
+ break;
10542
+ }
10543
+ const text = translator.get(t, [count]);
10544
+ return /*#__PURE__*/React__default.createElement("div", {
10545
+ className: "screenReaderOnly",
10546
+ "aria-live": "assertive"
10547
+ }, text);
10394
10548
  }
10395
- var rtlUtil = {
10396
- detectTextDirection,
10397
- isLtrChar,
10398
- isRtlChar,
10399
- isNeutralChar,
10400
- lrm,
10401
- rlm
10402
- };
10403
10549
 
10404
10550
  function RowColumn(_ref) {
10405
10551
  var _cell$qText, _cell$qHighlightRange, _cell$qHighlightRange2;
@@ -10437,7 +10583,10 @@ function RowColumn(_ref) {
10437
10583
  focusListItems,
10438
10584
  listCount,
10439
10585
  itemPadding,
10440
- frequencyWidth
10586
+ frequencyWidth,
10587
+ translator,
10588
+ showSearch,
10589
+ isModal
10441
10590
  } = data;
10442
10591
  const {
10443
10592
  dense = false,
@@ -10487,8 +10636,10 @@ function RowColumn(_ref) {
10487
10636
  }
10488
10637
  }, [rowRef.current]);
10489
10638
  const handleKeyDownCallback = useCallback(getFieldKeyboardNavigation(_objectSpread2(_objectSpread2({}, actions), {}, {
10490
- focusListItems
10491
- })), [actions]);
10639
+ focusListItems,
10640
+ keyboard,
10641
+ isModal
10642
+ })), [actions, keyboard === null || keyboard === void 0 ? void 0 : keyboard.innerTabStops]);
10492
10643
  const cell = useMemo$1(() => getCellFromPages({
10493
10644
  pages,
10494
10645
  cellIndex
@@ -10526,7 +10677,6 @@ function RowColumn(_ref) {
10526
10677
  }
10527
10678
  const isGridCol = dataLayout === 'grid' && layoutOrder === 'column';
10528
10679
  const label = (_cell$qText = cell === null || cell === void 0 ? void 0 : cell.qText) !== null && _cell$qText !== void 0 ? _cell$qText : '';
10529
- const textDirection = rtlUtil.detectTextDirection(label);
10530
10680
  // Search highlights. Split up labelText span into several and add the highlighted class to matching sub-strings.
10531
10681
 
10532
10682
  let labels;
@@ -10554,6 +10704,14 @@ function RowColumn(_ref) {
10554
10704
  const showTick = !checkboxes && isSelected && !isLocked;
10555
10705
  const showIcon = !checkboxes && sizePermitsTickOrLock;
10556
10706
  const cellPaddingRight = checkboxes || !sizePermitsTickOrLock;
10707
+ const ariaLabel = getValueLabel({
10708
+ translator,
10709
+ label,
10710
+ qState: cell.qState,
10711
+ currentIndex: count.currentIndex,
10712
+ maxIndex: count.max,
10713
+ showSearch
10714
+ });
10557
10715
  return /*#__PURE__*/React__default.createElement(RowColRoot$1, {
10558
10716
  className: rowColClasses.barContainer,
10559
10717
  flexBasisProp: flexBasisVal,
@@ -10564,6 +10722,11 @@ function RowColumn(_ref) {
10564
10722
  frequencyWidth: frequencyWidth,
10565
10723
  "data-testid": "listbox.item"
10566
10724
  }, /*#__PURE__*/React__default.createElement(ItemGrid, {
10725
+ role: "row",
10726
+ "aria-label": ariaLabel,
10727
+ "aria-selected": isSelected,
10728
+ "aria-setsize": count.max,
10729
+ "aria-rowindex": count.currentIndex,
10567
10730
  ref: rowRef,
10568
10731
  container: true,
10569
10732
  dataLayout: dataLayout,
@@ -10581,8 +10744,7 @@ function RowColumn(_ref) {
10581
10744
  onMouseEnter: onMouseEnter,
10582
10745
  onKeyDown: handleKeyDownCallback,
10583
10746
  onContextMenu: preventContextMenu,
10584
- role: column ? 'column' : 'row',
10585
- tabIndex: isFirstElement && (!keyboard.enabled || keyboard.active) ? 0 : -1,
10747
+ tabIndex: isFirstElement && keyboard.innerTabStops ? 0 : -1,
10586
10748
  "data-n": cell === null || cell === void 0 ? void 0 : cell.qElemNumber
10587
10749
  }, (cell === null || cell === void 0 ? void 0 : cell.qFrequency) && /*#__PURE__*/React__default.createElement(Histogram, {
10588
10750
  qFrequency: cell === null || cell === void 0 ? void 0 : cell.qFrequency,
@@ -10608,8 +10770,7 @@ function RowColumn(_ref) {
10608
10770
  cell: cell,
10609
10771
  isGridCol: isGridCol,
10610
10772
  isSingleSelect: isSingleSelect,
10611
- valueTextAlign: valueTextAlign,
10612
- textDirection: textDirection
10773
+ valueTextAlign: valueTextAlign
10613
10774
  }) : /*#__PURE__*/React__default.createElement(Field$1, {
10614
10775
  onChange: onChange,
10615
10776
  label: label,
@@ -12199,7 +12360,10 @@ function getListBoxComponents(_ref) {
12199
12360
  setCurrentScrollIndex,
12200
12361
  constraints,
12201
12362
  frequencyMax,
12202
- freqIsAllowed
12363
+ freqIsAllowed,
12364
+ translator,
12365
+ showSearch,
12366
+ isModal
12203
12367
  } = _ref;
12204
12368
  const {
12205
12369
  layoutOptions = {}
@@ -12253,7 +12417,10 @@ function getListBoxComponents(_ref) {
12253
12417
  showTick,
12254
12418
  dataOffset: local.current.dataOffset,
12255
12419
  focusListItems,
12256
- direction
12420
+ direction,
12421
+ translator,
12422
+ showSearch,
12423
+ isModal
12257
12424
  });
12258
12425
  const List = _ref2 => {
12259
12426
  let {
@@ -12695,17 +12862,14 @@ function useDataStore(model) {
12695
12862
  };
12696
12863
  }
12697
12864
 
12698
- function ListBoxDisclaimer(_ref) {
12865
+ const StyledText = styled$1(Typography, {
12866
+ shouldForwardProp: p => !['width', 'dense'].includes(p)
12867
+ })(_ref => {
12699
12868
  let {
12700
12869
  width,
12701
- text,
12702
- dense,
12703
- tooltip
12870
+ dense
12704
12871
  } = _ref;
12705
- const {
12706
- translator
12707
- } = useContext(InstanceContext);
12708
- const StyledText = styled$1(Typography)(() => _objectSpread2({
12872
+ return _objectSpread2({
12709
12873
  minWidth: "".concat(width, "px"),
12710
12874
  textAlign: 'center',
12711
12875
  fontSize: "".concat(dense ? '12px' : '14px')
@@ -12714,10 +12878,23 @@ function ListBoxDisclaimer(_ref) {
12714
12878
  overflow: 'hidden',
12715
12879
  whiteSpace: 'nowrap',
12716
12880
  width
12717
- }));
12881
+ });
12882
+ });
12883
+ function ListBoxDisclaimer(_ref2) {
12884
+ let {
12885
+ width,
12886
+ text,
12887
+ dense,
12888
+ tooltip
12889
+ } = _ref2;
12890
+ const {
12891
+ translator
12892
+ } = useContext(InstanceContext);
12718
12893
  return /*#__PURE__*/React__default.createElement(Tooltip, {
12719
12894
  title: tooltip ? translator.get(text) : ''
12720
12895
  }, /*#__PURE__*/React__default.createElement(StyledText, {
12896
+ width: width,
12897
+ dense: dense,
12721
12898
  component: "div",
12722
12899
  variant: "body1",
12723
12900
  py: "12px"
@@ -13085,6 +13262,14 @@ const useFrequencyMax = (app, layout) => {
13085
13262
 
13086
13263
  const _excluded$4 = ["isLoadingData"];
13087
13264
  const DEFAULT_MIN_BATCH_SIZE = 100;
13265
+ const StyledWrapper = styled$4('div')(() => ({
13266
+ ["& .screenReaderOnly"]: {
13267
+ position: 'absolute',
13268
+ height: 0,
13269
+ width: 0,
13270
+ overflow: 'hidden'
13271
+ }
13272
+ }));
13088
13273
  function ListBox(_ref) {
13089
13274
  var _layout$qListObject$q, _loaderRef$current, _loaderRef$current$_l, _loaderRef$current$_l2;
13090
13275
  let {
@@ -13115,8 +13300,13 @@ function ListBox(_ref) {
13115
13300
  set: () => {}
13116
13301
  },
13117
13302
  renderedCallback,
13118
- onCtrlF
13303
+ onCtrlF,
13304
+ showSearch,
13305
+ isModal
13119
13306
  } = _ref;
13307
+ const {
13308
+ translator
13309
+ } = useContext(InstanceContext);
13120
13310
  const [initScrollPosIsSet, setInitScrollPosIsSet] = useState$1(false);
13121
13311
  const isSingleSelect = !!(layout && layout.qListObject.qDimensionInfo.qIsOneAndOnlyOne);
13122
13312
  const {
@@ -13371,7 +13561,10 @@ function ListBox(_ref) {
13371
13561
  setCurrentScrollIndex: currentScrollIndex.set,
13372
13562
  constraints,
13373
13563
  frequencyMax,
13374
- freqIsAllowed
13564
+ freqIsAllowed,
13565
+ translator,
13566
+ showSearch,
13567
+ isModal
13375
13568
  });
13376
13569
  const {
13377
13570
  columnWidth,
@@ -13386,7 +13579,10 @@ function ListBox(_ref) {
13386
13579
  itemHeight
13387
13580
  });
13388
13581
  }
13389
- return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, !listCount && /*#__PURE__*/React__default.createElement(ListBoxDisclaimer, {
13582
+ return /*#__PURE__*/React__default.createElement(StyledWrapper, null, /*#__PURE__*/React__default.createElement(ScreenReaderForSelections, {
13583
+ className: "screenReaderOnly",
13584
+ layout: layout
13585
+ }), !listCount && /*#__PURE__*/React__default.createElement(ListBoxDisclaimer, {
13390
13586
  width: width,
13391
13587
  text: "Listbox.NoMatchesForYourTerms"
13392
13588
  }), /*#__PURE__*/React__default.createElement(InfiniteLoader, {
@@ -13398,7 +13594,8 @@ function ListBox(_ref) {
13398
13594
  }),
13399
13595
  threshold: 0,
13400
13596
  minimumBatchSize: minimumBatchSize,
13401
- ref: loaderRef
13597
+ ref: loaderRef,
13598
+ role: "grid"
13402
13599
  }, isVertical ? List : Grid), overflowDisclaimer.show && !overflowDisclaimer.dismissed && /*#__PURE__*/React__default.createElement(ListBoxFooter, {
13403
13600
  text: "Listbox.ItemsOverflow",
13404
13601
  dismiss: () => setOverflowDisclaimer(state => _objectSpread2(_objectSpread2({}, state), {}, {
@@ -13550,6 +13747,7 @@ const Item = React__default.forwardRef((_ref, ref) => {
13550
13747
  if (hidden) return null;
13551
13748
  const spacing = Number.parseInt(theme.spacing(0.5), 10);
13552
13749
  const handleKeyDown = item.keyboardAction ? e => ['Enter', ' ', 'Spacebar'].includes(e.key) && item.keyboardAction() : null;
13750
+ const btnId = "actions-toolbar-".concat(item.key);
13553
13751
  return /*#__PURE__*/React__default.createElement(IconButton, {
13554
13752
  ref: !addAnchor ? ref : null,
13555
13753
  title: item.label,
@@ -13557,12 +13755,12 @@ const Item = React__default.forwardRef((_ref, ref) => {
13557
13755
  onKeyDown: handleKeyDown,
13558
13756
  disabled: disabled,
13559
13757
  style: style,
13560
- className: ActionElement.className,
13758
+ className: [ActionElement.className, btnId].join(' '),
13561
13759
  size: "large",
13562
13760
  disableRipple: true,
13563
13761
  "aria-expanded": ariaExpanded,
13564
13762
  "aria-controls": "moreMenuList",
13565
- "data-testid": "actions-toolbar-".concat(item.key)
13763
+ "data-testid": btnId
13566
13764
  }, hasSvgIconShape && SvgIcon$2(item.getSvgIconShape()), addAnchor && /*#__PURE__*/React__default.createElement("div", {
13567
13765
  ref: ref,
13568
13766
  style: {
@@ -13741,6 +13939,70 @@ const More$1 = React__default.forwardRef((_ref3, ref) => {
13741
13939
  }))));
13742
13940
  });
13743
13941
 
13942
+ const getActionButtonIndex = btn => {
13943
+ const toolbar = btn.closest('#actions-toolbar');
13944
+ const nodeList = toolbar === null || toolbar === void 0 ? void 0 : toolbar.querySelectorAll('.njs-cell-action');
13945
+ return Array.from(nodeList).indexOf(btn);
13946
+ };
13947
+ const focusButton = index => {
13948
+ const toolbar = document.querySelector('#actions-toolbar');
13949
+ const nodeList = toolbar === null || toolbar === void 0 ? void 0 : toolbar.querySelectorAll('.njs-cell-action');
13950
+ if (!nodeList.length) {
13951
+ return;
13952
+ }
13953
+ const ix = Math.min(Math.max(0, index), nodeList.length - 1);
13954
+ const btn = nodeList[ix];
13955
+ btn.focus();
13956
+ };
13957
+ function getActionsKeyDownHandler(_ref) {
13958
+ let {
13959
+ keyboardNavigation,
13960
+ focusHandler,
13961
+ getEnabledButton
13962
+ } = _ref;
13963
+ const handleActionsKeyDown = evt => {
13964
+ const {
13965
+ target,
13966
+ nativeEvent
13967
+ } = evt;
13968
+ const {
13969
+ keyCode
13970
+ } = nativeEvent;
13971
+ switch (keyCode) {
13972
+ case KEYS.ARROW_LEFT:
13973
+ case KEYS.ARROW_DOWN:
13974
+ case KEYS.ARROW_RIGHT:
13975
+ case KEYS.ARROW_UP:
13976
+ {
13977
+ const isActionButton = target.classList.contains('njs-cell-action');
13978
+ if (isActionButton) {
13979
+ const index = getActionButtonIndex(target);
13980
+ const pressedLeft = [KEYS.ARROW_LEFT, KEYS.ARROW_DOWN].includes(keyCode);
13981
+ focusButton(pressedLeft ? index - 1 : index + 1);
13982
+ }
13983
+ evt.stopPropagation();
13984
+ evt.preventDefault();
13985
+ break;
13986
+ }
13987
+ case KEYS.SPACE:
13988
+ evt.preventDefault(); // prevent scrolling in listbox
13989
+ break;
13990
+ case KEYS.TAB:
13991
+ if (keyboardNavigation && focusHandler !== null && focusHandler !== void 0 && focusHandler.refocusContent) {
13992
+ const isTabbingOut = evt.shiftKey && getEnabledButton(false) === evt.target || !evt.shiftKey && getEnabledButton(true) === evt.target;
13993
+ if (isTabbingOut) {
13994
+ evt.preventDefault();
13995
+ evt.stopPropagation();
13996
+ // if keyboardNavigation is true, create a callback to handle tabbing from the first/last button in the toolbar that resets focus on the content
13997
+ focusHandler.refocusContent();
13998
+ }
13999
+ }
14000
+ break;
14001
+ }
14002
+ };
14003
+ return handleActionsKeyDown;
14004
+ }
14005
+
13744
14006
  const PREFIX$7 = 'ActionsToolbar';
13745
14007
  const classes$7 = {
13746
14008
  item: "".concat(PREFIX$7, "-item"),
@@ -13776,6 +14038,7 @@ const ActionToolbarElement = {
13776
14038
  };
13777
14039
  const ActionsGroup = React__default.forwardRef((_ref2, ref) => {
13778
14040
  let {
14041
+ className,
13779
14042
  ariaExpanded = false,
13780
14043
  actions = [],
13781
14044
  first = false,
@@ -13788,7 +14051,8 @@ const ActionsGroup = React__default.forwardRef((_ref2, ref) => {
13788
14051
  container: true,
13789
14052
  gap: 0,
13790
14053
  flexDirection: isRtl ? 'row-reverse' : 'row',
13791
- wrap: "nowrap"
14054
+ wrap: "nowrap",
14055
+ className: className
13792
14056
  }, actions.map((e, ix) => {
13793
14057
  let cls = [];
13794
14058
  const isFirstItem = first && ix === 0;
@@ -13856,22 +14120,27 @@ function ActionsToolbar(_ref3) {
13856
14120
  keyboardNavigation
13857
14121
  } = useContext(InstanceContext);
13858
14122
  const [showMoreItems, setShowMoreItems] = useState$1(false);
13859
- const moreRef = useRef();
14123
+ const popoverAnchorOrigin = {
14124
+ vertical: 7,
14125
+ horizontal: ((_popover$anchorEl$cli = (_popover$anchorEl = popover.anchorEl) === null || _popover$anchorEl === void 0 ? void 0 : _popover$anchorEl.clientWidth) !== null && _popover$anchorEl$cli !== void 0 ? _popover$anchorEl$cli : 0) - 7
14126
+ };
13860
14127
  const actionsRef = useRef();
14128
+ const moreRef = useRef();
13861
14129
  const theme = useTheme$1();
13862
14130
  const dividerStyle = useMemo$1(() => ({
13863
14131
  margin: theme.spacing(0.5, 0)
13864
14132
  }));
13865
- const popoverAnchorOrigin = {
13866
- vertical: 15,
13867
- horizontal: ((_popover$anchorEl$cli = (_popover$anchorEl = popover.anchorEl) === null || _popover$anchorEl === void 0 ? void 0 : _popover$anchorEl.clientWidth) !== null && _popover$anchorEl$cli !== void 0 ? _popover$anchorEl$cli : 0) - 7
13868
- };
13869
14133
  const getEnabledButton = last => {
13870
14134
  const actionsElement = actionsRef.current || actionsRefMock;
13871
14135
  if (!actionsElement) return null;
13872
14136
  const buttons = actionsElement.querySelectorAll('button:not(.Mui-disabled)');
13873
14137
  return buttons[last ? buttons.length - 1 : 0];
13874
14138
  };
14139
+ const handleActionsKeyDown = useMemo$1(() => getActionsKeyDownHandler({
14140
+ keyboardNavigation,
14141
+ focusHandler,
14142
+ getEnabledButton
14143
+ }), [keyboardNavigation, focusHandler, getEnabledButton]);
13875
14144
  useEffect$1(() => () => {
13876
14145
  setShowMoreItems(false);
13877
14146
  }, [popover.show, show, selections.show]);
@@ -13911,27 +14180,18 @@ function ActionsToolbar(_ref3) {
13911
14180
  enabled: () => moreEnabled,
13912
14181
  action: () => setShowMoreItems(!showMoreItems)
13913
14182
  };
13914
- const tabCallback =
13915
- // if keyboardNavigation is true, create a callback to handle tabbing from the first/last button in the toolbar that resets focus on the content
13916
- keyboardNavigation && focusHandler && focusHandler.refocusContent ? evt => {
13917
- if (evt.key !== 'Tab') return;
13918
- const isTabbingOut = evt.shiftKey && getEnabledButton(false) === evt.target || !evt.shiftKey && getEnabledButton(true) === evt.target;
13919
- if (isTabbingOut) {
13920
- evt.preventDefault();
13921
- evt.stopPropagation();
13922
- focusHandler.refocusContent();
13923
- }
13924
- } : null;
13925
14183
  const showActions = newActions.length > 0;
13926
14184
  const showMore = moreActions.length > 0;
13927
14185
  const showDivider = showActions && selections.show || showMore && selections.show;
13928
14186
  const isRtl = direction === 'rtl';
13929
14187
  const Actions = /*#__PURE__*/React__default.createElement(Grid, {
13930
14188
  ref: actionsRef,
13931
- onKeyDown: tabCallback,
14189
+ onKeyDown: handleActionsKeyDown,
13932
14190
  container: true,
13933
14191
  gap: 0,
13934
14192
  wrap: "nowrap",
14193
+ id: "actions-toolbar",
14194
+ "data-testid": "actions-toolbar",
13935
14195
  sx: {
13936
14196
  flexDirection: isRtl ? 'row-reverse' : 'row'
13937
14197
  }
@@ -13940,6 +14200,8 @@ function ActionsToolbar(_ref3) {
13940
14200
  first: true,
13941
14201
  last: !showMore && !selections.show
13942
14202
  }), showMore && /*#__PURE__*/React__default.createElement(ActionsGroup, {
14203
+ id: "actions-toolbar-show-more",
14204
+ "data-testid": "actions-toolbar-show-more",
13943
14205
  ref: moreRef,
13944
14206
  ariaExpanded: showMoreItems,
13945
14207
  actions: [moreItem],
@@ -13953,6 +14215,7 @@ function ActionsToolbar(_ref3) {
13953
14215
  }, /*#__PURE__*/React__default.createElement(Divider, {
13954
14216
  orientation: "vertical"
13955
14217
  })), selections.show && /*#__PURE__*/React__default.createElement(ActionsGroup, {
14218
+ className: "actions-toolbar-default-actions",
13956
14219
  actions: defaultSelectionActions,
13957
14220
  first: !showActions && !showMore,
13958
14221
  last: true,
@@ -13976,6 +14239,8 @@ function ActionsToolbar(_ref3) {
13976
14239
  hideBackdrop: true,
13977
14240
  style: popoverStyle,
13978
14241
  PaperProps: {
14242
+ id: 'njs-action-toolbar-popover',
14243
+ 'data-testid': 'njs-action-toolbar-popover',
13979
14244
  className: ActionToolbarElement.className,
13980
14245
  style: {
13981
14246
  pointerEvents: 'auto',
@@ -14103,29 +14368,57 @@ function ListBoxSearch(_ref3) {
14103
14368
  }
14104
14369
  return response;
14105
14370
  };
14371
+ function focusRow(container) {
14372
+ const row = (container === null || container === void 0 ? void 0 : container.querySelector('.last-focused')) || (container === null || container === void 0 ? void 0 : container.querySelector('[role="row"]:first-child'));
14373
+ row.setAttribute('tabIndex', 0);
14374
+ row === null || row === void 0 ? void 0 : row.focus();
14375
+ }
14106
14376
  const onKeyDown = async e => {
14107
- let response;
14377
+ const {
14378
+ currentTarget
14379
+ } = e;
14380
+ const container = currentTarget.closest('.listbox-container');
14108
14381
  switch (e.key) {
14109
14382
  case 'Enter':
14110
- response = await performSearch();
14383
+ performSearch();
14111
14384
  break;
14112
14385
  case 'Escape':
14113
- response = cancel();
14114
- e.preventDefault();
14115
- e.stopPropagation();
14116
- break;
14386
+ {
14387
+ focusRow(container);
14388
+ cancel();
14389
+ break;
14390
+ }
14391
+ case 'Tab':
14392
+ {
14393
+ if (e.shiftKey) {
14394
+ keyboard.focusSelection();
14395
+ } else {
14396
+ // Focus the row we last visited or the first one.
14397
+ focusRow(container);
14398
+
14399
+ // Clean up.
14400
+ container === null || container === void 0 ? void 0 : container.querySelectorAll('.last-focused').forEach(elm => {
14401
+ elm.classList.remove('last-focused');
14402
+ });
14403
+ }
14404
+ break;
14405
+ }
14117
14406
  case 'f':
14118
14407
  case 'F':
14119
14408
  if (e.ctrlKey || e.metaKey) {
14120
14409
  if (hide) {
14121
14410
  hide();
14122
14411
  }
14123
- e.preventDefault();
14124
- e.stopPropagation();
14412
+ } else {
14413
+ return undefined;
14125
14414
  }
14126
14415
  break;
14416
+ default:
14417
+ return undefined;
14127
14418
  }
14128
- return response;
14419
+ e.preventDefault();
14420
+ e.stopPropagation();
14421
+ return undefined;
14129
14422
  };
14130
14423
  if (!visible || searchEnabled === false) {
14131
14424
  return null;
@@ -14171,10 +14464,11 @@ function ListBoxSearch(_ref3) {
14171
14464
  onKeyDown: onKeyDown,
14172
14465
  autoFocus: autoFocus,
14173
14466
  inputProps: {
14174
- tabIndex: keyboard && (!keyboard.enabled || keyboard.active) ? 0 : -1,
14467
+ tabIndex: keyboard.innerTabStops ? 0 : -1,
14175
14468
  style: {
14176
14469
  textAlign: "".concat(inpuTextAlign)
14177
- }
14470
+ },
14471
+ 'data-testid': 'search-input-field'
14178
14472
  }
14179
14473
  });
14180
14474
  }
@@ -14418,6 +14712,12 @@ function useObjectSelections(app, model, elements, options) {
14418
14712
  objectSelections.addListener('activated', activateClickOut);
14419
14713
  objectSelections.addListener('deactivated', deactivateClickOut);
14420
14714
  return () => {
14715
+ // confirm selection before removing event handler
14716
+ // to end the selection when the object is removed
14717
+ // and remove the (ClickOut) mousedown handler from the document
14718
+ if (objectSelections.isActive()) {
14719
+ objectSelections.confirm();
14720
+ }
14421
14721
  objectSelections.removeListener('activated', activateClickOut);
14422
14722
  objectSelections.removeListener('deactivated', deactivateClickOut);
14423
14723
  };
@@ -16073,6 +16373,23 @@ function getListboxActionProps(_ref) {
16073
16373
  };
16074
16374
  }
16075
16375
 
16376
+ const StyledDiv = styled$1('div')(() => ({
16377
+ display: 'flex',
16378
+ width: '100%',
16379
+ height: '100%',
16380
+ alignItems: 'center',
16381
+ justifyContent: 'center'
16382
+ }));
16383
+ function ListBoxError(_ref) {
16384
+ let {
16385
+ text
16386
+ } = _ref;
16387
+ const {
16388
+ translator
16389
+ } = useContext(InstanceContext);
16390
+ return /*#__PURE__*/React__default.createElement(StyledDiv, null, translator.get(text));
16391
+ }
16392
+
16076
16393
  const PREFIX$4 = 'ListBoxInline';
16077
16394
  const classes$4 = {
16078
16395
  listBoxHeader: "".concat(PREFIX$4, "-listBoxHeader"),
@@ -16124,12 +16441,20 @@ const Title = styled$1(Typography)(_ref2 => {
16124
16441
  fontWeight: ((_theme$listBox5 = theme.listBox) === null || _theme$listBox5 === void 0 ? void 0 : (_theme$listBox5$title = _theme$listBox5.title) === null || _theme$listBox5$title === void 0 ? void 0 : (_theme$listBox5$title2 = _theme$listBox5$title.main) === null || _theme$listBox5$title2 === void 0 ? void 0 : _theme$listBox5$title2.fontWeight) || 'bold'
16125
16442
  };
16126
16443
  });
16127
- function ListBoxInline(_ref3) {
16444
+ const isModal = _ref3 => {
16445
+ var _app$isInModalSelecti, _app$isInModalSelecti2;
16446
+ let {
16447
+ app,
16448
+ appSelections
16449
+ } = _ref3;
16450
+ return (_app$isInModalSelecti = (_app$isInModalSelecti2 = app.isInModalSelection) === null || _app$isInModalSelecti2 === void 0 ? void 0 : _app$isInModalSelecti2.call(app)) !== null && _app$isInModalSelecti !== void 0 ? _app$isInModalSelecti : appSelections.isInModal();
16451
+ };
16452
+ function ListBoxInline(_ref4) {
16128
16453
  var _layoutOptions$dense;
16129
16454
  let {
16130
16455
  options,
16131
16456
  layout
16132
- } = _ref3;
16457
+ } = _ref4;
16133
16458
  const {
16134
16459
  app,
16135
16460
  direction,
@@ -16147,9 +16472,7 @@ function ListBoxInline(_ref3) {
16147
16472
  calculatePagesHeight,
16148
16473
  showGray = true,
16149
16474
  scrollState = undefined,
16150
- renderedCallback
16151
- } = options;
16152
- let {
16475
+ renderedCallback,
16153
16476
  toolbar = true
16154
16477
  } = options;
16155
16478
 
@@ -16179,7 +16502,6 @@ function ListBoxInline(_ref3) {
16179
16502
  const [searchContainer, searchContainerRef] = useRefWithCallback();
16180
16503
  const [showToolbar, setShowToolbar] = useState$1(false);
16181
16504
  const [showSearch, setShowSearch] = useState$1(false);
16182
- const [keyboardActive, setKeyboardActive] = useState$1(false);
16183
16505
  const [hovering, setHovering] = useState$1(false);
16184
16506
  const [keyScroll, setKeyScroll] = useState$1({
16185
16507
  down: 0,
@@ -16194,12 +16516,22 @@ function ListBoxInline(_ref3) {
16194
16516
  const [appSelections] = useAppSelections(app);
16195
16517
  const titleRef = useRef(null);
16196
16518
  const [selectionState$1] = useState$1(() => selectionState());
16519
+ const keyboard = useTempKeyboard({
16520
+ containerRef,
16521
+ enabled: keyboardNavigation
16522
+ });
16523
+ const isModalMode = useCallback(() => isModal({
16524
+ app,
16525
+ appSelections
16526
+ }), [app, appSelections]);
16527
+ const isInvalid = layout === null || layout === void 0 ? void 0 : layout.qListObject.qDimensionInfo.qError;
16528
+ const errorText = isInvalid && constraints.active ? 'Visualization.Invalid.Dimension' : 'Visualization.Incomplete';
16197
16529
  const {
16198
16530
  handleKeyDown,
16199
16531
  handleOnMouseEnter,
16200
16532
  handleOnMouseLeave
16201
16533
  } = getListboxInlineKeyboardNavigation({
16202
- setKeyboardActive,
16534
+ keyboard,
16203
16535
  hovering,
16204
16536
  setHovering,
16205
16537
  updateKeyScroll,
@@ -16207,20 +16539,11 @@ function ListBoxInline(_ref3) {
16207
16539
  currentScrollIndex,
16208
16540
  app,
16209
16541
  appSelections,
16210
- constraints
16542
+ constraints,
16543
+ isModal: isModalMode
16211
16544
  });
16212
-
16213
- // Expose the keyboard flags in the same way as the keyboard hook does.
16214
- const keyboard = {
16215
- enabled: keyboardNavigation,
16216
- // this will be static until we can access the useKeyboard hook
16217
- active: keyboardActive
16218
- };
16219
- if ((layout === null || layout === void 0 ? void 0 : layout.toolbar) !== undefined) {
16220
- toolbar = layout.toolbar;
16221
- }
16222
- const toolbarDetachedOnly = toolbar && (layout === null || layout === void 0 ? void 0 : layout.title) === '';
16223
- toolbar = toolbar && (layout === null || layout === void 0 ? void 0 : layout.title) !== '';
16545
+ const showDetachedToolbarOnly = toolbar && ((layout === null || layout === void 0 ? void 0 : layout.title) === '' || (layout === null || layout === void 0 ? void 0 : layout.showTitle) === false);
16546
+ const showToolbarWithTitle = toolbar && (layout === null || layout === void 0 ? void 0 : layout.title) !== '' && (layout === null || layout === void 0 ? void 0 : layout.showTitle) !== false;
16224
16547
  useEffect$1(() => {
16225
16548
  const show = () => {
16226
16549
  setShowToolbar(true);
@@ -16244,7 +16567,7 @@ function ListBoxInline(_ref3) {
16244
16567
  selections.removeListener('deactivated', hide);
16245
16568
  }
16246
16569
  };
16247
- }, [selections, toolbar]);
16570
+ }, [selections]);
16248
16571
  useEffect$1(() => {
16249
16572
  if (!searchContainer || !searchContainer.current) {
16250
16573
  return;
@@ -16278,7 +16601,7 @@ function ListBoxInline(_ref3) {
16278
16601
  const searchHeight = dense ? 27 : 40;
16279
16602
  const extraheight = dense ? 39 : 49;
16280
16603
  const searchAddHeight = searchVisible ? searchHeight : 0;
16281
- const minHeight = toolbar ? 49 + searchAddHeight + extraheight : 0;
16604
+ const minHeight = showToolbarWithTitle ? 49 + searchAddHeight + extraheight : 0;
16282
16605
  const headerHeight = 32;
16283
16606
  const onShowSearch = () => {
16284
16607
  const newValue = !showSearch;
@@ -16350,12 +16673,12 @@ function ListBoxInline(_ref3) {
16350
16673
  fontSize: '12px'
16351
16674
  }
16352
16675
  }));
16353
- return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, toolbarDetachedOnly && /*#__PURE__*/React__default.createElement(ActionsToolbar, _extends$6({
16676
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, showDetachedToolbarOnly && /*#__PURE__*/React__default.createElement(ActionsToolbar, _extends$6({
16354
16677
  direction: direction
16355
16678
  }, getActionToolbarProps(true))), /*#__PURE__*/React__default.createElement(StyledGrid$3, {
16356
16679
  className: "listbox-container",
16357
16680
  container: true,
16358
- tabIndex: keyboard.enabled && !keyboard.active ? 0 : -1,
16681
+ tabIndex: keyboard.outerTabStops ? 0 : -1,
16359
16682
  direction: "column",
16360
16683
  gap: 0,
16361
16684
  containerPadding: containerPadding,
@@ -16369,7 +16692,7 @@ function ListBoxInline(_ref3) {
16369
16692
  onMouseLeave: handleOnMouseLeave,
16370
16693
  ref: containerRef,
16371
16694
  hasIcon: showIcons
16372
- }, toolbar && /*#__PURE__*/React__default.createElement(Grid, {
16695
+ }, showToolbarWithTitle && /*#__PURE__*/React__default.createElement(Grid, {
16373
16696
  item: true,
16374
16697
  container: true,
16375
16698
  style: {
@@ -16459,11 +16782,13 @@ function ListBoxInline(_ref3) {
16459
16782
  className: classes$4.listboxWrapper
16460
16783
  }, /*#__PURE__*/React__default.createElement("div", {
16461
16784
  className: classes$4.screenReaderOnly
16462
- }, translator.get('Listbox.ScreenReaderInstructions')), /*#__PURE__*/React__default.createElement(AutoSizer, null, _ref4 => {
16785
+ }, translator.get('Listbox.ScreenReaderInstructions')), isInvalid ? /*#__PURE__*/React__default.createElement(ListBoxError, {
16786
+ text: errorText
16787
+ }) : /*#__PURE__*/React__default.createElement(AutoSizer, null, _ref5 => {
16463
16788
  let {
16464
16789
  height,
16465
16790
  width
16466
- } = _ref4;
16791
+ } = _ref5;
16467
16792
  return /*#__PURE__*/React__default.createElement(ListBox, {
16468
16793
  model: model,
16469
16794
  app: app,
@@ -16498,15 +16823,16 @@ function ListBoxInline(_ref3) {
16498
16823
  set: setCurrentScrollIndex
16499
16824
  },
16500
16825
  renderedCallback: renderedCallback,
16501
- onCtrlF: onCtrlF
16826
+ onCtrlF: onCtrlF,
16827
+ isModal: isModalMode
16502
16828
  });
16503
16829
  })))));
16504
16830
  }
16505
16831
  const ListBoxInlineMemoed = React__default.memo(ListBoxInline);
16506
- function IsolateUseLayoutWrapper(_ref5) {
16832
+ function IsolateUseLayoutWrapper(_ref6) {
16507
16833
  let {
16508
16834
  options = {}
16509
- } = _ref5;
16835
+ } = _ref6;
16510
16836
  const {
16511
16837
  model
16512
16838
  } = options;
@@ -16908,7 +17234,7 @@ function removeIndex(array, index) {
16908
17234
  array.splice(removeIdx, 1);
16909
17235
  return removeIdx;
16910
17236
  }
16911
- const nxDimension = f => ({
17237
+ const nxDimension$1 = f => ({
16912
17238
  qDef: {
16913
17239
  qFieldDefs: [f]
16914
17240
  }
@@ -16939,7 +17265,7 @@ function hcHandler(_ref) {
16939
17265
  return hc.qMeasures;
16940
17266
  },
16941
17267
  addDimension(d) {
16942
- const dimension = typeof d === 'string' ? nxDimension(d) : _objectSpread2(_objectSpread2({}, d), {}, {
17268
+ const dimension = typeof d === 'string' ? nxDimension$1(d) : _objectSpread2(_objectSpread2({}, d), {}, {
16943
17269
  qDef: d.qDef || {}
16944
17270
  });
16945
17271
  dimension.qDef.cId = dimension.qDef.cId || uid();
@@ -17022,6 +17348,69 @@ function hcHandler(_ref) {
17022
17348
  return handler;
17023
17349
  }
17024
17350
 
17351
+ const nxDimension = f => ({
17352
+ qDef: {
17353
+ qFieldDefs: [f]
17354
+ }
17355
+ });
17356
+ function loHandler(_ref) {
17357
+ let {
17358
+ dc: lo,
17359
+ def,
17360
+ properties
17361
+ } = _ref;
17362
+ lo.qInitialDataFetch = lo.qInitialDataFetch || [];
17363
+ const objectProperties = properties;
17364
+ const handler = {
17365
+ dimensions() {
17366
+ if (!lo.qLibraryId && (!lo.qDef || !lo.qDef.qFieldDefs || lo.qDef.qFieldDefs.length === 0)) return [];
17367
+ return [lo];
17368
+ },
17369
+ measures() {
17370
+ return [];
17371
+ },
17372
+ addDimension(d) {
17373
+ const dimension = typeof d === 'string' ? nxDimension(d) : _objectSpread2(_objectSpread2({}, d), {}, {
17374
+ qDef: d.qDef || {}
17375
+ });
17376
+ dimension.qDef.cId = dimension.qDef.cId || uid();
17377
+ dimension.qDef.qSortCriterias = lo.qDef.qSortCriterias || [{
17378
+ qSortByState: 1,
17379
+ qSortByLoadOrder: 1,
17380
+ qSortByNumeric: 1,
17381
+ qSortByAscii: 1
17382
+ }];
17383
+ Object.keys(dimension).forEach(k => {
17384
+ lo[k] = dimension[k];
17385
+ });
17386
+ def.dimensions.added(dimension, objectProperties);
17387
+ return dimension;
17388
+ },
17389
+ removeDimension(idx) {
17390
+ const dimension = lo;
17391
+ delete lo.qDef;
17392
+ delete lo.qLibraryId;
17393
+ def.dimensions.removed(dimension, objectProperties, idx);
17394
+ return dimension;
17395
+ },
17396
+ addMeasure() {},
17397
+ removeMeasure() {},
17398
+ maxDimensions() {
17399
+ return 1;
17400
+ },
17401
+ maxMeasures() {
17402
+ return 0;
17403
+ },
17404
+ canAddDimension() {
17405
+ return handler.dimensions().length === 0;
17406
+ },
17407
+ canAddMeasure() {
17408
+ return false;
17409
+ }
17410
+ };
17411
+ return handler;
17412
+ }
17413
+
17025
17414
  /**
17026
17415
  * @interface LibraryField
17027
17416
  * @property {string} qLibraryId
@@ -17066,7 +17455,8 @@ function populateData(_ref) {
17066
17455
  const s = parts[i];
17067
17456
  p = s ? p[s] : p;
17068
17457
  }
17069
- const hc = hcHandler({
17458
+ const createHandler = propertyPath.match('/qListObjectDef') ? loHandler : hcHandler;
17459
+ const handler = createHandler({
17070
17460
  dc: p,
17071
17461
  def: target,
17072
17462
  properties
@@ -17074,9 +17464,9 @@ function populateData(_ref) {
17074
17464
  fields.forEach(f => {
17075
17465
  const type = fieldType(f);
17076
17466
  if (type === 'measure') {
17077
- hc.addMeasure(f);
17467
+ handler.addMeasure(f);
17078
17468
  } else {
17079
- hc.addDimension(f);
17469
+ handler.addDimension(f);
17080
17470
  }
17081
17471
  });
17082
17472
  }
@@ -18307,7 +18697,8 @@ function Header(_ref2) {
18307
18697
  sn,
18308
18698
  anchorEl,
18309
18699
  hovering,
18310
- focusHandler
18700
+ focusHandler,
18701
+ titleStyles = {}
18311
18702
  } = _ref2;
18312
18703
  const showTitle = layout.showTitles && !!layout.title;
18313
18704
  const showSubtitle = layout.showTitles && !!layout.subtitle;
@@ -18365,11 +18756,13 @@ function Header(_ref2) {
18365
18756
  }, showTitle && /*#__PURE__*/React__default.createElement(Typography, {
18366
18757
  variant: "h6",
18367
18758
  noWrap: true,
18368
- className: CellTitle.className
18759
+ className: CellTitle.className,
18760
+ style: titleStyles.main
18369
18761
  }, layout.title), showSubtitle && /*#__PURE__*/React__default.createElement(Typography, {
18370
18762
  variant: "body2",
18371
18763
  noWrap: true,
18372
- className: CellSubTitle.className
18764
+ className: CellSubTitle.className,
18765
+ style: titleStyles.subTitle
18373
18766
  }, layout.subtitle))), /*#__PURE__*/React__default.createElement(Grid, {
18374
18767
  item: true
18375
18768
  }, Toolbar));
@@ -18402,7 +18795,8 @@ const CellFooter = {
18402
18795
  };
18403
18796
  function Footer(_ref2) {
18404
18797
  let {
18405
- layout
18798
+ layout,
18799
+ titleStyles = {}
18406
18800
  } = _ref2;
18407
18801
  return layout && layout.showTitles && layout.footnote ? /*#__PURE__*/React__default.createElement(StyledGrid, {
18408
18802
  container: true
@@ -18412,7 +18806,8 @@ function Footer(_ref2) {
18412
18806
  }, /*#__PURE__*/React__default.createElement(Typography, {
18413
18807
  noWrap: true,
18414
18808
  variant: "body2",
18415
- className: CellFooter.className
18809
+ className: CellFooter.className,
18810
+ style: titleStyles.footer
18416
18811
  }, layout.footnote))) : null;
18417
18812
  }
18418
18813
 
@@ -18642,7 +19037,7 @@ function getBackgroundSize(bgComp) {
18642
19037
  function resolveImageUrl(app, relativeUrl) {
18643
19038
  return relativeUrl ? getSenseServerUrl(app) + relativeUrl : undefined;
18644
19039
  }
18645
- const resolveBgImage = (bgComp, app) => {
19040
+ function resolveBgImage(bgComp, app) {
18646
19041
  const bgImageDef = bgComp === null || bgComp === void 0 ? void 0 : bgComp.bgImage;
18647
19042
  if (bgImageDef) {
18648
19043
  let url = '';
@@ -18663,8 +19058,8 @@ const resolveBgImage = (bgComp, app) => {
18663
19058
  } : undefined;
18664
19059
  }
18665
19060
  return undefined;
18666
- };
18667
- const resolveBgColor = (bgComp, theme) => {
19061
+ }
19062
+ function resolveBgColor(bgComp, theme, objectType) {
18668
19063
  const bgColor = bgComp === null || bgComp === void 0 ? void 0 : bgComp.bgColor;
18669
19064
  if (bgColor && theme) {
18670
19065
  if (bgColor.useExpression) {
@@ -18672,8 +19067,32 @@ const resolveBgColor = (bgComp, theme) => {
18672
19067
  }
18673
19068
  return bgColor.color && bgColor.color.color !== 'none' ? theme.getColorPickerColor(bgColor.color, true) : undefined;
18674
19069
  }
19070
+ if (theme && objectType) {
19071
+ return theme.getStyle("object.".concat(objectType), '', 'backgroundColor');
19072
+ }
19073
+ if (theme) {
19074
+ return theme.getStyle('', '', 'backgroundColor');
19075
+ }
18675
19076
  return undefined;
18676
- };
19077
+ }
19078
+ function unfurlFontStyle(fontStyle, target) {
19079
+ if (fontStyle && Array.isArray(fontStyle)) {
19080
+ return fontStyle;
19081
+ }
19082
+ return target === 'main' ? ['bold'] : [];
19083
+ }
19084
+ function resolveTextStyle(textComp, target, theme, objectType) {
19085
+ var _textComp$title;
19086
+ const textProps = (textComp === null || textComp === void 0 ? void 0 : (_textComp$title = textComp.title) === null || _textComp$title === void 0 ? void 0 : _textComp$title[target]) || {};
19087
+ const fontStyle = unfurlFontStyle(textProps.fontStyle, target);
19088
+ return {
19089
+ fontFamily: textProps.fontFamily || theme.getStyle("object.".concat(objectType), "title.".concat(target), 'fontFamily'),
19090
+ color: textProps.color && textProps.color.color !== 'none' ? theme.getColorPickerColor(textProps.color, true) : theme.getStyle("object.".concat(objectType), target, 'color'),
19091
+ fontWeight: fontStyle.includes('bold') ? 'bold' : 'normal',
19092
+ fontStyle: fontStyle.includes('italic') ? 'italic' : 'normal',
19093
+ textDecoration: fontStyle.includes('underline') ? 'underline' : 'initial'
19094
+ };
19095
+ }
18677
19096
 
18678
19097
  /**
18679
19098
  * @interface
@@ -18915,7 +19334,8 @@ const loadType = async _ref5 => {
18915
19334
  app,
18916
19335
  selections,
18917
19336
  nebbie,
18918
- focusHandler
19337
+ focusHandler,
19338
+ emitter
18919
19339
  } = _ref5;
18920
19340
  try {
18921
19341
  const snType = await getType({
@@ -18928,7 +19348,8 @@ const loadType = async _ref5 => {
18928
19348
  app,
18929
19349
  selections,
18930
19350
  nebbie,
18931
- focusHandler
19351
+ focusHandler,
19352
+ emitter
18932
19353
  });
18933
19354
  return sn;
18934
19355
  } catch (err) {
@@ -18958,7 +19379,8 @@ const Cell = forwardRef((_ref6, ref) => {
18958
19379
  initialSnPlugins,
18959
19380
  initialError,
18960
19381
  onMount,
18961
- currentId
19382
+ currentId,
19383
+ emitter
18962
19384
  } = _ref6;
18963
19385
  const {
18964
19386
  app,
@@ -18997,7 +19419,7 @@ const Cell = forwardRef((_ref6, ref) => {
18997
19419
  });
18998
19420
  const [bgColor, setBgColor] = useState$1(undefined);
18999
19421
  const [bgImage, setBgImage] = useState$1(undefined); // {url: "", size: "", pos: ""}
19000
-
19422
+ const [titleStyles, setTitleStyles] = useState$1(undefined);
19001
19423
  const focusHandler = useRef({
19002
19424
  focusToolbarButton(last) {
19003
19425
  // eslint-disable-next-line react/no-this-in-sfc
@@ -19008,9 +19430,16 @@ const Cell = forwardRef((_ref6, ref) => {
19008
19430
  eventmixin(focusHandler.current);
19009
19431
  }, []);
19010
19432
  useEffect$1(() => {
19011
- const bgComp = layout !== null && layout !== void 0 && layout.components ? layout.components.find(comp => comp.key === 'general') : null;
19012
- setBgColor(resolveBgColor(bgComp, halo.public.theme));
19013
- setBgImage(resolveBgImage(bgComp, halo.app));
19433
+ if (layout && halo.public.theme) {
19434
+ const bgComp = layout.components ? layout.components.find(comp => comp.key === 'general') : null;
19435
+ setTitleStyles({
19436
+ main: resolveTextStyle(bgComp, 'main', halo.public.theme, layout.visualization),
19437
+ footer: resolveTextStyle(bgComp, 'footer', halo.public.theme, layout.visualization),
19438
+ subTitle: resolveTextStyle(bgComp, 'subTitle', halo.public.theme, layout.visualization)
19439
+ });
19440
+ setBgColor(resolveBgColor(bgComp, halo.public.theme, layout.visualization));
19441
+ setBgImage(resolveBgImage(bgComp, halo.app));
19442
+ }
19014
19443
  }, [layout, halo.public.theme, halo.app, themeName]);
19015
19444
  focusHandler.current.blurCallback = resetFocus => {
19016
19445
  halo.root.toggleFocusOfCells();
@@ -19082,7 +19511,8 @@ const Cell = forwardRef((_ref6, ref) => {
19082
19511
  app,
19083
19512
  selections,
19084
19513
  nebbie,
19085
- focusHandler: focusHandler.current
19514
+ focusHandler: focusHandler.current,
19515
+ emitter
19086
19516
  });
19087
19517
  if (sn) {
19088
19518
  dispatch({
@@ -19224,7 +19654,8 @@ const Cell = forwardRef((_ref6, ref) => {
19224
19654
  sn: state.sn,
19225
19655
  anchorEl: cellNode,
19226
19656
  hovering: hovering,
19227
- focusHandler: focusHandler.current
19657
+ focusHandler: focusHandler.current,
19658
+ titleStyles: titleStyles
19228
19659
  }, "\xA0"), /*#__PURE__*/React__default.createElement(Grid, {
19229
19660
  tabIndex: keyboardNavigation ? 0 : -1,
19230
19661
  onKeyDown: keyboardNavigation ? handleKeyDown : null,
@@ -19235,7 +19666,8 @@ const Cell = forwardRef((_ref6, ref) => {
19235
19666
  },
19236
19667
  ref: contentRef
19237
19668
  }, Content), /*#__PURE__*/React__default.createElement(Footer, {
19238
- layout: layout
19669
+ layout: layout,
19670
+ titleStyles: titleStyles
19239
19671
  })), state.longRunningQuery && /*#__PURE__*/React__default.createElement(LongRunningQuery, {
19240
19672
  canCancel: canCancel,
19241
19673
  canRetry: canRetry,
@@ -19251,6 +19683,7 @@ function glue$1(_ref) {
19251
19683
  initialSnOptions,
19252
19684
  initialSnPlugins,
19253
19685
  onMount,
19686
+ emitter,
19254
19687
  initialError
19255
19688
  } = _ref;
19256
19689
  const {
@@ -19266,7 +19699,8 @@ function glue$1(_ref) {
19266
19699
  initialSnOptions: initialSnOptions,
19267
19700
  initialSnPlugins: initialSnPlugins,
19268
19701
  initialError: initialError,
19269
- onMount: onMount
19702
+ onMount: onMount,
19703
+ emitter: emitter
19270
19704
  }), element, currentId);
19271
19705
  const unmount = () => {
19272
19706
  root.remove(portal);
@@ -19366,6 +19800,7 @@ function viz() {
19366
19800
  });
19367
19801
  let initialSnOptions = {};
19368
19802
  let initialSnPlugins = [];
19803
+ const emitter = new nodeEventEmitter();
19369
19804
  const setSnOptions = async opts => {
19370
19805
  if (mountedReference) {
19371
19806
  (async () => {
@@ -19456,6 +19891,24 @@ function viz() {
19456
19891
  }
19457
19892
  return propertyTree;
19458
19893
  },
19894
+ /**
19895
+ * Listens to custom events from inside the visualization. See useEmitter
19896
+ * @experimental
19897
+ * @param {string} eventName Event name to listen to
19898
+ * @param {Function} listener Callback function to invoke
19899
+ */
19900
+ on(eventName, listener) {
19901
+ emitter.on(eventName, listener);
19902
+ },
19903
+ /**
19904
+ * Removes a listener
19905
+ * @experimental
19906
+ * @param {string} eventName Event name to remove from
19907
+ * @param {Function} listener Callback function to remove
19908
+ */
19909
+ off(eventName, listener) {
19910
+ emitter.off(eventName, listener);
19911
+ },
19459
19912
  // ===== unexposed experimental API - use at own risk ======
19460
19913
  __DO_NOT_USE__: {
19461
19914
  mount(element) {
@@ -19470,7 +19923,8 @@ function viz() {
19470
19923
  initialSnOptions,
19471
19924
  initialSnPlugins,
19472
19925
  initialError,
19473
- onMount
19926
+ onMount,
19927
+ emitter
19474
19928
  });
19475
19929
  return mounted;
19476
19930
  },
@@ -21417,7 +21871,7 @@ function onTakeSnapshot(cb) {
21417
21871
  * @ignore
21418
21872
  * @example
21419
21873
  * import { onContextMenu } from '@nebula.js/stardust';
21420
-
21874
+
21421
21875
  * onContextMenu((menu, event) => {
21422
21876
  * menu.addItem(item, index);
21423
21877
  * });
@@ -21471,6 +21925,32 @@ function useRenderState() {
21471
21925
  };
21472
21926
  }
21473
21927
 
21928
+ /**
21929
+ * Gets an event emitter instance for the visualization.
21930
+ * @entry
21931
+ * @experimental
21932
+ * @returns {Emitter} The emitter instance. Implements https://nodejs.org/api/events.html#class-eventemitter.
21933
+ * @example
21934
+ * // In a Nebula visualization
21935
+ * import { useEmitter } from '@nebula.js/stardust';
21936
+ * useEffect(()=> {
21937
+ * // on some trigger
21938
+ * emitter.emit("trigger", params)
21939
+ * }, [...])
21940
+ *
21941
+ * // In a mashup
21942
+ * const viz = await n.render({
21943
+ * element: el,
21944
+ * id: 'abcdef'
21945
+ * });
21946
+ * viz.on("trigger", ()=> {
21947
+ * // do something
21948
+ * })
21949
+ */
21950
+ function useEmitter() {
21951
+ return useInternalContext('emitter');
21952
+ }
21953
+
21474
21954
  /**
21475
21955
  * @experimental
21476
21956
  * @interface Keyboard
@@ -21652,6 +22132,7 @@ function createWithHooks(generator, opts, galaxy) {
21652
22132
  nebbie: opts.nebbie,
21653
22133
  element: undefined,
21654
22134
  // set on mount
22135
+ emitter: opts.emitter,
21655
22136
  // ---- singletons ----
21656
22137
  deviceType: galaxy.deviceType,
21657
22138
  theme: undefined,
@@ -24841,5 +25322,5 @@ const __DO_NOT_USE__ = {
24841
25322
  locale
24842
25323
  };
24843
25324
 
24844
- export { mocker as EnigmaMocker, __DO_NOT_USE__, conversion, index as embed, onContextMenu, onTakeSnapshot, useAction, useApp, useAppLayout, useConstraints, useDeviceType, useEffect, useElement, useEmbed, useGlobal, useImperativeHandle, useKeyboard, useLayout, useMemo, useModel, useOptions, usePlugins, usePromise, useRect, useRenderState, useSelections, useStaleLayout, useState, useTheme, useTranslator };
25325
+ export { mocker as EnigmaMocker, __DO_NOT_USE__, conversion, index as embed, onContextMenu, onTakeSnapshot, useAction, useApp, useAppLayout, useConstraints, useDeviceType, useEffect, useElement, useEmbed, useEmitter, useGlobal, useImperativeHandle, useKeyboard, useLayout, useMemo, useModel, useOptions, usePlugins, usePromise, useRect, useRenderState, useSelections, useStaleLayout, useState, useTheme, useTranslator };
24845
25326
  //# sourceMappingURL=dev.js.map