@nebula.js/stardust 2.7.0 → 2.10.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 v2.7.0
2
+ * @nebula.js/stardust v2.10.0
3
3
  * Copyright (c) 2022 QlikTech International AB
4
4
  * Released under the MIT license.
5
5
  */
@@ -7,7 +7,9 @@
7
7
  import React, { useState as useState$1, useEffect as useEffect$1, useReducer, forwardRef, useMemo as useMemo$1, useImperativeHandle as useImperativeHandle$1, useCallback, useLayoutEffect as useLayoutEffect$1, createElement, PureComponent, useRef, useContext } from 'react';
8
8
  import ReactDOM from 'react-dom';
9
9
  import { createGenerateClassName, StylesProvider, ThemeProvider, makeStyles, useTheme as useTheme$1 } from '@material-ui/styles';
10
- import { Checkbox, Grid, FormControlLabel, Typography, IconButton, makeStyles as makeStyles$1, Popover, MenuList, MenuItem, ListItemIcon, Divider, OutlinedInput, InputAdornment, Badge, List, ListItem, Button, Box, Icon, CircularProgress, Paper } from '@material-ui/core';
10
+ import { Checkbox, Radio, Grid, FormControlLabel, Typography, IconButton, makeStyles as makeStyles$1, Popover, MenuList, MenuItem, ListItemIcon, Divider, OutlinedInput, InputAdornment, Badge, List, ListItem, Button, Box, Icon, CircularProgress, Paper } from '@material-ui/core';
11
+
12
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
11
13
 
12
14
  var runtime = {exports: {}};
13
15
 
@@ -5275,7 +5277,7 @@ function useAppSelections(app) {
5275
5277
  return [appSelections, navState];
5276
5278
  }
5277
5279
 
5278
- const NEBULA_VERSION_HASH = "b1d7" ;
5280
+ const NEBULA_VERSION_HASH = "fcc9" ;
5279
5281
  let counter = 0;
5280
5282
  const NebulaApp = forwardRef((_ref, ref) => {
5281
5283
  let {
@@ -5335,7 +5337,7 @@ function boot(_ref2) {
5335
5337
  const appRef = React.createRef();
5336
5338
  const element = document.createElement('div');
5337
5339
  element.style.display = 'none';
5338
- element.setAttribute('data-nebulajs-version', "2.7.0" );
5340
+ element.setAttribute('data-nebulajs-version', "2.10.0" );
5339
5341
  element.setAttribute('data-app-id', app.id);
5340
5342
  document.body.appendChild(element);
5341
5343
  ReactDOM.render( /*#__PURE__*/React.createElement(NebulaApp, {
@@ -6502,13 +6504,22 @@ function getSelectedValues(pages) {
6502
6504
  return flatten(elementNbrs);
6503
6505
  }
6504
6506
  function applySelectionsOnPages(pages, elmNumbers) {
6507
+ let clearAllButElmNumbers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
6508
+
6505
6509
  const getNewSelectionState = qState => elmNumbers.length <= 1 && isStateSelected(qState) ? 'A' : 'S';
6506
6510
 
6507
6511
  const matrices = pages.map(page => {
6508
6512
  const qMatrix = page.qMatrix.map(p => {
6509
6513
  const [p0] = p;
6510
6514
  const selectionMatchesElement = elmNumbers.includes(p0.qElemNumber);
6511
- const qState = selectionMatchesElement ? getNewSelectionState(p0.qState) : p0.qState;
6515
+ let qState;
6516
+
6517
+ if (clearAllButElmNumbers) {
6518
+ qState = selectionMatchesElement ? 'S' : 'A';
6519
+ } else {
6520
+ qState = selectionMatchesElement ? getNewSelectionState(p0.qState) : p0.qState;
6521
+ }
6522
+
6512
6523
  return [_objectSpread2(_objectSpread2({}, p0), {}, {
6513
6524
  qState
6514
6525
  }), p.slice(1)];
@@ -6608,21 +6619,19 @@ function useSelectionsInteractions(_ref) {
6608
6619
  layout,
6609
6620
  selections,
6610
6621
  pages = [],
6611
- rangeSelect = true,
6612
6622
  checkboxes = false,
6613
6623
  selectDisabled,
6614
- doc = document
6624
+ doc = document,
6625
+ isSingleSelect: singleSelect = false
6615
6626
  } = _ref;
6616
6627
  const [instantPages, setInstantPages] = useState$1(pages);
6617
6628
  const [mouseDown, setMouseDown] = useState$1(false);
6618
6629
  const [selectingValues, setSelectingValues] = useState$1(false);
6630
+ const [isSingleSelect, setIsSingleSelect] = useState$1(singleSelect);
6619
6631
  const [selected, setSelected] = useState$1([]);
6620
6632
  const [isRangeSelection, setIsRangeSelection] = useState$1(false);
6621
6633
  const [preSelected, setPreSelected] = useState$1([]);
6622
- const elemNumbersOrdered = getElemNumbersFromPages(pages);
6623
-
6624
- const getIsSingleSelect = () => !!(layout && layout.qListObject.qDimensionInfo.qIsOneAndOnlyOne); // Select values for real, by calling the backend.
6625
-
6634
+ const elemNumbersOrdered = getElemNumbersFromPages(pages); // Select values for real, by calling the backend.
6626
6635
 
6627
6636
  const select = async function () {
6628
6637
  let elemNumbers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
@@ -6633,7 +6642,6 @@ function useSelectionsInteractions(_ref) {
6633
6642
  }
6634
6643
 
6635
6644
  setSelectingValues(true);
6636
- const isSingleSelect = getIsSingleSelect();
6637
6645
  const filtered = additive ? elemNumbers.filter(n => !selected.includes(n)) : elemNumbers;
6638
6646
  await selectValues({
6639
6647
  selections,
@@ -6641,6 +6649,7 @@ function useSelectionsInteractions(_ref) {
6641
6649
  isSingleSelect
6642
6650
  });
6643
6651
  setSelectingValues(false);
6652
+ setPreSelected([]);
6644
6653
  }; // Show estimated selection states instantly before applying the selections for real.
6645
6654
 
6646
6655
 
@@ -6662,6 +6671,8 @@ function useSelectionsInteractions(_ref) {
6662
6671
  const selectManually = function () {
6663
6672
  let elementIds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
6664
6673
  let additive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
6674
+ setIsRangeSelection(false); // range is not supported for manual select
6675
+
6665
6676
  setMouseDown(true);
6666
6677
  preSelect(elementIds, additive || isRangeSelection);
6667
6678
  const p = select(elementIds, additive || isRangeSelection);
@@ -6669,6 +6680,15 @@ function useSelectionsInteractions(_ref) {
6669
6680
  return p;
6670
6681
  };
6671
6682
 
6683
+ const handleSingleSelectKey = event => {
6684
+ if (event.ctrlKey || event.metaKey) {
6685
+ setIsSingleSelect(true);
6686
+ event.currentTarget.focus(); // will not be focused otherwise
6687
+
6688
+ event.preventDefault();
6689
+ }
6690
+ };
6691
+
6672
6692
  const onClick = useCallback(event => {
6673
6693
  if (selectingValues || selectDisabled()) {
6674
6694
  return;
@@ -6676,6 +6696,7 @@ function useSelectionsInteractions(_ref) {
6676
6696
 
6677
6697
  const elemNumber = +event.currentTarget.getAttribute('data-n');
6678
6698
  setPreSelected([elemNumber]);
6699
+ handleSingleSelectKey(event);
6679
6700
  }, [selectingValues, selectDisabled]);
6680
6701
  const onMouseDown = useCallback(event => {
6681
6702
  if (selectingValues || selectDisabled()) {
@@ -6686,11 +6707,12 @@ function useSelectionsInteractions(_ref) {
6686
6707
  setMouseDown(true);
6687
6708
  const elemNumber = +event.currentTarget.getAttribute('data-n');
6688
6709
  setPreSelected([elemNumber]);
6710
+ handleSingleSelectKey(event);
6689
6711
  }, [selectingValues, selectDisabled]);
6690
6712
  const onMouseUp = useCallback(event => {
6691
6713
  const elemNumber = +event.currentTarget.getAttribute('data-n');
6692
6714
 
6693
- if (getIsSingleSelect() || !rangeSelect || !mouseDown || selectingValues || preSelected.length === 1 && preSelected[0] === elemNumber // prevent toggling again on mouseup
6715
+ if (isSingleSelect || !mouseDown || selectingValues || preSelected.length === 1 && preSelected[0] === elemNumber // prevent toggling again on mouseup
6694
6716
  ) {
6695
6717
  return;
6696
6718
  }
@@ -6701,9 +6723,11 @@ function useSelectionsInteractions(_ref) {
6701
6723
  // Ensure we end interactions when mouseup happens outside the Listbox.
6702
6724
  setMouseDown(false);
6703
6725
  setSelectingValues(false);
6726
+ setIsRangeSelection(false);
6727
+ setIsSingleSelect(singleSelect);
6704
6728
  }, []);
6705
6729
  const onMouseEnter = useCallback(event => {
6706
- if (getIsSingleSelect() || !mouseDown || selectingValues || selectDisabled()) {
6730
+ if (isSingleSelect || !mouseDown || selectingValues || selectDisabled()) {
6707
6731
  return;
6708
6732
  }
6709
6733
 
@@ -6743,7 +6767,7 @@ function useSelectionsInteractions(_ref) {
6743
6767
  } // Render pre-selections before they have been selected in Engine.
6744
6768
 
6745
6769
 
6746
- const newPages = applySelectionsOnPages(pages, preSelected);
6770
+ const newPages = applySelectionsOnPages(pages, preSelected, isSingleSelect);
6747
6771
  setInstantPages(newPages);
6748
6772
  }, [preSelected]);
6749
6773
  const interactionEvents = {};
@@ -6752,17 +6776,12 @@ function useSelectionsInteractions(_ref) {
6752
6776
  Object.assign(interactionEvents, {
6753
6777
  onClick
6754
6778
  });
6755
- } else if (rangeSelect) {
6779
+ } else {
6756
6780
  Object.assign(interactionEvents, {
6757
6781
  onMouseUp,
6758
6782
  onMouseDown,
6759
6783
  onMouseEnter
6760
6784
  });
6761
- } else {
6762
- Object.assign(interactionEvents, {
6763
- onMouseUp,
6764
- onMouseDown
6765
- });
6766
6785
  }
6767
6786
 
6768
6787
  return {
@@ -6786,17 +6805,21 @@ var Tick = (props => SvgIcon(tick(props)));
6786
6805
 
6787
6806
  const CheckboxChecked = "url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath" + " fill-rule='evenodd' clip-rule='evenodd' d='M12 5c-.28 0-.53.11-.71.29L7 9.59l-2.29-2.3a1.003 " + "1.003 0 00-1.42 1.42l3 3c.18.18.43.29.71.29s.53-.11.71-.29l5-5A1.003 1.003 0 0012 5z' fill='%23fff'/%3E%3C/svg%3E\")";
6788
6807
 
6789
- const useStyles$c = makeStyles(theme => ({
6808
+ const borderRadius = 2;
6809
+ const useStyles$e = makeStyles(theme => ({
6790
6810
  cbIcon: {
6791
- borderRadius: 3,
6811
+ borderRadius,
6792
6812
  width: 16,
6793
6813
  height: 16,
6794
6814
  boxShadow: 'inset 0 0 0 1px rgba(16,22,26,.2), inset 0 -1px 0 rgba(16,22,26,.1)',
6795
6815
  backgroundColor: '#f5f8fa',
6796
- backgroundImage: 'linear-gradient(180deg,hsla(0,0%,100%,.8),hsla(0,0%,100%,0))'
6816
+ backgroundImage: 'linear-gradient(180deg,hsla(0,0%,100%,.8),hsla(0,0%,100%,0))',
6817
+ display: 'flex',
6818
+ alignItems: 'center',
6819
+ justifyContent: 'center'
6797
6820
  },
6798
6821
  cbIconChecked: {
6799
- borderRadius: 3,
6822
+ borderRadius,
6800
6823
  backgroundColor: theme.palette.selected.main,
6801
6824
  backgroundImage: 'linear-gradient(180deg,hsla(0,0%,100%,.1),hsla(0,0%,100%,0))',
6802
6825
  '&:before': {
@@ -6807,6 +6830,18 @@ const useStyles$c = makeStyles(theme => ({
6807
6830
  content: '""'
6808
6831
  }
6809
6832
  },
6833
+ cbIconExcluded: {
6834
+ borderRadius,
6835
+ width: 12,
6836
+ height: 12,
6837
+ backgroundColor: theme.palette.selected.excluded
6838
+ },
6839
+ cbIconAlternative: {
6840
+ borderRadius,
6841
+ width: 12,
6842
+ height: 12,
6843
+ backgroundColor: theme.palette.selected.alternative
6844
+ },
6810
6845
  checkbox: {
6811
6846
  margin: 0,
6812
6847
  '&:hover': {
@@ -6817,13 +6852,28 @@ const useStyles$c = makeStyles(theme => ({
6817
6852
  padding: '4px 8px'
6818
6853
  }
6819
6854
  }));
6855
+
6856
+ const getIcon = function (styles) {
6857
+ let showGray = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
6858
+ let excluded = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
6859
+ let alternative = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
6860
+ return /*#__PURE__*/React.createElement("span", {
6861
+ className: styles.cbIcon
6862
+ }, (excluded || alternative) && /*#__PURE__*/React.createElement("span", {
6863
+ className: [showGray && excluded && styles.cbIconExcluded, showGray && alternative && styles.cbIconAlternative].filter(Boolean).join(' ')
6864
+ }));
6865
+ };
6866
+
6820
6867
  function ListboxCheckbox(_ref) {
6821
6868
  let {
6822
6869
  checked,
6823
6870
  label,
6824
- dense
6871
+ dense,
6872
+ excluded,
6873
+ alternative,
6874
+ showGray = true
6825
6875
  } = _ref;
6826
- const styles = useStyles$c();
6876
+ const styles = useStyles$e();
6827
6877
  return /*#__PURE__*/React.createElement(Checkbox, {
6828
6878
  edge: "start",
6829
6879
  checked: checked,
@@ -6833,9 +6883,7 @@ function ListboxCheckbox(_ref) {
6833
6883
  'aria-labelledby': label
6834
6884
  },
6835
6885
  name: label,
6836
- icon: /*#__PURE__*/React.createElement("span", {
6837
- className: styles.cbIcon
6838
- }),
6886
+ icon: getIcon(styles, showGray, excluded, alternative),
6839
6887
  checkedIcon: /*#__PURE__*/React.createElement("span", {
6840
6888
  className: styles.cbIconChecked
6841
6889
  })
@@ -6910,6 +6958,41 @@ function getSegmentsFromRanges(label, ranges) {
6910
6958
  return labels;
6911
6959
  }
6912
6960
 
6961
+ const useStyles$d = makeStyles(() => ({
6962
+ denseRadioButton: {
6963
+ height: '100%',
6964
+ boxSizing: 'border-box',
6965
+ '& svg': {
6966
+ width: '0.7em',
6967
+ height: '0.7em'
6968
+ }
6969
+ },
6970
+ radioButton: {
6971
+ right: '5px'
6972
+ }
6973
+ }));
6974
+ function ListBoxRadioButton(_ref) {
6975
+ let {
6976
+ checked,
6977
+ label,
6978
+ dense
6979
+ } = _ref;
6980
+ const styles = useStyles$d();
6981
+ return /*#__PURE__*/React.createElement(Radio, {
6982
+ checked: checked,
6983
+ value: label,
6984
+ name: label,
6985
+ inputProps: {
6986
+ 'aria-labelledby': label
6987
+ },
6988
+ className: dense ? styles.denseRadioButton : styles.radioButton,
6989
+ style: {
6990
+ backgroundColor: 'transparent'
6991
+ },
6992
+ disableRipple: true
6993
+ });
6994
+ }
6995
+
6913
6996
  const KEYS = Object.freeze({
6914
6997
  ENTER: 13,
6915
6998
  ESCAPE: 27,
@@ -7087,7 +7170,25 @@ const barPadPx = 4;
7087
7170
  const barBorderWidthPx = 1;
7088
7171
  const barWithCheckboxLeftPadEm = 2;
7089
7172
  const frequencyTextNone = '0';
7090
- const useStyles$b = makeStyles(theme => ({
7173
+
7174
+ const getSelectedStyle = _ref => {
7175
+ let {
7176
+ theme
7177
+ } = _ref;
7178
+ return {
7179
+ background: theme.palette.selected.main,
7180
+ color: theme.palette.selected.mainContrastText,
7181
+ '&:focus': {
7182
+ boxShadow: "inset 0 0 0 2px rgba(0, 0, 0, 0.3)",
7183
+ outline: 'none'
7184
+ },
7185
+ '& $cell': {
7186
+ paddingRight: 0
7187
+ }
7188
+ };
7189
+ };
7190
+
7191
+ const useStyles$c = makeStyles(theme => ({
7091
7192
  row: {
7092
7193
  flexWrap: 'nowrap',
7093
7194
  borderBottom: "1px solid ".concat(theme.palette.divider),
@@ -7113,8 +7214,8 @@ const useStyles$b = makeStyles(theme => ({
7113
7214
  minWidth: 0,
7114
7215
  flexGrow: 1,
7115
7216
  // Note that this padding is overridden when using checkboxes.
7116
- paddingLeft: '12px',
7117
- paddingRight: '12px'
7217
+ paddingLeft: '9px',
7218
+ paddingRight: '9px'
7118
7219
  },
7119
7220
  // The leaf node, containing the label text.
7120
7221
  labelText: _objectSpread2({
@@ -7140,34 +7241,40 @@ const useStyles$b = makeStyles(theme => ({
7140
7241
  checkboxLabel: {
7141
7242
  margin: 0,
7142
7243
  width: '100%',
7143
- // For checkboxes the first child is the checkbox container, second is the label container.
7244
+ height: '100%',
7245
+ // The checkbox's span
7246
+ '& > span:nth-child(1)': {
7247
+ paddingRight: '7px'
7248
+ },
7249
+ // The checkbox's label container.
7144
7250
  '& > span:nth-child(2)': _objectSpread2(_objectSpread2({}, ellipsis), {}, {
7145
7251
  display: 'flex',
7146
7252
  alignItems: 'center',
7147
- paddingLeft: '8px'
7253
+ paddingLeft: 0
7148
7254
  })
7149
7255
  },
7150
7256
  // The icons container holding tick and lock, shown inside fields.
7151
7257
  icon: {
7152
7258
  display: 'flex',
7153
- padding: theme.spacing(1)
7154
- },
7155
- // Selection styles (S=Selected, A=Available, X=Excluded).
7156
- S: {
7157
- background: theme.palette.selected.main,
7158
- color: theme.palette.selected.mainContrastText,
7159
- '&:focus': {
7160
- boxShadow: "inset 0 0 0 2px rgba(0, 0, 0, 0.3)",
7161
- outline: 'none'
7162
- }
7259
+ padding: theme.spacing(1, 1, 1, 0)
7163
7260
  },
7261
+ // Selection styles (S=Selected, XS=ExcludedSelected, A=Available, X=Excluded).
7262
+ S: _objectSpread2({}, getSelectedStyle({
7263
+ theme
7264
+ })),
7265
+ XS: _objectSpread2(_objectSpread2({}, getSelectedStyle({
7266
+ theme
7267
+ })), {}, {
7268
+ background: theme.palette.selected.excluded,
7269
+ color: theme.palette.selected.mainContrastText
7270
+ }),
7164
7271
  A: {
7165
7272
  background: theme.palette.selected.alternative,
7166
7273
  color: theme.palette.selected.alternativeContrastText
7167
7274
  },
7168
7275
  X: {
7169
7276
  background: theme.palette.selected.excluded,
7170
- color: theme.palette.selected.excludedContrastText
7277
+ color: theme.palette.selected.mainContrastText
7171
7278
  },
7172
7279
  frequencyCount: {
7173
7280
  paddingLeft: '8px',
@@ -7202,13 +7309,14 @@ const useStyles$b = makeStyles(theme => ({
7202
7309
  color: '#828282'
7203
7310
  }
7204
7311
  }));
7205
- function RowColumn(_ref) {
7312
+
7313
+ function RowColumn(_ref2) {
7206
7314
  let {
7207
7315
  index,
7208
7316
  style,
7209
7317
  data,
7210
7318
  column = false
7211
- } = _ref;
7319
+ } = _ref2;
7212
7320
  const {
7213
7321
  onClick,
7214
7322
  onMouseDown,
@@ -7219,15 +7327,17 @@ function RowColumn(_ref) {
7219
7327
  checkboxes = false,
7220
7328
  dense = false,
7221
7329
  frequencyMode = 'N',
7330
+ isSingleSelect,
7222
7331
  actions,
7223
7332
  frequencyMax = '',
7224
7333
  histogram = false,
7225
- keyboard
7334
+ keyboard,
7335
+ showGray = true
7226
7336
  } = data;
7227
7337
  const handleKeyDownCallback = useCallback(getFieldKeyboardNavigation(actions), [actions]);
7228
7338
  const [isSelected, setSelected] = useState$1(false);
7229
7339
  const [cell, setCell] = useState$1();
7230
- const classes = useStyles$b();
7340
+ const classes = useStyles$c();
7231
7341
  const [classArr, setClassArr] = useState$1([]);
7232
7342
  useEffect$1(() => {
7233
7343
  if (!pages) {
@@ -7262,11 +7372,13 @@ function RowColumn(_ref) {
7262
7372
  const clazzArr = [column ? classes.column : classes.row];
7263
7373
 
7264
7374
  if (!checkboxes) {
7265
- if (cell.qState === 'S' || cell.qState === 'L') {
7375
+ if (cell.qState === 'XS') {
7376
+ clazzArr.push(showGray ? classes.XS : classes.S);
7377
+ } else if (cell.qState === 'S' || cell.qState === 'L') {
7266
7378
  clazzArr.push(classes.S);
7267
- } else if (isAlternative(cell)) {
7379
+ } else if (showGray && isAlternative(cell)) {
7268
7380
  clazzArr.push(classes.A);
7269
- } else if (isExcluded(cell)) {
7381
+ } else if (showGray && isExcluded(cell)) {
7270
7382
  clazzArr.push(classes.X);
7271
7383
  }
7272
7384
  }
@@ -7276,20 +7388,20 @@ function RowColumn(_ref) {
7276
7388
 
7277
7389
  const joinClassNames = namesArray => namesArray.filter(c => !!c).join(' ').trim();
7278
7390
 
7279
- const hasGrayText = () => (isAlternative(cell) || isExcluded(cell)) && checkboxes ? classes.excludedTextWithCheckbox : false;
7391
+ const excludedOrAlternative = () => (isAlternative(cell) || isExcluded(cell)) && checkboxes;
7280
7392
 
7281
- const getValueField = _ref2 => {
7393
+ const getValueField = _ref3 => {
7282
7394
  let {
7283
7395
  lbl,
7284
7396
  ix,
7285
7397
  color,
7286
7398
  highlighted = false
7287
- } = _ref2;
7399
+ } = _ref3;
7288
7400
  return /*#__PURE__*/React.createElement(Typography, {
7289
7401
  component: "span",
7290
7402
  variant: "body2",
7291
7403
  key: ix,
7292
- className: joinClassNames([classes.labelText, highlighted && classes.highlighted, dense && classes.labelDense, hasGrayText()]),
7404
+ className: joinClassNames([classes.labelText, highlighted && classes.highlighted, dense && classes.labelDense, showGray && excludedOrAlternative() && classes.excludedTextWithCheckbox]),
7293
7405
  color: color
7294
7406
  }, /*#__PURE__*/React.createElement("span", {
7295
7407
  style: {
@@ -7298,13 +7410,30 @@ function RowColumn(_ref) {
7298
7410
  }, lbl));
7299
7411
  };
7300
7412
 
7301
- const getCheckboxField = _ref3 => {
7413
+ const preventContextMenu = event => {
7414
+ if (checkboxes) {
7415
+ // Event will not propagate in the checkbox/radiobutton case
7416
+ onClick(event);
7417
+ }
7418
+
7419
+ event.preventDefault();
7420
+ };
7421
+
7422
+ const getCheckboxField = _ref4 => {
7302
7423
  let {
7303
7424
  lbl,
7304
7425
  color,
7305
7426
  qElemNumber
7306
- } = _ref3;
7427
+ } = _ref4;
7307
7428
  const cb = /*#__PURE__*/React.createElement(ListboxCheckbox, {
7429
+ label: lbl,
7430
+ checked: isSelected,
7431
+ dense: dense,
7432
+ excluded: isExcluded(cell),
7433
+ alternative: isAlternative(cell),
7434
+ showGray: showGray
7435
+ });
7436
+ const rb = /*#__PURE__*/React.createElement(ListBoxRadioButton, {
7308
7437
  label: lbl,
7309
7438
  checked: isSelected,
7310
7439
  dense: dense
@@ -7316,7 +7445,7 @@ function RowColumn(_ref) {
7316
7445
  }) : lbl;
7317
7446
  return /*#__PURE__*/React.createElement(FormControlLabel, {
7318
7447
  color: color,
7319
- control: cb,
7448
+ control: isSingleSelect ? rb : cb,
7320
7449
  className: classes.checkboxLabel,
7321
7450
  label: labelTag,
7322
7451
  key: qElemNumber
@@ -7338,12 +7467,12 @@ function RowColumn(_ref) {
7338
7467
  const labels = getSegmentsFromRanges(label, ranges);
7339
7468
  const getField = checkboxes ? getCheckboxField : getValueField;
7340
7469
 
7341
- const getFieldWithRanges = _ref4 => {
7470
+ const getFieldWithRanges = _ref5 => {
7342
7471
  let {
7343
7472
  lbls
7344
- } = _ref4;
7345
- const labelsWithRanges = lbls.map((_ref5, ix) => {
7346
- let [lbl, highlighted] = _ref5;
7473
+ } = _ref5;
7474
+ const labelsWithRanges = lbls.map((_ref6, ix) => {
7475
+ let [lbl, highlighted] = _ref6;
7347
7476
  return getValueField({
7348
7477
  ix,
7349
7478
  highlighted,
@@ -7396,6 +7525,7 @@ function RowColumn(_ref) {
7396
7525
  onMouseUp: onMouseUp,
7397
7526
  onMouseEnter: onMouseEnter,
7398
7527
  onKeyDown: handleKeyDownCallback,
7528
+ onContextMenu: preventContextMenu,
7399
7529
  role: column ? 'column' : 'row',
7400
7530
  tabIndex: isFirstElement && (!keyboard.enabled || keyboard.active) ? 0 : -1,
7401
7531
  "data-n": cell && cell.qElemNumber
@@ -7407,7 +7537,7 @@ function RowColumn(_ref) {
7407
7537
  }), /*#__PURE__*/React.createElement(Grid, {
7408
7538
  item: true,
7409
7539
  style: cellStyle,
7410
- className: classes.cell,
7540
+ className: joinClassNames([classes.cell, classes.selectedCell]),
7411
7541
  title: "".concat(label)
7412
7542
  }, ranges.length === 0 ? getField({
7413
7543
  lbl: label,
@@ -7425,7 +7555,7 @@ function RowColumn(_ref) {
7425
7555
  noWrap: true,
7426
7556
  color: "inherit",
7427
7557
  variant: "body2",
7428
- className: joinClassNames([dense && classes.labelDense, classes.labelText, hasGrayText()])
7558
+ className: joinClassNames([dense && classes.labelDense, classes.labelText, showGray && excludedOrAlternative() && classes.excludedTextWithCheckbox])
7429
7559
  }, getFrequencyText())), (showLock || showTick) && /*#__PURE__*/React.createElement(Grid, {
7430
7560
  item: true,
7431
7561
  className: classes.icon
@@ -7438,6 +7568,29 @@ function RowColumn(_ref) {
7438
7568
  }))));
7439
7569
  }
7440
7570
 
7571
+ const scrollBarThumb = '#BBB';
7572
+ const scrollBarThumbHover = '#555';
7573
+ const scrollBarBackground = '#f1f1f1';
7574
+ const useStyles$b = makeStyles(() => ({
7575
+ styledScrollbars: {
7576
+ scrollbarColor: "".concat(scrollBarThumb, " ").concat(scrollBarBackground),
7577
+ '&::-webkit-scrollbar': {
7578
+ width: 10,
7579
+ height: 10
7580
+ },
7581
+ '&::-webkit-scrollbar-track': {
7582
+ backgroundColor: scrollBarBackground
7583
+ },
7584
+ '&::-webkit-scrollbar-thumb': {
7585
+ backgroundColor: scrollBarThumb,
7586
+ borderRadius: '1rem'
7587
+ },
7588
+ '&::-webkit-scrollbar-thumb:hover': {
7589
+ backgroundColor: scrollBarThumbHover
7590
+ }
7591
+ }
7592
+ }));
7593
+
7441
7594
  function getSizeInfo(_ref) {
7442
7595
  let {
7443
7596
  isVertical,
@@ -7469,16 +7622,19 @@ function ListBox(_ref2) {
7469
7622
  listLayout = 'vertical',
7470
7623
  frequencyMode = 'N',
7471
7624
  histogram = false,
7472
- rangeSelect = true,
7473
7625
  checkboxes = false,
7474
7626
  update = undefined,
7627
+ fetchStart = undefined,
7475
7628
  dense = false,
7476
7629
  keyboard = {},
7630
+ showGray = true,
7477
7631
  selectDisabled = () => false
7478
7632
  } = _ref2;
7479
7633
  const [layout] = useLayout$1(model);
7634
+ const isSingleSelect = !!(layout && layout.qListObject.qDimensionInfo.qIsOneAndOnlyOne);
7480
7635
  const [pages, setPages] = useState$1(null);
7481
7636
  const [isLoadingData, setIsLoadingData] = useState$1(false);
7637
+ const styles = useStyles$b();
7482
7638
  const {
7483
7639
  instantPages = [],
7484
7640
  interactionEvents,
@@ -7487,10 +7643,10 @@ function ListBox(_ref2) {
7487
7643
  layout,
7488
7644
  selections,
7489
7645
  pages,
7490
- rangeSelect,
7491
7646
  checkboxes,
7492
7647
  selectDisabled,
7493
- doc: document
7648
+ doc: document,
7649
+ isSingleSelect
7494
7650
  });
7495
7651
  const loaderRef = useRef(null);
7496
7652
  const local = useRef({
@@ -7511,7 +7667,9 @@ function ListBox(_ref2) {
7511
7667
 
7512
7668
  const page = pages.filter(p => isLoaded(p))[0];
7513
7669
  return page && isLoaded(page);
7514
- }, [layout, pages]);
7670
+ }, [layout, pages]); // The time from scroll end until new data is being fetched, may be exposed in API later on.
7671
+
7672
+ const scrollTimeout = 0;
7515
7673
  const loadMoreItems = useCallback((startIndex, stopIndex) => {
7516
7674
  local.current.queue.push({
7517
7675
  start: startIndex,
@@ -7528,7 +7686,7 @@ function ListBox(_ref2) {
7528
7686
  return new Promise(resolve => {
7529
7687
  local.current.timeout = setTimeout(() => {
7530
7688
  const sorted = local.current.queue.slice(-2).sort((a, b) => a.start - b.start);
7531
- model.getListObjectData('/qListObjectDef', sorted.map(s => ({
7689
+ const reqPromise = model.getListObjectData('/qListObjectDef', sorted.map(s => ({
7532
7690
  qTop: s.start,
7533
7691
  qHeight: s.stop - s.start + 1,
7534
7692
  qLeft: 0,
@@ -7540,7 +7698,8 @@ function ListBox(_ref2) {
7540
7698
  setIsLoadingData(false);
7541
7699
  resolve();
7542
7700
  });
7543
- }, isScrolling ? 500 : 0);
7701
+ fetchStart && fetchStart(reqPromise);
7702
+ }, isScrolling ? scrollTimeout : 0);
7544
7703
  });
7545
7704
  }, [layout]);
7546
7705
 
@@ -7616,6 +7775,7 @@ function ListBox(_ref2) {
7616
7775
  width: width,
7617
7776
  itemCount: count,
7618
7777
  layout: listLayout,
7778
+ className: styles.styledScrollbars,
7619
7779
  itemData: _objectSpread2(_objectSpread2({
7620
7780
  isLocked,
7621
7781
  column: !isVertical,
@@ -7624,6 +7784,7 @@ function ListBox(_ref2) {
7624
7784
  checkboxes,
7625
7785
  dense,
7626
7786
  frequencyMode,
7787
+ isSingleSelect,
7627
7788
  actions: {
7628
7789
  select,
7629
7790
  confirm: () => selections && selections.confirm.call(selections),
@@ -7631,7 +7792,8 @@ function ListBox(_ref2) {
7631
7792
  },
7632
7793
  frequencyMax,
7633
7794
  histogram,
7634
- keyboard
7795
+ keyboard,
7796
+ showGray
7635
7797
  }),
7636
7798
  itemSize: itemSize,
7637
7799
  onItemsRendered: onItemsRendered,
@@ -8232,7 +8394,6 @@ function ListBoxSearch(_ref) {
8232
8394
  let {
8233
8395
  model,
8234
8396
  keyboard,
8235
- autoFocus = true,
8236
8397
  dense = false
8237
8398
  } = _ref;
8238
8399
  const {
@@ -8266,7 +8427,6 @@ function ListBoxSearch(_ref) {
8266
8427
  size: dense ? 'small' : 'normal'
8267
8428
  })),
8268
8429
  className: ['search', classes.root, dense && classes.dense].filter(Boolean).join(' '),
8269
- autoFocus: autoFocus,
8270
8430
  margin: "dense",
8271
8431
  fullWidth: true,
8272
8432
  placeholder: translator.get('Listbox.Search'),
@@ -8274,7 +8434,7 @@ function ListBoxSearch(_ref) {
8274
8434
  onChange: onChange,
8275
8435
  onKeyDown: onKeyDown,
8276
8436
  inputProps: {
8277
- tabIndex: !keyboard.enabled || keyboard.active ? 0 : -1
8437
+ tabIndex: keyboard && (!keyboard.enabled || keyboard.active) ? 0 : -1
8278
8438
  }
8279
8439
  });
8280
8440
  }
@@ -9883,8 +10043,10 @@ function ListBoxInline(_ref) {
9883
10043
  sessionModel = undefined,
9884
10044
  selectionsApi = undefined,
9885
10045
  update = undefined,
10046
+ fetchStart = undefined,
9886
10047
  dense = false,
9887
- selectDisabled = () => false
10048
+ selectDisabled = () => false,
10049
+ showGray = true
9888
10050
  } = options;
9889
10051
  let {
9890
10052
  frequencyMode,
@@ -9918,7 +10080,19 @@ function ListBoxInline(_ref) {
9918
10080
  break;
9919
10081
  }
9920
10082
 
9921
- const getListdefFrequencyMode = () => histogram && frequencyMode === 'N' ? 'V' : frequencyMode;
10083
+ const getListdefFrequencyMode = () => histogram && frequencyMode === 'N' ? 'V' : frequencyMode; // Hook that will trigger update when used in useEffects.
10084
+ // Modified from: https://medium.com/@teh_builder/ref-objects-inside-useeffect-hooks-eb7c15198780
10085
+
10086
+
10087
+ const useRefWithCallback = () => {
10088
+ const [ref, setInternalRef] = useState$1({});
10089
+ const setRef = useCallback(node => {
10090
+ setInternalRef({
10091
+ current: node
10092
+ });
10093
+ }, [setInternalRef]);
10094
+ return [ref, setRef];
10095
+ };
9922
10096
 
9923
10097
  const listdef = _objectSpread2({
9924
10098
  qInfo: {
@@ -9989,10 +10163,10 @@ function ListBoxInline(_ref) {
9989
10163
  keyboardNavigation
9990
10164
  } = useContext(InstanceContext);
9991
10165
  const moreAlignTo = useRef();
10166
+ const [searchContainer, searchContainerRef] = useRefWithCallback();
9992
10167
  const [layout] = useLayout$1(model);
9993
10168
  const [showToolbar, setShowToolbar] = useState$1(false);
9994
10169
  const [showSearch, setShowSearch] = useState$1(false);
9995
- const [autoFocusSearch, setAutoFocusSearch] = useState$1(focusSearch);
9996
10170
  const [keyboardActive, setKeyboardActive] = useState$1(false);
9997
10171
  const handleKeyDown = getListboxInlineKeyboardNavigation({
9998
10172
  setKeyboardActive
@@ -10014,12 +10188,30 @@ function ListBoxInline(_ref) {
10014
10188
  });
10015
10189
  }
10016
10190
  }
10191
+
10192
+ return () => {
10193
+ if (selections) {
10194
+ selections.off('deactivated');
10195
+ selections.off('activated');
10196
+ }
10197
+ };
10017
10198
  }, [selections]);
10018
10199
  useEffect$1(() => {
10019
10200
  if (selections) {
10020
10201
  setShowToolbar(selections.isActive());
10021
10202
  }
10022
10203
  }, [selections]);
10204
+ useEffect$1(() => {
10205
+ if (!searchContainer || !searchContainer.current) {
10206
+ return;
10207
+ } // Focus search field on toggle-show or when focusSearch is true.
10208
+
10209
+
10210
+ if (search && focusSearch || search === 'toggle' && showSearch) {
10211
+ const input = searchContainer.current.querySelector('input');
10212
+ input && input.focus();
10213
+ }
10214
+ }, [searchContainer && searchContainer.current, showSearch, search, focusSearch]);
10023
10215
 
10024
10216
  if (!model || !layout || !translator) {
10025
10217
  return null;
@@ -10039,7 +10231,6 @@ function ListBoxInline(_ref) {
10039
10231
  const onShowSearch = () => {
10040
10232
  const newValue = !showSearch;
10041
10233
  setShowSearch(newValue);
10042
- setAutoFocusSearch(newValue);
10043
10234
  };
10044
10235
 
10045
10236
  const getSearchOrUnlock = () => search === 'toggle' && !hasSelections ? /*#__PURE__*/React.createElement(IconButton, {
@@ -10107,10 +10298,10 @@ function ListBoxInline(_ref) {
10107
10298
  onCancel: () => {}
10108
10299
  }
10109
10300
  }))), searchVisible && /*#__PURE__*/React.createElement(Grid, {
10110
- item: true
10301
+ item: true,
10302
+ ref: searchContainerRef
10111
10303
  }, /*#__PURE__*/React.createElement(ListBoxSearch, {
10112
10304
  model: model,
10113
- autoFocus: autoFocusSearch,
10114
10305
  dense: dense,
10115
10306
  keyboard: keyboard
10116
10307
  })), /*#__PURE__*/React.createElement(Grid, {
@@ -10135,9 +10326,11 @@ function ListBoxInline(_ref) {
10135
10326
  height: height,
10136
10327
  width: width,
10137
10328
  update: update,
10329
+ fetchStart: fetchStart,
10138
10330
  dense: dense,
10139
10331
  selectDisabled: selectDisabled,
10140
- keyboard: keyboard
10332
+ keyboard: keyboard,
10333
+ showGray: showGray
10141
10334
  });
10142
10335
  })));
10143
10336
  }
@@ -10538,7 +10731,7 @@ const setValue = (data, reference, value) => {
10538
10731
  dataContainer = dataContainer[step];
10539
10732
  }
10540
10733
 
10541
- if (typeof value !== 'undefined') {
10734
+ if (typeof value !== 'undefined' && propertyName !== '__proto__' && propertyName !== 'constructor') {
10542
10735
  dataContainer[propertyName] = value;
10543
10736
  } else {
10544
10737
  delete dataContainer[propertyName];
@@ -11511,7 +11704,7 @@ function Error$1(_ref3) {
11511
11704
  }));
11512
11705
  }
11513
11706
 
11514
- const _excluded$1 = ["size"];
11707
+ const _excluded$2 = ["size"];
11515
11708
  const useStyles$3 = makeStyles(theme => ({
11516
11709
  root: {
11517
11710
  position: 'relative',
@@ -11537,7 +11730,7 @@ function Progress(_ref) {
11537
11730
  let {
11538
11731
  size = 'medium'
11539
11732
  } = _ref,
11540
- props = _objectWithoutProperties$1(_ref, _excluded$1);
11733
+ props = _objectWithoutProperties$1(_ref, _excluded$2);
11541
11734
 
11542
11735
  const classes = useStyles$3();
11543
11736
  const s = SIZES[size];
@@ -11558,7 +11751,7 @@ function Progress(_ref) {
11558
11751
  }, props)));
11559
11752
  }
11560
11753
 
11561
- const _excluded = ["cancel", "translator"],
11754
+ const _excluded$1 = ["cancel", "translator"],
11562
11755
  _excluded2 = ["retry", "translator"];
11563
11756
  const useStyles$2 = makeStyles$1(() => ({
11564
11757
  stripes: {
@@ -11580,7 +11773,7 @@ function Cancel(_ref) {
11580
11773
  cancel,
11581
11774
  translator
11582
11775
  } = _ref,
11583
- props = _objectWithoutProperties$1(_ref, _excluded);
11776
+ props = _objectWithoutProperties$1(_ref, _excluded$1);
11584
11777
 
11585
11778
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Grid, {
11586
11779
  container: true,
@@ -11594,7 +11787,8 @@ function Cancel(_ref) {
11594
11787
  item: true
11595
11788
  }, /*#__PURE__*/React.createElement(Typography, {
11596
11789
  variant: "h6",
11597
- align: "center"
11790
+ align: "center",
11791
+ "data-tid": "update-active"
11598
11792
  }, translator.get('Object.Update.Active')))), /*#__PURE__*/React.createElement(Grid, _extends$4({
11599
11793
  item: true
11600
11794
  }, props), /*#__PURE__*/React.createElement(Button, {
@@ -11619,7 +11813,8 @@ function Retry(_ref2) {
11619
11813
  item: true
11620
11814
  }, /*#__PURE__*/React.createElement(Typography, {
11621
11815
  variant: "h6",
11622
- align: "center"
11816
+ align: "center",
11817
+ "data-tid": "update-cancelled"
11623
11818
  }, translator.get('Object.Update.Cancelled'))), /*#__PURE__*/React.createElement(Grid, {
11624
11819
  item: true
11625
11820
  }, /*#__PURE__*/React.createElement(Button, _extends$4({
@@ -12908,6 +13103,10 @@ function viz() {
12908
13103
 
12909
13104
  takeSnapshot() {
12910
13105
  return cellRef.current.takeSnapshot();
13106
+ },
13107
+
13108
+ getModel() {
13109
+ return model;
12911
13110
  }
12912
13111
 
12913
13112
  } // old QVisualization API
@@ -17181,9 +17380,9 @@ function create(_ref) {
17181
17380
  };
17182
17381
  }
17183
17382
 
17383
+ const _excluded = ["__DO_NOT_USE__"];
17184
17384
  /**
17185
17385
  * @interface Context
17186
- * @property {boolean=} disableCellPadding
17187
17386
  * @property {boolean=} keyboardNavigation
17188
17387
  * @property {object=} constraints
17189
17388
  * @property {boolean=} constraints.active
@@ -17298,6 +17497,59 @@ const mergeConfigs = (base, c) => ({
17298
17497
  flags: mergeObj(base.flags, c.flags),
17299
17498
  anything: mergeObj(base.anything, c.anything)
17300
17499
  });
17500
+ /**
17501
+ * @ignore
17502
+ * @typedef {function(promise)} PromiseFunction A callback function which receives a request promise as the first argument.
17503
+ */
17504
+
17505
+ /**
17506
+ * @ignore
17507
+ * @typedef {function(function)} ReceiverFunction A callback function which receives another function as input.
17508
+ */
17509
+
17510
+ /**
17511
+ * @ignore
17512
+ * @typedef {object} DoNotUseOptions Options strictly recommended not to use as they might change anytime. Documenting them to keep track of them, but not exposing them to API docs.
17513
+ * @property {boolean=} [focusSearch=false] Initialize the Listbox with the search input focused. Only applicable when
17514
+ * search is true, since toggling will always focus the search input on show.
17515
+ * @property {boolean=} [options.showGray=true] Render fields or checkboxes in shades of gray instead of white when their state is excluded or alternative.
17516
+ * @property {object} [options.sessionModel] Use a custom sessionModel.
17517
+ * @property {object} [options.selectionsApi] Use a custom selectionsApi to customize how values are selected.
17518
+ * @property {function():boolean} [options.selectDisabled=] Define a function which tells when selections are disabled (true) or enabled (false). By default, always returns false.
17519
+ * @property {PromiseFunction} [options.fetchStart] A function called when the Listbox starts fetching data. Receives the fetch request promise as an argument.
17520
+ * @property {ReceiverFunction} [options.update] A function which receives an update function which upon call will trigger a data fetch.
17521
+ */
17522
+
17523
+ /**
17524
+ * @ignore
17525
+ * @param {object} usersOptions Options sent in to fieldInstance.mount.
17526
+ * @param {DoNotUseOptions} __DO_NOT_USE__
17527
+ * @returns {object} Squashed options with defaults given for non-exposed options.
17528
+ */
17529
+
17530
+
17531
+ const getOptions = function () {
17532
+ let usersOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
17533
+
17534
+ const {
17535
+ __DO_NOT_USE__ = {}
17536
+ } = usersOptions,
17537
+ exposedOptions = _objectWithoutProperties$1(usersOptions, _excluded);
17538
+
17539
+ const DO_NOT_USE_DEFAULTS = {
17540
+ update: undefined,
17541
+ fetchStart: undefined,
17542
+ showGray: true,
17543
+ focusSearch: false,
17544
+ sessionModel: undefined,
17545
+ selectionsApi: undefined,
17546
+ selectDisabled: undefined
17547
+ };
17548
+
17549
+ const squashedOptions = _objectSpread2(_objectSpread2(_objectSpread2({}, exposedOptions), DO_NOT_USE_DEFAULTS), __DO_NOT_USE__);
17550
+
17551
+ return squashedOptions;
17552
+ };
17301
17553
 
17302
17554
  function nuked() {
17303
17555
  let configuration = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -17538,11 +17790,7 @@ function nuked() {
17538
17790
  */
17539
17791
 
17540
17792
  /**
17541
- * @typedef { false | true | 'toggle' } SearchMode
17542
- */
17543
-
17544
- /**
17545
- * @typedef {function(function)} ReceiverFunction A callback function which receives another function as input.
17793
+ * @typedef { boolean | 'toggle' } SearchMode
17546
17794
  */
17547
17795
 
17548
17796
  /**
@@ -17565,18 +17813,12 @@ function nuked() {
17565
17813
  * @param {FrequencyMode=} [options.frequencyMode=none] Show frequency none|value|percent|relative
17566
17814
  * @param {boolean=} [options.histogram=false] Show histogram bar
17567
17815
  * @param {SearchMode=} [options.search=true] Show the search bar permanently or using the toggle button: false|true|toggle|toggleShow
17568
- * @param {boolean=} [options.focusSearch=false] Initialize the Listbox with the search input focused. Only applicable when
17569
- * search is true, since toggling will always focus the search input on show.
17570
17816
  * @param {boolean=} [options.toolbar=true] Show the toolbar
17571
17817
  * @param {boolean=} [options.checkboxes=false] Show values as checkboxes instead of as fields
17572
- * @param {boolean=} [options.rangeSelect=true] Enable range selection
17573
17818
  * @param {boolean=} [options.dense=false] Reduces padding and text size
17574
17819
  * @param {boolean=} [options.stateName="$"] Sets the state to make selections in
17575
17820
  * @param {object=} [options.properties={}] Properties object to extend default properties with
17576
- * @param {object} [options.sessionModel] Use a custom sessionModel.
17577
- * @param {object} [options.selectionsApi] Use a custom selectionsApi to customize how values are selected.
17578
- * @param {function():boolean} [options.selectDisabled=] Define a function which tells when selections are disabled (true) or enabled (false). By default, always returns false.
17579
- * @param {ReceiverFunction} [options.update] A function which receives an update function which upon call will trigger a data fetch.
17821
+ *
17580
17822
  * @since 1.1.0
17581
17823
  * @instance
17582
17824
  * @example
@@ -17597,7 +17839,7 @@ function nuked() {
17597
17839
  element,
17598
17840
  app,
17599
17841
  fieldIdentifier,
17600
- options,
17842
+ options: getOptions(options),
17601
17843
  stateName: options.stateName || '$'
17602
17844
  });
17603
17845
  root.add(this._instance);
@@ -17694,13 +17936,535 @@ function nuked() {
17694
17936
 
17695
17937
  var index = nuked(DEFAULT_CONFIG);
17696
17938
 
17939
+ var enigmaMocker_dev = {exports: {}};
17940
+
17941
+ /*
17942
+ * @nebula.js/enigma-mocker v2.9.0
17943
+ * Copyright (c) 2022 QlikTech International AB
17944
+ * Released under the MIT license.
17945
+ */
17946
+
17947
+ (function (module, exports) {
17948
+ (function (global, factory) {
17949
+ module.exports = factory() ;
17950
+ })(commonjsGlobal, function () {
17951
+
17952
+ function SessionMock() {
17953
+ return {
17954
+ getObjectApi() {
17955
+ return Promise.resolve({
17956
+ id: "sessapi - ".concat(+Date.now())
17957
+ });
17958
+ }
17959
+
17960
+ };
17961
+ }
17962
+
17963
+ function ownKeys(object, enumerableOnly) {
17964
+ var keys = Object.keys(object);
17965
+
17966
+ if (Object.getOwnPropertySymbols) {
17967
+ var symbols = Object.getOwnPropertySymbols(object);
17968
+ enumerableOnly && (symbols = symbols.filter(function (sym) {
17969
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
17970
+ })), keys.push.apply(keys, symbols);
17971
+ }
17972
+
17973
+ return keys;
17974
+ }
17975
+
17976
+ function _objectSpread2(target) {
17977
+ for (var i = 1; i < arguments.length; i++) {
17978
+ var source = null != arguments[i] ? arguments[i] : {};
17979
+ i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
17980
+ _defineProperty(target, key, source[key]);
17981
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
17982
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
17983
+ });
17984
+ }
17985
+
17986
+ return target;
17987
+ }
17988
+
17989
+ function _defineProperty(obj, key, value) {
17990
+ if (key in obj) {
17991
+ Object.defineProperty(obj, key, {
17992
+ value: value,
17993
+ enumerable: true,
17994
+ configurable: true,
17995
+ writable: true
17996
+ });
17997
+ } else {
17998
+ obj[key] = value;
17999
+ }
18000
+
18001
+ return obj;
18002
+ }
18003
+
18004
+ function _objectWithoutPropertiesLoose(source, excluded) {
18005
+ if (source == null) return {};
18006
+ var target = {};
18007
+ var sourceKeys = Object.keys(source);
18008
+ var key, i;
18009
+
18010
+ for (i = 0; i < sourceKeys.length; i++) {
18011
+ key = sourceKeys[i];
18012
+ if (excluded.indexOf(key) >= 0) continue;
18013
+ target[key] = source[key];
18014
+ }
18015
+
18016
+ return target;
18017
+ }
18018
+
18019
+ function _objectWithoutProperties(source, excluded) {
18020
+ if (source == null) return {};
18021
+
18022
+ var target = _objectWithoutPropertiesLoose(source, excluded);
18023
+
18024
+ var key, i;
18025
+
18026
+ if (Object.getOwnPropertySymbols) {
18027
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
18028
+
18029
+ for (i = 0; i < sourceSymbolKeys.length; i++) {
18030
+ key = sourceSymbolKeys[i];
18031
+ if (excluded.indexOf(key) >= 0) continue;
18032
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
18033
+ target[key] = source[key];
18034
+ }
18035
+ }
18036
+
18037
+ return target;
18038
+ }
18039
+
18040
+ var hasOwn = Object.prototype.hasOwnProperty;
18041
+ var toStr = Object.prototype.toString;
18042
+ var defineProperty = Object.defineProperty;
18043
+ var gOPD = Object.getOwnPropertyDescriptor;
18044
+
18045
+ var isArray = function isArray(arr) {
18046
+ if (typeof Array.isArray === 'function') {
18047
+ return Array.isArray(arr);
18048
+ }
18049
+
18050
+ return toStr.call(arr) === '[object Array]';
18051
+ };
18052
+
18053
+ var isPlainObject = function isPlainObject(obj) {
18054
+ if (!obj || toStr.call(obj) !== '[object Object]') {
18055
+ return false;
18056
+ }
18057
+
18058
+ var hasOwnConstructor = hasOwn.call(obj, 'constructor');
18059
+ var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); // Not own constructor property must be Object
18060
+
18061
+ if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {
18062
+ return false;
18063
+ } // Own properties are enumerated firstly, so to speed up,
18064
+ // if last one is own, then all properties are own.
18065
+
18066
+
18067
+ var key;
18068
+
18069
+ for (key in obj) {
18070
+ /**/
18071
+ }
18072
+
18073
+ return typeof key === 'undefined' || hasOwn.call(obj, key);
18074
+ }; // If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target
18075
+
18076
+
18077
+ var setProperty = function setProperty(target, options) {
18078
+ if (defineProperty && options.name === '__proto__') {
18079
+ defineProperty(target, options.name, {
18080
+ enumerable: true,
18081
+ configurable: true,
18082
+ value: options.newValue,
18083
+ writable: true
18084
+ });
18085
+ } else {
18086
+ target[options.name] = options.newValue;
18087
+ }
18088
+ }; // Return undefined instead of __proto__ if '__proto__' is not an own property
18089
+
18090
+
18091
+ var getProperty = function getProperty(obj, name) {
18092
+ if (name === '__proto__') {
18093
+ if (!hasOwn.call(obj, name)) {
18094
+ return void 0;
18095
+ } else if (gOPD) {
18096
+ // In early versions of node, obj['__proto__'] is buggy when obj has
18097
+ // __proto__ as an own property. Object.getOwnPropertyDescriptor() works.
18098
+ return gOPD(obj, name).value;
18099
+ }
18100
+ }
18101
+
18102
+ return obj[name];
18103
+ };
18104
+
18105
+ var extend = function extend() {
18106
+ var options, name, src, copy, copyIsArray, clone;
18107
+ var target = arguments[0];
18108
+ var i = 1;
18109
+ var length = arguments.length;
18110
+ var deep = false; // Handle a deep copy situation
18111
+
18112
+ if (typeof target === 'boolean') {
18113
+ deep = target;
18114
+ target = arguments[1] || {}; // skip the boolean and the target
18115
+
18116
+ i = 2;
18117
+ }
18118
+
18119
+ if (target == null || typeof target !== 'object' && typeof target !== 'function') {
18120
+ target = {};
18121
+ }
18122
+
18123
+ for (; i < length; ++i) {
18124
+ options = arguments[i]; // Only deal with non-null/undefined values
18125
+
18126
+ if (options != null) {
18127
+ // Extend the base object
18128
+ for (name in options) {
18129
+ src = getProperty(target, name);
18130
+ copy = getProperty(options, name); // Prevent never-ending loop
18131
+
18132
+ if (target !== copy) {
18133
+ // Recurse if we're merging plain objects or arrays
18134
+ if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
18135
+ if (copyIsArray) {
18136
+ copyIsArray = false;
18137
+ clone = src && isArray(src) ? src : [];
18138
+ } else {
18139
+ clone = src && isPlainObject(src) ? src : {};
18140
+ } // Never move original objects, clone them
18141
+
18142
+
18143
+ setProperty(target, {
18144
+ name: name,
18145
+ newValue: extend(deep, clone, copy)
18146
+ }); // Don't bring in undefined values
18147
+ } else if (typeof copy !== 'undefined') {
18148
+ setProperty(target, {
18149
+ name: name,
18150
+ newValue: copy
18151
+ });
18152
+ }
18153
+ }
18154
+ }
18155
+ }
18156
+ } // Return the modified object
18157
+
18158
+
18159
+ return target;
18160
+ };
18161
+
18162
+ function CreateSessionObjectMock() {
18163
+ return props => {
18164
+ const mockedInclusions = props ? props._mock : null;
18165
+ let layout = props;
18166
+
18167
+ if (mockedInclusions) {
18168
+ delete props._mock; // eslint-disable-line no-param-reassign
18169
+
18170
+ layout = extend({}, props, mockedInclusions);
18171
+ }
18172
+
18173
+ return Promise.resolve(_objectSpread2({
18174
+ on: () => {},
18175
+ once: () => {},
18176
+ getLayout: () => Promise.resolve(layout),
18177
+ getProperties: () => Promise.resolve(props),
18178
+ getEffectiveProperties: () => Promise.resolve(props),
18179
+ id: props && props.qInfo && props.qInfo.qId ? props.qInfo.qId : "sel - ".concat(+Date.now())
18180
+ }, props));
18181
+ };
18182
+ }
18183
+ /**
18184
+ * Get value for a fixture property.
18185
+ *
18186
+ * The value is either static (e.g. pass a string / object / similar) or dynamic when passing a function.
18187
+ *
18188
+ * It falls back to the default value in case the fixture has no value specified.
18189
+ *
18190
+ * Example
18191
+ * ```js
18192
+ * const fixture = {
18193
+ * id: 'grid-chart-1',
18194
+ * };
18195
+ * const app = {
18196
+ * id: getValue(fixture.id, { defaultValue: 'object-id-${+Date.now()}'}),
18197
+ * }
18198
+ * ```
18199
+ *
18200
+ * @param {any} prop Fixture property. Either a fixed value (string / object / boolean / ...) or a function invoked when the value is needed.
18201
+ * @param {object} options Options.
18202
+ * @param {Array<any>} options.args Arguments used to evaluate the property value.
18203
+ * @param {any} options.defaultValue Default value in case not value is defined in fixture.
18204
+ * @returns The property value.
18205
+ */
18206
+
18207
+
18208
+ const getPropValue = function (prop) {
18209
+ let {
18210
+ args = [],
18211
+ defaultValue
18212
+ } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
18213
+
18214
+ if (typeof prop === 'function') {
18215
+ return prop(...args);
18216
+ }
18217
+
18218
+ if (prop !== undefined) {
18219
+ return prop;
18220
+ }
18221
+
18222
+ return defaultValue;
18223
+ };
18224
+ /**
18225
+ * Get function for a fixture property.
18226
+ *
18227
+ * When the returned function is invoked it resolves the value - using `defaultValue` as fallback - and returns it. The value is returned as a promise if `option.usePromise` is `true`.
18228
+ *
18229
+ * Example:
18230
+ * ```js
18231
+ * const fixture = {
18232
+ * getHyperCubeData(path, page) {
18233
+ * return [ ... ];
18234
+ * }
18235
+ * }
18236
+ * const app = {
18237
+ * getHyperCubeData: getPropFn(fixture.getHyperCubeData, { defaultValue: [], usePromise: true })
18238
+ * };
18239
+ * ```
18240
+ *
18241
+ * @param {any} prop Fixture property. Either a fixed value (string / object / boolean / ...) or a function invoked when the value is needed.
18242
+ * @param {object} options Options.
18243
+ * @param {any} options.defaultValue Default value in case not value is defined in fixture.
18244
+ * @param {boolean} options.async When `true` the returns value is wrapped in a promise, otherwise the value is directly returned.
18245
+ * @param {number} options.number Delay before value is returned.
18246
+ * @returns A fixture property function
18247
+ */
18248
+
18249
+
18250
+ const getPropFn = function (prop) {
18251
+ let {
18252
+ defaultValue,
18253
+ async = true,
18254
+ delay = 0
18255
+ } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
18256
+ return function () {
18257
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
18258
+ args[_key] = arguments[_key];
18259
+ }
18260
+
18261
+ const value = getPropValue(prop, {
18262
+ defaultValue,
18263
+ args
18264
+ });
18265
+ return async ? new Promise(resolve => {
18266
+ setTimeout(() => resolve(value), delay);
18267
+ }) : value;
18268
+ };
18269
+ };
18270
+
18271
+ const _excluded = ["id", "session"];
18272
+ /**
18273
+ * Properties on `getObject()` operating synchronously.
18274
+ */
18275
+
18276
+ const PROPS_SYNC = ['addListener', 'emit', 'listeners', 'on', 'once', 'removeAllListeners', 'removeListener', 'setMaxListerners'];
18277
+ /**
18278
+ * Is property operating asynchrously.
18279
+ * @param {string} name Property name.
18280
+ * @returns `true` if property is operating asynchrously, otherwise `false`.
18281
+ */
18282
+
18283
+ function isPropAsync(name) {
18284
+ return !PROPS_SYNC.includes(name);
18285
+ }
18286
+ /**
18287
+ * Get `qId` for visualization.
18288
+ * @param {object} genericObject Generic object describing behaviour of mock
18289
+ * @returns The `qId`, undefined if not present
18290
+ */
18291
+
18292
+
18293
+ function getQId(genericObject) {
18294
+ const layout = getPropValue(genericObject.getLayout);
18295
+ return layout.qInfo && layout.qInfo.qId;
18296
+ }
18297
+ /**
18298
+ * Create a mock of a generic object. Mandatory properties are added, functions returns async values where applicable etc.
18299
+ * @param {object} genericObject Generic object describing behaviour of mock
18300
+ * @param {EnigmaMockerOptions} options Options.
18301
+ * @returns The mocked object
18302
+ */
18303
+
18304
+
18305
+ function createMock(genericObject, options) {
18306
+ const qId = getQId(genericObject);
18307
+ const {
18308
+ delay
18309
+ } = options;
18310
+
18311
+ const {
18312
+ id,
18313
+ session
18314
+ } = genericObject,
18315
+ props = _objectWithoutProperties(genericObject, _excluded);
18316
+
18317
+ const mock = _objectSpread2({
18318
+ id: getPropValue(id, {
18319
+ defaultValue: "object - ".concat(+Date.now())
18320
+ }),
18321
+ session: getPropValue(session, {
18322
+ defaultValue: true
18323
+ }),
18324
+ on: () => {},
18325
+ once: () => {}
18326
+ }, Object.entries(props).reduce((fns, _ref) => {
18327
+ let [name, value] = _ref;
18328
+ return _objectSpread2(_objectSpread2({}, fns), {}, {
18329
+ [name]: getPropFn(value, {
18330
+ async: isPropAsync(name),
18331
+ delay
18332
+ })
18333
+ });
18334
+ }, {}));
18335
+
18336
+ return {
18337
+ [qId]: mock
18338
+ };
18339
+ }
18340
+ /**
18341
+ * Create mocked objects from list of generic objects.
18342
+ * @param {Array<object>} genericObjects Generic objects describing behaviour of mock
18343
+ * @param {EnigmaMockerOptions} options options
18344
+ * @returns Object with mocks where key is `qId` and value is the mocked object.
18345
+ */
18346
+
18347
+
18348
+ function createMocks(genericObjects, options) {
18349
+ return genericObjects.reduce((mocks, genericObject) => _objectSpread2(_objectSpread2({}, mocks), createMock(genericObject, options)), {});
18350
+ }
18351
+ /**
18352
+ * Validates if mandatory information is available.
18353
+ * @param {object} genericObject Generic object to validate
18354
+ * @throws {}
18355
+ * <ul>
18356
+ * <li>{Error} If getLayout is missing</li>
18357
+ * <li>{Error} If getLayout.qInfo.qId is missing</li>
18358
+ * </ul>
18359
+ */
18360
+
18361
+
18362
+ function validate(genericObject) {
18363
+ if (!genericObject.getLayout) {
18364
+ throw new Error('Generic object is missing "getLayout"');
18365
+ }
18366
+
18367
+ const qId = getQId(genericObject);
18368
+
18369
+ if (!qId) {
18370
+ throw new Error('Generic object is missing "qId" for path "getLayout().qInfo.qId"');
18371
+ }
18372
+ }
18373
+ /**
18374
+ * Creates mock of `getObject(id)` based on an array of generic objects.
18375
+ * @param {Array<object>} genericObjects Generic objects.
18376
+ * @param {EnigmaMockerOptions} options Options.
18377
+ * @returns Function to retrieve the mocked generic object with the corresponding id.
18378
+ */
18379
+
18380
+
18381
+ function GetObjectMock() {
18382
+ let genericObjects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
18383
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
18384
+
18385
+ if (!Array.isArray(genericObjects) || genericObjects.length === 0) {
18386
+ return () => {
18387
+ throw new Error('No "genericObjects" specified');
18388
+ };
18389
+ }
18390
+
18391
+ genericObjects.forEach(validate);
18392
+ const mocks = createMocks(genericObjects, options);
18393
+ return async id => Promise.resolve(mocks[id]);
18394
+ }
18395
+
18396
+ function GetAppLayoutMock() {
18397
+ return () => Promise.resolve({
18398
+ id: 'app-layout'
18399
+ });
18400
+ }
18401
+ /**
18402
+ * @interface EnigmaMockerOptions
18403
+ * @property {number} delay Simulate delay (in ms) for calls in enigma-mocker.
18404
+ */
18405
+
18406
+ /**
18407
+ * Mocks Engima app functionality. It accepts one / many generic objects as input argument and returns the mocked Enigma app. Each generic object represents one visulization and specifies how it behaves. For example, what layout to use the data to present.
18408
+ *
18409
+ * The generic object is represented with a Javascript object with a number of properties. The name of the property correlates to the name in the Enigma model for `app.getObject(id)`. For example, the property `getLayout` in the generic object is used to define `app.getObject(id).getLayout()`. Any property can be added to the fixture (just make sure it exists and behaves as in the Enigma model!).
18410
+ *
18411
+ * The value for each property is either fixed (string / boolean / number / object) or a function. Arguments are forwarded to the function to allow for greater flexibility. For example, this can be used to return different hypercube data when scrolling in the chart.
18412
+ *
18413
+ * @param {Array<object>} genericObjects Generic objects controling behaviour of visualizations.
18414
+ * @param {EnigmaMockerOptions} options Options
18415
+ * @returns {Promise<enigma.Doc>}
18416
+ * @example
18417
+ * const genericObject = {
18418
+ * getLayout() {
18419
+ * return {
18420
+ * qInfo: {
18421
+ * qId: 'qqj4zx',
18422
+ * qType: 'sn-grid-chart'
18423
+ * },
18424
+ * ...
18425
+ * }
18426
+ * },
18427
+ * getHyperCubeData(path, page) {
18428
+ * return [ ... ];
18429
+ * }
18430
+ * };
18431
+ * const app = await EnigmaMocker.fromGenericObjects([genericObject]);
18432
+ */
18433
+
18434
+
18435
+ var fromGenericObjects = function (genericObjects) {
18436
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
18437
+ const session = new SessionMock();
18438
+ const createSessionObject = new CreateSessionObjectMock();
18439
+ const getObject = new GetObjectMock(genericObjects, options);
18440
+ const getAppLayout = new GetAppLayoutMock();
18441
+ const app = {
18442
+ id: "app - ".concat(+Date.now()),
18443
+ session,
18444
+ createSessionObject,
18445
+ getObject,
18446
+ getAppLayout
18447
+ };
18448
+ return Promise.resolve(app);
18449
+ };
18450
+
18451
+ var index = {
18452
+ fromGenericObjects
18453
+ };
18454
+ return index;
18455
+ });
18456
+ })(enigmaMocker_dev);
18457
+
18458
+ var enigmaMocker = enigmaMocker_dev.exports;
18459
+
17697
18460
  /* eslint no-underscore-dangle: 0 */
17698
18461
 
17699
18462
  const __DO_NOT_USE__ = {
17700
18463
  generator: generatorFn,
17701
18464
  hook,
17702
18465
  theme,
17703
- locale
18466
+ locale,
18467
+ EnigmaMocker: enigmaMocker
17704
18468
  };
17705
18469
 
17706
18470
  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 };