@nebula.js/stardust 1.7.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/core/esm/dev.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * @nebula.js/stardust v1.7.0
2
+ * @nebula.js/stardust v2.2.0
3
3
  * Copyright (c) 2021 QlikTech International AB
4
4
  * Released under the MIT license.
5
5
  */
@@ -5690,7 +5690,7 @@ function useAppSelections(app) {
5690
5690
  return [appSelections, navState];
5691
5691
  }
5692
5692
 
5693
- var NEBULA_VERSION_HASH = "6a15" ;
5693
+ var NEBULA_VERSION_HASH = "34e9" ;
5694
5694
  var counter = 0;
5695
5695
  var NebulaApp = forwardRef(function (_ref, ref) {
5696
5696
  var initialContext = _ref.initialContext,
@@ -5766,7 +5766,7 @@ function boot(_ref2) {
5766
5766
  var appRef = React.createRef();
5767
5767
  var element = document.createElement('div');
5768
5768
  element.style.display = 'none';
5769
- element.setAttribute('data-nebulajs-version', "1.7.0" );
5769
+ element.setAttribute('data-nebulajs-version', "2.2.0" );
5770
5770
  element.setAttribute('data-app-id', app.id);
5771
5771
  document.body.appendChild(element);
5772
5772
  ReactDOM.render( /*#__PURE__*/React.createElement(NebulaApp, {
@@ -5774,7 +5774,17 @@ function boot(_ref2) {
5774
5774
  app: app,
5775
5775
  initialContext: context
5776
5776
  }), element, resolveRender);
5777
+ var cells = {};
5777
5778
  return [{
5779
+ toggleFocusOfCells: function toggleFocusOfCells(cellIdToFocus) {
5780
+ Object.keys(cells).forEach(function (i) {
5781
+ cells[i].current.toggleFocus(i === cellIdToFocus);
5782
+ });
5783
+ },
5784
+ cells: cells,
5785
+ addCell: function addCell(id, cell) {
5786
+ cells[id] = cell;
5787
+ },
5778
5788
  add: function add(component) {
5779
5789
  _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
5780
5790
  return regeneratorRuntime.wrap(function _callee$(_context) {
@@ -7597,6 +7607,16 @@ function useActionState(item) {
7597
7607
  };
7598
7608
  }
7599
7609
 
7610
+ /**
7611
+ * @interface
7612
+ * @extends HTMLElement
7613
+ * @since 2.0.0
7614
+ */
7615
+
7616
+ var ActionElement = {
7617
+ /** @type {'njs-cell-action'} */
7618
+ className: 'njs-cell-action'
7619
+ };
7600
7620
  var Item = React.forwardRef(function (_ref, ref) {
7601
7621
  var item = _ref.item,
7602
7622
  _ref$addAnchor = _ref.addAnchor,
@@ -7614,8 +7634,12 @@ var Item = React.forwardRef(function (_ref, ref) {
7614
7634
  ref: !addAnchor ? ref : null,
7615
7635
  title: item.label,
7616
7636
  onClick: item.action,
7637
+ onKeyDown: function onKeyDown(e) {
7638
+ return ['Enter', ' ', 'Spacebar'].includes(e.key) && item.keyboardAction();
7639
+ },
7617
7640
  disabled: disabled,
7618
- style: style
7641
+ style: style,
7642
+ className: ActionElement.className
7619
7643
  }, hasSvgIconShape && SvgIcon(item.getSvgIconShape()), addAnchor && /*#__PURE__*/React.createElement("div", {
7620
7644
  ref: ref,
7621
7645
  style: {
@@ -7659,7 +7683,9 @@ function useDefaultSelectionActions(_ref) {
7659
7683
  _ref$onConfirm = _ref.onConfirm,
7660
7684
  onConfirm = _ref$onConfirm === void 0 ? function () {} : _ref$onConfirm,
7661
7685
  _ref$onCancel = _ref.onCancel,
7662
- onCancel = _ref$onCancel === void 0 ? function () {} : _ref$onCancel;
7686
+ onCancel = _ref$onCancel === void 0 ? function () {} : _ref$onCancel,
7687
+ _ref$onKeyDeactivate = _ref.onKeyDeactivate,
7688
+ onKeyDeactivate = _ref$onKeyDeactivate === void 0 ? function () {} : _ref$onKeyDeactivate;
7663
7689
 
7664
7690
  var _useContext = useContext(InstanceContext),
7665
7691
  translator = _useContext.translator;
@@ -7683,8 +7709,13 @@ function useDefaultSelectionActions(_ref) {
7683
7709
  return api.canCancel();
7684
7710
  },
7685
7711
  action: function action() {
7712
+ onCancel();
7686
7713
  api.cancel();
7714
+ },
7715
+ keyboardAction: function keyboardAction(e) {
7716
+ onKeyDeactivate(e);
7687
7717
  onCancel();
7718
+ api.cancel();
7688
7719
  },
7689
7720
  getSvgIconShape: close
7690
7721
  }, {
@@ -7695,8 +7726,13 @@ function useDefaultSelectionActions(_ref) {
7695
7726
  return api.canConfirm();
7696
7727
  },
7697
7728
  action: function action() {
7729
+ onConfirm();
7698
7730
  api.confirm();
7731
+ },
7732
+ keyboardAction: function keyboardAction(e) {
7733
+ onKeyDeactivate(e);
7699
7734
  onConfirm();
7735
+ api.confirm();
7700
7736
  },
7701
7737
  getSvgIconShape: tick
7702
7738
  }];
@@ -7793,6 +7829,16 @@ var More$1 = React.forwardRef(function (_ref2, ref) {
7793
7829
  })));
7794
7830
  });
7795
7831
 
7832
+ /**
7833
+ * @interface
7834
+ * @extends HTMLElement
7835
+ * @since 2.1.0
7836
+ */
7837
+
7838
+ var ActionToolbarElement = {
7839
+ /** @type {'njs-action-toolbar-popover'} */
7840
+ className: 'njs-action-toolbar-popover'
7841
+ };
7796
7842
  var useStyles$8 = makeStyles$1(function (theme) {
7797
7843
  return {
7798
7844
  itemSpacing: {
@@ -7893,14 +7939,19 @@ var ActionsToolbar = function ActionsToolbar(_ref2) {
7893
7939
  popover = _ref2$popover === void 0 ? {
7894
7940
  show: false,
7895
7941
  anchorEl: null
7896
- } : _ref2$popover;
7942
+ } : _ref2$popover,
7943
+ _ref2$focusHandler = _ref2.focusHandler,
7944
+ focusHandler = _ref2$focusHandler === void 0 ? null : _ref2$focusHandler,
7945
+ _ref2$actionsRefMock = _ref2.actionsRefMock,
7946
+ actionsRefMock = _ref2$actionsRefMock === void 0 ? null : _ref2$actionsRefMock;
7897
7947
  var defaultSelectionActions = useDefaultSelectionActions(selections);
7898
7948
 
7899
7949
  var _useStyles2 = useStyles$8(),
7900
7950
  itemSpacing = _useStyles2.itemSpacing;
7901
7951
 
7902
7952
  var _useContext = useContext(InstanceContext),
7903
- translator = _useContext.translator;
7953
+ translator = _useContext.translator,
7954
+ keyboardNavigation = _useContext.keyboardNavigation;
7904
7955
 
7905
7956
  var _useState = useState$1(false),
7906
7957
  _useState2 = _slicedToArray(_useState, 2),
@@ -7923,12 +7974,21 @@ var ActionsToolbar = function ActionsToolbar(_ref2) {
7923
7974
  setMoreAlignTo = _useState8[1];
7924
7975
 
7925
7976
  var moreRef = useRef();
7977
+ var actionsRef = useRef();
7926
7978
  var theme = useTheme$1();
7927
7979
  var dividerStyle = useMemo$1(function () {
7928
7980
  return {
7929
7981
  margin: theme.spacing(0.5, 0)
7930
7982
  };
7931
7983
  });
7984
+
7985
+ var getEnabledButton = function getEnabledButton(last) {
7986
+ var actionsElement = actionsRef.current || actionsRefMock;
7987
+ if (!actionsElement) return null;
7988
+ var buttons = actionsElement.querySelectorAll('button:not(.Mui-disabled)');
7989
+ return buttons[last ? buttons.length - 1 : 0];
7990
+ };
7991
+
7932
7992
  useEffect$1(function () {
7933
7993
  return function () {
7934
7994
  return setShowMoreItems(false);
@@ -7937,6 +7997,22 @@ var ActionsToolbar = function ActionsToolbar(_ref2) {
7937
7997
  useEffect$1(function () {
7938
7998
  setMoreEnabled(more$1.enabled);
7939
7999
  }, [more$1.enabled]);
8000
+ useEffect$1(function () {
8001
+ if (!focusHandler) return;
8002
+
8003
+ var focusFirst = function focusFirst() {
8004
+ var enabledButton = getEnabledButton(false);
8005
+ enabledButton && enabledButton.focus();
8006
+ };
8007
+
8008
+ var focusLast = function focusLast() {
8009
+ var enabledButton = getEnabledButton(true);
8010
+ enabledButton && enabledButton.focus();
8011
+ };
8012
+
8013
+ focusHandler.on('focus_toolbar_first', focusFirst);
8014
+ focusHandler.on('focus_toolbar_last', focusLast);
8015
+ }, []);
7940
8016
  var newActions = useMemo$1(function () {
7941
8017
  return actions.filter(function (a) {
7942
8018
  return !a.hidden;
@@ -7969,10 +8045,23 @@ var ActionsToolbar = function ActionsToolbar(_ref2) {
7969
8045
  setMoreAlignTo(moreRef);
7970
8046
  }
7971
8047
 
8048
+ var tabCallback = // if keyboardNavigation is true, create a callback to handle tabbing from the first/last button in the toolbar that resets focus on the content
8049
+ keyboardNavigation && focusHandler && focusHandler.refocusContent ? function (evt) {
8050
+ if (evt.key !== 'Tab') return;
8051
+ var isTabbingOut = evt.shiftKey && getEnabledButton(false) === evt.target || !evt.shiftKey && getEnabledButton(true) === evt.target;
8052
+
8053
+ if (isTabbingOut) {
8054
+ evt.preventDefault();
8055
+ evt.stopPropagation();
8056
+ focusHandler.refocusContent();
8057
+ }
8058
+ } : null;
7972
8059
  var showActions = newActions.length > 0;
7973
8060
  var showMore = moreActions.length > 0;
7974
8061
  var showDivider = showActions && selections.show || showMore && selections.show;
7975
8062
  var Actions = /*#__PURE__*/React.createElement(Grid, {
8063
+ ref: actionsRef,
8064
+ onKeyDown: tabCallback,
7976
8065
  container: true,
7977
8066
  spacing: 0,
7978
8067
  wrap: "nowrap"
@@ -8015,6 +8104,7 @@ var ActionsToolbar = function ActionsToolbar(_ref2) {
8015
8104
  hideBackdrop: true,
8016
8105
  style: popoverStyle,
8017
8106
  PaperProps: {
8107
+ className: ActionToolbarElement.className,
8018
8108
  style: {
8019
8109
  pointerEvents: 'auto',
8020
8110
  padding: theme.spacing(1, 1)
@@ -8050,7 +8140,9 @@ var useStyles$7 = makeStyles(function (theme) {
8050
8140
  });
8051
8141
  var TREE_PATH = '/qListObjectDef';
8052
8142
  function ListBoxSearch(_ref) {
8053
- var model = _ref.model;
8143
+ var model = _ref.model,
8144
+ _ref$autoFocus = _ref.autoFocus,
8145
+ autoFocus = _ref$autoFocus === void 0 ? true : _ref$autoFocus;
8054
8146
 
8055
8147
  var _useContext = useContext(InstanceContext),
8056
8148
  translator = _useContext.translator;
@@ -8084,7 +8176,7 @@ function ListBoxSearch(_ref) {
8084
8176
  position: "start"
8085
8177
  }, /*#__PURE__*/React.createElement(Search, null)),
8086
8178
  className: [classes.root].join(' '),
8087
- autoFocus: true,
8179
+ autoFocus: autoFocus,
8088
8180
  margin: "dense",
8089
8181
  fullWidth: true,
8090
8182
  placeholder: translator.get('Listbox.Search'),
@@ -9344,6 +9436,106 @@ function mount(_ref2) {
9344
9436
  }), element);
9345
9437
  }
9346
9438
 
9439
+ var classCallCheck = function (instance, Constructor) {
9440
+ if (!(instance instanceof Constructor)) {
9441
+ throw new TypeError("Cannot call a class as a function");
9442
+ }
9443
+ };
9444
+
9445
+ var createClass = function () {
9446
+ function defineProperties(target, props) {
9447
+ for (var i = 0; i < props.length; i++) {
9448
+ var descriptor = props[i];
9449
+ descriptor.enumerable = descriptor.enumerable || false;
9450
+ descriptor.configurable = true;
9451
+ if ("value" in descriptor) descriptor.writable = true;
9452
+ Object.defineProperty(target, descriptor.key, descriptor);
9453
+ }
9454
+ }
9455
+
9456
+ return function (Constructor, protoProps, staticProps) {
9457
+ if (protoProps) defineProperties(Constructor.prototype, protoProps);
9458
+ if (staticProps) defineProperties(Constructor, staticProps);
9459
+ return Constructor;
9460
+ };
9461
+ }();
9462
+
9463
+ var _extends = Object.assign || function (target) {
9464
+ for (var i = 1; i < arguments.length; i++) {
9465
+ var source = arguments[i];
9466
+
9467
+ for (var key in source) {
9468
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
9469
+ target[key] = source[key];
9470
+ }
9471
+ }
9472
+ }
9473
+
9474
+ return target;
9475
+ };
9476
+
9477
+ var inherits = function (subClass, superClass) {
9478
+ if (typeof superClass !== "function" && superClass !== null) {
9479
+ throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
9480
+ }
9481
+
9482
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
9483
+ constructor: {
9484
+ value: subClass,
9485
+ enumerable: false,
9486
+ writable: true,
9487
+ configurable: true
9488
+ }
9489
+ });
9490
+ if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
9491
+ };
9492
+
9493
+ var possibleConstructorReturn = function (self, call) {
9494
+ if (!self) {
9495
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
9496
+ }
9497
+
9498
+ return call && (typeof call === "object" || typeof call === "function") ? call : self;
9499
+ };
9500
+
9501
+ var slicedToArray = function () {
9502
+ function sliceIterator(arr, i) {
9503
+ var _arr = [];
9504
+ var _n = true;
9505
+ var _d = false;
9506
+ var _e = undefined;
9507
+
9508
+ try {
9509
+ for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
9510
+ _arr.push(_s.value);
9511
+
9512
+ if (i && _arr.length === i) break;
9513
+ }
9514
+ } catch (err) {
9515
+ _d = true;
9516
+ _e = err;
9517
+ } finally {
9518
+ try {
9519
+ if (!_n && _i["return"]) _i["return"]();
9520
+ } finally {
9521
+ if (_d) throw _e;
9522
+ }
9523
+ }
9524
+
9525
+ return _arr;
9526
+ }
9527
+
9528
+ return function (arr, i) {
9529
+ if (Array.isArray(arr)) {
9530
+ return arr;
9531
+ } else if (Symbol.iterator in Object(arr)) {
9532
+ return sliceIterator(arr, i);
9533
+ } else {
9534
+ throw new TypeError("Invalid attempt to destructure non-iterable instance");
9535
+ }
9536
+ };
9537
+ }();
9538
+
9347
9539
  /**
9348
9540
  * Detect Element Resize.
9349
9541
  * https://github.com/sdecima/javascript-detect-element-resize
@@ -9356,37 +9548,77 @@ function mount(_ref2) {
9356
9548
  * 4) Add nonce for style element.
9357
9549
  **/
9358
9550
 
9359
- function createDetectElementResize(nonce) {
9360
- // Check `document` and `window` in case of server-side rendering
9361
- var _window;
9362
- if (typeof window !== 'undefined') {
9363
- _window = window;
9364
- } else if (typeof self !== 'undefined') {
9365
- _window = self;
9366
- } else {
9367
- _window = global;
9368
- }
9551
+ // Check `document` and `window` in case of server-side rendering
9552
+ var windowObject = void 0;
9553
+ if (typeof window !== 'undefined') {
9554
+ windowObject = window;
9369
9555
 
9370
- var attachEvent = typeof document !== 'undefined' && document.attachEvent;
9556
+ // eslint-disable-next-line no-restricted-globals
9557
+ } else if (typeof self !== 'undefined') {
9558
+ // eslint-disable-next-line no-restricted-globals
9559
+ windowObject = self;
9560
+ } else {
9561
+ windowObject = global;
9562
+ }
9371
9563
 
9372
- if (!attachEvent) {
9373
- var requestFrame = function () {
9374
- var raf = _window.requestAnimationFrame || _window.mozRequestAnimationFrame || _window.webkitRequestAnimationFrame || function (fn) {
9375
- return _window.setTimeout(fn, 20);
9376
- };
9377
- return function (fn) {
9378
- return raf(fn);
9379
- };
9380
- }();
9564
+ var cancelFrame = null;
9565
+ var requestFrame = null;
9381
9566
 
9382
- var cancelFrame = function () {
9383
- var cancel = _window.cancelAnimationFrame || _window.mozCancelAnimationFrame || _window.webkitCancelAnimationFrame || _window.clearTimeout;
9384
- return function (id) {
9385
- return cancel(id);
9386
- };
9387
- }();
9567
+ var TIMEOUT_DURATION = 20;
9568
+
9569
+ var clearTimeoutFn = windowObject.clearTimeout;
9570
+ var setTimeoutFn = windowObject.setTimeout;
9388
9571
 
9389
- var resetTriggers = function resetTriggers(element) {
9572
+ var cancelAnimationFrameFn = windowObject.cancelAnimationFrame || windowObject.mozCancelAnimationFrame || windowObject.webkitCancelAnimationFrame;
9573
+
9574
+ var requestAnimationFrameFn = windowObject.requestAnimationFrame || windowObject.mozRequestAnimationFrame || windowObject.webkitRequestAnimationFrame;
9575
+
9576
+ if (cancelAnimationFrameFn == null || requestAnimationFrameFn == null) {
9577
+ // For environments that don't support animation frame,
9578
+ // fallback to a setTimeout based approach.
9579
+ cancelFrame = clearTimeoutFn;
9580
+ requestFrame = function requestAnimationFrameViaSetTimeout(callback) {
9581
+ return setTimeoutFn(callback, TIMEOUT_DURATION);
9582
+ };
9583
+ } else {
9584
+ // Counter intuitively, environments that support animation frames can be trickier.
9585
+ // Chrome's "Throttle non-visible cross-origin iframes" flag can prevent rAFs from being called.
9586
+ // In this case, we should fallback to a setTimeout() implementation.
9587
+ cancelFrame = function cancelFrame(_ref) {
9588
+ var _ref2 = slicedToArray(_ref, 2),
9589
+ animationFrameID = _ref2[0],
9590
+ timeoutID = _ref2[1];
9591
+
9592
+ cancelAnimationFrameFn(animationFrameID);
9593
+ clearTimeoutFn(timeoutID);
9594
+ };
9595
+ requestFrame = function requestAnimationFrameWithSetTimeoutFallback(callback) {
9596
+ var animationFrameID = requestAnimationFrameFn(function animationFrameCallback() {
9597
+ clearTimeoutFn(timeoutID);
9598
+ callback();
9599
+ });
9600
+
9601
+ var timeoutID = setTimeoutFn(function timeoutCallback() {
9602
+ cancelAnimationFrameFn(animationFrameID);
9603
+ callback();
9604
+ }, TIMEOUT_DURATION);
9605
+
9606
+ return [animationFrameID, timeoutID];
9607
+ };
9608
+ }
9609
+
9610
+ function createDetectElementResize(nonce) {
9611
+ var animationKeyframes = void 0;
9612
+ var animationName = void 0;
9613
+ var animationStartEvent = void 0;
9614
+ var animationStyle = void 0;
9615
+ var checkTriggers = void 0;
9616
+ var resetTriggers = void 0;
9617
+ var scrollListener = void 0;
9618
+
9619
+ var attachEvent = typeof document !== 'undefined' && document.attachEvent;
9620
+ if (!attachEvent) {
9621
+ resetTriggers = function resetTriggers(element) {
9390
9622
  var triggers = element.__resizeTriggers__,
9391
9623
  expand = triggers.firstElementChild,
9392
9624
  contract = triggers.lastElementChild,
@@ -9399,11 +9631,11 @@ function createDetectElementResize(nonce) {
9399
9631
  expand.scrollTop = expand.scrollHeight;
9400
9632
  };
9401
9633
 
9402
- var checkTriggers = function checkTriggers(element) {
9403
- return element.offsetWidth != element.__resizeLast__.width || element.offsetHeight != element.__resizeLast__.height;
9634
+ checkTriggers = function checkTriggers(element) {
9635
+ return element.offsetWidth !== element.__resizeLast__.width || element.offsetHeight !== element.__resizeLast__.height;
9404
9636
  };
9405
9637
 
9406
- var scrollListener = function scrollListener(e) {
9638
+ scrollListener = function scrollListener(e) {
9407
9639
  // Don't measure (which forces) reflow for scrolls that happen inside of children!
9408
9640
  if (e.target.className && typeof e.target.className.indexOf === 'function' && e.target.className.indexOf('contract-trigger') < 0 && e.target.className.indexOf('expand-trigger') < 0) {
9409
9641
  return;
@@ -9414,11 +9646,11 @@ function createDetectElementResize(nonce) {
9414
9646
  if (this.__resizeRAF__) {
9415
9647
  cancelFrame(this.__resizeRAF__);
9416
9648
  }
9417
- this.__resizeRAF__ = requestFrame(function () {
9649
+ this.__resizeRAF__ = requestFrame(function animationFrame() {
9418
9650
  if (checkTriggers(element)) {
9419
9651
  element.__resizeLast__.width = element.offsetWidth;
9420
9652
  element.__resizeLast__.height = element.offsetHeight;
9421
- element.__resizeListeners__.forEach(function (fn) {
9653
+ element.__resizeListeners__.forEach(function forEachResizeListener(fn) {
9422
9654
  fn.call(element, e);
9423
9655
  });
9424
9656
  }
@@ -9426,12 +9658,12 @@ function createDetectElementResize(nonce) {
9426
9658
  };
9427
9659
 
9428
9660
  /* Detect CSS Animations support to detect element display/re-attach */
9429
- var animation = false,
9430
- keyframeprefix = '',
9431
- animationstartevent = 'animationstart',
9432
- domPrefixes = 'Webkit Moz O ms'.split(' '),
9433
- startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '),
9434
- pfx = '';
9661
+ var animation = false;
9662
+ var keyframeprefix = '';
9663
+ animationStartEvent = 'animationstart';
9664
+ var domPrefixes = 'Webkit Moz O ms'.split(' ');
9665
+ var startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' ');
9666
+ var pfx = '';
9435
9667
  {
9436
9668
  var elm = document.createElement('fakeelement');
9437
9669
  if (elm.style.animationName !== undefined) {
@@ -9443,7 +9675,7 @@ function createDetectElementResize(nonce) {
9443
9675
  if (elm.style[domPrefixes[i] + 'AnimationName'] !== undefined) {
9444
9676
  pfx = domPrefixes[i];
9445
9677
  keyframeprefix = '-' + pfx.toLowerCase() + '-';
9446
- animationstartevent = startEvents[i];
9678
+ animationStartEvent = startEvents[i];
9447
9679
  animation = true;
9448
9680
  break;
9449
9681
  }
@@ -9451,9 +9683,9 @@ function createDetectElementResize(nonce) {
9451
9683
  }
9452
9684
  }
9453
9685
 
9454
- var animationName = 'resizeanim';
9455
- var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } ';
9456
- var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; ';
9686
+ animationName = 'resizeanim';
9687
+ animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } ';
9688
+ animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; ';
9457
9689
  }
9458
9690
 
9459
9691
  var createStyles = function createStyles(doc) {
@@ -9486,8 +9718,8 @@ function createDetectElementResize(nonce) {
9486
9718
  } else {
9487
9719
  if (!element.__resizeTriggers__) {
9488
9720
  var doc = element.ownerDocument;
9489
- var elementStyle = _window.getComputedStyle(element);
9490
- if (elementStyle && elementStyle.position == 'static') {
9721
+ var elementStyle = windowObject.getComputedStyle(element);
9722
+ if (elementStyle && elementStyle.position === 'static') {
9491
9723
  element.style.position = 'relative';
9492
9724
  }
9493
9725
  createStyles(doc);
@@ -9506,13 +9738,13 @@ function createDetectElementResize(nonce) {
9506
9738
  element.addEventListener('scroll', scrollListener, true);
9507
9739
 
9508
9740
  /* Listen for a css animation to detect element display/re-attach */
9509
- if (animationstartevent) {
9741
+ if (animationStartEvent) {
9510
9742
  element.__resizeTriggers__.__animationListener__ = function animationListener(e) {
9511
- if (e.animationName == animationName) {
9743
+ if (e.animationName === animationName) {
9512
9744
  resetTriggers(element);
9513
9745
  }
9514
9746
  };
9515
- element.__resizeTriggers__.addEventListener(animationstartevent, element.__resizeTriggers__.__animationListener__);
9747
+ element.__resizeTriggers__.addEventListener(animationStartEvent, element.__resizeTriggers__.__animationListener__);
9516
9748
  }
9517
9749
  }
9518
9750
  element.__resizeListeners__.push(fn);
@@ -9527,7 +9759,7 @@ function createDetectElementResize(nonce) {
9527
9759
  if (!element.__resizeListeners__.length) {
9528
9760
  element.removeEventListener('scroll', scrollListener, true);
9529
9761
  if (element.__resizeTriggers__.__animationListener__) {
9530
- element.__resizeTriggers__.removeEventListener(animationstartevent, element.__resizeTriggers__.__animationListener__);
9762
+ element.__resizeTriggers__.removeEventListener(animationStartEvent, element.__resizeTriggers__.__animationListener__);
9531
9763
  element.__resizeTriggers__.__animationListener__ = null;
9532
9764
  }
9533
9765
  try {
@@ -9545,68 +9777,6 @@ function createDetectElementResize(nonce) {
9545
9777
  };
9546
9778
  }
9547
9779
 
9548
- var classCallCheck = function (instance, Constructor) {
9549
- if (!(instance instanceof Constructor)) {
9550
- throw new TypeError("Cannot call a class as a function");
9551
- }
9552
- };
9553
-
9554
- var createClass = function () {
9555
- function defineProperties(target, props) {
9556
- for (var i = 0; i < props.length; i++) {
9557
- var descriptor = props[i];
9558
- descriptor.enumerable = descriptor.enumerable || false;
9559
- descriptor.configurable = true;
9560
- if ("value" in descriptor) descriptor.writable = true;
9561
- Object.defineProperty(target, descriptor.key, descriptor);
9562
- }
9563
- }
9564
-
9565
- return function (Constructor, protoProps, staticProps) {
9566
- if (protoProps) defineProperties(Constructor.prototype, protoProps);
9567
- if (staticProps) defineProperties(Constructor, staticProps);
9568
- return Constructor;
9569
- };
9570
- }();
9571
-
9572
- var _extends = Object.assign || function (target) {
9573
- for (var i = 1; i < arguments.length; i++) {
9574
- var source = arguments[i];
9575
-
9576
- for (var key in source) {
9577
- if (Object.prototype.hasOwnProperty.call(source, key)) {
9578
- target[key] = source[key];
9579
- }
9580
- }
9581
- }
9582
-
9583
- return target;
9584
- };
9585
-
9586
- var inherits = function (subClass, superClass) {
9587
- if (typeof superClass !== "function" && superClass !== null) {
9588
- throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
9589
- }
9590
-
9591
- subClass.prototype = Object.create(superClass && superClass.prototype, {
9592
- constructor: {
9593
- value: subClass,
9594
- enumerable: false,
9595
- writable: true,
9596
- configurable: true
9597
- }
9598
- });
9599
- if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
9600
- };
9601
-
9602
- var possibleConstructorReturn = function (self, call) {
9603
- if (!self) {
9604
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
9605
- }
9606
-
9607
- return call && (typeof call === "object" || typeof call === "function") ? call : self;
9608
- };
9609
-
9610
9780
  var AutoSizer = function (_React$PureComponent) {
9611
9781
  inherits(AutoSizer, _React$PureComponent);
9612
9782
 
@@ -9733,7 +9903,8 @@ var AutoSizer = function (_React$PureComponent) {
9733
9903
  {
9734
9904
  className: className,
9735
9905
  ref: this._setRef,
9736
- style: _extends({}, outerStyle, style) },
9906
+ style: _extends({}, outerStyle, style)
9907
+ },
9737
9908
  !bailoutOnChildren && children(childParams)
9738
9909
  );
9739
9910
  }
@@ -9928,7 +10099,8 @@ function ListBoxInline(_ref2) {
9928
10099
  }))), search ? /*#__PURE__*/React.createElement(Grid, {
9929
10100
  item: true
9930
10101
  }, /*#__PURE__*/React.createElement(ListBoxSearch, {
9931
- model: model
10102
+ model: model,
10103
+ autoFocus: false
9932
10104
  })) : '', /*#__PURE__*/React.createElement(Grid, {
9933
10105
  item: true,
9934
10106
  xs: true
@@ -10108,7 +10280,9 @@ function hcHandler(_ref) {
10108
10280
 
10109
10281
  function fieldType(f) {
10110
10282
  if ( // a string starting with '=' is just a convention we use
10111
- typeof f === 'string' && f[0] === '=' || _typeof$1(f) === 'object' && f.qDef && f.qDef.qDef || _typeof$1(f) === 'object' && f.qLibraryId && f.type === 'measure') {
10283
+ typeof f === 'string' && f[0] === '=' || // based on NxMeasure and NxInlineMeasureDef
10284
+ _typeof$1(f) === 'object' && f.qDef && f.qDef.qDef || // use 'type' instead of 'qType' since this is not a real property
10285
+ _typeof$1(f) === 'object' && f.qLibraryId && f.type === 'measure') {
10112
10286
  return 'measure';
10113
10287
  }
10114
10288
 
@@ -10165,14 +10339,12 @@ function populateData(_ref) {
10165
10339
  * An object that imports from this structure is responsible for putting the existing properties where they should be
10166
10340
  * in the new model.
10167
10341
  * @interface ExportFormat
10168
- * @experimental
10169
10342
  * @since 1.1.0
10170
10343
  * @property {(ExportDataDef[])=} data
10171
10344
  * @property {object=} properties
10172
10345
  */
10173
10346
 
10174
10347
  /**
10175
- * @experimental
10176
10348
  * @since 1.1.0
10177
10349
  * @interface ExportDataDef
10178
10350
  * @property {qae.NxDimension[]} dimensions
@@ -10183,7 +10355,6 @@ function populateData(_ref) {
10183
10355
  */
10184
10356
 
10185
10357
  /**
10186
- * @experimental
10187
10358
  * @since 1.1.0
10188
10359
  * @ignore
10189
10360
  * @param {number} nDataGroups
@@ -10957,7 +11128,6 @@ function importProperties(_ref) {
10957
11128
 
10958
11129
  /**
10959
11130
  * @interface hyperCubeConversion
10960
- * @experimental
10961
11131
  * @since 1.1.0
10962
11132
  * @implements {ConversionType}
10963
11133
  */
@@ -11104,7 +11274,6 @@ var convertTo = /*#__PURE__*/function () {
11104
11274
  }();
11105
11275
  /**
11106
11276
  * @interface ConversionType
11107
- * @experimental
11108
11277
  * @since 1.1.0
11109
11278
  * @property {importProperties} importProperties
11110
11279
  * @property {exportProperties} exportProperties
@@ -11113,7 +11282,6 @@ var convertTo = /*#__PURE__*/function () {
11113
11282
  /**
11114
11283
  * @interface
11115
11284
  * @alias Conversion
11116
- * @experimental
11117
11285
  * @since 1.1.0
11118
11286
  * @description Provides conversion functionality to extensions.
11119
11287
  * @example
@@ -11135,7 +11303,6 @@ var convertTo = /*#__PURE__*/function () {
11135
11303
  var conversion = {
11136
11304
  /**
11137
11305
  * @type {hyperCubeConversion}
11138
- * @experimental
11139
11306
  * @since 1.1.0
11140
11307
  * @description Provides conversion functionality to extensions with hyperCubes.
11141
11308
  */
@@ -11469,6 +11636,26 @@ var ITEM_SPACING = 4;
11469
11636
  var DIVIDER = 1;
11470
11637
  var NUMBER_OF_ITEMS = 6;
11471
11638
  var MIN_WIDTH = (ITEM_WIDTH + ITEM_SPACING) * NUMBER_OF_ITEMS + DIVIDER + ITEM_SPACING;
11639
+ /**
11640
+ * @interface
11641
+ * @extends HTMLElement
11642
+ * @since 2.0.0
11643
+ */
11644
+
11645
+ var CellTitle = {
11646
+ /** @type {'njs-cell-title'} */
11647
+ className: 'njs-cell-title'
11648
+ };
11649
+ /**
11650
+ * @interface
11651
+ * @extends HTMLElement
11652
+ * @since 2.0.0
11653
+ */
11654
+
11655
+ var CellSubTitle = {
11656
+ /** @type {'njs-cell-sub-title'} */
11657
+ className: 'njs-cell-sub-title'
11658
+ };
11472
11659
  var useStyles$1 = makeStyles$1(function (theme) {
11473
11660
  return {
11474
11661
  containerStyle: {
@@ -11484,7 +11671,8 @@ var Header = function Header(_ref) {
11484
11671
  var layout = _ref.layout,
11485
11672
  sn = _ref.sn,
11486
11673
  anchorEl = _ref.anchorEl,
11487
- hovering = _ref.hovering;
11674
+ hovering = _ref.hovering,
11675
+ focusHandler = _ref.focusHandler;
11488
11676
  var showTitle = layout.showTitles && !!layout.title;
11489
11677
  var showSubtitle = layout.showTitles && !!layout.subtitle;
11490
11678
  var showInSelectionActions = layout.qSelectionInfo && layout.qSelectionInfo.qInSelections;
@@ -11530,13 +11718,15 @@ var Header = function Header(_ref) {
11530
11718
  show: showToolbar,
11531
11719
  selections: {
11532
11720
  show: showInSelectionActions,
11533
- api: sn.component.selections
11721
+ api: sn.component.selections,
11722
+ onKeyDeactivate: focusHandler.refocusContent
11534
11723
  },
11535
11724
  actions: actions,
11536
11725
  popover: {
11537
11726
  show: showPopoverToolbar,
11538
11727
  anchorEl: anchorEl
11539
- }
11728
+ },
11729
+ focusHandler: focusHandler
11540
11730
  });
11541
11731
  return /*#__PURE__*/React.createElement(Grid, {
11542
11732
  ref: containerRef,
@@ -11554,15 +11744,27 @@ var Header = function Header(_ref) {
11554
11744
  direction: "column"
11555
11745
  }, showTitle && /*#__PURE__*/React.createElement(Typography, {
11556
11746
  variant: "h6",
11557
- noWrap: true
11747
+ noWrap: true,
11748
+ className: CellTitle.className
11558
11749
  }, layout.title), showSubtitle && /*#__PURE__*/React.createElement(Typography, {
11559
11750
  variant: "body2",
11560
- noWrap: true
11751
+ noWrap: true,
11752
+ className: CellSubTitle.className
11561
11753
  }, layout.subtitle))), /*#__PURE__*/React.createElement(Grid, {
11562
11754
  item: true
11563
11755
  }, Toolbar));
11564
11756
  };
11565
11757
 
11758
+ /**
11759
+ * @interface
11760
+ * @extends HTMLElement
11761
+ * @since 2.0.0
11762
+ */
11763
+
11764
+ var CellFooter = {
11765
+ /** @type {'njs-cell-footer'} */
11766
+ className: 'njs-cell-footer'
11767
+ };
11566
11768
  var useStyles = makeStyles$1(function (theme) {
11567
11769
  return {
11568
11770
  itemStyle: {
@@ -11585,10 +11787,103 @@ var Footer = function Footer(_ref) {
11585
11787
  className: itemStyle
11586
11788
  }, /*#__PURE__*/React.createElement(Typography, {
11587
11789
  noWrap: true,
11588
- variant: "body2"
11790
+ variant: "body2",
11791
+ className: CellFooter.className
11589
11792
  }, layout.footnote))) : null;
11590
11793
  };
11591
11794
 
11795
+ var RenderDebouncer = /*#__PURE__*/function () {
11796
+ function RenderDebouncer() {
11797
+ _classCallCheck(this, RenderDebouncer);
11798
+
11799
+ this.timer = null;
11800
+ this.next = null;
11801
+ this.running = false;
11802
+ }
11803
+
11804
+ _createClass(RenderDebouncer, [{
11805
+ key: "start",
11806
+ value: function start() {
11807
+ if (this.running) {
11808
+ return;
11809
+ }
11810
+
11811
+ this.running = true;
11812
+ this.scheduleNext();
11813
+ }
11814
+ }, {
11815
+ key: "scheduleNext",
11816
+ value: function scheduleNext() {
11817
+ var _this = this;
11818
+
11819
+ this.timer = setTimeout(function () {
11820
+ _this.doNext();
11821
+ }, 10);
11822
+ }
11823
+ }, {
11824
+ key: "doNext",
11825
+ value: function () {
11826
+ var _doNext = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
11827
+ var fn;
11828
+ return regeneratorRuntime.wrap(function _callee$(_context) {
11829
+ while (1) {
11830
+ switch (_context.prev = _context.next) {
11831
+ case 0:
11832
+ fn = this.next;
11833
+ this.next = null;
11834
+
11835
+ if (!fn) {
11836
+ _context.next = 8;
11837
+ break;
11838
+ }
11839
+
11840
+ _context.next = 5;
11841
+ return fn();
11842
+
11843
+ case 5:
11844
+ this.scheduleNext();
11845
+ _context.next = 9;
11846
+ break;
11847
+
11848
+ case 8:
11849
+ this.stop();
11850
+
11851
+ case 9:
11852
+ case "end":
11853
+ return _context.stop();
11854
+ }
11855
+ }
11856
+ }, _callee, this);
11857
+ }));
11858
+
11859
+ function doNext() {
11860
+ return _doNext.apply(this, arguments);
11861
+ }
11862
+
11863
+ return doNext;
11864
+ }()
11865
+ }, {
11866
+ key: "schedule",
11867
+ value: function schedule(fn) {
11868
+ this.next = fn;
11869
+ this.start();
11870
+ }
11871
+ }, {
11872
+ key: "stop",
11873
+ value: function stop() {
11874
+ if (!this.running) {
11875
+ return;
11876
+ }
11877
+
11878
+ clearTimeout(this.timer);
11879
+ this.timer = null;
11880
+ this.running = false;
11881
+ }
11882
+ }]);
11883
+
11884
+ return RenderDebouncer;
11885
+ }();
11886
+
11592
11887
  /**
11593
11888
  * @interface
11594
11889
  * @extends HTMLElement
@@ -11612,19 +11907,24 @@ var Supernova = function Supernova(_ref) {
11612
11907
  var _useContext = useContext(InstanceContext),
11613
11908
  themeName = _useContext.theme,
11614
11909
  language = _useContext.language,
11615
- constraints = _useContext.constraints;
11616
-
11617
- var renderDebouncer = useRef(null);
11910
+ constraints = _useContext.constraints,
11911
+ keyboardNavigation = _useContext.keyboardNavigation;
11618
11912
 
11619
- var _useState = useState$1(false),
11620
- _useState2 = _slicedToArray(_useState, 2),
11621
- isMounted = _useState2[0],
11622
- setIsMounted = _useState2[1];
11913
+ var _useState = useState$1(function () {
11914
+ return new RenderDebouncer();
11915
+ }),
11916
+ _useState2 = _slicedToArray(_useState, 1),
11917
+ renderDebouncer = _useState2[0];
11623
11918
 
11624
- var _useState3 = useState$1(0),
11919
+ var _useState3 = useState$1(false),
11625
11920
  _useState4 = _slicedToArray(_useState3, 2),
11626
- renderCnt = _useState4[0],
11627
- setRenderCnt = _useState4[1];
11921
+ isMounted = _useState4[0],
11922
+ setIsMounted = _useState4[1];
11923
+
11924
+ var _useState5 = useState$1(0),
11925
+ _useState6 = _slicedToArray(_useState5, 2),
11926
+ renderCnt = _useState6[0],
11927
+ setRenderCnt = _useState6[1];
11628
11928
 
11629
11929
  var _useRect = useRect$1(),
11630
11930
  _useRect2 = _slicedToArray(_useRect, 3),
@@ -11632,10 +11932,10 @@ var Supernova = function Supernova(_ref) {
11632
11932
  containerRect = _useRect2[1],
11633
11933
  containerNode = _useRect2[2];
11634
11934
 
11635
- var _useState5 = useState$1(null),
11636
- _useState6 = _slicedToArray(_useState5, 2),
11637
- snNode = _useState6[0],
11638
- setSnNode = _useState6[1];
11935
+ var _useState7 = useState$1(null),
11936
+ _useState8 = _slicedToArray(_useState7, 2),
11937
+ snNode = _useState8[0],
11938
+ setSnNode = _useState8[1];
11639
11939
 
11640
11940
  var snRef = useCallback(function (ref) {
11641
11941
  if (!ref) {
@@ -11653,8 +11953,7 @@ var Supernova = function Supernova(_ref) {
11653
11953
  component.mounted(snNode);
11654
11954
  setIsMounted(true);
11655
11955
  return function () {
11656
- clearTimeout(renderDebouncer.current);
11657
- renderDebouncer.current = null;
11956
+ renderDebouncer.stop();
11658
11957
  component.willUnmount();
11659
11958
  };
11660
11959
  }, [snNode, component]); // Render
@@ -11669,13 +11968,7 @@ var Supernova = function Supernova(_ref) {
11669
11968
  return;
11670
11969
  }
11671
11970
 
11672
- if (renderDebouncer.current) {
11673
- // rendering already scheduled
11674
- return;
11675
- }
11676
-
11677
- renderDebouncer.current = setTimeout(function () {
11678
- // temporarily map constraints to permissions
11971
+ renderDebouncer.schedule(function () {
11679
11972
  var permissions = [];
11680
11973
 
11681
11974
  if (!constraints.passive) {
@@ -11694,7 +11987,7 @@ var Supernova = function Supernova(_ref) {
11694
11987
  permissions.push('fetch');
11695
11988
  }
11696
11989
 
11697
- Promise.resolve(component.render({
11990
+ return Promise.resolve(component.render({
11698
11991
  layout: layout,
11699
11992
  options: options,
11700
11993
  plugins: plugins,
@@ -11703,7 +11996,8 @@ var Supernova = function Supernova(_ref) {
11703
11996
  constraints: constraints,
11704
11997
  // halo.public.theme is a singleton so themeName is used as dep to make sure this effect is triggered
11705
11998
  theme: halo.public.theme,
11706
- appLayout: appLayout
11999
+ appLayout: appLayout,
12000
+ keyboardNavigation: keyboardNavigation
11707
12001
  }, component.isHooked ? {} : {
11708
12002
  logicalSize: sn.logicalSize({
11709
12003
  layout: layout
@@ -11711,8 +12005,10 @@ var Supernova = function Supernova(_ref) {
11711
12005
  localeInfo: (appLayout || {}).qLocaleInfo,
11712
12006
  permissions: permissions
11713
12007
  })
11714
- })).then(function () {
11715
- renderDebouncer.current = null;
12008
+ })).then(function (done) {
12009
+ if (done === false) {
12010
+ return;
12011
+ }
11716
12012
 
11717
12013
  if (renderCnt === 0 && typeof options.onInitialRender === 'function') {
11718
12014
  options.onInitialRender.call(null);
@@ -11720,8 +12016,8 @@ var Supernova = function Supernova(_ref) {
11720
12016
 
11721
12017
  setRenderCnt(renderCnt + 1);
11722
12018
  });
11723
- }, 10);
11724
- }, [containerRect, options, plugins, snNode, containerNode, layout, appLayout, themeName, language, constraints, isMounted]);
12019
+ });
12020
+ }, [containerRect, options, plugins, snNode, containerNode, layout, appLayout, themeName, language, constraints, isMounted, keyboardNavigation]);
11725
12021
  return /*#__PURE__*/React.createElement("div", {
11726
12022
  ref: containerRef,
11727
12023
  "data-render-count": renderCnt,
@@ -11835,7 +12131,7 @@ var LoadingSn = function LoadingSn(_ref) {
11835
12131
  return clearTimeout(handle);
11836
12132
  };
11837
12133
  }, []);
11838
- return showLoading && /*#__PURE__*/React.createElement(Loading, null);
12134
+ return showLoading ? /*#__PURE__*/React.createElement(Loading, null) : null;
11839
12135
  };
11840
12136
 
11841
12137
  var handleModal = function handleModal(_ref2) {
@@ -12076,12 +12372,12 @@ var getType = /*#__PURE__*/function () {
12076
12372
 
12077
12373
  var loadType = /*#__PURE__*/function () {
12078
12374
  var _ref8 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(_ref7) {
12079
- var dispatch, types, visualization, version, model, app, selections, nebbie, snType, sn;
12375
+ var dispatch, types, visualization, version, model, app, selections, nebbie, focusHandler, snType, sn;
12080
12376
  return regeneratorRuntime.wrap(function _callee3$(_context3) {
12081
12377
  while (1) {
12082
12378
  switch (_context3.prev = _context3.next) {
12083
12379
  case 0:
12084
- dispatch = _ref7.dispatch, types = _ref7.types, visualization = _ref7.visualization, version = _ref7.version, model = _ref7.model, app = _ref7.app, selections = _ref7.selections, nebbie = _ref7.nebbie;
12380
+ dispatch = _ref7.dispatch, types = _ref7.types, visualization = _ref7.visualization, version = _ref7.version, model = _ref7.model, app = _ref7.app, selections = _ref7.selections, nebbie = _ref7.nebbie, focusHandler = _ref7.focusHandler;
12085
12381
  _context3.prev = 1;
12086
12382
  _context3.next = 4;
12087
12383
  return getType({
@@ -12096,7 +12392,8 @@ var loadType = /*#__PURE__*/function () {
12096
12392
  model: model,
12097
12393
  app: app,
12098
12394
  selections: selections,
12099
- nebbie: nebbie
12395
+ nebbie: nebbie,
12396
+ focusHandler: focusHandler
12100
12397
  });
12101
12398
  return _context3.abrupt("return", sn);
12102
12399
 
@@ -12132,14 +12429,16 @@ var Cell = forwardRef(function (_ref9, ref) {
12132
12429
  initialSnOptions = _ref9.initialSnOptions,
12133
12430
  initialSnPlugins = _ref9.initialSnPlugins,
12134
12431
  initialError = _ref9.initialError,
12135
- onMount = _ref9.onMount;
12432
+ onMount = _ref9.onMount,
12433
+ currentId = _ref9.currentId;
12136
12434
  var app = halo.app,
12137
12435
  types = halo.types;
12138
12436
  var nebbie = halo.public.nebbie;
12139
12437
 
12140
12438
  var _useContext = useContext(InstanceContext),
12141
12439
  translator = _useContext.translator,
12142
- language = _useContext.language;
12440
+ language = _useContext.language,
12441
+ keyboardNavigation = _useContext.keyboardNavigation;
12143
12442
 
12144
12443
  var theme = useTheme$1();
12145
12444
 
@@ -12168,9 +12467,10 @@ var Cell = forwardRef(function (_ref9, ref) {
12168
12467
  appLayout = _useAppLayout2[0];
12169
12468
 
12170
12469
  var _useRect3 = useRect$1(),
12171
- _useRect4 = _slicedToArray(_useRect3, 2),
12470
+ _useRect4 = _slicedToArray(_useRect3, 3),
12172
12471
  contentRef = _useRect4[0],
12173
- contentRect = _useRect4[1];
12472
+ contentRect = _useRect4[1],
12473
+ contentNode = _useRect4[2];
12174
12474
 
12175
12475
  var _useState3 = useState$1(initialSnOptions),
12176
12476
  _useState4 = _slicedToArray(_useState3, 2),
@@ -12195,6 +12495,27 @@ var Cell = forwardRef(function (_ref9, ref) {
12195
12495
  enter: null,
12196
12496
  leave: null
12197
12497
  });
12498
+ var focusHandler = useRef({
12499
+ focusToolbarButton: function focusToolbarButton(last) {
12500
+ // eslint-disable-next-line react/no-this-in-sfc
12501
+ this.emit(last ? 'focus_toolbar_last' : 'focus_toolbar_first');
12502
+ }
12503
+ });
12504
+ useEffect$1(function () {
12505
+ eventmixin(focusHandler.current);
12506
+ }, []);
12507
+
12508
+ focusHandler.current.blurCallback = function (resetFocus) {
12509
+ halo.root.toggleFocusOfCells();
12510
+
12511
+ if (resetFocus && contentNode) {
12512
+ contentNode.focus();
12513
+ }
12514
+ };
12515
+
12516
+ focusHandler.current.refocusContent = function () {
12517
+ state.sn.component && typeof state.sn.component.focus === 'function' && state.sn.component.focus();
12518
+ };
12198
12519
 
12199
12520
  var handleOnMouseEnter = function handleOnMouseEnter() {
12200
12521
  if (hoveringDebouncer.current.leave) {
@@ -12220,6 +12541,13 @@ var Cell = forwardRef(function (_ref9, ref) {
12220
12541
  }, 750);
12221
12542
  };
12222
12543
 
12544
+ var handleKeyDown = function handleKeyDown(e) {
12545
+ // Enter or space
12546
+ if (['Enter', ' ', 'Spacebar'].includes(e.key)) {
12547
+ halo.root.toggleFocusOfCells(currentId);
12548
+ }
12549
+ };
12550
+
12223
12551
  useEffect$1(function () {
12224
12552
  if (initialError || !appLayout || !layout) {
12225
12553
  return undefined;
@@ -12291,7 +12619,8 @@ var Cell = forwardRef(function (_ref9, ref) {
12291
12619
  model: model,
12292
12620
  app: app,
12293
12621
  selections: selections,
12294
- nebbie: nebbie
12622
+ nebbie: nebbie,
12623
+ focusHandler: focusHandler.current
12295
12624
  });
12296
12625
 
12297
12626
  case 3:
@@ -12364,6 +12693,15 @@ var Cell = forwardRef(function (_ref9, ref) {
12364
12693
  getQae: function getQae() {
12365
12694
  return state.sn.generator.qae;
12366
12695
  },
12696
+ toggleFocus: function toggleFocus(active) {
12697
+ if (typeof state.sn.component.focus === 'function') {
12698
+ if (active) {
12699
+ state.sn.component.focus();
12700
+ } else {
12701
+ state.sn.component.blur();
12702
+ }
12703
+ }
12704
+ },
12367
12705
  setSnOptions: setSnOptions,
12368
12706
  setSnPlugins: setSnPlugins,
12369
12707
  takeSnapshot: function takeSnapshot() {
@@ -12505,8 +12843,11 @@ var Cell = forwardRef(function (_ref9, ref) {
12505
12843
  layout: layout,
12506
12844
  sn: state.sn,
12507
12845
  anchorEl: cellNode,
12508
- hovering: hovering
12846
+ hovering: hovering,
12847
+ focusHandler: focusHandler.current
12509
12848
  }, "\xA0"), /*#__PURE__*/React.createElement(Grid, {
12849
+ tabIndex: keyboardNavigation ? 0 : -1,
12850
+ onKeyDown: keyboardNavigation ? handleKeyDown : null,
12510
12851
  item: true,
12511
12852
  xs: true,
12512
12853
  style: {
@@ -12532,10 +12873,12 @@ function glue(_ref) {
12532
12873
  initialError = _ref.initialError;
12533
12874
  var root = halo.root;
12534
12875
  var cellRef = React.createRef();
12876
+ var currentId = uid();
12535
12877
  var portal = ReactDOM.createPortal( /*#__PURE__*/React.createElement(Cell, {
12536
12878
  ref: cellRef,
12537
12879
  halo: halo,
12538
12880
  model: model,
12881
+ currentId: currentId,
12539
12882
  initialSnOptions: initialSnOptions,
12540
12883
  initialSnPlugins: initialSnPlugins,
12541
12884
  initialError: initialError,
@@ -12548,7 +12891,9 @@ function glue(_ref) {
12548
12891
  };
12549
12892
 
12550
12893
  model.on('closed', unmount);
12551
- root.add(portal);
12894
+ root.add(portal); // Cannot use model.id as it is not unique in a given mashup
12895
+
12896
+ root.addCell(currentId, cellRef);
12552
12897
  return [unmount, cellRef];
12553
12898
  }
12554
12899
 
@@ -12800,7 +13145,6 @@ function viz() {
12800
13145
 
12801
13146
  /**
12802
13147
  * Converts the visualization to a different registered type
12803
- * @experimental
12804
13148
  * @since 1.1.0
12805
13149
  * @param {string} newType - Which registered type to convert to.
12806
13150
  * @param {boolean=} forceUpdate - Whether to run setProperties or not, defaults to true.
@@ -13710,6 +14054,7 @@ function initiate(component) {
13710
14054
  component.__hooks = {
13711
14055
  obsolete: false,
13712
14056
  error: false,
14057
+ waitForData: false,
13713
14058
  chain: {
13714
14059
  promise: null,
13715
14060
  resolve: function resolve() {}
@@ -13725,6 +14070,9 @@ function initiate(component) {
13725
14070
  resizer: {
13726
14071
  setters: [],
13727
14072
  explicitResize: explicitResize
14073
+ },
14074
+ accessibility: {
14075
+ setter: null
13728
14076
  }
13729
14077
  };
13730
14078
  }
@@ -13737,6 +14085,7 @@ function teardown(component) {
13737
14085
  component.__hooks.actions = null;
13738
14086
  component.__hooks.imperativeHandle = null;
13739
14087
  component.__hooks.resizer = null;
14088
+ component.__hooks.accessibility = null;
13740
14089
  component.__actionsDispatch = null;
13741
14090
  clearTimeout(component.__hooks.micro);
13742
14091
  cancelAnimationFrame(component.__hooks.macro);
@@ -13840,7 +14189,7 @@ function maybeEndChain(hooks) {
13840
14189
  }
13841
14190
 
13842
14191
  hooks.chain.promise = null;
13843
- hooks.chain.resolve();
14192
+ hooks.chain.resolve(!hooks.waitForData);
13844
14193
  }
13845
14194
 
13846
14195
  function runSnaps(component, layout) {
@@ -13932,6 +14281,8 @@ function hook(cb) {
13932
14281
  run: run,
13933
14282
  teardown: teardown,
13934
14283
  runSnaps: runSnaps,
14284
+ focus: focus,
14285
+ blur: blur,
13935
14286
  observeActions: observeActions,
13936
14287
  getImperativeHandle: getImperativeHandle,
13937
14288
  updateRectOnNextRun: updateRectOnNextRun
@@ -14446,6 +14797,7 @@ function useTheme() {
14446
14797
  * Gets the embed instance used.
14447
14798
  * @entry
14448
14799
  * @experimental
14800
+ * @since 1.7.0
14449
14801
  * @returns {Embed} The embed instance used.
14450
14802
  * @example
14451
14803
  * import { useEmbed } from '@nebula.js/stardust';
@@ -14578,9 +14930,9 @@ function useAction(fn, deps) {
14578
14930
  }
14579
14931
  /**
14580
14932
  * @interface Constraints
14581
- * @property {boolean=} passive
14582
- * @property {boolean=} active
14583
- * @property {boolean=} select
14933
+ * @property {boolean=} passive Whether or not passive constraints are on. Should block any passive interaction by users, ie: tooltips
14934
+ * @property {boolean=} active Whether or not active constraints are on. Should block any active interaction by users, ie: scroll, click
14935
+ * @property {boolean=} select Whether or not active select are on. Should block any selection action. Implied when active is true.
14584
14936
  */
14585
14937
 
14586
14938
  /**
@@ -14739,6 +15091,183 @@ function onTakeSnapshot(cb) {
14739
15091
 
14740
15092
  h.fn = cb;
14741
15093
  }
15094
+ /**
15095
+ * Gets render state instance.
15096
+ *
15097
+ * Used to update properties and get a new layout without triggering onInitialRender.
15098
+ * @entry
15099
+ * @experimental
15100
+ * @returns {{ pending, restore }} The render state.
15101
+ * @example
15102
+ * import { useRenderState } from '@nebula.js/stardust';
15103
+ *
15104
+ * const renderState = useRenderState();
15105
+ * useState(() => {
15106
+ * if(needProperteisUpdate(...)) {
15107
+ * useRenderState.pending();
15108
+ * updateProperties(...);
15109
+ * } else {
15110
+ * useRenderState.restore();
15111
+ * ...
15112
+ * }
15113
+ * }, [...]);
15114
+ */
15115
+
15116
+ function useRenderState() {
15117
+ getHook(++currentIndex);
15118
+ var hooks = currentComponent.__hooks;
15119
+ return {
15120
+ pending: function pending() {
15121
+ hooks.waitForData = true;
15122
+ },
15123
+ restore: function restore() {
15124
+ hooks.waitForData = false;
15125
+ }
15126
+ };
15127
+ }
15128
+ /**
15129
+ * @experimental
15130
+ * @interface Keyboard
15131
+ * @property {boolean} enabled Whether or not Nebula handles keyboard navigation or not.
15132
+ * @property {boolean} active Set to true when the chart is activated, ie a user tabs to the chart and presses Enter or Space.
15133
+ * @property {function=} blur Function used by the visualization to tell Nebula to it wants to relinquish focus
15134
+ * @property {function=} focus Function used by the visualization to tell Nebula to it wants focus
15135
+ * @property {function=} focusSelection Function used by the visualization to tell Nebula to focus the selection toolbar
15136
+ */
15137
+
15138
+ /**
15139
+ * Gets the desired keyboard settings and status to applied when rendering the visualization.
15140
+ * A visualization should in general only have tab stops if either `keyboard.enabled` is false or if active is true.
15141
+ * This means that either Nebula isn't configured to handle keyboard input or the chart is currently focused.
15142
+ * Enabling or disabling keyboardNavigation are set on the embed configuration and
15143
+ * should be respected by the visualization.
15144
+ * @entry
15145
+ * @returns {Keyboard}
15146
+ * @example
15147
+ * // configure nebula to enable navigation between charts
15148
+ * embed(app, {
15149
+ * context: {
15150
+ * keyboardNavigation: true, // tell Nebula to handle navigation
15151
+ * }
15152
+ * }).render({ element, id: 'sdfsdf' });
15153
+ *
15154
+ * @example
15155
+ * import { useKeyboard } from '@nebula.js/stardust';
15156
+ * // ...
15157
+ * const keyboard = useKeyboard();
15158
+ * useEffect(() => {
15159
+ * // Set a tab stop on our button if in focus or if Nebulas navigation is disabled
15160
+ * button.setAttribute('tabIndex', keyboard.active || !keyboard.enabled ? 0 : -1);
15161
+ * // If navigation is enabled and focus has shifted, lets focus the button
15162
+ * keyboard.enabled && keyboard.active && button.focus();
15163
+ * }, [keyboard])
15164
+ *
15165
+ */
15166
+
15167
+ function useKeyboard() {
15168
+ var keyboardNavigation = useInternalContext('keyboardNavigation');
15169
+ var focusHandler = useInternalContext('focusHandler');
15170
+
15171
+ if (!currentComponent.__hooks.accessibility.exitFunction) {
15172
+ var exitFunction = function (resetFocus) {
15173
+ var acc = this.__hooks.accessibility;
15174
+
15175
+ if (acc.enabled && acc.active) {
15176
+ blur(this);
15177
+ focusHandler && focusHandler.blurCallback && focusHandler.blurCallback(resetFocus);
15178
+ }
15179
+ }.bind(currentComponent);
15180
+
15181
+ currentComponent.__hooks.accessibility.exitFunction = exitFunction;
15182
+
15183
+ var focusFunction = function () {
15184
+ var acc = this.__hooks.accessibility;
15185
+
15186
+ if (acc.enabled && !acc.active) {
15187
+ focusHandler && focusHandler.blurCallback && focusHandler.blurCallback(false);
15188
+ focus(this);
15189
+ }
15190
+ }.bind(currentComponent);
15191
+
15192
+ currentComponent.__hooks.accessibility.focusFunction = focusFunction;
15193
+
15194
+ var focusSelectionFunction = function (focusLast) {
15195
+ var acc = this.__hooks.accessibility;
15196
+
15197
+ if (acc.enabled) {
15198
+ focusHandler && focusHandler.focusToolbarButton && focusHandler.focusToolbarButton(focusLast);
15199
+ }
15200
+ }.bind(currentComponent);
15201
+
15202
+ currentComponent.__hooks.accessibility.focusSelectionFunction = focusSelectionFunction;
15203
+ }
15204
+
15205
+ var focusFunc = currentComponent.__hooks.accessibility.focusFunction;
15206
+ var exitFunc = currentComponent.__hooks.accessibility.exitFunction;
15207
+ var focusSelectionFunc = currentComponent.__hooks.accessibility.focusSelectionFunction;
15208
+
15209
+ var _useState9 = useState({
15210
+ active: false,
15211
+ enabled: keyboardNavigation,
15212
+ blur: exitFunc,
15213
+ focus: focusFunc,
15214
+ focusSelection: focusSelectionFunc
15215
+ }),
15216
+ _useState10 = _slicedToArray(_useState9, 2),
15217
+ acc = _useState10[0],
15218
+ setAcc = _useState10[1];
15219
+
15220
+ currentComponent.__hooks.accessibility.setter = setAcc;
15221
+ currentComponent.__hooks.accessibility.enabled = keyboardNavigation;
15222
+ useEffect(function () {
15223
+ return setAcc({
15224
+ active: false,
15225
+ enabled: keyboardNavigation,
15226
+ blur: exitFunc,
15227
+ focus: focusFunc,
15228
+ focusSelection: focusSelectionFunc
15229
+ });
15230
+ }, [keyboardNavigation]);
15231
+ return acc;
15232
+ }
15233
+ function focus(component) {
15234
+ var acc = component.__hooks.accessibility;
15235
+
15236
+ if (acc.active) {
15237
+ return;
15238
+ }
15239
+
15240
+ acc.active = true;
15241
+
15242
+ if (acc && acc.setter) {
15243
+ acc.setter({
15244
+ active: true,
15245
+ enabled: acc.enabled,
15246
+ blur: acc.exitFunction,
15247
+ focus: acc.focusFunction,
15248
+ focusSelection: acc.focusSelectionFunction
15249
+ });
15250
+ }
15251
+ }
15252
+ function blur(component) {
15253
+ var acc = component.__hooks.accessibility; // Incomplete/Invalid/Legacy viz hasn't been initialized with hooks
15254
+
15255
+ if (!acc || !acc.active) {
15256
+ return;
15257
+ }
15258
+
15259
+ acc.active = false;
15260
+
15261
+ if (acc && acc.setter) {
15262
+ acc.setter({
15263
+ active: false,
15264
+ enabled: acc.enabled,
15265
+ blur: acc.exitFunction,
15266
+ focus: acc.focusFunction,
15267
+ focusSelection: acc.focusSelectionFunction
15268
+ });
15269
+ }
15270
+ }
14742
15271
 
14743
15272
  var defaultComponent = {
14744
15273
  app: null,
@@ -14810,6 +15339,8 @@ function createWithHooks(generator, opts, galaxy) {
14810
15339
  // --- dynamic values ---
14811
15340
  layout: {},
14812
15341
  appLayout: {},
15342
+ keyboardNavigation: opts.keyboardNavigation,
15343
+ focusHandler: opts.focusHandler,
14813
15344
  constraints: forcedConstraints,
14814
15345
  options: {},
14815
15346
  plugins: []
@@ -14836,6 +15367,17 @@ function createWithHooks(generator, opts, galaxy) {
14836
15367
  if (r.context && r.context.theme) {
14837
15368
  // changed is set further down only if the name is different
14838
15369
  this.context.theme = r.context.theme;
15370
+ } // false equals undefined, so we to cast to bool here
15371
+
15372
+
15373
+ if (r.context && !!r.context.keyboardNavigation !== !!this.context.keyboardNavigation) {
15374
+ this.context.keyboardNavigation = !!r.context.keyboardNavigation;
15375
+ changed = true;
15376
+ }
15377
+
15378
+ if (r.context && r.context.focusHandler) {
15379
+ // Needs to be added here due to how the client renders
15380
+ this.context.focusHandler = r.context.focusHandler;
14839
15381
  }
14840
15382
 
14841
15383
  if (r.options) {
@@ -14935,6 +15477,12 @@ function createWithHooks(generator, opts, galaxy) {
14935
15477
  setSnapshotData: function setSnapshotData(layout) {
14936
15478
  return generator.component.runSnaps(this, layout);
14937
15479
  },
15480
+ focus: function focus() {
15481
+ generator.component.focus(this);
15482
+ },
15483
+ blur: function blur() {
15484
+ generator.component.blur(this);
15485
+ },
14938
15486
  getImperativeHandle: function getImperativeHandle() {
14939
15487
  return generator.component.getImperativeHandle(this);
14940
15488
  },
@@ -15098,7 +15646,6 @@ var noop = function noop() {};
15098
15646
  /**
15099
15647
  * @function importProperties
15100
15648
  * @description Imports properties for a chart with a hypercube.
15101
- * @experimental
15102
15649
  * @since 1.1.0
15103
15650
  * @param {Object} args
15104
15651
  * @param {ExportFormat} args.exportFormat The export object which is the output of exportProperties.
@@ -15112,7 +15659,6 @@ var noop = function noop() {};
15112
15659
  /**
15113
15660
  * @function exportProperties
15114
15661
  * @description Exports properties for a chart with a hypercube.
15115
- * @experimental
15116
15662
  * @since 1.1.0
15117
15663
  * @param {Object} args
15118
15664
  * @param {Object} args.propertyTree
@@ -17134,6 +17680,7 @@ function create(_ref) {
17134
17680
 
17135
17681
  /**
17136
17682
  * @interface Context
17683
+ * @property {boolean=} keyboardNavigation
17137
17684
  * @property {object=} constraints
17138
17685
  * @property {boolean=} constraints.active
17139
17686
  * @property {boolean=} constraints.passive
@@ -17151,7 +17698,8 @@ var DEFAULT_CONTEXT =
17151
17698
 
17152
17699
  /** @type {string=} */
17153
17700
  deviceType: 'auto',
17154
- constraints: {}
17701
+ constraints: {},
17702
+ keyboardNavigation: false
17155
17703
  };
17156
17704
  /**
17157
17705
  * @interface SnapshotConfiguration
@@ -17442,8 +17990,8 @@ function nuked() {
17442
17990
  switch (_context4.prev = _context4.next) {
17443
17991
  case 0:
17444
17992
  // filter valid values to avoid triggering unnecessary rerender
17445
- ['theme', 'language', 'constraints'].forEach(function (key) {
17446
- if (ctx[key] && ctx[key] !== currentContext[key]) {
17993
+ ['theme', 'language', 'constraints', 'keyboardNavigation'].forEach(function (key) {
17994
+ if (Object.prototype.hasOwnProperty.call(ctx, key) && ctx[key] !== currentContext[key]) {
17447
17995
  if (!changes) {
17448
17996
  changes = {};
17449
17997
  }
@@ -17571,7 +18119,6 @@ function nuked() {
17571
18119
  * Gets the listbox instance of the specified field
17572
18120
  * @param {string|LibraryField} fieldIdentifier Fieldname as a string or a Library dimension
17573
18121
  * @returns {Promise<FieldInstance>}
17574
- * @experimental
17575
18122
  * @since 1.1.0
17576
18123
  * @example
17577
18124
  * const fieldInstance = await n.field("MyField");
@@ -17597,7 +18144,6 @@ function nuked() {
17597
18144
  /**
17598
18145
  * @class
17599
18146
  * @alias FieldInstance
17600
- * @experimental
17601
18147
  * @since 1.1.0
17602
18148
  */
17603
18149
  fieldSels = {
@@ -17613,7 +18159,6 @@ function nuked() {
17613
18159
  * @param {boolean=} [options.search=true] To show the search bar
17614
18160
  * @param {boolean=} [options.stateName="$"] Sets the state to make selections in
17615
18161
  * @param {object=} [options.properties={}] Properties object to extend default properties with
17616
- * @experimental
17617
18162
  * @since 1.1.0
17618
18163
  * @example
17619
18164
  * fieldInstance.mount(element);
@@ -17641,7 +18186,6 @@ function nuked() {
17641
18186
 
17642
18187
  /**
17643
18188
  * Unmounts the field listbox from the DOM.
17644
- * @experimental
17645
18189
  * @since 1.1.0
17646
18190
  * @example
17647
18191
  * listbox.unmount();
@@ -17748,5 +18292,5 @@ var __DO_NOT_USE__ = {
17748
18292
  locale: locale
17749
18293
  };
17750
18294
 
17751
- export { __DO_NOT_USE__, conversion, index as embed, onTakeSnapshot, useAction, useApp, useAppLayout, useConstraints, useDeviceType, useEffect, useElement, useEmbed, useGlobal, useImperativeHandle, useLayout, useMemo, useModel, useOptions, usePlugins, usePromise, useRect, useSelections, useStaleLayout, useState, useTheme, useTranslator };
18295
+ export { __DO_NOT_USE__, conversion, index as embed, 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 };
17752
18296
  //# sourceMappingURL=dev.js.map