@nebula.js/stardust 3.3.0 → 4.0.0-alpha.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 v3.3.0
2
+ * @nebula.js/stardust v4.0.0-alpha.0
3
3
  * Copyright (c) 2023 QlikTech International AB
4
4
  * Released under the MIT license.
5
5
  */
@@ -1613,6 +1613,12 @@ var Visualization_UnfulfilledCalculationCondition = {
1613
1613
  "zh-TW": "不符計算條件"
1614
1614
  }
1615
1615
  };
1616
+ var Listbox_DrillDown = {
1617
+ id: "Listbox.DrillDown",
1618
+ locale: {
1619
+ "en-US": "Drill-down dimension"
1620
+ }
1621
+ };
1616
1622
  var all = {
1617
1623
  Cancel: Cancel$1,
1618
1624
  CurrentSelections_All: CurrentSelections_All,
@@ -1649,7 +1655,8 @@ var all = {
1649
1655
  Visualization_Invalid_Dimension: Visualization_Invalid_Dimension,
1650
1656
  Visualization_Invalid_Measure: Visualization_Invalid_Measure,
1651
1657
  Visualization_LayoutError: Visualization_LayoutError,
1652
- Visualization_UnfulfilledCalculationCondition: Visualization_UnfulfilledCalculationCondition
1658
+ Visualization_UnfulfilledCalculationCondition: Visualization_UnfulfilledCalculationCondition,
1659
+ Listbox_DrillDown: Listbox_DrillDown
1653
1660
  };
1654
1661
 
1655
1662
  function appLocaleFn(language) {
@@ -3438,6 +3445,14 @@ function deviceTypeFn(deviceType) {
3438
3445
  return detectTouchscreen() ? 'touch' : 'desktop';
3439
3446
  }
3440
3447
 
3448
+ var client = {};
3449
+
3450
+ var m = ReactDOM;
3451
+ {
3452
+ client.createRoot = m.createRoot;
3453
+ client.hydrateRoot = m.hydrateRoot;
3454
+ }
3455
+
3441
3456
  function _extends$5() {
3442
3457
  _extends$5 = Object.assign ? Object.assign.bind() : function (target) {
3443
3458
  for (var i = 1; i < arguments.length; i++) {
@@ -7972,7 +7987,7 @@ function create$3(definition) {
7972
7987
  return cache[key];
7973
7988
  }
7974
7989
 
7975
- const NEBULA_VERSION_HASH = "593e" ;
7990
+ const NEBULA_VERSION_HASH = "b1a6" ;
7976
7991
  ClassNameGenerator$1.configure(componentName => {
7977
7992
  return "njs-".concat(NEBULA_VERSION_HASH, "-").concat(componentName.replace('Mui', ''));
7978
7993
  });
@@ -8134,7 +8149,8 @@ function useAppSelections(app) {
8134
8149
  const NebulaApp = forwardRef((_ref, ref) => {
8135
8150
  let {
8136
8151
  initialContext,
8137
- app
8152
+ app,
8153
+ renderCallback
8138
8154
  } = _ref;
8139
8155
  const [appSelections] = useAppSelections(app);
8140
8156
  const [context, setContext] = useState$1(initialContext);
@@ -8145,21 +8161,20 @@ const NebulaApp = forwardRef((_ref, ref) => {
8145
8161
  theme: create$3(muiThemeName)
8146
8162
  }), [muiThemeName]);
8147
8163
  const [components, setComponents] = useState$1([]);
8164
+
8165
+ // Will be called directly after the first render pass
8166
+ // See: https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html
8167
+ useEffect$1(() => {
8168
+ renderCallback && renderCallback();
8169
+ }, []);
8148
8170
  useImperativeHandle$1(ref, () => ({
8149
- addComponent(component) {
8150
- setComponents([...components, component]);
8151
- },
8152
- removeComponent(component) {
8153
- const ix = components.indexOf(component);
8154
- if (ix !== -1) {
8155
- components.splice(ix, 1);
8156
- setComponents([...components]);
8157
- }
8171
+ setComps(comps) {
8172
+ setComponents([...comps]);
8158
8173
  },
8159
8174
  setMuiThemeName,
8160
8175
  setContext: ctx => setContext(oldContext => JSON.stringify(oldContext) !== JSON.stringify(ctx) ? ctx : oldContext),
8161
8176
  getAppSelections: () => appSelections
8162
- }));
8177
+ }), []);
8163
8178
  return /*#__PURE__*/React__default.createElement(StyledEngineProvider, {
8164
8179
  injectFirst: true
8165
8180
  }, /*#__PURE__*/React__default.createElement(ThemeProvider, {
@@ -8180,15 +8195,18 @@ function boot(_ref2) {
8180
8195
  const appRef = React__default.createRef();
8181
8196
  const element = document.createElement('div');
8182
8197
  element.style.display = 'none';
8183
- element.setAttribute('data-nebulajs-version', "3.3.0" );
8198
+ element.setAttribute('data-nebulajs-version', "4.0.0-alpha.0" );
8184
8199
  element.setAttribute('data-app-id', app.id);
8185
8200
  document.body.appendChild(element);
8186
- ReactDOM.render( /*#__PURE__*/React__default.createElement(NebulaApp, {
8201
+ const root = client.createRoot(element);
8202
+ root.render( /*#__PURE__*/React__default.createElement(NebulaApp, {
8187
8203
  ref: appRef,
8188
8204
  app: app,
8189
- initialContext: context
8190
- }), element, resolveRender);
8205
+ initialContext: context,
8206
+ renderCallback: resolveRender
8207
+ }));
8191
8208
  const cells = {};
8209
+ const components = [];
8192
8210
  return [{
8193
8211
  toggleFocusOfCells(cellIdToFocus) {
8194
8212
  Object.keys(cells).forEach(i => {
@@ -8205,13 +8223,18 @@ function boot(_ref2) {
8205
8223
  add(component) {
8206
8224
  (async () => {
8207
8225
  await rendered;
8208
- appRef.current.addComponent(component);
8226
+ components.push(component);
8227
+ appRef.current.setComps(components);
8209
8228
  })();
8210
8229
  },
8211
8230
  remove(component) {
8212
8231
  (async () => {
8213
8232
  await rendered;
8214
- appRef.current.removeComponent(component);
8233
+ const ix = components.indexOf(component);
8234
+ if (ix !== -1) {
8235
+ components.splice(ix, 1);
8236
+ }
8237
+ appRef.current.setComps(components);
8215
8238
  })();
8216
8239
  },
8217
8240
  setMuiThemeName(themeName) {
@@ -8864,9 +8887,6 @@ const flatten = arr => arr.reduce((prev, cur) => prev.concat(cur));
8864
8887
  function isStateSelected(qState) {
8865
8888
  return SELECTED_STATES.includes(qState);
8866
8889
  }
8867
- function getUniques(arr) {
8868
- return Array.isArray(arr) ? Array.from(new Set(arr)) : undefined;
8869
- }
8870
8890
  function getSelectedValues(pages) {
8871
8891
  if (!pages || !pages.length) {
8872
8892
  return [];
@@ -8880,45 +8900,38 @@ function getSelectedValues(pages) {
8880
8900
  });
8881
8901
  return flatten(elementNbrs);
8882
8902
  }
8883
- function applySelectionsOnPages(pages, elmNumbers) {
8884
- let clearAllButElmNumbers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
8885
- const getNewSelectionState = qState => elmNumbers.length <= 1 && isStateSelected(qState) ? 'A' : 'S';
8886
- const matrices = pages.map(page => {
8887
- const qMatrix = page.qMatrix.map(p => {
8888
- const [p0] = p;
8889
- const selectionMatchesElement = elmNumbers.includes(p0.qElemNumber);
8890
- let qState;
8891
- if (clearAllButElmNumbers) {
8892
- qState = selectionMatchesElement ? 'S' : 'A';
8893
- } else {
8894
- qState = selectionMatchesElement ? getNewSelectionState(p0.qState) : p0.qState;
8895
- }
8896
- return [_objectSpread2(_objectSpread2({}, p0), {}, {
8897
- qState
8898
- }), p.slice(1)];
8899
- });
8900
- return _objectSpread2(_objectSpread2({}, page), {}, {
8901
- qMatrix
8902
- });
8903
- });
8904
- return matrices;
8905
- }
8906
8903
  async function selectValues(_ref) {
8907
8904
  let {
8908
8905
  selections,
8909
8906
  elemNumbers,
8910
- isSingleSelect = false
8907
+ toggle,
8908
+ isSingleSelect
8911
8909
  } = _ref;
8912
- let resolved = Promise.resolve(false);
8910
+ if (elemNumbers.length === 0) {
8911
+ return false;
8912
+ }
8913
8913
  const hasNanValues = elemNumbers.some(elemNumber => Number.isNaN(elemNumber));
8914
+ let success = false;
8914
8915
  if (!hasNanValues) {
8915
8916
  const elemNumbersToSelect = elemNumbers;
8916
- resolved = selections.select({
8917
- method: 'selectListObjectValues',
8918
- params: ['/qListObjectDef', elemNumbersToSelect, !isSingleSelect]
8919
- }).then(success => success !== false).catch(() => false);
8917
+ try {
8918
+ const response = await selections.select({
8919
+ method: 'selectListObjectValues',
8920
+ params: ['/qListObjectDef', elemNumbersToSelect, toggle]
8921
+ });
8922
+ success = response !== false;
8923
+ } catch (_unused) {
8924
+ success = false;
8925
+ }
8926
+ if (!success) {
8927
+ if (isSingleSelect) {
8928
+ selections.cancel(); // revert selection
8929
+ } else {
8930
+ selections.clear();
8931
+ }
8932
+ }
8920
8933
  }
8921
- return resolved;
8934
+ return success;
8922
8935
  }
8923
8936
  function getElemNumbersFromPages(pages) {
8924
8937
  if (!pages || !pages.length) {
@@ -8981,126 +8994,132 @@ function fillRange(elementNbrs, elemNumbersOrdered) {
8981
8994
  return elemNumbersOrdered.slice(min, max + 1);
8982
8995
  }
8983
8996
 
8997
+ const getKeyAsToggleSelected = event => !(event.metaKey || event.ctrlKey);
8984
8998
  function useSelectionsInteractions(_ref) {
8985
8999
  let {
8986
- layout,
9000
+ selectionState,
8987
9001
  selections,
8988
- pages = [],
8989
9002
  checkboxes = false,
8990
- selectDisabled,
8991
- doc = document,
8992
- isSingleSelect: singleSelect = false
9003
+ doc = document
8993
9004
  } = _ref;
8994
- const [instantPages, setInstantPages] = useState$1(pages);
8995
- const [mouseDown, setMouseDown] = useState$1(false);
8996
- const [selectingValues, setSelectingValues] = useState$1(false);
8997
- const [isSingleSelect, setIsSingleSelect] = useState$1(singleSelect);
8998
- const [selected, setSelected] = useState$1([]);
8999
- const [isRangeSelection, setIsRangeSelection] = useState$1(false);
9000
- const [preSelected, setPreSelected] = useState$1([]);
9001
- const elemNumbersOrdered = getElemNumbersFromPages(pages);
9002
- useEffect$1(() => {
9003
- setIsSingleSelect(singleSelect);
9004
- }, [singleSelect]);
9005
+ const currentSelect = useRef({
9006
+ startElemNumber: undefined,
9007
+ elemNumbers: [],
9008
+ isRange: false,
9009
+ toggle: false,
9010
+ active: false
9011
+ });
9005
9012
 
9006
- // Select values for real, by calling the backend.
9007
- const select = async function () {
9008
- let elemNumbers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
9009
- let additive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
9010
- if (selectDisabled()) {
9011
- return;
9012
- }
9013
- setSelectingValues(true);
9014
- const filtered = additive ? elemNumbers.filter(n => !selected.includes(n)) : elemNumbers;
9015
- await selectValues({
9013
+ // eslint-disable-next-line arrow-body-style
9014
+ const doSelect = () => {
9015
+ selectionState.setSelectableValuesUpdating();
9016
+ return selectValues({
9016
9017
  selections,
9017
- elemNumbers: filtered,
9018
- isSingleSelect
9018
+ elemNumbers: currentSelect.current.elemNumbers,
9019
+ isSingleSelect: selectionState.isSingleSelect,
9020
+ toggle: currentSelect.current.toggle
9019
9021
  });
9020
- setSelectingValues(false);
9021
- setPreSelected([]);
9022
9022
  };
9023
-
9024
- // Show estimated selection states instantly before applying the selections for real.
9025
- const preSelect = function (elemNumbers) {
9026
- let additive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
9027
- if (selectDisabled()) {
9023
+ const addToRange = elemNumber => {
9024
+ const {
9025
+ startElemNumber
9026
+ } = currentSelect.current;
9027
+ if (startElemNumber === elemNumber) {
9028
9028
  return;
9029
9029
  }
9030
- setPreSelected(existing => {
9031
- const uniques = getUniques([...existing, ...elemNumbers]);
9032
- const filtered = additive ? uniques.filter(n => !selected.includes(n)) : uniques;
9033
- const filled = additive ? fillRange(uniques, elemNumbersOrdered) : filtered;
9034
- return filled;
9035
- });
9030
+ const rangeEnds = [currentSelect.current.startElemNumber, elemNumber];
9031
+ const elemNumbersOrdered = getElemNumbersFromPages(selectionState.enginePages);
9032
+ const toMaybeAdd = fillRange(rangeEnds, elemNumbersOrdered);
9033
+ selectionState.updateItems(toMaybeAdd, true, currentSelect.current.elemNumbers);
9036
9034
  };
9037
9035
  const selectManually = function () {
9038
9036
  let elementIds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
9039
9037
  let additive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
9040
- setIsRangeSelection(false); // range is not supported for manual select
9041
- setMouseDown(true);
9042
- preSelect(elementIds, additive || isRangeSelection);
9043
- const p = select(elementIds, additive || isRangeSelection);
9044
- setMouseDown(false);
9045
- return p;
9038
+ const elemNumbers = [];
9039
+ selectionState.updateItems(elementIds, additive, elemNumbers);
9040
+ selectionState.setSelectableValuesUpdating();
9041
+ return selectValues({
9042
+ selections,
9043
+ elemNumbers: additive ? elemNumbers : elementIds,
9044
+ isSingleSelect: selectionState.isSingleSelect,
9045
+ toggle: !selectionState.isSingleSelect
9046
+ });
9046
9047
  };
9047
- const handleSingleSelectKey = event => {
9048
+ const handleSingleSelectKey = (event, target) => {
9048
9049
  if (event.ctrlKey || event.metaKey) {
9049
- setIsSingleSelect(true);
9050
- event.currentTarget.focus(); // will not be focused otherwise
9050
+ target.focus(); // will not be focused otherwise
9051
9051
  event.preventDefault();
9052
9052
  }
9053
9053
  };
9054
- const onClick = useCallback(event => {
9055
- if (selectingValues || selectDisabled()) {
9054
+ const onChange = useCallback(event => {
9055
+ if (selectionState.selectDisabled()) {
9056
9056
  return;
9057
9057
  }
9058
- const elemNumber = +event.currentTarget.getAttribute('data-n');
9059
- setPreSelected([elemNumber]);
9060
- handleSingleSelectKey(event);
9061
- }, [selectingValues, selectDisabled]);
9058
+ const elemNumber = +event.target.getAttribute('data-n');
9059
+ const toggle = !selectionState.isSingleSelect && getKeyAsToggleSelected(event.nativeEvent);
9060
+ currentSelect.current.elemNumbers = [elemNumber];
9061
+ currentSelect.current.toggle = toggle;
9062
+ if (!toggle) {
9063
+ selectionState.clearItemStates(true);
9064
+ }
9065
+ selectionState.updateItem(elemNumber);
9066
+ currentSelect.current.active = false;
9067
+ doSelect();
9068
+ }, []);
9062
9069
  const onMouseDown = useCallback(event => {
9063
- if (selectingValues || selectDisabled()) {
9070
+ if (selectionState.selectDisabled()) {
9064
9071
  return;
9065
9072
  }
9066
- setIsRangeSelection(false);
9067
- setMouseDown(true);
9068
9073
  const elemNumber = +event.currentTarget.getAttribute('data-n');
9069
- setPreSelected([elemNumber]);
9070
- handleSingleSelectKey(event);
9071
- }, [selectingValues, selectDisabled]);
9074
+ const toggle = !selectionState.isSingleSelect && getKeyAsToggleSelected(event);
9075
+ currentSelect.current.isRange = false;
9076
+ currentSelect.current.startElemNumber = elemNumber;
9077
+ currentSelect.current.elemNumbers = [elemNumber];
9078
+ currentSelect.current.toggle = toggle;
9079
+ currentSelect.current.active = true;
9080
+ if (!toggle) {
9081
+ selectionState.clearItemStates(true);
9082
+ }
9083
+ selectionState.updateItem(elemNumber);
9084
+ if (selectionState.isSingleSelect) {
9085
+ currentSelect.current.active = false;
9086
+ doSelect();
9087
+ }
9088
+ handleSingleSelectKey(event, event.currentTarget);
9089
+ }, []);
9072
9090
  const onMouseUp = useCallback(event => {
9073
- const elemNumber = +event.currentTarget.getAttribute('data-n');
9074
- if (isSingleSelect || !mouseDown || selectingValues || preSelected.length === 1 && preSelected[0] === elemNumber // prevent toggling again on mouseup
9075
- ) {
9091
+ if (!currentSelect.current.active) {
9076
9092
  return;
9077
9093
  }
9078
- preSelect([elemNumber]);
9079
- }, [mouseDown, selectingValues, preSelected, selected, isRangeSelection, selectDisabled]);
9094
+ currentSelect.current.active = false;
9095
+ if (currentSelect.current.isRange) {
9096
+ const elemNumber = +event.currentTarget.getAttribute('data-n');
9097
+ addToRange(elemNumber);
9098
+ }
9099
+ doSelect();
9100
+ }, []);
9080
9101
  const onMouseUpDoc = useCallback(() => {
9081
9102
  // Ensure we end interactions when mouseup happens outside the Listbox.
9082
- setMouseDown(false);
9083
- setSelectingValues(false);
9084
- setIsRangeSelection(false);
9085
- setIsSingleSelect(singleSelect);
9086
- }, [singleSelect]);
9087
- const onMouseEnter = useCallback(event => {
9088
- if (isSingleSelect || !mouseDown || selectingValues || selectDisabled()) {
9103
+ if (!currentSelect.current.active) {
9089
9104
  return;
9090
9105
  }
9091
- setIsRangeSelection(true);
9092
- const elemNumber = +event.currentTarget.getAttribute('data-n');
9093
- preSelect([elemNumber], true);
9094
- }, [mouseDown, selectingValues, isRangeSelection, preSelected, selected, selectDisabled, layout && layout.qListObject.qDimensionInfo.qIsOneAndOnlyOne]);
9095
- useEffect$1(() => {
9096
- // Perform selections of pre-selected values. This can
9097
- // happen only when interactions have finished (mouseup).
9098
- const interactionIsFinished = !mouseDown;
9099
- if (!preSelected || !preSelected.length || selectingValues || !interactionIsFinished || !layout) {
9106
+ currentSelect.current.active = false;
9107
+ doSelect();
9108
+ }, []);
9109
+ const onMouseEnter = useCallback(event => {
9110
+ if (!currentSelect.current.active) {
9100
9111
  return;
9101
9112
  }
9102
- select(preSelected, isRangeSelection);
9103
- }, [preSelected, mouseDown, selectDisabled()]);
9113
+ if (!currentSelect.current.isRange) {
9114
+ currentSelect.current.isRange = true;
9115
+ if (!selectionState.isSelected(currentSelect.current.startElemNumber)) {
9116
+ selectionState.updateItem(currentSelect.current.startElemNumber, true);
9117
+ currentSelect.current.elemNumbers = [];
9118
+ }
9119
+ }
9120
+ const elemNumber = +event.currentTarget.getAttribute('data-n');
9121
+ addToRange(elemNumber);
9122
+ }, []);
9104
9123
  useEffect$1(() => {
9105
9124
  doc.addEventListener('mouseup', onMouseUpDoc);
9106
9125
  return () => {
@@ -9108,25 +9127,24 @@ function useSelectionsInteractions(_ref) {
9108
9127
  };
9109
9128
  }, [onMouseUpDoc]);
9110
9129
  useEffect$1(() => {
9111
- if (selectingValues || mouseDown) {
9112
- return;
9113
- }
9114
- // Keep track of (truely) selected fields so we can prevent toggling them on range select.
9115
- const alreadySelected = getSelectedValues(pages);
9116
- setSelected(alreadySelected);
9117
- }, [pages]);
9118
- useEffect$1(() => {
9119
- if (selectingValues || !pages || !checkboxes && !mouseDown) {
9120
- return;
9121
- }
9122
- // Render pre-selections before they have been selected in Engine.
9123
- const newPages = applySelectionsOnPages(pages, preSelected, isSingleSelect);
9124
- setInstantPages(newPages);
9125
- }, [preSelected]);
9130
+ const onDeactivated = () => {
9131
+ selectionState.clearItemStates(false);
9132
+ };
9133
+ const onCleared = () => {
9134
+ selectionState.clearItemStates(true);
9135
+ selectionState.triggerStateChanged();
9136
+ };
9137
+ selections.on('deactivated', onDeactivated);
9138
+ selections.on('cleared', onCleared);
9139
+ return () => {
9140
+ selections.removeListener('activated', onDeactivated);
9141
+ selections.removeListener('cleared', onCleared);
9142
+ };
9143
+ }, [selections]);
9126
9144
  const interactionEvents = {};
9127
9145
  if (checkboxes) {
9128
9146
  Object.assign(interactionEvents, {
9129
- onClick
9147
+ onChange
9130
9148
  });
9131
9149
  } else {
9132
9150
  Object.assign(interactionEvents, {
@@ -9136,7 +9154,6 @@ function useSelectionsInteractions(_ref) {
9136
9154
  });
9137
9155
  }
9138
9156
  return {
9139
- instantPages,
9140
9157
  interactionEvents,
9141
9158
  select: selectManually // preselect and select without having to trigger an event
9142
9159
  };
@@ -9483,6 +9500,34 @@ const excludedOrAlternative = _ref => {
9483
9500
  } = _ref;
9484
9501
  return (isAlternative(cell) || isExcluded(cell)) && checkboxes;
9485
9502
  };
9503
+ const getValueStateClasses = _ref2 => {
9504
+ let {
9505
+ column,
9506
+ histogram,
9507
+ checkboxes,
9508
+ cell,
9509
+ showGray
9510
+ } = _ref2;
9511
+ const clazzArr = [column ? rowColClasses.column : rowColClasses.row];
9512
+ if (!histogram) {
9513
+ clazzArr.push(rowColClasses.rowBorderBottom);
9514
+ }
9515
+ if (!cell) {
9516
+ return [];
9517
+ }
9518
+ if (!checkboxes) {
9519
+ if (cell.qState === 'XS') {
9520
+ clazzArr.push(showGray ? rowColClasses.XS : rowColClasses.S);
9521
+ } else if (cell.qState === 'S' || cell.qState === 'L') {
9522
+ clazzArr.push(rowColClasses.S);
9523
+ } else if (showGray && isAlternative(cell)) {
9524
+ clazzArr.push(rowColClasses.A);
9525
+ } else if (showGray && isExcluded(cell)) {
9526
+ clazzArr.push(rowColClasses.X);
9527
+ }
9528
+ }
9529
+ return clazzArr;
9530
+ };
9486
9531
 
9487
9532
  const frequencyTextNone = '-';
9488
9533
  const barPadPx = 4;
@@ -9513,6 +9558,9 @@ const getFrequencyText = _ref2 => {
9513
9558
  return '';
9514
9559
  };
9515
9560
 
9561
+ const ICON_PADDING = 7;
9562
+ const CELL_PADDING_LEFT = 9;
9563
+
9516
9564
  const getSelectedStyle = _ref => {
9517
9565
  let {
9518
9566
  theme
@@ -9532,10 +9580,11 @@ const getSelectedStyle = _ref => {
9532
9580
  const ellipsis = {
9533
9581
  width: '100%',
9534
9582
  overflow: 'hidden',
9535
- textOverflow: 'ellipsis'
9583
+ textOverflow: 'ellipsis',
9584
+ whiteSpace: 'nowrap'
9536
9585
  };
9537
9586
  const RowColRoot = styled$1('div', {
9538
- shouldForwardProp: prop => !['flexBasisProp', 'isGridMode', 'isGridCol', 'dense'].includes(prop)
9587
+ shouldForwardProp: prop => !['flexBasisProp', 'isGridMode', 'isGridCol', 'dense', 'frequencyWidth'].includes(prop)
9539
9588
  })(_ref2 => {
9540
9589
  var _theme$listBox$conten, _theme$listBox, _theme$listBox$conten2, _theme$listBox$conten3, _theme$listBox2, _theme$listBox2$conte, _theme$listBox3, _theme$listBox3$conte, _theme$listBox4, _theme$listBox4$conte;
9541
9590
  let {
@@ -9543,7 +9592,8 @@ const RowColRoot = styled$1('div', {
9543
9592
  flexBasisProp,
9544
9593
  isGridMode,
9545
9594
  isGridCol,
9546
- dense
9595
+ dense,
9596
+ frequencyWidth
9547
9597
  } = _ref2;
9548
9598
  return {
9549
9599
  '&:focus': {
@@ -9572,18 +9622,18 @@ const RowColRoot = styled$1('div', {
9572
9622
  minWidth: 0,
9573
9623
  flexGrow: 1,
9574
9624
  // Note that this padding is overridden when using checkboxes.
9575
- paddingLeft: '9px',
9576
- paddingRight: '9px'
9625
+ paddingLeft: "".concat(CELL_PADDING_LEFT, "px"),
9626
+ paddingRight: 0
9577
9627
  },
9578
9628
  // The leaf node, containing the label text.
9579
9629
  ["& .".concat(rowColClasses.labelText)]: _objectSpread2(_objectSpread2({
9580
9630
  flexBasis: flexBasisProp,
9581
9631
  lineHeight: '16px',
9582
9632
  userSelect: 'none',
9633
+ paddingRight: '1px'
9634
+ }, ellipsis), {}, {
9583
9635
  whiteSpace: 'pre',
9584
9636
  // to keep white-space on highlight
9585
- paddingRight: '9px'
9586
- }, ellipsis), {}, {
9587
9637
  fontSize: (_theme$listBox3 = theme.listBox) === null || _theme$listBox3 === void 0 ? void 0 : (_theme$listBox3$conte = _theme$listBox3.content) === null || _theme$listBox3$conte === void 0 ? void 0 : _theme$listBox3$conte.fontSize,
9588
9638
  fontFamily: (_theme$listBox4 = theme.listBox) === null || _theme$listBox4 === void 0 ? void 0 : (_theme$listBox4$conte = _theme$listBox4.content) === null || _theme$listBox4$conte === void 0 ? void 0 : _theme$listBox4$conte.fontFamily
9589
9639
  }),
@@ -9621,7 +9671,10 @@ const RowColRoot = styled$1('div', {
9621
9671
  // The icons container holding tick and lock, shown inside fields.
9622
9672
  ["& .".concat(rowColClasses.icon)]: {
9623
9673
  display: 'flex',
9624
- padding: theme.spacing(1, 1, 1, 0)
9674
+ justifyContent: 'center',
9675
+ width: 24,
9676
+ minWidth: 24,
9677
+ maxWidth: 24
9625
9678
  },
9626
9679
  // Selection styles (S=Selected, XS=ExcludedSelected, A=Available, X=Excluded).
9627
9680
  ["& .".concat(rowColClasses.S)]: _objectSpread2(_objectSpread2({}, getSelectedStyle({
@@ -9646,10 +9699,13 @@ const RowColRoot = styled$1('div', {
9646
9699
  color: theme.palette.selected.excludedContrastText,
9647
9700
  border: isGridMode ? 'none' : undefined
9648
9701
  },
9649
- ["& .".concat(rowColClasses.frequencyCount)]: {
9650
- width: '66px',
9702
+ ["& .".concat(rowColClasses.frequencyCount)]: _objectSpread2(_objectSpread2({
9651
9703
  justifyContent: 'flex-end'
9652
- },
9704
+ }, ellipsis), {}, {
9705
+ flex: "0 1 ".concat(frequencyWidth, "px"),
9706
+ textAlign: 'right',
9707
+ paddingLeft: '2px'
9708
+ }),
9653
9709
  ["&.".concat(rowColClasses.barContainer)]: {
9654
9710
  height: '100%',
9655
9711
  display: 'flex',
@@ -9684,6 +9740,7 @@ const RowColRoot = styled$1('div', {
9684
9740
  }
9685
9741
  };
9686
9742
  });
9743
+ var RowColRoot$1 = React__default.memo(RowColRoot);
9687
9744
 
9688
9745
  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\")";
9689
9746
 
@@ -9759,19 +9816,23 @@ const getIcon = function (cls) {
9759
9816
  };
9760
9817
  function ListboxCheckbox(_ref2) {
9761
9818
  let {
9819
+ onChange,
9762
9820
  checked,
9763
9821
  label,
9764
9822
  dense,
9765
9823
  excluded,
9766
- showGray = true
9824
+ showGray = true,
9825
+ dataN
9767
9826
  } = _ref2;
9768
9827
  return /*#__PURE__*/React__default.createElement(StyledCheckbox, {
9769
9828
  edge: "start",
9829
+ onChange: onChange,
9770
9830
  checked: checked,
9771
9831
  disableRipple: true,
9772
9832
  className: [classes$b.checkbox, dense && classes$b.dense].filter(Boolean).join(' '),
9773
9833
  inputProps: {
9774
- 'aria-labelledby': label
9834
+ 'aria-labelledby': label,
9835
+ 'data-n': dataN
9775
9836
  },
9776
9837
  name: label,
9777
9838
  icon: getIcon(classes$b, showGray, excluded),
@@ -9800,15 +9861,21 @@ const StyledRadio = styled$1(Radio)(_ref => {
9800
9861
  });
9801
9862
  function ListBoxRadioButton(_ref2) {
9802
9863
  let {
9864
+ onChange,
9803
9865
  checked,
9804
9866
  label,
9805
- dense
9867
+ dense,
9868
+ dataN
9806
9869
  } = _ref2;
9807
9870
  return /*#__PURE__*/React__default.createElement(StyledRadio, {
9808
9871
  checked: checked,
9872
+ onChange: onChange,
9809
9873
  value: label,
9810
9874
  name: label,
9811
9875
  className: classes$a.radioButton,
9876
+ inputProps: {
9877
+ 'data-n': dataN
9878
+ },
9812
9879
  style: {
9813
9880
  backgroundColor: 'transparent'
9814
9881
  },
@@ -9839,7 +9906,7 @@ function ValueField(_ref) {
9839
9906
  checkboxes
9840
9907
  }) && rowColClasses.excludedTextWithCheckbox]),
9841
9908
  color: color,
9842
- justifyContent: valueTextAlign
9909
+ align: valueTextAlign
9843
9910
  }, /*#__PURE__*/React__default.createElement("span", {
9844
9911
  style: {
9845
9912
  whiteSpace: 'pre'
@@ -9875,6 +9942,7 @@ function LabelTag(_ref) {
9875
9942
 
9876
9943
  function CheckboxField(_ref) {
9877
9944
  let {
9945
+ onChange,
9878
9946
  label,
9879
9947
  color,
9880
9948
  qElemNumber,
@@ -9889,17 +9957,21 @@ function CheckboxField(_ref) {
9889
9957
  valueTextAlign
9890
9958
  } = _ref;
9891
9959
  const cb = /*#__PURE__*/React__default.createElement(ListboxCheckbox, {
9960
+ onChange: onChange,
9892
9961
  label: label,
9893
9962
  checked: isSelected,
9894
9963
  dense: dense,
9895
9964
  excluded: isExcluded(cell),
9896
9965
  isGridCol: isGridCol,
9897
- showGray: showGray
9966
+ showGray: showGray,
9967
+ dataN: qElemNumber
9898
9968
  });
9899
9969
  const rb = /*#__PURE__*/React__default.createElement(ListBoxRadioButton, {
9970
+ onChange: onChange,
9900
9971
  label: label,
9901
9972
  checked: isSelected,
9902
- dense: dense
9973
+ dense: dense,
9974
+ dataN: qElemNumber
9903
9975
  });
9904
9976
  return /*#__PURE__*/React__default.createElement(FormControlLabel, {
9905
9977
  color: color,
@@ -9926,11 +9998,12 @@ function LabelsWithRanges(_ref) {
9926
9998
  showGray,
9927
9999
  checkboxes
9928
10000
  } = _ref;
9929
- return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, labels.map(_ref2 => {
10001
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, labels.map((_ref2, index) => {
9930
10002
  let [label, highlighted] = _ref2;
10003
+ const key = "".concat(index);
9931
10004
  return /*#__PURE__*/React__default.createElement(ValueField, {
9932
10005
  label: label,
9933
- key: label,
10006
+ key: key,
9934
10007
  highlighted: highlighted,
9935
10008
  dense: dense,
9936
10009
  showGray: showGray,
@@ -9940,6 +10013,7 @@ function LabelsWithRanges(_ref) {
9940
10013
  }
9941
10014
  function FieldWithRanges(_ref3) {
9942
10015
  let {
10016
+ onChange,
9943
10017
  labels,
9944
10018
  checkboxes,
9945
10019
  dense,
@@ -9959,6 +10033,7 @@ function FieldWithRanges(_ref3) {
9959
10033
  checkboxes: checkboxes
9960
10034
  });
9961
10035
  return checkboxes ? /*#__PURE__*/React__default.createElement(CheckboxField, {
10036
+ onChange: onChange,
9962
10037
  label: LWR,
9963
10038
  color: color,
9964
10039
  qElemNumber: qElemNumber,
@@ -9975,6 +10050,7 @@ function FieldWithRanges(_ref3) {
9975
10050
 
9976
10051
  function Field(_ref) {
9977
10052
  let {
10053
+ onChange,
9978
10054
  label,
9979
10055
  color,
9980
10056
  qElemNumber,
@@ -9989,6 +10065,7 @@ function Field(_ref) {
9989
10065
  valueTextAlign
9990
10066
  } = _ref;
9991
10067
  return checkboxes ? /*#__PURE__*/React__default.createElement(CheckboxField, {
10068
+ onChange: onChange,
9992
10069
  label: label,
9993
10070
  color: color,
9994
10071
  qElemNumber: qElemNumber,
@@ -10012,6 +10089,7 @@ function Field(_ref) {
10012
10089
  valueTextAlign: valueTextAlign
10013
10090
  });
10014
10091
  }
10092
+ var Field$1 = React__default.memo(Field);
10015
10093
 
10016
10094
  function Histogram(_ref) {
10017
10095
  let {
@@ -10084,12 +10162,16 @@ function getGridItemSizes(_ref) {
10084
10162
  case 'row':
10085
10163
  return {
10086
10164
  height: "calc(100% - ".concat(itemPadding, "px)"),
10087
- width: "calc(100% - ".concat(2 * itemPadding, "px)")
10165
+ width: "calc(100% - ".concat(2 * itemPadding, "px)"),
10166
+ position: 'absolute',
10167
+ left: 4
10088
10168
  };
10089
10169
  case 'column':
10090
10170
  return {
10091
10171
  height: "calc(100% - ".concat(itemPadding, "px)"),
10092
- width: "calc(100% - ".concat(2 * itemPadding, "px)")
10172
+ width: "calc(100% - ".concat(2 * itemPadding, "px)"),
10173
+ position: 'absolute',
10174
+ left: 4
10093
10175
  };
10094
10176
  default:
10095
10177
  return {};
@@ -10097,24 +10179,43 @@ function getGridItemSizes(_ref) {
10097
10179
  }
10098
10180
 
10099
10181
  const ItemGrid = styled$1(Grid, {
10100
- shouldForwardProp: prop => !['dataLayout', 'layoutOrder', 'itemPadding'].includes(prop)
10182
+ shouldForwardProp: prop => !['dataLayout', 'layoutOrder', 'itemPadding', 'checkboxes'].includes(prop)
10101
10183
  })(_ref => {
10102
10184
  let {
10103
10185
  dataLayout,
10104
10186
  layoutOrder,
10105
- itemPadding
10187
+ itemPadding,
10188
+ checkboxes
10106
10189
  } = _ref;
10107
10190
  return {
10108
- ["&.".concat(rowColClasses.fieldRoot)]: getGridItemSizes({
10191
+ ["&.".concat(rowColClasses.fieldRoot)]: _objectSpread2(_objectSpread2({}, getGridItemSizes({
10109
10192
  dataLayout,
10110
10193
  layoutOrder,
10111
10194
  itemPadding
10195
+ })), {}, {
10196
+ paddingRight: checkboxes ? '8px' : undefined
10112
10197
  })
10113
10198
  };
10114
10199
  });
10115
10200
 
10201
+ function getCellFromPages(_ref) {
10202
+ let {
10203
+ pages,
10204
+ cellIndex
10205
+ } = _ref;
10206
+ let c;
10207
+ const page = pages.filter(p => p.qArea.qTop <= cellIndex && cellIndex < p.qArea.qTop + p.qArea.qHeight)[0];
10208
+ if (page) {
10209
+ const area = page.qArea;
10210
+ if (cellIndex >= area.qTop && cellIndex < area.qTop + area.qHeight) {
10211
+ [c] = page.qMatrix[cellIndex - area.qTop];
10212
+ }
10213
+ }
10214
+ return c;
10215
+ }
10216
+
10116
10217
  function RowColumn(_ref) {
10117
- var _cell$qText;
10218
+ var _cell$qText, _cell$qHighlightRange, _cell$qHighlightRange2;
10118
10219
  let {
10119
10220
  index,
10120
10221
  rowIndex,
@@ -10123,6 +10224,7 @@ function RowColumn(_ref) {
10123
10224
  data
10124
10225
  } = _ref;
10125
10226
  const {
10227
+ onChange,
10126
10228
  onClick,
10127
10229
  onMouseDown,
10128
10230
  onMouseUp,
@@ -10146,7 +10248,8 @@ function RowColumn(_ref) {
10146
10248
  dataOffset,
10147
10249
  focusListItems,
10148
10250
  listCount,
10149
- itemPadding
10251
+ itemPadding,
10252
+ frequencyWidth
10150
10253
  } = data;
10151
10254
  const {
10152
10255
  dense = false,
@@ -10198,44 +10301,25 @@ function RowColumn(_ref) {
10198
10301
  const handleKeyDownCallback = useCallback(getFieldKeyboardNavigation(_objectSpread2(_objectSpread2({}, actions), {}, {
10199
10302
  focusListItems
10200
10303
  })), [actions]);
10201
- const [isSelected, setSelected] = useState$1(false);
10202
- const [cell, setCell] = useState$1();
10203
- const [classArr, setClassArr] = useState$1([]);
10204
- useEffect$1(() => {
10205
- if (!pages) {
10206
- return;
10207
- }
10208
- let c;
10209
- const page = pages.filter(p => p.qArea.qTop <= cellIndex && cellIndex < p.qArea.qTop + p.qArea.qHeight)[0];
10210
- if (page) {
10211
- const area = page.qArea;
10212
- if (cellIndex >= area.qTop && cellIndex < area.qTop + area.qHeight) {
10213
- [c] = page.qMatrix[cellIndex - area.qTop];
10214
- }
10215
- }
10216
- setCell(c);
10217
- }, [pages]);
10218
- useEffect$1(() => {
10219
- if (!cell) {
10220
- return;
10221
- }
10222
- const selected = cell.qState === 'S' || cell.qState === 'XS' || cell.qState === 'L';
10223
- setSelected(selected);
10224
- const clazzArr = [column ? rowColClasses.column : rowColClasses.row];
10225
- if (!(histogram && (dense || checkboxes))) clazzArr.push(rowColClasses.rowBorderBottom);
10226
- if (!checkboxes) {
10227
- if (cell.qState === 'XS') {
10228
- clazzArr.push(showGray ? rowColClasses.XS : rowColClasses.S);
10229
- } else if (cell.qState === 'S' || cell.qState === 'L') {
10230
- clazzArr.push(rowColClasses.S);
10231
- } else if (showGray && isAlternative(cell)) {
10232
- clazzArr.push(rowColClasses.A);
10233
- } else if (showGray && isExcluded(cell)) {
10234
- clazzArr.push(rowColClasses.X);
10235
- }
10304
+ const cell = useMemo$1(() => getCellFromPages({
10305
+ pages,
10306
+ cellIndex
10307
+ }), [pages, cellIndex]);
10308
+ const isSelected = (cell === null || cell === void 0 ? void 0 : cell.qState) === 'S' || (cell === null || cell === void 0 ? void 0 : cell.qState) === 'XS' || (cell === null || cell === void 0 ? void 0 : cell.qState) === 'L';
10309
+ const classArr = useMemo$1(() => getValueStateClasses({
10310
+ column,
10311
+ histogram,
10312
+ checkboxes,
10313
+ cell,
10314
+ showGray
10315
+ }), [cell === null || cell === void 0 ? void 0 : cell.qState, histogram, dense, checkboxes]);
10316
+ const preventContextMenu = useCallback(event => {
10317
+ if (checkboxes) {
10318
+ // Event will not propagate in the checkbox/radiobutton case
10319
+ onClick(event);
10236
10320
  }
10237
- setClassArr(clazzArr);
10238
- }, [cell && cell.qState, histogram, dense, checkboxes]);
10321
+ event.preventDefault();
10322
+ }, [checkboxes]);
10239
10323
  if (!cell) {
10240
10324
  return null; // prevent rendering empty rows
10241
10325
  }
@@ -10252,19 +10336,16 @@ function RowColumn(_ref) {
10252
10336
  } else {
10253
10337
  valueTextAlign = (textAlign === null || textAlign === void 0 ? void 0 : textAlign.align) || 'left';
10254
10338
  }
10255
- const preventContextMenu = event => {
10256
- if (checkboxes) {
10257
- // Event will not propagate in the checkbox/radiobutton case
10258
- onClick(event);
10259
- }
10260
- event.preventDefault();
10261
- };
10262
10339
  const isGridCol = dataLayout === 'grid' && layoutOrder === 'column';
10263
10340
  const label = (_cell$qText = cell === null || cell === void 0 ? void 0 : cell.qText) !== null && _cell$qText !== void 0 ? _cell$qText : '';
10264
10341
 
10265
10342
  // Search highlights. Split up labelText span into several and add the highlighted class to matching sub-strings.
10266
- const ranges = cell && cell.qHighlightRanges && cell.qHighlightRanges.qRanges.sort((a, b) => a.qCharPos - b.qCharPos) || [];
10267
- const labels = getSegmentsFromRanges(label, ranges);
10343
+
10344
+ let labels;
10345
+ if ((_cell$qHighlightRange = cell.qHighlightRanges) !== null && _cell$qHighlightRange !== void 0 && (_cell$qHighlightRange2 = _cell$qHighlightRange.qRanges) !== null && _cell$qHighlightRange2 !== void 0 && _cell$qHighlightRange2.length) {
10346
+ const ranges = cell.qHighlightRanges.qRanges.sort((a, b) => a.qCharPos - b.qCharPos) || [];
10347
+ labels = getSegmentsFromRanges(label, ranges);
10348
+ }
10268
10349
  const iconStyles = {
10269
10350
  alignItems: 'center',
10270
10351
  display: 'flex',
@@ -10277,22 +10358,24 @@ function RowColumn(_ref) {
10277
10358
  alignItems: 'center',
10278
10359
  minWidth: 0,
10279
10360
  flexGrow: 1,
10280
- padding: checkboxes ? 0 : undefined,
10361
+ paddingLeft: checkboxes ? 0 : undefined,
10281
10362
  justifyContent: valueTextAlign
10282
10363
  };
10283
10364
  const isFirstElement = index === 0;
10284
10365
  const flexBasisVal = checkboxes ? 'auto' : 'max-content';
10285
- return /*#__PURE__*/React__default.createElement(RowColRoot, {
10366
+ return /*#__PURE__*/React__default.createElement(RowColRoot$1, {
10286
10367
  className: rowColClasses.barContainer,
10287
10368
  flexBasisProp: flexBasisVal,
10288
10369
  style: styles,
10289
10370
  isGridCol: isGridCol,
10290
10371
  isGridMode: dataLayout === 'grid',
10291
- dense: dense
10372
+ dense: dense,
10373
+ frequencyWidth: frequencyWidth
10292
10374
  }, /*#__PURE__*/React__default.createElement(ItemGrid, {
10293
10375
  ref: rowRef,
10294
10376
  container: true,
10295
10377
  dataLayout: dataLayout,
10378
+ checkboxes: checkboxes,
10296
10379
  layoutOrder: layoutOrder,
10297
10380
  itemPadding: itemPadding,
10298
10381
  gap: 0,
@@ -10308,7 +10391,7 @@ function RowColumn(_ref) {
10308
10391
  onContextMenu: preventContextMenu,
10309
10392
  role: column ? 'column' : 'row',
10310
10393
  tabIndex: isFirstElement && (!keyboard.enabled || keyboard.active) ? 0 : -1,
10311
- "data-n": cell && cell.qElemNumber
10394
+ "data-n": cell === null || cell === void 0 ? void 0 : cell.qElemNumber
10312
10395
  }, /*#__PURE__*/React__default.createElement(Histogram, {
10313
10396
  cell: cell,
10314
10397
  histogram: histogram,
@@ -10320,18 +10403,8 @@ function RowColumn(_ref) {
10320
10403
  style: cellStyle,
10321
10404
  className: joinClassNames([rowColClasses.cell, rowColClasses.selectedCell]),
10322
10405
  title: "".concat(label)
10323
- }, ranges.length === 0 ? /*#__PURE__*/React__default.createElement(Field, {
10324
- label: label,
10325
- color: "inherit",
10326
- qElemNumber: cell.qElemNumber,
10327
- isSelected: isSelected,
10328
- dense: dense,
10329
- cell: cell,
10330
- isGridCol: isGridCol,
10331
- showGray: showGray,
10332
- isSingleSelect: isSingleSelect,
10333
- checkboxes: checkboxes
10334
- }) : /*#__PURE__*/React__default.createElement(FieldWithRanges, {
10406
+ }, labels ? /*#__PURE__*/React__default.createElement(FieldWithRanges, {
10407
+ onChange: onChange,
10335
10408
  labels: labels,
10336
10409
  checkboxes: checkboxes,
10337
10410
  dense: dense,
@@ -10344,6 +10417,19 @@ function RowColumn(_ref) {
10344
10417
  isGridCol: isGridCol,
10345
10418
  isSingleSelect: isSingleSelect,
10346
10419
  valueTextAlign: valueTextAlign
10420
+ }) : /*#__PURE__*/React__default.createElement(Field$1, {
10421
+ onChange: onChange,
10422
+ label: label,
10423
+ color: "inherit",
10424
+ qElemNumber: cell.qElemNumber,
10425
+ isSelected: isSelected,
10426
+ dense: dense,
10427
+ cell: cell,
10428
+ isGridCol: isGridCol,
10429
+ showGray: showGray,
10430
+ isSingleSelect: isSingleSelect,
10431
+ checkboxes: checkboxes,
10432
+ valueTextAlign: valueTextAlign
10347
10433
  })), freqIsAllowed && /*#__PURE__*/React__default.createElement(Frequency, {
10348
10434
  cell: cell,
10349
10435
  checkboxes: checkboxes,
@@ -10365,21 +10451,6 @@ function RowColumn(_ref) {
10365
10451
  }))));
10366
10452
  }
10367
10453
 
10368
- const FREQUENCY_MIN_SHOW_WIDTH = 80;
10369
- function getFrequencyAllowed(_ref) {
10370
- let {
10371
- width,
10372
- layout,
10373
- frequencyMode
10374
- } = _ref;
10375
- const widthPermitsFreq = width > FREQUENCY_MIN_SHOW_WIDTH;
10376
- const {
10377
- frequencyEnabled = false
10378
- } = (layout === null || layout === void 0 ? void 0 : layout.qListObject) || {};
10379
- const hasValidFreqOption = !['none', undefined].includes(frequencyMode);
10380
- return !!(widthPermitsFreq && (hasValidFreqOption || frequencyEnabled));
10381
- }
10382
-
10383
10454
  function deriveRenderOptions(options) {
10384
10455
  const {
10385
10456
  renderProps,
@@ -11826,8 +11897,9 @@ const classes$9 = {
11826
11897
  styledScrollbars: "".concat(PREFIX$9, "-styledScrollbars")
11827
11898
  };
11828
11899
  function getStyledComponents() {
11829
- const scrollbarStyling = {
11900
+ const getScrollbarStyling = scrollDisabled => ({
11830
11901
  scrollbarColor: "".concat(scrollBarThumb, " ").concat(scrollBarBackground),
11902
+ overflow: scrollDisabled ? 'hidden !important' : undefined,
11831
11903
  '&::-webkit-scrollbar': {
11832
11904
  width: 10,
11833
11905
  height: 10
@@ -11842,42 +11914,27 @@ function getStyledComponents() {
11842
11914
  '&::-webkit-scrollbar-thumb:hover': {
11843
11915
  backgroundColor: scrollBarThumbHover
11844
11916
  }
11845
- };
11846
- const StyledFixedSizeList = styled$3(FixedSizeList)(() => ({
11847
- ["&.".concat(classes$9.styledScrollbars)]: scrollbarStyling,
11848
- // TODO: Verify these props and make generic together with grid component.
11849
- '&::-webkit-scrollbar': {
11850
- width: 10,
11851
- height: 10
11852
- },
11853
- '&::-webkit-scrollbar-track': {
11854
- backgroundColor: scrollBarBackground
11855
- },
11856
- '&::-webkit-scrollbar-thumb': {
11857
- backgroundColor: scrollBarThumb,
11858
- borderRadius: '1rem'
11859
- },
11860
- '&::-webkit-scrollbar-thumb:hover': {
11861
- backgroundColor: scrollBarThumbHover
11862
- }
11863
- }));
11864
- const StyledFixedSizeGrid = styled$3(FixedSizeGrid)(() => ({
11865
- ["&.".concat(classes$9.styledScrollbars)]: scrollbarStyling,
11866
- '&::-webkit-scrollbar': {
11867
- width: 10,
11868
- height: 10
11869
- },
11870
- '&::-webkit-scrollbar-track': {
11871
- backgroundColor: scrollBarBackground
11872
- },
11873
- '&::-webkit-scrollbar-thumb': {
11874
- backgroundColor: scrollBarThumb,
11875
- borderRadius: '1rem'
11876
- },
11877
- '&::-webkit-scrollbar-thumb:hover': {
11878
- backgroundColor: scrollBarThumbHover
11879
- }
11880
- }));
11917
+ });
11918
+ const StyledFixedSizeList = styled$3(FixedSizeList, {
11919
+ shouldForwardProp: prop => prop !== 'scrollDisabled'
11920
+ })(_ref => {
11921
+ let {
11922
+ scrollDisabled
11923
+ } = _ref;
11924
+ return {
11925
+ ["&.".concat(classes$9.styledScrollbars)]: getScrollbarStyling(scrollDisabled)
11926
+ };
11927
+ });
11928
+ const StyledFixedSizeGrid = styled$3(FixedSizeGrid, {
11929
+ shouldForwardProp: prop => prop !== 'scrollDisabled'
11930
+ })(_ref2 => {
11931
+ let {
11932
+ scrollDisabled
11933
+ } = _ref2;
11934
+ return {
11935
+ ["&.".concat(classes$9.styledScrollbars)]: getScrollbarStyling(scrollDisabled)
11936
+ };
11937
+ });
11881
11938
  return {
11882
11939
  StyledFixedSizeList,
11883
11940
  StyledFixedSizeGrid
@@ -11943,13 +12000,14 @@ function getListBoxComponents(_ref) {
11943
12000
  showGray,
11944
12001
  scrollState,
11945
12002
  direction,
11946
- listLayout,
11947
12003
  sizes,
11948
12004
  listCount,
11949
12005
  overflowDisclaimer,
11950
12006
  setScrollPosition,
11951
12007
  focusListItems,
11952
- setCurrentScrollIndex
12008
+ setCurrentScrollIndex,
12009
+ constraints,
12010
+ freqIsAllowed
11953
12011
  } = _ref;
11954
12012
  const {
11955
12013
  layoutOptions = {},
@@ -11960,7 +12018,8 @@ function getListBoxComponents(_ref) {
11960
12018
  listHeight,
11961
12019
  itemSize,
11962
12020
  rowCount,
11963
- columnCount
12021
+ columnCount,
12022
+ frequencyWidth
11964
12023
  } = sizes || {};
11965
12024
 
11966
12025
  // Options common for List and Grid.
@@ -11980,14 +12039,11 @@ function getListBoxComponents(_ref) {
11980
12039
  checkboxes,
11981
12040
  layoutOptions,
11982
12041
  frequencyMode,
11983
- freqIsAllowed: getFrequencyAllowed({
11984
- width,
11985
- layout,
11986
- frequencyMode
11987
- }),
12042
+ freqIsAllowed,
11988
12043
  isSingleSelect,
11989
12044
  textAlign,
11990
12045
  itemPadding,
12046
+ frequencyWidth,
11991
12047
  actions: {
11992
12048
  select,
11993
12049
  confirm: () => selections === null || selections === void 0 ? void 0 : selections.confirm.call(selections),
@@ -12012,10 +12068,10 @@ function getListBoxComponents(_ref) {
12012
12068
  // eslint-disable-next-line react/jsx-props-no-spreading
12013
12069
  , _extends$6({}, commonComponentOptions, {
12014
12070
  dataTestid: "fixed-size-list",
12071
+ scrollDisabled: constraints === null || constraints === void 0 ? void 0 : constraints.active,
12015
12072
  height: listHeight,
12016
12073
  width: width,
12017
12074
  itemCount: listCount,
12018
- layout: listLayout,
12019
12075
  itemData: _objectSpread2(_objectSpread2({}, commonItemData), {}, {
12020
12076
  listCount
12021
12077
  }),
@@ -12090,6 +12146,7 @@ function getListBoxComponents(_ref) {
12090
12146
  // eslint-disable-next-line react/jsx-props-no-spreading
12091
12147
  , _extends$6({}, commonComponentOptions, {
12092
12148
  dataTestid: "fixed-size-grid",
12149
+ scrollDisabled: constraints === null || constraints === void 0 ? void 0 : constraints.active,
12093
12150
  height: gridHeight,
12094
12151
  width: width,
12095
12152
  columnCount: columnCount,
@@ -12114,6 +12171,9 @@ function getListBoxComponents(_ref) {
12114
12171
 
12115
12172
  const scrollBarWidth = 10; // TODO: ignore this - instead set the styling only show on hover...
12116
12173
 
12174
+ const ITEM_MIN_WIDTH = 56;
12175
+ const ITEM_MAX_WIDTH = 150;
12176
+ const FREQUENCY_WIDTH = 40;
12117
12177
  function getListSizes(_ref) {
12118
12178
  let {
12119
12179
  layout,
@@ -12121,7 +12181,8 @@ function getListSizes(_ref) {
12121
12181
  height,
12122
12182
  listCount,
12123
12183
  count,
12124
- textWidth
12184
+ textWidth,
12185
+ freqIsAllowed
12125
12186
  } = _ref;
12126
12187
  const {
12127
12188
  layoutOptions = {}
@@ -12133,7 +12194,8 @@ function getListSizes(_ref) {
12133
12194
  dense,
12134
12195
  dataLayout
12135
12196
  } = layoutOptions;
12136
- const columnAutoWidth = Math.min(150, textWidth + 18);
12197
+ const frequencyAddWidth = freqIsAllowed ? FREQUENCY_WIDTH : 0;
12198
+ const columnAutoWidth = Math.max(Math.min(ITEM_MAX_WIDTH, textWidth + 18 + frequencyAddWidth), ITEM_MIN_WIDTH + frequencyAddWidth);
12137
12199
  let overflowStyling;
12138
12200
  let columnCount;
12139
12201
  let columnWidth;
@@ -12150,18 +12212,21 @@ function getListSizes(_ref) {
12150
12212
  }
12151
12213
  const listHeight = height !== null && height !== void 0 ? height : 8 * itemSize;
12152
12214
  if (layoutOrder) {
12215
+ // Modify container width to achieve the exact design with 8px margins on each side (left and right).
12216
+ let containerWidth = width;
12153
12217
  if (layoutOrder === 'row') {
12218
+ containerWidth += itemPadding * 2;
12154
12219
  overflowStyling = {
12155
12220
  overflowX: 'hidden'
12156
12221
  };
12157
12222
  const maxColumns = (maxVisibleColumns === null || maxVisibleColumns === void 0 ? void 0 : maxVisibleColumns.maxColumns) || 3;
12158
12223
  if ((maxVisibleColumns === null || maxVisibleColumns === void 0 ? void 0 : maxVisibleColumns.auto) !== false) {
12159
- columnCount = Math.min(listCount, Math.ceil((width - scrollBarWidth) / columnAutoWidth)); // TODO: smarter sizing... based on glyph count + font size etc...??
12224
+ columnCount = Math.min(listCount, Math.ceil((containerWidth - scrollBarWidth) / columnAutoWidth)); // TODO: smarter sizing... based on glyph count + font size etc...??
12160
12225
  } else {
12161
12226
  columnCount = Math.min(listCount, maxColumns);
12162
12227
  }
12163
12228
  rowCount = Math.ceil(listCount / columnCount);
12164
- columnWidth = (width - scrollBarWidth) / columnCount;
12229
+ columnWidth = (containerWidth - scrollBarWidth) / columnCount;
12165
12230
  } else {
12166
12231
  overflowStyling = {
12167
12232
  overflowY: 'hidden'
@@ -12173,7 +12238,7 @@ function getListSizes(_ref) {
12173
12238
  rowCount = Math.min(listCount, maxRows);
12174
12239
  }
12175
12240
  columnCount = Math.ceil(listCount / rowCount);
12176
- columnWidth = Math.max(columnAutoWidth, width / columnCount);
12241
+ columnWidth = Math.max(columnAutoWidth, containerWidth / columnCount);
12177
12242
  }
12178
12243
  }
12179
12244
  columnCount = (dataLayout === 'singleColumn' ? 1 : columnCount) || 1;
@@ -12199,7 +12264,8 @@ function getListSizes(_ref) {
12199
12264
  row: maxRowCount,
12200
12265
  column: maxColumnCount
12201
12266
  },
12202
- itemPadding
12267
+ itemPadding,
12268
+ frequencyWidth: FREQUENCY_WIDTH
12203
12269
  };
12204
12270
  }
12205
12271
 
@@ -12695,19 +12761,35 @@ function getScrollIndex(_ref) {
12695
12761
  };
12696
12762
  }
12697
12763
 
12764
+ const FREQUENCY_MIN_SHOW_WIDTH = 80;
12765
+ function getFrequencyAllowed(_ref) {
12766
+ let {
12767
+ itemWidth,
12768
+ layout,
12769
+ frequencyMode
12770
+ } = _ref;
12771
+ const widthPermitsFreq = itemWidth > FREQUENCY_MIN_SHOW_WIDTH;
12772
+ const {
12773
+ frequencyEnabled = false
12774
+ } = (layout === null || layout === void 0 ? void 0 : layout.qListObject) || {};
12775
+ const hasValidFreqOption = !['none', undefined].includes(frequencyMode);
12776
+ return !!(widthPermitsFreq && (hasValidFreqOption || frequencyEnabled));
12777
+ }
12778
+
12698
12779
  const _excluded$4 = ["isLoadingData"];
12699
12780
  const DEFAULT_MIN_BATCH_SIZE = 100;
12700
12781
  function ListBox(_ref) {
12701
12782
  var _layout$qListObject$q, _loaderRef$current, _loaderRef$current$_l, _loaderRef$current$_l2;
12702
12783
  let {
12703
12784
  model,
12785
+ constraints,
12704
12786
  layout,
12705
12787
  selections,
12788
+ selectionState,
12706
12789
  direction,
12707
12790
  checkboxes: checkboxOption,
12708
12791
  height,
12709
12792
  width,
12710
- listLayout = 'vertical',
12711
12793
  frequencyMode,
12712
12794
  update = undefined,
12713
12795
  fetchStart = undefined,
@@ -12752,11 +12834,7 @@ function ListBox(_ref) {
12752
12834
  postProcessPages,
12753
12835
  listData
12754
12836
  }),
12755
- {
12756
- isLoadingData
12757
- } = _useItemsLoader,
12758
12837
  itemsLoader = _objectWithoutProperties(_useItemsLoader, _excluded$4);
12759
- const [pages, setPages] = useState$1([]);
12760
12838
  const {
12761
12839
  setStoreValue
12762
12840
  } = useDataStore(model);
@@ -12768,9 +12846,16 @@ function ListBox(_ref) {
12768
12846
  const showOverflowDisclaimer = show => setOverflowDisclaimer(state => _objectSpread2(_objectSpread2({}, state), {}, {
12769
12847
  show
12770
12848
  }));
12771
- useEffect$1(() => {
12772
- setPages((itemsLoader === null || itemsLoader === void 0 ? void 0 : itemsLoader.pages) || []);
12773
- }, [itemsLoader === null || itemsLoader === void 0 ? void 0 : itemsLoader.pages]);
12849
+ const [pages, setPages] = useState$1([]);
12850
+ if (itemsLoader !== null && itemsLoader !== void 0 && itemsLoader.pages) {
12851
+ selectionState.update({
12852
+ setPages,
12853
+ pages: itemsLoader === null || itemsLoader === void 0 ? void 0 : itemsLoader.pages,
12854
+ isSingleSelect,
12855
+ selectDisabled,
12856
+ layout
12857
+ });
12858
+ }
12774
12859
  const isItemLoaded = useCallback(index => {
12775
12860
  if (!(pages !== null && pages !== void 0 && pages.length) || !local.current.validPages) {
12776
12861
  return false;
@@ -12781,17 +12866,13 @@ function ListBox(_ref) {
12781
12866
  return page && isLoaded(page);
12782
12867
  }, [layout, pages]);
12783
12868
  const {
12784
- instantPages = [],
12785
12869
  interactionEvents,
12786
12870
  select
12787
12871
  } = useSelectionsInteractions({
12788
- layout,
12872
+ selectionState,
12789
12873
  selections,
12790
- pages,
12791
12874
  checkboxes,
12792
- selectDisabled,
12793
- doc: document,
12794
- isSingleSelect
12875
+ doc: document
12795
12876
  });
12796
12877
  const {
12797
12878
  layoutOptions = {}
@@ -12831,12 +12912,6 @@ function ListBox(_ref) {
12831
12912
  // Hand over the update function for manual refresh from hosting application.
12832
12913
  update.call(null, fetchData);
12833
12914
  }
12834
- useEffect$1(() => {
12835
- if (!instantPages || isLoadingData) {
12836
- return;
12837
- }
12838
- setPages(instantPages);
12839
- }, [instantPages]);
12840
12915
  useEffect$1(() => {
12841
12916
  if (scrollState && !initScrollPosIsSet && loaderRef.current) {
12842
12917
  loaderRef.current._listRef.scrollToItem(scrollState.initScrollPos);
@@ -12851,7 +12926,7 @@ function ListBox(_ref) {
12851
12926
  font: '14px Source sans pro'
12852
12927
  });
12853
12928
  let minimumBatchSize = DEFAULT_MIN_BATCH_SIZE;
12854
- const isVertical = layoutOptions.dataLayout ? layoutOptions.dataLayout === 'singleColumn' : listLayout !== 'horizontal';
12929
+ const isVertical = layoutOptions.dataLayout !== 'grid';
12855
12930
  const count = layout === null || layout === void 0 ? void 0 : (_layout$qListObject$q = layout.qListObject.qSize) === null || _layout$qListObject$q === void 0 ? void 0 : _layout$qListObject$q.qcy;
12856
12931
  const unlimitedListCount = getListCount({
12857
12932
  pages,
@@ -12861,14 +12936,28 @@ function ListBox(_ref) {
12861
12936
  layoutOptions,
12862
12937
  model
12863
12938
  });
12939
+ let freqIsAllowed = getFrequencyAllowed({
12940
+ itemWidth: width,
12941
+ layout,
12942
+ frequencyMode
12943
+ });
12864
12944
  const sizes = getListSizes({
12865
12945
  layout,
12866
12946
  width,
12867
12947
  height,
12868
12948
  listCount: unlimitedListCount,
12869
12949
  count,
12870
- textWidth
12950
+ textWidth,
12951
+ freqIsAllowed
12871
12952
  });
12953
+ if (sizes.columnWidth) {
12954
+ // In grid mode, where we have a dynamic item width, get a second opinion on showing/hiding frequency.
12955
+ freqIsAllowed = getFrequencyAllowed({
12956
+ itemWidth: sizes.columnWidth,
12957
+ layout,
12958
+ frequencyMode
12959
+ });
12960
+ }
12872
12961
  const {
12873
12962
  listCount
12874
12963
  } = sizes;
@@ -12887,7 +12976,7 @@ function ListBox(_ref) {
12887
12976
  });
12888
12977
  local.current.dataOffset = offset;
12889
12978
  if (triggerRerender) {
12890
- setPages(currentPages => [...currentPages]);
12979
+ selectionState.triggerStateChanged();
12891
12980
  }
12892
12981
  scrollToIndex(scrollIndex);
12893
12982
  };
@@ -12954,7 +13043,9 @@ function ListBox(_ref) {
12954
13043
  },
12955
13044
  setScrollPosition,
12956
13045
  focusListItems: getFocusState(),
12957
- setCurrentScrollIndex: currentScrollIndex.set
13046
+ setCurrentScrollIndex: currentScrollIndex.set,
13047
+ constraints,
13048
+ freqIsAllowed
12958
13049
  });
12959
13050
  const {
12960
13051
  columnWidth,
@@ -13032,7 +13123,8 @@ var createListboxSelectionToolbar = (_ref => {
13032
13123
  let {
13033
13124
  layout,
13034
13125
  model,
13035
- translator
13126
+ translator,
13127
+ selectionState
13036
13128
  } = _ref;
13037
13129
  if (layout.qListObject.qDimensionInfo.qIsOneAndOnlyOne) {
13038
13130
  return [];
@@ -13048,6 +13140,7 @@ var createListboxSelectionToolbar = (_ref => {
13048
13140
  getSvgIconShape: selectAll,
13049
13141
  enabled: canSelectAll,
13050
13142
  action: () => {
13143
+ selectionState.clearItemStates(false);
13051
13144
  model.selectListObjectAll('/qListObjectDef');
13052
13145
  }
13053
13146
  }, {
@@ -13057,6 +13150,7 @@ var createListboxSelectionToolbar = (_ref => {
13057
13150
  getSvgIconShape: selectPossible,
13058
13151
  enabled: canSelectPossible,
13059
13152
  action: () => {
13153
+ selectionState.clearItemStates(false);
13060
13154
  model.selectListObjectPossible('/qListObjectDef');
13061
13155
  }
13062
13156
  }, {
@@ -13066,6 +13160,7 @@ var createListboxSelectionToolbar = (_ref => {
13066
13160
  getSvgIconShape: selectAlternative,
13067
13161
  enabled: canSelectAlternative,
13068
13162
  action: () => {
13163
+ selectionState.clearItemStates(false);
13069
13164
  model.selectListObjectAlternative('/qListObjectDef');
13070
13165
  }
13071
13166
  }, {
@@ -13075,6 +13170,7 @@ var createListboxSelectionToolbar = (_ref => {
13075
13170
  getSvgIconShape: selectExcluded,
13076
13171
  enabled: canSelectExcluded,
13077
13172
  action: () => {
13173
+ selectionState.clearItemStates(false);
13078
13174
  model.selectListObjectExcluded('/qListObjectDef');
13079
13175
  }
13080
13176
  }];
@@ -13583,6 +13679,7 @@ const StyledOutlinedInput = styled$1(OutlinedInput)(_ref2 => {
13583
13679
  function ListBoxSearch(_ref3) {
13584
13680
  let {
13585
13681
  selections,
13682
+ selectionState,
13586
13683
  model,
13587
13684
  keyboard,
13588
13685
  dense = false,
@@ -13657,6 +13754,7 @@ function ListBoxSearch(_ref3) {
13657
13754
  response = model.acceptListObjectSearch(TREE_PATH, true);
13658
13755
  // eslint-disable-next-line no-param-reassign
13659
13756
  selections.selectionsMade = true;
13757
+ selectionState.clearItemStates(false);
13660
13758
  setValue('');
13661
13759
  }
13662
13760
  return response;
@@ -13696,7 +13794,8 @@ function ListBoxSearch(_ref3) {
13696
13794
  },
13697
13795
  '&:hover': {
13698
13796
  border: 'none'
13699
- }
13797
+ },
13798
+ paddingLeft: "".concat(CELL_PADDING_LEFT, "px")
13700
13799
  }, dense && {
13701
13800
  fontSize: 12,
13702
13801
  paddingLeft: theme.spacing(1),
@@ -13970,6 +14069,125 @@ function useObjectSelections(app, model, elements, options) {
13970
14069
  return [objectSelections];
13971
14070
  }
13972
14071
 
14072
+ function selectionState() {
14073
+ const state = {
14074
+ itemStates: {},
14075
+ ignoreSelectionState: false,
14076
+ selectedInEngine: [],
14077
+ enginePages: [],
14078
+ setPages: undefined,
14079
+ lastRowCount: undefined,
14080
+ lastApprMaxGlyphCount: undefined,
14081
+ update(_ref) {
14082
+ var _layout$qListObject$q, _layout$qListObject, _layout$qListObject$q2;
14083
+ let {
14084
+ setPages,
14085
+ pages,
14086
+ isSingleSelect,
14087
+ selectDisabled,
14088
+ layout
14089
+ } = _ref;
14090
+ this.setPages = setPages;
14091
+ const isSameRowCount = this.lastRowCount === layout.qListObject.qSize.qcy;
14092
+ const isSameMaxGlyphCnt = this.lastApprMaxGlyphCount === layout.qListObject.qDimensionInfo.qApprMaxGlyphCount;
14093
+ if (!isSameRowCount || !isSameMaxGlyphCnt) {
14094
+ this.lastRowCount = layout.qListObject.qSize.qcy;
14095
+ this.lastApprMaxGlyphCount = layout.qListObject.qDimensionInfo.qApprMaxGlyphCount;
14096
+
14097
+ // The field have probably changed (drill up/down)
14098
+ // need to clear the client side item states since the field values have changed
14099
+ this.clearItemStates(false);
14100
+ }
14101
+ if (state.enginePages !== pages && pages !== undefined) {
14102
+ state.enginePages = pages !== null && pages !== void 0 ? pages : [];
14103
+ state.selectedInEngine = getSelectedValues(pages);
14104
+ state.selectableValuesUpdating = false;
14105
+ state.triggerStateChanged();
14106
+ }
14107
+ state.isSingleSelect = isSingleSelect;
14108
+ state.selectDisabled = selectDisabled;
14109
+ state.isDimCalculated = (_layout$qListObject$q = layout === null || layout === void 0 ? void 0 : (_layout$qListObject = layout.qListObject) === null || _layout$qListObject === void 0 ? void 0 : (_layout$qListObject$q2 = _layout$qListObject.qDimensionInfo) === null || _layout$qListObject$q2 === void 0 ? void 0 : _layout$qListObject$q2.qIsCalculated) !== null && _layout$qListObject$q !== void 0 ? _layout$qListObject$q : false;
14110
+ },
14111
+ allowedToSelect() {
14112
+ if (state.selectDisabled()) {
14113
+ return false;
14114
+ }
14115
+ // When a dim is calculated, the rows must be done updating after previeous selection
14116
+ return !(state.isDimCalculated && state.selectableValuesUpdating);
14117
+ },
14118
+ setSelectableValuesUpdating() {
14119
+ state.selectableValuesUpdating = true;
14120
+ },
14121
+ useClientItemState(elementNumber) {
14122
+ return state.ignoreSelectionState || elementNumber in state.itemStates;
14123
+ },
14124
+ isSelected(elementNumber) {
14125
+ if (state.useClientItemState(elementNumber)) {
14126
+ return !!state.itemStates[elementNumber];
14127
+ }
14128
+ return state.selectedInEngine.includes(elementNumber);
14129
+ },
14130
+ getState(item) {
14131
+ const {
14132
+ qElemNumber,
14133
+ qState
14134
+ } = item;
14135
+ if (!state.useClientItemState(qElemNumber)) {
14136
+ return qState;
14137
+ }
14138
+ if (state.itemStates[qElemNumber]) {
14139
+ return qState === 'XS' ? 'XS' : 'S';
14140
+ }
14141
+ return qState === 'S' || qState === 'XS' ? 'A' : qState;
14142
+ },
14143
+ updateItemNoEvents(elementNumber, additive, selectedValues) {
14144
+ const selected = state.isSelected(elementNumber);
14145
+ if (selected && !additive) {
14146
+ state.itemStates[elementNumber] = false;
14147
+ } else if (!selected) {
14148
+ selectedValues === null || selectedValues === void 0 ? void 0 : selectedValues.push(elementNumber);
14149
+ state.itemStates[elementNumber] = true;
14150
+ }
14151
+ },
14152
+ triggerStateChanged() {
14153
+ if (this.setPages) {
14154
+ const pages = state.applySelectionsOnPages(state.enginePages);
14155
+ this.setPages(pages);
14156
+ }
14157
+ },
14158
+ applySelectionsOnPages(pages) {
14159
+ const matrices = pages.map(page => {
14160
+ const qMatrix = page.qMatrix.map(p => {
14161
+ const [p0] = p;
14162
+ const qState = state.getState(p0);
14163
+ return [_objectSpread2(_objectSpread2({}, p0), {}, {
14164
+ qState
14165
+ }), ...p.slice(1)];
14166
+ });
14167
+ return _objectSpread2(_objectSpread2({}, page), {}, {
14168
+ qMatrix
14169
+ });
14170
+ });
14171
+ return matrices;
14172
+ },
14173
+ updateItem(elementNumber, additive, selectedValues) {
14174
+ state.updateItemNoEvents(elementNumber, additive, selectedValues);
14175
+ state.triggerStateChanged();
14176
+ },
14177
+ updateItems(elementNumbers, additive, selectedValues) {
14178
+ elementNumbers.forEach(elementNumber => {
14179
+ state.updateItemNoEvents(elementNumber, additive, selectedValues);
14180
+ });
14181
+ state.triggerStateChanged();
14182
+ },
14183
+ clearItemStates(ignoreSelectionState) {
14184
+ state.itemStates = {};
14185
+ state.ignoreSelectionState = ignoreSelectionState;
14186
+ }
14187
+ };
14188
+ return state;
14189
+ }
14190
+
13973
14191
  const getValue$1 = function (obj, prop) {
13974
14192
  var _obj$prop;
13975
14193
  let defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
@@ -14041,6 +14259,7 @@ function ListBoxPopover(_ref) {
14041
14259
  const containerRef = useRef();
14042
14260
  const [selections] = useObjectSelections(app, model, containerRef);
14043
14261
  const [layout] = useLayout$1(model);
14262
+ const [selectionState$1] = useState$1(() => selectionState());
14044
14263
  useEffect$1(() => {
14045
14264
  if (selections && open) {
14046
14265
  if (!selections.isModal(model)) {
@@ -14060,7 +14279,8 @@ function ListBoxPopover(_ref) {
14060
14279
  const listboxSelectionToolbarItems = createListboxSelectionToolbar({
14061
14280
  layout,
14062
14281
  model,
14063
- translator
14282
+ translator,
14283
+ selectionState: selectionState$1
14064
14284
  });
14065
14285
  const hasSelections$1 = hasSelections(layout);
14066
14286
  return /*#__PURE__*/React__default.createElement(Popover, {
@@ -14133,6 +14353,7 @@ function ListBoxPopover(_ref) {
14133
14353
  model: model,
14134
14354
  listCount: listCount,
14135
14355
  selections: selections,
14356
+ selectionState: selectionState$1,
14136
14357
  keyboard: {
14137
14358
  enabled: false
14138
14359
  },
@@ -14141,6 +14362,7 @@ function ListBoxPopover(_ref) {
14141
14362
  model: model,
14142
14363
  layout: layout,
14143
14364
  selections: selections,
14365
+ selectionState: selectionState$1,
14144
14366
  direction: "ltr",
14145
14367
  onSetListCount: c => setListCount(c)
14146
14368
  }))));
@@ -15400,6 +15622,16 @@ AutoSizer.defaultProps = {
15400
15622
  style: {}
15401
15623
  };
15402
15624
 
15625
+ const drillDown = props => _objectSpread2(_objectSpread2({}, props), {}, {
15626
+ shapes: [{
15627
+ type: 'path',
15628
+ attrs: {
15629
+ d: 'M15.9993744,3 L15.9993744,5 L4.99937445,5 L4.99937445,3 L15.9993744,3 Z M8.99937445,7 L15.9993744,7 L15.9993744,9 L8.99937445,9 L8.99937445,7 Z M11.9993744,11 L15.9993744,11 L15.9993744,13 L11.9993744,13 L11.9993744,11 Z M2.2,11 L7,11 L7,9.00369263 C7,8.89323568 7.08954305,8.80369263 7.2,8.80369263 C7.2549016,8.80369263 7.30738916,8.82626165 7.34515712,8.86610844 L10.1852182,11.8624926 C10.2583124,11.93961 10.258346,12.0604218 10.1852948,12.13758 L7.34523376,15.1373102 C7.2692928,15.2175206 7.14270711,15.2209817 7.06249671,15.1450407 C7.02260076,15.1072683 7,15.0547472 7,14.9998069 L7,12.9043747 C4.79351111,12.9043747 2.8018683,12.9266213 1.02507156,12.9711145 L1.02507252,12.9711526 C0.472939773,12.9849787 0.014139487,12.5485949 0.000313396522,11.9964622 C0.000104473692,11.988119 -1.32268838e-12,11.9797736 -1.3231638e-12,11.9714278 L-1.83320026e-12,3 L2,3 L2,10.8 C2,10.9104569 2.08954305,11 2.2,11 Z'
15630
+ }
15631
+ }]
15632
+ });
15633
+ var DrillDownIcon = (props => SvgIcon$2(drillDown(props)));
15634
+
15403
15635
  const addListboxTheme = themeApi => {
15404
15636
  const getListboxStyle = prop => themeApi.getStyle('object', '', "listBox.".concat(prop));
15405
15637
  return {
@@ -15421,14 +15653,19 @@ const addListboxTheme = themeApi => {
15421
15653
 
15422
15654
  const PREFIX$4 = 'ListBoxInline';
15423
15655
  const searchIconWidth = 28;
15656
+ const drillDownIconWidth = 24;
15424
15657
  const classes$4 = {
15425
15658
  listBoxHeader: "".concat(PREFIX$4, "-listBoxHeader"),
15426
- screenReaderOnly: "".concat(PREFIX$4, "-screenReaderOnly")
15659
+ screenReaderOnly: "".concat(PREFIX$4, "-screenReaderOnly"),
15660
+ listboxWrapper: "".concat(PREFIX$4, "-listboxWrapper")
15427
15661
  };
15428
- const StyledGrid$3 = styled$1(Grid)(_ref => {
15662
+ const StyledGrid$3 = styled$1(Grid, {
15663
+ shouldForwardProp: p => !['containerPadding'].includes(p)
15664
+ })(_ref => {
15429
15665
  var _theme$listBox$backgr, _theme$listBox;
15430
15666
  let {
15431
- theme
15667
+ theme,
15668
+ containerPadding
15432
15669
  } = _ref;
15433
15670
  return {
15434
15671
  backgroundColor: (_theme$listBox$backgr = (_theme$listBox = theme.listBox) === null || _theme$listBox === void 0 ? void 0 : _theme$listBox.backgroundColor) !== null && _theme$listBox$backgr !== void 0 ? _theme$listBox$backgr : theme.palette.background.default,
@@ -15442,6 +15679,9 @@ const StyledGrid$3 = styled$1(Grid)(_ref => {
15442
15679
  height: 0,
15443
15680
  width: 0,
15444
15681
  overflow: 'hidden'
15682
+ },
15683
+ ["& .".concat(classes$4.listboxWrapper)]: {
15684
+ padding: containerPadding
15445
15685
  }
15446
15686
  };
15447
15687
  });
@@ -15457,7 +15697,7 @@ const Title = styled$1(Typography)(_ref2 => {
15457
15697
  };
15458
15698
  });
15459
15699
  function ListBoxInline(_ref3) {
15460
- var _layout$layoutOptions, _layout$layoutOptions2;
15700
+ var _layoutOptions$dense;
15461
15701
  let {
15462
15702
  options,
15463
15703
  layout
@@ -15466,7 +15706,6 @@ function ListBoxInline(_ref3) {
15466
15706
  app,
15467
15707
  direction,
15468
15708
  frequencyMode,
15469
- listLayout,
15470
15709
  checkboxes,
15471
15710
  search = true,
15472
15711
  focusSearch = false,
@@ -15525,6 +15764,7 @@ function ListBoxInline(_ref3) {
15525
15764
  stop: 0
15526
15765
  });
15527
15766
  const [appSelections] = useAppSelections(app);
15767
+ const [selectionState$1] = useState$1(() => selectionState());
15528
15768
  const {
15529
15769
  handleKeyDown,
15530
15770
  handleOnMouseEnter,
@@ -15592,17 +15832,23 @@ function ListBoxInline(_ref3) {
15592
15832
  return null;
15593
15833
  }
15594
15834
  const isLocked = layout.qListObject.qDimensionInfo.qLocked === true;
15835
+ const isDrillDown = layout.qListObject.qDimensionInfo.qGrouping === 'H';
15595
15836
  const listboxSelectionToolbarItems = toolbar ? createListboxSelectionToolbar({
15596
15837
  layout,
15597
15838
  model,
15598
- translator
15839
+ translator,
15840
+ selectionState: selectionState$1
15599
15841
  }) : [];
15600
15842
  const showSearchToggle = search === 'toggle' && showSearch;
15601
15843
  const searchVisible = (search === true || showSearchToggle) && !selectDisabled();
15602
- const dense = (_layout$layoutOptions = (_layout$layoutOptions2 = layout.layoutOptions) === null || _layout$layoutOptions2 === void 0 ? void 0 : _layout$layoutOptions2.dense) !== null && _layout$layoutOptions !== void 0 ? _layout$layoutOptions : false;
15844
+ const {
15845
+ layoutOptions = {}
15846
+ } = layout;
15847
+ const dense = (_layoutOptions$dense = layoutOptions.dense) !== null && _layoutOptions$dense !== void 0 ? _layoutOptions$dense : false;
15603
15848
  const searchHeight = dense ? 27 : 40;
15604
15849
  const extraheight = dense ? 39 : 49;
15605
15850
  const minHeight = 49 + (searchVisible ? searchHeight : 0) + extraheight;
15851
+ const headerHeight = 32;
15606
15852
  const {
15607
15853
  wildCardSearch,
15608
15854
  searchEnabled
@@ -15612,12 +15858,26 @@ function ListBoxInline(_ref3) {
15612
15858
  setShowSearch(newValue);
15613
15859
  };
15614
15860
  const shouldAutoFocus = searchVisible && search === 'toggle';
15861
+ const showSearchIcon = searchEnabled !== false && search === 'toggle' && !(constraints !== null && constraints !== void 0 && constraints.active);
15862
+ const showSearchOrLockIcon = isLocked || showSearchIcon;
15863
+ const showIcons = showSearchOrLockIcon || isDrillDown;
15864
+ const iconsWidth = (showSearchOrLockIcon ? searchIconWidth : 0) + (isDrillDown ? drillDownIconWidth : 0);
15865
+ const drillDownPaddingLeft = showSearchOrLockIcon ? 0 : ICON_PADDING;
15866
+ const headerPaddingLeft = CELL_PADDING_LEFT - (showIcons ? ICON_PADDING : 0);
15867
+
15868
+ // Add a container padding for grid mode to harmonize with the grid item margins (should sum to 8px).
15869
+ const isGridMode = (layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.dataLayout) === 'grid';
15870
+ let containerPadding;
15871
+ if (isGridMode) {
15872
+ containerPadding = layoutOptions.layoutOrder === 'row' ? '2px 4px' : '2px 6px 2px 4px';
15873
+ }
15615
15874
  return /*#__PURE__*/React__default.createElement(StyledGrid$3, {
15616
15875
  className: "listbox-container",
15617
15876
  container: true,
15618
15877
  tabIndex: keyboard.enabled && !keyboard.active ? 0 : -1,
15619
15878
  direction: "column",
15620
15879
  gap: 0,
15880
+ containerPadding: containerPadding,
15621
15881
  style: {
15622
15882
  height: '100%',
15623
15883
  minHeight: "".concat(minHeight, "px"),
@@ -15631,45 +15891,60 @@ function ListBoxInline(_ref3) {
15631
15891
  item: true,
15632
15892
  container: true,
15633
15893
  style: {
15634
- padding: theme.spacing(1)
15894
+ padding: theme.spacing(1),
15895
+ paddingLeft: "".concat(headerPaddingLeft, "px")
15635
15896
  },
15636
15897
  wrap: "nowrap"
15637
15898
  }, /*#__PURE__*/React__default.createElement(Grid, {
15638
15899
  item: true,
15639
15900
  container: true,
15901
+ height: headerHeight,
15640
15902
  wrap: "nowrap"
15641
- }, /*#__PURE__*/React__default.createElement(Grid, {
15903
+ }, showIcons && /*#__PURE__*/React__default.createElement(Grid, {
15642
15904
  item: true,
15643
15905
  sx: {
15644
15906
  display: 'flex',
15645
15907
  alignItems: 'center',
15646
- width: searchIconWidth
15908
+ width: iconsWidth
15647
15909
  }
15648
15910
  }, isLocked ? /*#__PURE__*/React__default.createElement(IconButton, {
15649
15911
  tabIndex: -1,
15650
15912
  onClick: unlock,
15651
- disabled: !isLocked,
15913
+ disabled: selectDisabled(),
15652
15914
  size: "large"
15653
15915
  }, /*#__PURE__*/React__default.createElement(Lock, {
15654
15916
  title: translator.get('Listbox.Unlock'),
15655
15917
  style: {
15656
15918
  fontSize: '12px'
15657
15919
  }
15658
- })) : searchEnabled !== false && /*#__PURE__*/React__default.createElement(IconButton, {
15920
+ })) : showSearchIcon && /*#__PURE__*/React__default.createElement(IconButton, {
15659
15921
  onClick: onShowSearch,
15660
15922
  tabIndex: -1,
15661
15923
  title: translator.get('Listbox.Search'),
15662
- size: "large"
15924
+ size: "large",
15925
+ "data-testid": "search-toggle-btn"
15663
15926
  }, /*#__PURE__*/React__default.createElement(SearchIcon, {
15664
15927
  style: {
15665
15928
  fontSize: '12px'
15666
15929
  }
15930
+ })), isDrillDown && /*#__PURE__*/React__default.createElement(IconButton, {
15931
+ tabIndex: -1,
15932
+ title: translator.get('Listbox.DrillDown'),
15933
+ size: "large",
15934
+ sx: {
15935
+ paddingLeft: "".concat(drillDownPaddingLeft, "px")
15936
+ }
15937
+ }, /*#__PURE__*/React__default.createElement(DrillDownIcon, {
15938
+ style: {
15939
+ fontSize: '12px'
15940
+ }
15667
15941
  }))), /*#__PURE__*/React__default.createElement(Grid, {
15668
15942
  item: true,
15669
15943
  className: classes$4.listBoxHeader
15670
15944
  }, /*#__PURE__*/React__default.createElement(Title, {
15671
15945
  variant: "h6",
15672
- noWrap: true
15946
+ noWrap: true,
15947
+ title: layout.title
15673
15948
  }, layout.title))), /*#__PURE__*/React__default.createElement(Grid, {
15674
15949
  item: true,
15675
15950
  xs: true
@@ -15713,6 +15988,7 @@ function ListBoxInline(_ref3) {
15713
15988
  className: classes$4.screenReaderOnly
15714
15989
  }, translator.get('Listbox.Search.ScreenReaderInstructions')), /*#__PURE__*/React__default.createElement(ListBoxSearch, {
15715
15990
  selections: selections,
15991
+ selectionState: selectionState$1,
15716
15992
  model: model,
15717
15993
  dense: dense,
15718
15994
  keyboard: keyboard,
@@ -15724,7 +16000,8 @@ function ListBoxInline(_ref3) {
15724
16000
  searchEnabled: searchEnabled
15725
16001
  })), /*#__PURE__*/React__default.createElement(Grid, {
15726
16002
  item: true,
15727
- xs: true
16003
+ xs: true,
16004
+ className: classes$4.listboxWrapper
15728
16005
  }, /*#__PURE__*/React__default.createElement("div", {
15729
16006
  className: classes$4.screenReaderOnly
15730
16007
  }, translator.get('Listbox.ScreenReaderInstructions')), /*#__PURE__*/React__default.createElement(AutoSizer, null, _ref4 => {
@@ -15734,10 +16011,11 @@ function ListBoxInline(_ref3) {
15734
16011
  } = _ref4;
15735
16012
  return /*#__PURE__*/React__default.createElement(ListBox, {
15736
16013
  model: model,
16014
+ constraints: constraints,
15737
16015
  layout: layout,
15738
16016
  selections: selections,
16017
+ selectionState: selectionState$1,
15739
16018
  direction: direction,
15740
- listLayout: listLayout,
15741
16019
  frequencyMode: frequencyMode,
15742
16020
  rangeSelect: rangeSelect,
15743
16021
  checkboxes: checkboxes,
@@ -15806,6 +16084,9 @@ function useExistingModel(_ref) {
15806
16084
  } else {
15807
16085
  const m = await app.getObject(qId);
15808
16086
  modelStore.set(m.id, m);
16087
+ m.once('closed', () => {
16088
+ modelStore.clear(m.id);
16089
+ });
15809
16090
  setModel(m);
15810
16091
  }
15811
16092
  }
@@ -15859,6 +16140,7 @@ function useOnTheFlyModel(_ref) {
15859
16140
  const {
15860
16141
  dense,
15861
16142
  checkboxes,
16143
+ listLayout,
15862
16144
  properties = {}
15863
16145
  } = options;
15864
16146
  let {
@@ -15887,6 +16169,20 @@ function useOnTheFlyModel(_ref) {
15887
16169
  break;
15888
16170
  }
15889
16171
  const getListdefFrequencyMode = () => histogram && frequencyMode === 'N' ? 'V' : frequencyMode;
16172
+ const layoutOptions = {
16173
+ dense
16174
+ };
16175
+ if (listLayout === 'horizontal') {
16176
+ layoutOptions.dataLayout = 'grid';
16177
+ layoutOptions.layoutOrder = 'column';
16178
+ layoutOptions.maxVisibleColumns = {
16179
+ auto: true
16180
+ };
16181
+ layoutOptions.maxVisibleRows = {
16182
+ auto: false,
16183
+ maxRows: 1
16184
+ };
16185
+ }
15890
16186
  const id = useRef();
15891
16187
  if (!id.current) {
15892
16188
  id.current = uid();
@@ -15899,6 +16195,7 @@ function useOnTheFlyModel(_ref) {
15899
16195
  qListObjectDef: {
15900
16196
  qStateName: stateName,
15901
16197
  qShowAlternatives: true,
16198
+ frequencyEnabled: false,
15902
16199
  qFrequencyMode: getListdefFrequencyMode(),
15903
16200
  qInitialDataFetch: [{
15904
16201
  qTop: 0,
@@ -15917,9 +16214,7 @@ function useOnTheFlyModel(_ref) {
15917
16214
  },
15918
16215
  histogram,
15919
16216
  checkboxes,
15920
- layoutOptions: {
15921
- dense
15922
- },
16217
+ layoutOptions,
15923
16218
  title
15924
16219
  };
15925
16220
  extend$1(true, listdef, properties);