@nebula.js/stardust 4.0.0-alpha.0 → 4.0.0-alpha.1

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 v4.0.0-alpha.0
2
+ * @nebula.js/stardust v4.0.0-alpha.1
3
3
  * Copyright (c) 2023 QlikTech International AB
4
4
  * Released under the MIT license.
5
5
  */
@@ -7756,7 +7756,7 @@ const light = {
7756
7756
  disabled: 'rgba(0, 0, 0, 0.3)'
7757
7757
  },
7758
7758
  action: {
7759
- active: colors.grey25,
7759
+ active: '#545454',
7760
7760
  // color for actionable things like icon buttons
7761
7761
  hover: 'rgba(0, 0, 0, 0.03)',
7762
7762
  // color for hoverable things like list items
@@ -7896,10 +7896,21 @@ const overrides = theme => ({
7896
7896
  padding: 7,
7897
7897
  borderRadius: 2,
7898
7898
  border: '1px solid transparent',
7899
- // should ideally use $focusVisible, but that messes up focus in all other places where Iconbutton is used (Checkbox, Switch etc)
7900
- '&:focus': {
7899
+ '&:hover': {
7900
+ backgroundColor: theme.palette.btn.hover
7901
+ },
7902
+ '&:focus-visible': {
7901
7903
  borderColor: theme.palette.custom.focusBorder,
7902
7904
  boxShadow: "0 0 0 2px ".concat(theme.palette.custom.focusOutline)
7905
+ },
7906
+ '&:active': {
7907
+ borderColor: 'transparent',
7908
+ boxShadow: 'none',
7909
+ backgroundColor: theme.palette.btn.active
7910
+ },
7911
+ '&:not(:active):not(:focus-visible)': {
7912
+ borderColor: 'transparent',
7913
+ boxShadow: 'none'
7903
7914
  }
7904
7915
  }
7905
7916
  },
@@ -7987,7 +7998,7 @@ function create$3(definition) {
7987
7998
  return cache[key];
7988
7999
  }
7989
8000
 
7990
- const NEBULA_VERSION_HASH = "b1a6" ;
8001
+ const NEBULA_VERSION_HASH = "f871" ;
7991
8002
  ClassNameGenerator$1.configure(componentName => {
7992
8003
  return "njs-".concat(NEBULA_VERSION_HASH, "-").concat(componentName.replace('Mui', ''));
7993
8004
  });
@@ -8195,7 +8206,7 @@ function boot(_ref2) {
8195
8206
  const appRef = React__default.createRef();
8196
8207
  const element = document.createElement('div');
8197
8208
  element.style.display = 'none';
8198
- element.setAttribute('data-nebulajs-version', "4.0.0-alpha.0" );
8209
+ element.setAttribute('data-nebulajs-version', "4.0.0-alpha.1" );
8199
8210
  element.setAttribute('data-app-id', app.id);
8200
8211
  document.body.appendChild(element);
8201
8212
  const root = client.createRoot(element);
@@ -9067,7 +9078,7 @@ function useSelectionsInteractions(_ref) {
9067
9078
  doSelect();
9068
9079
  }, []);
9069
9080
  const onMouseDown = useCallback(event => {
9070
- if (selectionState.selectDisabled()) {
9081
+ if (event.button !== 0 || selectionState.selectDisabled()) {
9071
9082
  return;
9072
9083
  }
9073
9084
  const elemNumber = +event.currentTarget.getAttribute('data-n');
@@ -9088,7 +9099,7 @@ function useSelectionsInteractions(_ref) {
9088
9099
  handleSingleSelectKey(event, event.currentTarget);
9089
9100
  }, []);
9090
9101
  const onMouseUp = useCallback(event => {
9091
- if (!currentSelect.current.active) {
9102
+ if (event.button !== 0 || !currentSelect.current.active) {
9092
9103
  return;
9093
9104
  }
9094
9105
  currentSelect.current.active = false;
@@ -9098,9 +9109,9 @@ function useSelectionsInteractions(_ref) {
9098
9109
  }
9099
9110
  doSelect();
9100
9111
  }, []);
9101
- const onMouseUpDoc = useCallback(() => {
9112
+ const onMouseUpDoc = useCallback(event => {
9102
9113
  // Ensure we end interactions when mouseup happens outside the Listbox.
9103
- if (!currentSelect.current.active) {
9114
+ if (event.button !== 0 || !currentSelect.current.active) {
9104
9115
  return;
9105
9116
  }
9106
9117
  currentSelect.current.active = false;
@@ -9127,17 +9138,19 @@ function useSelectionsInteractions(_ref) {
9127
9138
  };
9128
9139
  }, [onMouseUpDoc]);
9129
9140
  useEffect$1(() => {
9130
- const onDeactivated = () => {
9141
+ const clearItemStates = () => {
9131
9142
  selectionState.clearItemStates(false);
9132
9143
  };
9133
9144
  const onCleared = () => {
9134
9145
  selectionState.clearItemStates(true);
9135
9146
  selectionState.triggerStateChanged();
9136
9147
  };
9137
- selections.on('deactivated', onDeactivated);
9148
+ selections.on('clearItemStates', clearItemStates);
9149
+ selections.on('deactivated', clearItemStates);
9138
9150
  selections.on('cleared', onCleared);
9139
9151
  return () => {
9140
- selections.removeListener('activated', onDeactivated);
9152
+ selections.removeListener('clearItemStates', clearItemStates);
9153
+ selections.removeListener('deactivated', clearItemStates);
9141
9154
  selections.removeListener('cleared', onCleared);
9142
9155
  };
9143
9156
  }, [selections]);
@@ -9558,8 +9571,10 @@ const getFrequencyText = _ref2 => {
9558
9571
  return '';
9559
9572
  };
9560
9573
 
9561
- const ICON_PADDING = 7;
9562
9574
  const CELL_PADDING_LEFT = 9;
9575
+ const ICON_WIDTH = 12;
9576
+ const ICON_PADDING = 7;
9577
+ const BUTTON_ICON_WIDTH = ICON_WIDTH + (ICON_PADDING + 1) * 2; // 1 is border width
9563
9578
 
9564
9579
  const getSelectedStyle = _ref => {
9565
9580
  let {
@@ -9686,7 +9701,7 @@ const RowColRoot = styled$1('div', {
9686
9701
  theme
9687
9702
  })), {}, {
9688
9703
  background: theme.palette.selected.excluded,
9689
- color: theme.palette.selected.mainContrastText,
9704
+ color: theme.palette.selected.excludedContrastText,
9690
9705
  border: isGridMode ? 'none' : undefined
9691
9706
  }),
9692
9707
  ["& .".concat(rowColClasses.A)]: {
@@ -10305,7 +10320,7 @@ function RowColumn(_ref) {
10305
10320
  pages,
10306
10321
  cellIndex
10307
10322
  }), [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';
10323
+ 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' || (cell === null || cell === void 0 ? void 0 : cell.qState) === 'XL';
10309
10324
  const classArr = useMemo$1(() => getValueStateClasses({
10310
10325
  column,
10311
10326
  histogram,
@@ -10314,10 +10329,6 @@ function RowColumn(_ref) {
10314
10329
  showGray
10315
10330
  }), [cell === null || cell === void 0 ? void 0 : cell.qState, histogram, dense, checkboxes]);
10316
10331
  const preventContextMenu = useCallback(event => {
10317
- if (checkboxes) {
10318
- // Event will not propagate in the checkbox/radiobutton case
10319
- onClick(event);
10320
- }
10321
10332
  event.preventDefault();
10322
10333
  }, [checkboxes]);
10323
10334
  if (!cell) {
@@ -13233,6 +13244,7 @@ const Item = React__default.forwardRef((_ref, ref) => {
13233
13244
  style: style,
13234
13245
  className: ActionElement.className,
13235
13246
  size: "large",
13247
+ disableRipple: true,
13236
13248
  "aria-expanded": ariaExpanded,
13237
13249
  "aria-controls": "moreMenuList"
13238
13250
  }, hasSvgIconShape && SvgIcon$2(item.getSvgIconShape()), addAnchor && /*#__PURE__*/React__default.createElement("div", {
@@ -13640,7 +13652,7 @@ function ActionsToolbar(_ref3) {
13640
13652
  className: ActionToolbarElement.className,
13641
13653
  style: {
13642
13654
  pointerEvents: 'auto',
13643
- padding: theme.spacing(1, 1)
13655
+ padding: theme.spacing(0.8)
13644
13656
  }
13645
13657
  }
13646
13658
  }, Actions) : show && Actions;
@@ -15651,9 +15663,58 @@ const addListboxTheme = themeApi => {
15651
15663
  };
15652
15664
  };
15653
15665
 
15666
+ function showToolbarDetached(_ref) {
15667
+ var _containerRef$current, _containerRef$current2, _titleRef$current$cli, _titleRef$current, _titleRef$current2, _titleRef$current3;
15668
+ let {
15669
+ containerRef,
15670
+ titleRef,
15671
+ iconsWidth
15672
+ } = _ref;
15673
+ const containerWidth = (_containerRef$current = containerRef === null || containerRef === void 0 ? void 0 : (_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 ? void 0 : _containerRef$current2.clientWidth) !== null && _containerRef$current !== void 0 ? _containerRef$current : 0;
15674
+ const padding = 16;
15675
+ const contentWidth = ((_titleRef$current$cli = titleRef === null || titleRef === void 0 ? void 0 : (_titleRef$current = titleRef.current) === null || _titleRef$current === void 0 ? void 0 : _titleRef$current.clientWidth) !== null && _titleRef$current$cli !== void 0 ? _titleRef$current$cli : 0) + iconsWidth + padding;
15676
+ const actionToolbarWidth = 128;
15677
+ const notSufficientSpace = containerWidth < contentWidth + actionToolbarWidth;
15678
+ const isTruncated = (titleRef === null || titleRef === void 0 ? void 0 : (_titleRef$current2 = titleRef.current) === null || _titleRef$current2 === void 0 ? void 0 : _titleRef$current2.scrollWidth) > (titleRef === null || titleRef === void 0 ? void 0 : (_titleRef$current3 = titleRef.current) === null || _titleRef$current3 === void 0 ? void 0 : _titleRef$current3.offsetWidth);
15679
+ return !!(notSufficientSpace | isTruncated);
15680
+ }
15681
+
15682
+ function getListboxActionProps(_ref) {
15683
+ let {
15684
+ isPopover,
15685
+ showToolbar,
15686
+ containerRef,
15687
+ isLocked,
15688
+ listboxSelectionToolbarItems,
15689
+ selections
15690
+ } = _ref;
15691
+ return {
15692
+ show: showToolbar && !isPopover,
15693
+ popover: {
15694
+ show: showToolbar && isPopover,
15695
+ anchorEl: containerRef.current
15696
+ },
15697
+ more: {
15698
+ enabled: !isLocked,
15699
+ actions: listboxSelectionToolbarItems,
15700
+ popoverProps: {
15701
+ elevation: 0
15702
+ },
15703
+ popoverPaperStyle: {
15704
+ boxShadow: '0 12px 8px -8px rgba(0, 0, 0, 0.2)',
15705
+ minWidth: '250px'
15706
+ }
15707
+ },
15708
+ selections: {
15709
+ show: showToolbar,
15710
+ api: selections,
15711
+ onConfirm: () => {},
15712
+ onCancel: () => {}
15713
+ }
15714
+ };
15715
+ }
15716
+
15654
15717
  const PREFIX$4 = 'ListBoxInline';
15655
- const searchIconWidth = 28;
15656
- const drillDownIconWidth = 24;
15657
15718
  const classes$4 = {
15658
15719
  listBoxHeader: "".concat(PREFIX$4, "-listBoxHeader"),
15659
15720
  screenReaderOnly: "".concat(PREFIX$4, "-screenReaderOnly"),
@@ -15672,7 +15733,7 @@ const StyledGrid$3 = styled$1(Grid, {
15672
15733
  ["& .".concat(classes$4.listBoxHeader)]: {
15673
15734
  alignSelf: 'center',
15674
15735
  display: 'inline-flex',
15675
- width: "calc(100% - ".concat(searchIconWidth, "px)")
15736
+ width: "calc(100% - ".concat(BUTTON_ICON_WIDTH, "px)")
15676
15737
  },
15677
15738
  ["& .".concat(classes$4.screenReaderOnly)]: {
15678
15739
  position: 'absolute',
@@ -15746,7 +15807,6 @@ function ListBoxInline(_ref3) {
15746
15807
  constraints
15747
15808
  } = useContext(InstanceContext);
15748
15809
  theme.listBox = addListboxTheme(themeApi);
15749
- const moreAlignTo = useRef();
15750
15810
  const containerRef = useRef();
15751
15811
  const [searchContainer, searchContainerRef] = useRefWithCallback();
15752
15812
  const [showToolbar, setShowToolbar] = useState$1(false);
@@ -15764,6 +15824,7 @@ function ListBoxInline(_ref3) {
15764
15824
  stop: 0
15765
15825
  });
15766
15826
  const [appSelections] = useAppSelections(app);
15827
+ const titleRef = useRef(null);
15767
15828
  const [selectionState$1] = useState$1(() => selectionState());
15768
15829
  const {
15769
15830
  handleKeyDown,
@@ -15790,6 +15851,7 @@ function ListBoxInline(_ref3) {
15790
15851
  if ((layout === null || layout === void 0 ? void 0 : layout.toolbar) !== undefined) {
15791
15852
  toolbar = layout.toolbar;
15792
15853
  }
15854
+ const toolbarDetachedOnly = toolbar && (layout === null || layout === void 0 ? void 0 : layout.title) === '';
15793
15855
  toolbar = toolbar && (layout === null || layout === void 0 ? void 0 : layout.title) !== '';
15794
15856
  useEffect$1(() => {
15795
15857
  const show = () => {
@@ -15806,15 +15868,15 @@ function ListBoxInline(_ref3) {
15806
15868
  };
15807
15869
  if (selections) {
15808
15870
  if (!selections.isModal()) {
15809
- selections.on('deactivated', hide);
15810
15871
  selections.on('activated', show);
15872
+ selections.on('deactivated', hide);
15811
15873
  }
15812
15874
  setShowToolbar(selections.isActive());
15813
15875
  }
15814
15876
  return () => {
15815
15877
  if (selections && selections.removeListener) {
15816
- selections.removeListener('deactivated', show);
15817
- selections.removeListener('activated', hide);
15878
+ selections.removeListener('activated', show);
15879
+ selections.removeListener('deactivated', hide);
15818
15880
  }
15819
15881
  };
15820
15882
  }, [selections, toolbar]);
@@ -15833,12 +15895,12 @@ function ListBoxInline(_ref3) {
15833
15895
  }
15834
15896
  const isLocked = layout.qListObject.qDimensionInfo.qLocked === true;
15835
15897
  const isDrillDown = layout.qListObject.qDimensionInfo.qGrouping === 'H';
15836
- const listboxSelectionToolbarItems = toolbar ? createListboxSelectionToolbar({
15898
+ const listboxSelectionToolbarItems = createListboxSelectionToolbar({
15837
15899
  layout,
15838
15900
  model,
15839
15901
  translator,
15840
15902
  selectionState: selectionState$1
15841
- }) : [];
15903
+ });
15842
15904
  const showSearchToggle = search === 'toggle' && showSearch;
15843
15905
  const searchVisible = (search === true || showSearchToggle) && !selectDisabled();
15844
15906
  const {
@@ -15857,13 +15919,20 @@ function ListBoxInline(_ref3) {
15857
15919
  const newValue = !showSearch;
15858
15920
  setShowSearch(newValue);
15859
15921
  };
15922
+ const getActionToolbarProps = isPopover => getListboxActionProps({
15923
+ isPopover,
15924
+ showToolbar,
15925
+ containerRef,
15926
+ isLocked,
15927
+ listboxSelectionToolbarItems,
15928
+ selections
15929
+ });
15860
15930
  const shouldAutoFocus = searchVisible && search === 'toggle';
15861
15931
  const showSearchIcon = searchEnabled !== false && search === 'toggle' && !(constraints !== null && constraints !== void 0 && constraints.active);
15862
15932
  const showSearchOrLockIcon = isLocked || showSearchIcon;
15863
15933
  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);
15934
+ const iconsWidth = (showSearchOrLockIcon ? BUTTON_ICON_WIDTH : 0) + (isDrillDown ? ICON_WIDTH + ICON_PADDING : 0); // Drill-down icon needs padding right so there is space between the icon and the title
15935
+ const headerPaddingLeft = CELL_PADDING_LEFT - (showSearchOrLockIcon ? ICON_PADDING : 0);
15867
15936
 
15868
15937
  // Add a container padding for grid mode to harmonize with the grid item margins (should sum to 8px).
15869
15938
  const isGridMode = (layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.dataLayout) === 'grid';
@@ -15871,7 +15940,7 @@ function ListBoxInline(_ref3) {
15871
15940
  if (isGridMode) {
15872
15941
  containerPadding = layoutOptions.layoutOrder === 'row' ? '2px 4px' : '2px 6px 2px 4px';
15873
15942
  }
15874
- return /*#__PURE__*/React__default.createElement(StyledGrid$3, {
15943
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, toolbarDetachedOnly && /*#__PURE__*/React__default.createElement(ActionsToolbar, getActionToolbarProps(true)), /*#__PURE__*/React__default.createElement(StyledGrid$3, {
15875
15944
  className: "listbox-container",
15876
15945
  container: true,
15877
15946
  tabIndex: keyboard.enabled && !keyboard.active ? 0 : -1,
@@ -15914,6 +15983,7 @@ function ListBoxInline(_ref3) {
15914
15983
  size: "large"
15915
15984
  }, /*#__PURE__*/React__default.createElement(Lock, {
15916
15985
  title: translator.get('Listbox.Unlock'),
15986
+ disableRipple: true,
15917
15987
  style: {
15918
15988
  fontSize: '12px'
15919
15989
  }
@@ -15922,54 +15992,37 @@ function ListBoxInline(_ref3) {
15922
15992
  tabIndex: -1,
15923
15993
  title: translator.get('Listbox.Search'),
15924
15994
  size: "large",
15995
+ disableRipple: true,
15925
15996
  "data-testid": "search-toggle-btn"
15926
15997
  }, /*#__PURE__*/React__default.createElement(SearchIcon, {
15927
15998
  style: {
15928
15999
  fontSize: '12px'
15929
16000
  }
15930
- })), isDrillDown && /*#__PURE__*/React__default.createElement(IconButton, {
16001
+ })), isDrillDown && /*#__PURE__*/React__default.createElement(DrillDownIcon, {
15931
16002
  tabIndex: -1,
15932
16003
  title: translator.get('Listbox.DrillDown'),
15933
16004
  size: "large",
15934
- sx: {
15935
- paddingLeft: "".concat(drillDownPaddingLeft, "px")
15936
- }
15937
- }, /*#__PURE__*/React__default.createElement(DrillDownIcon, {
15938
16005
  style: {
15939
16006
  fontSize: '12px'
15940
16007
  }
15941
- }))), /*#__PURE__*/React__default.createElement(Grid, {
16008
+ })), /*#__PURE__*/React__default.createElement(Grid, {
15942
16009
  item: true,
15943
16010
  className: classes$4.listBoxHeader
15944
16011
  }, /*#__PURE__*/React__default.createElement(Title, {
15945
16012
  variant: "h6",
15946
16013
  noWrap: true,
16014
+ ref: titleRef,
15947
16015
  title: layout.title
15948
16016
  }, layout.title))), /*#__PURE__*/React__default.createElement(Grid, {
15949
16017
  item: true,
15950
16018
  xs: true
15951
16019
  }), /*#__PURE__*/React__default.createElement(Grid, {
15952
16020
  item: true
15953
- }, /*#__PURE__*/React__default.createElement(ActionsToolbar, {
15954
- more: {
15955
- enabled: !isLocked,
15956
- actions: listboxSelectionToolbarItems,
15957
- alignTo: moreAlignTo,
15958
- popoverProps: {
15959
- elevation: 0
15960
- },
15961
- popoverPaperStyle: {
15962
- boxShadow: '0 12px 8px -8px rgba(0, 0, 0, 0.2)',
15963
- minWidth: '250px'
15964
- }
15965
- },
15966
- selections: {
15967
- show: showToolbar,
15968
- api: selections,
15969
- onConfirm: () => {},
15970
- onCancel: () => {}
15971
- }
15972
- }))), /*#__PURE__*/React__default.createElement(Grid, {
16021
+ }, /*#__PURE__*/React__default.createElement(ActionsToolbar, getActionToolbarProps(showToolbarDetached({
16022
+ containerRef,
16023
+ titleRef,
16024
+ iconsWidth
16025
+ }))))), /*#__PURE__*/React__default.createElement(Grid, {
15973
16026
  item: true,
15974
16027
  container: true,
15975
16028
  direction: "column",
@@ -15979,9 +16032,7 @@ function ListBoxInline(_ref3) {
15979
16032
  },
15980
16033
  role: "region",
15981
16034
  "aria-label": translator.get('Listbox.ResultFilterLabel')
15982
- }, /*#__PURE__*/React__default.createElement("div", {
15983
- ref: moreAlignTo
15984
- }), /*#__PURE__*/React__default.createElement(Grid, {
16035
+ }, /*#__PURE__*/React__default.createElement(Grid, {
15985
16036
  item: true,
15986
16037
  ref: searchContainerRef
15987
16038
  }, /*#__PURE__*/React__default.createElement("div", {
@@ -16042,7 +16093,7 @@ function ListBoxInline(_ref3) {
16042
16093
  set: setCurrentScrollIndex
16043
16094
  }
16044
16095
  });
16045
- }))));
16096
+ })))));
16046
16097
  }
16047
16098
  const ListBoxInlineMemoed = React__default.memo(ListBoxInline);
16048
16099
  function IsolateUseLayoutWrapper(_ref5) {
@@ -16336,7 +16387,7 @@ function ListBoxWrapper(_ref) {
16336
16387
  options
16337
16388
  });
16338
16389
  const elementRef = useRef(element);
16339
- const selections = hasExternalSelectionsApi ? options.selectionsApi : useObjectSelections(app, model, [elementRef, '.njs-action-toolbar-more'], options)[0];
16390
+ const selections = hasExternalSelectionsApi ? options.selectionsApi : useObjectSelections(app, model, [elementRef, '.njs-action-toolbar-more', '.njs-action-toolbar-popover'], options)[0];
16340
16391
  const opts = useMemo$1(() => _objectSpread2(_objectSpread2({}, options), {}, {
16341
16392
  selections,
16342
16393
  model,