@nebula.js/stardust 5.10.1 → 5.12.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.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * @nebula.js/stardust v5.10.1
2
+ * @nebula.js/stardust v5.12.0
3
3
  * Copyright (c) 2025 QlikTech International AB
4
4
  * Released under the MIT license.
5
5
  */
@@ -30,7 +30,7 @@
30
30
  }
31
31
 
32
32
  function getAugmentedNamespace(n) {
33
- if (n.__esModule) return n;
33
+ if (Object.prototype.hasOwnProperty.call(n, '__esModule')) return n;
34
34
  var f = n.default;
35
35
  if (typeof f == "function") {
36
36
  var a = function a () {
@@ -2978,11 +2978,13 @@
2978
2978
  title: {
2979
2979
  main: {
2980
2980
  color: "@B50",
2981
- fontSize: "15px"
2981
+ fontSize: "15px",
2982
+ backgroundColor: "transparent"
2982
2983
  },
2983
2984
  subTitle: {
2984
2985
  color: "@B50",
2985
- fontSize: "12px"
2986
+ fontSize: "12px",
2987
+ backgroundColor: "transparent"
2986
2988
  },
2987
2989
  footer: {
2988
2990
  color: "@B50",
@@ -4922,12 +4924,13 @@
4922
4924
  uiPalettes() {
4923
4925
  const pals = [];
4924
4926
  resolvedTheme.palettes.ui.forEach(s => {
4927
+ const colors = s.colors[0] !== 'none' ? ['none', ...s.colors] : s.colors;
4925
4928
  pals.push({
4926
4929
  key: 'ui',
4927
4930
  name: s.name,
4928
4931
  translation: s.translation,
4929
4932
  type: 'row',
4930
- colors: s.colors
4933
+ colors
4931
4934
  });
4932
4935
  });
4933
4936
  return pals;
@@ -4943,7 +4946,7 @@
4943
4946
  others: resolvedTheme.dataColors.othersColor
4944
4947
  };
4945
4948
  },
4946
- uiColor(c, shift) {
4949
+ uiColor(c) {
4947
4950
  const indexIsValid = typeof (c === null || c === void 0 ? void 0 : c.index) === 'number' && !Number.isNaN(c === null || c === void 0 ? void 0 : c.index);
4948
4951
  const colorIsValid = typeof (c === null || c === void 0 ? void 0 : c.color) === 'string';
4949
4952
  const somethingIsValid = indexIsValid || colorIsValid;
@@ -4951,8 +4954,6 @@
4951
4954
  return undefined;
4952
4955
  }
4953
4956
  const getColor = () => {
4954
- // eslint-disable-next-line no-param-reassign
4955
- shift = !!shift;
4956
4957
  if ((c === null || c === void 0 ? void 0 : c.index) < 0 || typeof (c === null || c === void 0 ? void 0 : c.index) === 'undefined') {
4957
4958
  return c.color;
4958
4959
  }
@@ -4962,10 +4963,10 @@
4962
4963
  if (!uiPalette) {
4963
4964
  return c.color;
4964
4965
  }
4965
- if (typeof uiPalette.colors[c.index - shift] === 'undefined') {
4966
+ if (typeof uiPalette.colors[c.index] === 'undefined') {
4966
4967
  return c.color;
4967
4968
  }
4968
- return uiPalette.colors[c.index - shift];
4969
+ return uiPalette.colors[c.index];
4969
4970
  };
4970
4971
  const color = getColor();
4971
4972
  if (c.alpha === undefined || c.alpha >= 1 || c.alpha < 0) {
@@ -5392,12 +5393,10 @@
5392
5393
  * @param {object} c
5393
5394
  * @param {number=} c.index
5394
5395
  * @param {string=} c.color
5395
- * @param {boolean=} supportNone Shifts the palette index by one to account for the "none" color
5396
5396
  * @returns {string} The resolved color.
5397
5397
  *
5398
5398
  * @example
5399
5399
  * theme.getColorPickerColor({ index: 1 });
5400
- * theme.getColorPickerColor({ index: 1 }, true);
5401
5400
  * theme.getColorPickerColor({ color: 'red' });
5402
5401
  */
5403
5402
  getColorPickerColor() {
@@ -10446,12 +10445,12 @@
10446
10445
  unstable_applyStyles: applyStyles$2
10447
10446
  });
10448
10447
 
10449
- function isObjectEmpty(obj) {
10448
+ function isObjectEmpty$1(obj) {
10450
10449
  return Object.keys(obj).length === 0;
10451
10450
  }
10452
10451
  function useTheme$5(defaultTheme = null) {
10453
10452
  const contextTheme = reactExports.useContext(ThemeContext$1);
10454
- return !contextTheme || isObjectEmpty(contextTheme) ? defaultTheme : contextTheme;
10453
+ return !contextTheme || isObjectEmpty$1(contextTheme) ? defaultTheme : contextTheme;
10455
10454
  }
10456
10455
 
10457
10456
  const systemDefaultTheme$1 = createTheme$2();
@@ -12898,7 +12897,10 @@
12898
12897
  typography: typographyInput = {}
12899
12898
  } = options,
12900
12899
  other = _objectWithoutPropertiesLoose$3(options, _excluded$G);
12901
- if (options.vars) {
12900
+ if (options.vars &&
12901
+ // The error should throw only for the root theme creation because user is not allowed to use a custom node `vars`.
12902
+ // `generateCssVars` is the closest identifier for checking that the `options` is a result of `extendTheme` with CSS variables so that user can create new theme for nested ThemeProvider.
12903
+ options.generateCssVars === undefined) {
12902
12904
  throw new Error(formatMuiErrorMessage$1(18));
12903
12905
  }
12904
12906
  const palette = createPalette(paletteInput);
@@ -13261,9 +13263,21 @@
13261
13263
  } = _ref,
13262
13264
  props = _objectWithoutPropertiesLoose$3(_ref, _excluded$F);
13263
13265
  const scopedTheme = themeInput[THEME_ID];
13266
+ let finalTheme = scopedTheme || themeInput;
13267
+ if (typeof themeInput !== 'function') {
13268
+ if (scopedTheme && !scopedTheme.vars) {
13269
+ finalTheme = _extends$6({}, scopedTheme, {
13270
+ vars: null
13271
+ });
13272
+ } else if (themeInput && !themeInput.vars) {
13273
+ finalTheme = _extends$6({}, themeInput, {
13274
+ vars: null
13275
+ });
13276
+ }
13277
+ }
13264
13278
  return /*#__PURE__*/jsxRuntimeExports.jsx(ThemeProvider$1, _extends$6({}, props, {
13265
13279
  themeId: scopedTheme ? THEME_ID : undefined,
13266
- theme: scopedTheme || themeInput
13280
+ theme: finalTheme
13267
13281
  }));
13268
13282
  }
13269
13283
 
@@ -15297,7 +15311,7 @@
15297
15311
  return cache[key];
15298
15312
  }
15299
15313
 
15300
- const NEBULA_VERSION_HASH = "a207";
15314
+ const NEBULA_VERSION_HASH = "02d6";
15301
15315
  ClassNameGenerator.configure(componentName => {
15302
15316
  return "njs-".concat(NEBULA_VERSION_HASH, "-").concat(componentName.replace('Mui', ''));
15303
15317
  });
@@ -15356,6 +15370,7 @@
15356
15370
  let applyMiddleware = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : () => {};
15357
15371
  const sharedState = initialState;
15358
15372
  const hookListeners = [];
15373
+ const subscribedListeners = {};
15359
15374
  const store = {
15360
15375
  get: key => sharedState[key],
15361
15376
  set: (key, value) => {
@@ -15363,7 +15378,7 @@
15363
15378
  throw new Error("Invalid key: ".concat(JSON.stringify(key)));
15364
15379
  }
15365
15380
  sharedState[key] = value;
15366
- applyMiddleware({
15381
+ subscribedListeners[key] = applyMiddleware({
15367
15382
  type: 'SET',
15368
15383
  value
15369
15384
  });
@@ -15377,6 +15392,11 @@
15377
15392
  },
15378
15393
  dispatch: forceNewState => {
15379
15394
  hookListeners.forEach(listener => listener(forceNewState ? {} : sharedState));
15395
+ },
15396
+ destroy: () => {
15397
+ Object.keys(subscribedListeners).forEach(key => {
15398
+ subscribedListeners[key] && subscribedListeners[key]();
15399
+ });
15380
15400
  }
15381
15401
  };
15382
15402
  const useKeyStore = () => {
@@ -15413,6 +15433,7 @@
15413
15433
  modelChangedStore.dispatch(true); // Force new state to trigger hooks
15414
15434
  };
15415
15435
  const unsubscribe = () => {
15436
+ model.removeListener('closed', unsubscribe);
15416
15437
  model.removeListener('changed', onChanged);
15417
15438
  rpcResultStore.clear(model.id);
15418
15439
  rpcRequestStore.clear(model.id);
@@ -15425,9 +15446,7 @@
15425
15446
  case 'SET':
15426
15447
  if (!initialized) {
15427
15448
  model.on('changed', onChanged);
15428
- model.once('closed', () => {
15429
- unsubscribe();
15430
- });
15449
+ model.once('closed', unsubscribe);
15431
15450
  }
15432
15451
  break;
15433
15452
  }
@@ -15444,8 +15463,12 @@
15444
15463
  modelStore.clear(model.id);
15445
15464
  };
15446
15465
  };
15466
+ const destroy = () => {
15467
+ modelStore.destroy();
15468
+ };
15447
15469
  return {
15448
15470
  subscribe,
15471
+ destroy,
15449
15472
  useModelStore,
15450
15473
  modelStore,
15451
15474
  useModelChangedStore,
@@ -15529,7 +15552,7 @@
15529
15552
  const appRef = React.createRef();
15530
15553
  const element = document.createElement('div');
15531
15554
  element.style.display = 'none';
15532
- element.setAttribute('data-nebulajs-version', "5.10.1");
15555
+ element.setAttribute('data-nebulajs-version', "5.12.0");
15533
15556
  element.setAttribute('data-app-id', app.id);
15534
15557
  document.body.appendChild(element);
15535
15558
  if (context) {
@@ -15546,6 +15569,7 @@
15546
15569
  selectionStore: selectionStore
15547
15570
  }));
15548
15571
  const cells = {};
15572
+ const cellsUnmount = {};
15549
15573
  const components = [];
15550
15574
  return [{
15551
15575
  toggleFocusOfCells(cellIdToFocus) {
@@ -15554,11 +15578,14 @@
15554
15578
  });
15555
15579
  },
15556
15580
  cells,
15557
- addCell(id, cell) {
15581
+ addCell(id, cell, unmount) {
15558
15582
  cells[id] = cell;
15583
+ cellsUnmount[id] = unmount;
15559
15584
  },
15560
15585
  removeCell(id) {
15561
15586
  delete cells[id];
15587
+ cellsUnmount[id]();
15588
+ delete cellsUnmount[id];
15562
15589
  },
15563
15590
  add(component) {
15564
15591
  (async () => {
@@ -15592,6 +15619,12 @@
15592
15619
  }
15593
15620
  appRef.current.setContext(ctx);
15594
15621
  })();
15622
+ },
15623
+ destroy() {
15624
+ Object.keys(cellsUnmount).forEach(c => {
15625
+ cellsUnmount[c]();
15626
+ });
15627
+ modelStore.destroy();
15595
15628
  }
15596
15629
  }, modelStore, selectionStore, appRef, rendered];
15597
15630
  }
@@ -18270,8 +18303,15 @@
18270
18303
  transform: 'translateZ(0)'
18271
18304
  }
18272
18305
  };
18306
+ function isObjectEmpty(object) {
18307
+ // eslint-disable-next-line
18308
+ for (const _ in object) {
18309
+ return false;
18310
+ }
18311
+ return true;
18312
+ }
18273
18313
  function isEmpty$1(obj) {
18274
- return obj === undefined || obj === null || Object.keys(obj).length === 0 || obj.outerHeightStyle === 0 && !obj.overflowing;
18314
+ return isObjectEmpty(obj) || obj.outerHeightStyle === 0 && !obj.overflowing;
18275
18315
  }
18276
18316
 
18277
18317
  /**
@@ -18296,14 +18336,18 @@
18296
18336
  const {
18297
18337
  current: isControlled
18298
18338
  } = reactExports.useRef(value != null);
18299
- const inputRef = reactExports.useRef(null);
18300
- const handleRef = useForkRef(forwardedRef, inputRef);
18339
+ const textareaRef = reactExports.useRef(null);
18340
+ const handleRef = useForkRef(forwardedRef, textareaRef);
18301
18341
  const heightRef = reactExports.useRef(null);
18302
- const shadowRef = reactExports.useRef(null);
18342
+ const hiddenTextareaRef = reactExports.useRef(null);
18303
18343
  const calculateTextareaStyles = reactExports.useCallback(() => {
18304
- const input = inputRef.current;
18305
- const containerWindow = ownerWindow(input);
18306
- const computedStyle = containerWindow.getComputedStyle(input);
18344
+ const textarea = textareaRef.current;
18345
+ const hiddenTextarea = hiddenTextareaRef.current;
18346
+ if (!textarea || !hiddenTextarea) {
18347
+ return undefined;
18348
+ }
18349
+ const containerWindow = ownerWindow(textarea);
18350
+ const computedStyle = containerWindow.getComputedStyle(textarea);
18307
18351
 
18308
18352
  // If input's width is shrunk and it's not visible, don't sync height.
18309
18353
  if (computedStyle.width === '0px') {
@@ -18312,25 +18356,24 @@
18312
18356
  overflowing: false
18313
18357
  };
18314
18358
  }
18315
- const inputShallow = shadowRef.current;
18316
- inputShallow.style.width = computedStyle.width;
18317
- inputShallow.value = input.value || props.placeholder || 'x';
18318
- if (inputShallow.value.slice(-1) === '\n') {
18359
+ hiddenTextarea.style.width = computedStyle.width;
18360
+ hiddenTextarea.value = textarea.value || props.placeholder || 'x';
18361
+ if (hiddenTextarea.value.slice(-1) === '\n') {
18319
18362
  // Certain fonts which overflow the line height will cause the textarea
18320
18363
  // to report a different scrollHeight depending on whether the last line
18321
18364
  // is empty. Make it non-empty to avoid this issue.
18322
- inputShallow.value += ' ';
18365
+ hiddenTextarea.value += ' ';
18323
18366
  }
18324
18367
  const boxSizing = computedStyle.boxSizing;
18325
18368
  const padding = getStyleValue(computedStyle.paddingBottom) + getStyleValue(computedStyle.paddingTop);
18326
18369
  const border = getStyleValue(computedStyle.borderBottomWidth) + getStyleValue(computedStyle.borderTopWidth);
18327
18370
 
18328
18371
  // The height of the inner content
18329
- const innerHeight = inputShallow.scrollHeight;
18372
+ const innerHeight = hiddenTextarea.scrollHeight;
18330
18373
 
18331
18374
  // Measure height of a textarea with a single row
18332
- inputShallow.value = 'x';
18333
- const singleRowHeight = inputShallow.scrollHeight;
18375
+ hiddenTextarea.value = 'x';
18376
+ const singleRowHeight = hiddenTextarea.scrollHeight;
18334
18377
 
18335
18378
  // The height of the outer content
18336
18379
  let outerHeight = innerHeight;
@@ -18350,46 +18393,63 @@
18350
18393
  overflowing
18351
18394
  };
18352
18395
  }, [maxRows, minRows, props.placeholder]);
18396
+ const didHeightChange = useEventCallback(() => {
18397
+ const textarea = textareaRef.current;
18398
+ const textareaStyles = calculateTextareaStyles();
18399
+ if (!textarea || !textareaStyles || isEmpty$1(textareaStyles)) {
18400
+ return false;
18401
+ }
18402
+ const outerHeightStyle = textareaStyles.outerHeightStyle;
18403
+ return heightRef.current != null && heightRef.current !== outerHeightStyle;
18404
+ });
18353
18405
  const syncHeight = reactExports.useCallback(() => {
18406
+ const textarea = textareaRef.current;
18354
18407
  const textareaStyles = calculateTextareaStyles();
18355
- if (isEmpty$1(textareaStyles)) {
18408
+ if (!textarea || !textareaStyles || isEmpty$1(textareaStyles)) {
18356
18409
  return;
18357
18410
  }
18358
18411
  const outerHeightStyle = textareaStyles.outerHeightStyle;
18359
- const input = inputRef.current;
18360
18412
  if (heightRef.current !== outerHeightStyle) {
18361
18413
  heightRef.current = outerHeightStyle;
18362
- input.style.height = `${outerHeightStyle}px`;
18414
+ textarea.style.height = `${outerHeightStyle}px`;
18363
18415
  }
18364
- input.style.overflow = textareaStyles.overflowing ? 'hidden' : '';
18416
+ textarea.style.overflow = textareaStyles.overflowing ? 'hidden' : '';
18365
18417
  }, [calculateTextareaStyles]);
18418
+ const frameRef = reactExports.useRef(-1);
18366
18419
  useEnhancedEffect(() => {
18367
- const handleResize = () => {
18368
- syncHeight();
18369
- };
18370
- // Workaround a "ResizeObserver loop completed with undelivered notifications" error
18371
- // in test.
18372
- // Note that we might need to use this logic in production per https://github.com/WICG/resize-observer/issues/38
18373
- // Also see https://github.com/mui/mui-x/issues/8733
18374
- let rAF;
18375
- const debounceHandleResize = debounce$1(handleResize);
18376
- const input = inputRef.current;
18377
- const containerWindow = ownerWindow(input);
18378
- containerWindow.addEventListener('resize', debounceHandleResize);
18420
+ const debouncedHandleResize = debounce$1(syncHeight);
18421
+ const textarea = textareaRef == null ? void 0 : textareaRef.current;
18422
+ if (!textarea) {
18423
+ return undefined;
18424
+ }
18425
+ const containerWindow = ownerWindow(textarea);
18426
+ containerWindow.addEventListener('resize', debouncedHandleResize);
18379
18427
  let resizeObserver;
18380
18428
  if (typeof ResizeObserver !== 'undefined') {
18381
- resizeObserver = new ResizeObserver(handleResize);
18382
- resizeObserver.observe(input);
18429
+ resizeObserver = new ResizeObserver(() => {
18430
+ if (didHeightChange()) {
18431
+ // avoid "ResizeObserver loop completed with undelivered notifications" error
18432
+ // by temporarily unobserving the textarea element while manipulating the height
18433
+ // and reobserving one frame later
18434
+ resizeObserver.unobserve(textarea);
18435
+ cancelAnimationFrame(frameRef.current);
18436
+ syncHeight();
18437
+ frameRef.current = requestAnimationFrame(() => {
18438
+ resizeObserver.observe(textarea);
18439
+ });
18440
+ }
18441
+ });
18442
+ resizeObserver.observe(textarea);
18383
18443
  }
18384
18444
  return () => {
18385
- debounceHandleResize.clear();
18386
- cancelAnimationFrame(rAF);
18387
- containerWindow.removeEventListener('resize', debounceHandleResize);
18445
+ debouncedHandleResize.clear();
18446
+ cancelAnimationFrame(frameRef.current);
18447
+ containerWindow.removeEventListener('resize', debouncedHandleResize);
18388
18448
  if (resizeObserver) {
18389
18449
  resizeObserver.disconnect();
18390
18450
  }
18391
18451
  };
18392
- }, [calculateTextareaStyles, syncHeight]);
18452
+ }, [calculateTextareaStyles, syncHeight, didHeightChange]);
18393
18453
  useEnhancedEffect(() => {
18394
18454
  syncHeight();
18395
18455
  });
@@ -18414,7 +18474,7 @@
18414
18474
  "aria-hidden": true,
18415
18475
  className: props.className,
18416
18476
  readOnly: true,
18417
- ref: shadowRef,
18477
+ ref: hiddenTextareaRef,
18418
18478
  tabIndex: -1,
18419
18479
  style: _extends$6({}, styles$2.shadow, style, {
18420
18480
  paddingTop: 0,
@@ -25366,12 +25426,12 @@
25366
25426
  },
25367
25427
  // The leaf node, containing the label text.
25368
25428
  ["& .".concat(rowColClasses.labelText)]: _objectSpread2(_objectSpread2({
25369
- lineHeight: '16px',
25429
+ lineHeight: '24px',
25370
25430
  userSelect: 'none',
25371
25431
  paddingRight: '1px'
25372
25432
  }, ellipsis), contentFontStyles),
25373
25433
  ["& .".concat(rowColClasses.labelDense)]: {
25374
- fontSize: 12
25434
+ lineHeight: 18
25375
25435
  },
25376
25436
  // Highlight is added to labelText spans, which are created as children to original labelText,
25377
25437
  // when a search string is matched.
@@ -31067,10 +31127,9 @@
31067
31127
  return undefined;
31068
31128
  }
31069
31129
 
31070
- const supportNone = true;
31071
31130
  function resolveColor(colorObj, path, attribute, theme, objectType) {
31072
31131
  if (colorObj && theme) {
31073
- return colorObj.color !== 'none' ? theme.getColorPickerColor(colorObj, supportNone) : undefined;
31132
+ return colorObj.color !== 'none' ? theme.getColorPickerColor(colorObj) : undefined;
31074
31133
  }
31075
31134
  return resolveProperty(path, attribute, theme, objectType);
31076
31135
  }
@@ -31193,7 +31252,8 @@
31193
31252
  return {
31194
31253
  fontFamily: textProps.fontFamily || theme.getStyle("object.".concat(objectType), "title.".concat(target), 'fontFamily'),
31195
31254
  fontSize: textProps.fontSize || theme.getStyle("object.".concat(objectType), "title.".concat(target), 'fontSize'),
31196
- color: textProps.color && textProps.color.color !== 'none' ? theme.getColorPickerColor(textProps.color, true) : theme.getStyle("object.".concat(objectType), target, 'color'),
31255
+ color: textProps.color && textProps.color.color !== 'none' ? theme.getColorPickerColor(textProps.color) : theme.getStyle("object.".concat(objectType), target, 'color'),
31256
+ backgroundColor: textProps.backgroundColor || theme.getStyle("object.".concat(objectType), "title.".concat(target), 'backgroundColor'),
31197
31257
  fontWeight: fontStyle.includes('bold') ? 'bold' : 'normal',
31198
31258
  fontStyle: fontStyle.includes('italic') ? 'italic' : 'normal',
31199
31259
  textDecoration: fontStyle.includes('underline') ? 'underline' : 'initial'
@@ -31264,7 +31324,7 @@
31264
31324
  bgColor
31265
31325
  }, themeApi, 'listBox');
31266
31326
  } else {
31267
- color = themeApi.getColorPickerColor(bgColor === null || bgColor === void 0 ? void 0 : bgColor.color, false);
31327
+ color = themeApi.getColorPickerColor(bgColor === null || bgColor === void 0 ? void 0 : bgColor.color);
31268
31328
  }
31269
31329
  return color;
31270
31330
  }
@@ -31289,7 +31349,7 @@
31289
31349
  } = _ref3;
31290
31350
  const overrides = getOverridesAsObject(components);
31291
31351
  const getListboxStyle = (path, prop) => themeApi.getStyle('object.listBox', path, prop);
31292
- const getColorPickerColor = c => (c === null || c === void 0 ? void 0 : c.index) > 0 || c !== null && c !== void 0 && c.color ? themeApi.getColorPickerColor(c, false) : undefined;
31352
+ const getColorPickerColor = c => (c === null || c === void 0 ? void 0 : c.index) > 0 || c !== null && c !== void 0 && c.color ? themeApi.getColorPickerColor(c) : undefined;
31293
31353
  const selections = getSelectionColors({
31294
31354
  getColorPickerColor,
31295
31355
  theme,
@@ -35995,7 +36055,8 @@
35995
36055
  return {
35996
36056
  ["& .".concat(classes.itemStyle)]: {
35997
36057
  minWidth: 0,
35998
- paddingTop: theme.spacing(1)
36058
+ paddingTop: theme.spacing(1),
36059
+ width: '100%'
35999
36060
  }
36000
36061
  };
36001
36062
  });
@@ -36249,6 +36310,70 @@
36249
36310
  }
36250
36311
  }
36251
36312
 
36313
+ const NP_PADDINH_IN_CARDS_WITHOUT_TITLE = ['action-button', 'sn-nav-menu'];
36314
+ const NO_PADDING_IN_CARDS = ['pivot-table', 'table', 'sn-table', 'sn-pivot-table', 'kpi', 'map', 'filterpane', 'sn-calendar', 'sn-filter-pane', 'sn-layout-container', 'sn-listbox', 'sn-shape', 'sn-tabbed-container'];
36315
+ const shouldUseCardPadding = _ref => {
36316
+ let {
36317
+ isCardTheme,
36318
+ layout,
36319
+ isError
36320
+ } = _ref;
36321
+ const visualization = layout === null || layout === void 0 ? void 0 : layout.visualization;
36322
+ if (!isCardTheme) {
36323
+ return false;
36324
+ }
36325
+ if (isError) {
36326
+ return true;
36327
+ }
36328
+ if (NO_PADDING_IN_CARDS.indexOf(visualization) !== -1) {
36329
+ return false;
36330
+ }
36331
+ const showTitle = layout === null || layout === void 0 ? void 0 : layout.showTitles;
36332
+ if (!showTitle && NP_PADDINH_IN_CARDS_WITHOUT_TITLE.indexOf(visualization) !== -1) {
36333
+ return false;
36334
+ }
36335
+ return true;
36336
+ };
36337
+ const getPadding = _ref2 => {
36338
+ let {
36339
+ layout,
36340
+ isError,
36341
+ senseTheme,
36342
+ titleStyles
36343
+ } = _ref2;
36344
+ const isCardTheme = senseTheme === null || senseTheme === void 0 ? void 0 : senseTheme.getStyle('', '', '_cards');
36345
+ const cardPadding = shouldUseCardPadding({
36346
+ isCardTheme,
36347
+ layout,
36348
+ isError
36349
+ });
36350
+ if (isCardTheme) {
36351
+ const showTitle = (layout === null || layout === void 0 ? void 0 : layout.showTitles) && !!(layout !== null && layout !== void 0 && layout.title);
36352
+ const showSubtitle = (layout === null || layout === void 0 ? void 0 : layout.showTitles) && !!(layout !== null && layout !== void 0 && layout.subtitle);
36353
+ const showFootnote = (layout === null || layout === void 0 ? void 0 : layout.showTitles) && !!(layout !== null && layout !== void 0 && layout.footnote);
36354
+ if (showTitle && cardPadding) {
36355
+ // eslint-disable-next-line no-param-reassign
36356
+ titleStyles.main.padding = '10px 10px 0';
36357
+ }
36358
+ if (showSubtitle && cardPadding) {
36359
+ // eslint-disable-next-line no-param-reassign
36360
+ titleStyles.subTitle.padding = showTitle ? '0 10px' : '10px 10px 0';
36361
+ }
36362
+ if (showFootnote) {
36363
+ // eslint-disable-next-line no-param-reassign
36364
+ titleStyles.footer.borderTop = '1px solid #d9d9d9';
36365
+ // eslint-disable-next-line no-param-reassign
36366
+ titleStyles.footer.padding = '6px 10px';
36367
+ }
36368
+ let bodyPadding;
36369
+ if (cardPadding) {
36370
+ bodyPadding = "".concat(showTitle || showSubtitle ? '0' : '10px', " 10px ").concat(showFootnote ? '0' : '5px');
36371
+ }
36372
+ return bodyPadding;
36373
+ }
36374
+ return undefined;
36375
+ };
36376
+
36252
36377
  /**
36253
36378
  * @interface
36254
36379
  * @extends HTMLElement
@@ -36257,6 +36382,15 @@
36257
36382
  /** @type {'njs-cell'} */
36258
36383
  className: 'njs-cell'
36259
36384
  };
36385
+
36386
+ /**
36387
+ * @interface
36388
+ * @extends HTMLElement
36389
+ */
36390
+ const CellBody = {
36391
+ /** @type {'njs-cell-body'} */
36392
+ className: 'njs-cell-body'
36393
+ };
36260
36394
  const initialState = err => ({
36261
36395
  loading: false,
36262
36396
  loaded: false,
@@ -36538,6 +36672,7 @@
36538
36672
  }
36539
36673
  };
36540
36674
  const Cell = reactExports.forwardRef((_ref6, ref) => {
36675
+ var _halo$public$galaxy;
36541
36676
  let {
36542
36677
  halo,
36543
36678
  model: inputModel,
@@ -36787,6 +36922,25 @@
36787
36922
  appLayout: appLayout
36788
36923
  });
36789
36924
  }
36925
+ const flags = (_halo$public$galaxy = halo.public.galaxy) === null || _halo$public$galaxy === void 0 ? void 0 : _halo$public$galaxy.flags;
36926
+ let useOldCellPadding;
36927
+ let bodyPadding;
36928
+ if (disableCellPadding) {
36929
+ useOldCellPadding = false;
36930
+ bodyPadding = undefined;
36931
+ } else if (!(flags !== null && flags !== void 0 && flags.isEnabled('VNA-13_CELLPADDING_FROM_THEME'))) {
36932
+ useOldCellPadding = true;
36933
+ bodyPadding = undefined;
36934
+ } else {
36935
+ const senseTheme = halo.public.theme;
36936
+ useOldCellPadding = false;
36937
+ bodyPadding = getPadding({
36938
+ layout,
36939
+ isError: state.error,
36940
+ senseTheme,
36941
+ titleStyles
36942
+ });
36943
+ }
36790
36944
  return /*#__PURE__*/React.createElement(Paper, {
36791
36945
  style: {
36792
36946
  position: 'relative',
@@ -36818,7 +36972,7 @@
36818
36972
  position: 'relative',
36819
36973
  width: '100%',
36820
36974
  height: '100%'
36821
- }, !disableCellPadding ? {
36975
+ }, useOldCellPadding ? {
36822
36976
  padding: theme.spacing(1)
36823
36977
  } : {}), state.longRunningQuery ? {
36824
36978
  opacity: '0.3'
@@ -36835,9 +36989,12 @@
36835
36989
  onKeyDown: keyboardNavigation ? handleKeyDown : null,
36836
36990
  item: true,
36837
36991
  xs: true,
36838
- style: {
36992
+ className: CellBody.className,
36993
+ style: _objectSpread2({
36839
36994
  height: '100%'
36840
- },
36995
+ }, bodyPadding ? {
36996
+ padding: bodyPadding
36997
+ } : {}),
36841
36998
  ref: contentRef
36842
36999
  }, Content), cellNode && layout && state.sn && /*#__PURE__*/React.createElement(Footer, {
36843
37000
  layout: layout,
@@ -36887,7 +37044,7 @@
36887
37044
  model.on('closed', unmount);
36888
37045
  root.add(portal);
36889
37046
  // Cannot use model.id as it is not unique in a given mashup
36890
- root.addCell(currentId, cellRef);
37047
+ root.addCell(currentId, cellRef, unmount);
36891
37048
  return [unmount, cellRef];
36892
37049
  }
36893
37050
 
@@ -39070,9 +39227,20 @@
39070
39227
  * @returns {ExportFormat}
39071
39228
  */
39072
39229
 
39230
+ /**
39231
+ * @callback onPropertyChange
39232
+ * @param {qix.GenericObjectProperties} properties
39233
+ */
39234
+
39235
+ /**
39236
+ * @interface QAEProperties
39237
+ * @property {qix.GenericObjectProperties=} initial
39238
+ * @property {onPropertyChange=} onChange
39239
+ */
39240
+
39073
39241
  /**
39074
39242
  * @interface QAEDefinition
39075
- * @property {qix.GenericObjectProperties=} properties
39243
+ * @property {(QAEProperties|qix.GenericObjectProperties)=} properties
39076
39244
  * @property {object=} data
39077
39245
  * @property {DataTarget[]} data.targets
39078
39246
  * @property {importProperties=} importProperties
@@ -39883,21 +40051,28 @@
39883
40051
  /** @type {'njs-sheet'} */
39884
40052
  className: 'njs-sheet'
39885
40053
  };
39886
- function getCellRenderer(cell, halo, initialSnOptions, initialSnPlugins, initialError, onMount, navigation) {
40054
+ function getCellRenderer(cell, halo, initialSnOptions, initialSnPlugins, initialError, onMount, navigation, onError) {
40055
+ var _halo$public$galaxy;
39887
40056
  const {
39888
40057
  x,
39889
40058
  y,
39890
40059
  width,
39891
40060
  height
39892
40061
  } = cell.bounds;
40062
+ const style = {
40063
+ left: "".concat(x, "%"),
40064
+ top: "".concat(y, "%"),
40065
+ width: "".concat(width, "%"),
40066
+ height: "".concat(height, "%"),
40067
+ position: 'absolute'
40068
+ };
40069
+ const flags = (_halo$public$galaxy = halo.public.galaxy) === null || _halo$public$galaxy === void 0 ? void 0 : _halo$public$galaxy.flags;
40070
+ if (flags !== null && flags !== void 0 && flags.isEnabled('VNA-13_CELLPADDING_FROM_THEME')) {
40071
+ style.boxSizing = 'border-box';
40072
+ style.padding = '4px';
40073
+ }
39893
40074
  return /*#__PURE__*/React.createElement("div", {
39894
- style: {
39895
- left: "".concat(x, "%"),
39896
- top: "".concat(y, "%"),
39897
- width: "".concat(width, "%"),
39898
- height: "".concat(height, "%"),
39899
- position: 'absolute'
39900
- },
40075
+ style: style,
39901
40076
  key: cell.model.id
39902
40077
  }, /*#__PURE__*/React.createElement(Cell, {
39903
40078
  ref: cell.cellRef,
@@ -39908,7 +40083,8 @@
39908
40083
  initialSnPlugins: initialSnPlugins,
39909
40084
  initialError: initialError,
39910
40085
  onMount: onMount,
39911
- navigation: navigation
40086
+ navigation: navigation,
40087
+ onError: onError
39912
40088
  }));
39913
40089
  }
39914
40090
  function getBounds(pos, columns, rows) {
@@ -39932,7 +40108,8 @@
39932
40108
  initialError,
39933
40109
  onMount,
39934
40110
  unmount,
39935
- navigation
40111
+ navigation,
40112
+ onError
39936
40113
  } = _ref;
39937
40114
  const {
39938
40115
  root
@@ -39947,6 +40124,11 @@
39947
40124
  const [bgColor, setBgColor] = reactExports.useState(undefined);
39948
40125
  const [bgImage, setBgImage] = reactExports.useState(undefined);
39949
40126
  const [deepHash, setDeepHash] = reactExports.useState('');
40127
+ const renderState = reactExports.useRef({
40128
+ cellCount: 0,
40129
+ cellsRendered: 0,
40130
+ initialRender: false
40131
+ });
39950
40132
  navigation === null || navigation === void 0 || (_navigation$setCurren = navigation.setCurrentSheetId) === null || _navigation$setCurren === void 0 || _navigation$setCurren.call(navigation, model.id);
39951
40133
  /// For each object
39952
40134
  reactExports.useEffect(() => {
@@ -39967,6 +40149,15 @@
39967
40149
  root.removeCell(c.currentId);
39968
40150
  });
39969
40151
  const lCells = layout.cells;
40152
+ renderState.cellCount = lCells.length;
40153
+ renderState.cellsRendered = 0;
40154
+ const renderCallback = () => {
40155
+ renderState.cellsRendered++;
40156
+ if (renderState.cellsRendered === renderState.cellCount && !renderState.initialRender) {
40157
+ renderState.initialRender = true;
40158
+ initialSnOptions.onInitialRender();
40159
+ }
40160
+ };
39970
40161
  const {
39971
40162
  columns,
39972
40163
  rows
@@ -39994,7 +40185,10 @@
39994
40185
  cellRef: React.createRef(),
39995
40186
  currentId: uid(),
39996
40187
  mounted,
39997
- mountedPromise
40188
+ mountedPromise,
40189
+ options: _objectSpread2(_objectSpread2({}, initialSnOptions), {
40190
+ onInitialRender: renderCallback
40191
+ })
39998
40192
  };
39999
40193
  }));
40000
40194
  cs.forEach(c => root.addCell(c.currentId, c.cellRef));
@@ -40011,7 +40205,7 @@
40011
40205
  model.on('closed', onModelClose);
40012
40206
  return () => model.removeListener('closed', onModelClose);
40013
40207
  }, [model]);
40014
- const cellRenderers = reactExports.useMemo(() => cells ? cells.map(c => getCellRenderer(c, halo, initialSnOptions, initialSnPlugins, initialError, c.mounted, navigation)) : [], [cells]);
40208
+ const cellRenderers = reactExports.useMemo(() => cells ? cells.map(c => getCellRenderer(c, halo, c.options, initialSnPlugins, initialError, c.mounted, navigation, onError)) : [], [cells]);
40015
40209
  reactExports.useEffect(() => {
40016
40210
  const bgComp = layout !== null && layout !== void 0 && layout.components ? layout.components.find(comp => comp.key === 'general') : null;
40017
40211
  setBgColor(resolveBgColor(bgComp, halo.public.theme));
@@ -40061,7 +40255,8 @@
40061
40255
  initialSnPlugins,
40062
40256
  onMount,
40063
40257
  initialError,
40064
- navigation
40258
+ navigation,
40259
+ onError
40065
40260
  } = _ref;
40066
40261
  const {
40067
40262
  root
@@ -40080,7 +40275,8 @@
40080
40275
  initialError: initialError,
40081
40276
  onMount: onMount,
40082
40277
  unmount: unmount,
40083
- navigation: navigation
40278
+ navigation: navigation,
40279
+ onError: onError
40084
40280
  }), element, model.id);
40085
40281
  navigation.setSheetRef(sheetRef);
40086
40282
  root.add(portal);
@@ -40094,26 +40290,42 @@
40094
40290
  halo,
40095
40291
  navigation,
40096
40292
  initialError,
40097
- onDestroy = async () => {}
40293
+ onDestroy = async () => {},
40294
+ onRender = () => {},
40295
+ onError = () => {}
40098
40296
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
40099
40297
  let unmountSheet = noopi;
40100
40298
  let sheetRef = null;
40101
40299
  let mountedReference = null;
40102
40300
  let onMount = null;
40301
+ let onRenderResolve = null;
40103
40302
  const mounted = new Promise(resolve => {
40104
40303
  onMount = resolve;
40105
40304
  });
40305
+ const rendered = new Promise(resolve => {
40306
+ onRenderResolve = resolve;
40307
+ });
40308
+ const createOnInitialRender = override => () => {
40309
+ override === null || override === void 0 || override(); // from options.onInitialRender
40310
+ onRenderResolve(); // internal promise in viz to wait for render
40311
+ onRender(); // from RenderConfig
40312
+ };
40106
40313
  let initialSnOptions = {};
40107
40314
  let initialSnPlugins = [];
40108
40315
  const setSnOptions = async opts => {
40316
+ const override = opts.onInitialRender;
40109
40317
  if (mountedReference) {
40110
40318
  (async () => {
40111
40319
  await mounted;
40112
- sheetRef.current.setSnOptions(_objectSpread2(_objectSpread2({}, initialSnOptions), opts));
40320
+ sheetRef.current.setSnOptions(_objectSpread2(_objectSpread2(_objectSpread2({}, initialSnOptions), opts), {
40321
+ onInitialRender: createOnInitialRender(override)
40322
+ }));
40113
40323
  })();
40114
40324
  } else {
40115
40325
  // Handle setting options before mount
40116
- initialSnOptions = _objectSpread2(_objectSpread2({}, initialSnOptions), opts);
40326
+ initialSnOptions = _objectSpread2(_objectSpread2(_objectSpread2({}, initialSnOptions), opts), {
40327
+ onInitialRender: createOnInitialRender(override)
40328
+ });
40117
40329
  }
40118
40330
  };
40119
40331
  const setSnPlugins = async plugins => {
@@ -40160,6 +40372,15 @@
40160
40372
  * @type {Navigation}
40161
40373
  */
40162
40374
  navigation,
40375
+ /**
40376
+ * Gets the specific api that a Viz exposes.
40377
+ * @private currently empty and private
40378
+ * @returns {Promise<object>} object that contains the internal Viz api.
40379
+ */
40380
+ async getImperativeHandle() {
40381
+ await rendered;
40382
+ return sheetRef.current.getImperativeHandle();
40383
+ },
40163
40384
  /**
40164
40385
  * Destroys the sheet and removes it from the the DOM.
40165
40386
  * @example
@@ -40192,7 +40413,8 @@
40192
40413
  initialSnPlugins,
40193
40414
  initialError,
40194
40415
  onMount,
40195
- navigation
40416
+ navigation,
40417
+ onError
40196
40418
  });
40197
40419
  return mounted;
40198
40420
  },
@@ -40227,12 +40449,18 @@
40227
40449
  /* eslint no-underscore-dangle:0 */
40228
40450
  async function initSheet(model, optional, halo, navigation, initialError) {
40229
40451
  let onDestroy = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : async () => {};
40452
+ const {
40453
+ onRender,
40454
+ onError
40455
+ } = optional;
40230
40456
  const api = sheet({
40231
40457
  model,
40232
40458
  halo,
40233
40459
  navigation,
40234
40460
  initialError,
40235
- onDestroy
40461
+ onDestroy,
40462
+ onRender,
40463
+ onError
40236
40464
  });
40237
40465
  if (optional.options) {
40238
40466
  api.__DO_NOT_USE__.options(optional.options);
@@ -40375,7 +40603,9 @@
40375
40603
  return initSheet(model, {
40376
40604
  options,
40377
40605
  plugins,
40378
- element
40606
+ element,
40607
+ onRender,
40608
+ onError
40379
40609
  }, halo, navigation);
40380
40610
  }
40381
40611
  return init(model, {
@@ -42256,6 +42486,10 @@
42256
42486
  }
42257
42487
  return createSessionObject(cfg, halo, modelStore);
42258
42488
  },
42489
+ // TODO - document
42490
+ destroy: async () => {
42491
+ root.destroy();
42492
+ },
42259
42493
  /**
42260
42494
  * Creates a visualization model
42261
42495
  * @param {CreateConfig} cfg The create configuration.