@nebula.js/stardust 5.3.0 → 5.4.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.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * @nebula.js/stardust v5.3.0
2
+ * @nebula.js/stardust v5.4.1
3
3
  * Copyright (c) 2024 QlikTech International AB
4
4
  * Released under the MIT license.
5
5
  */
@@ -7349,7 +7349,7 @@
7349
7349
  }
7350
7350
 
7351
7351
  /**
7352
- * @mui/styled-engine v5.16.4
7352
+ * @mui/styled-engine v5.16.6
7353
7353
  *
7354
7354
  * @license MIT
7355
7355
  * This source code is licensed under the MIT license found in the
@@ -13544,7 +13544,7 @@
13544
13544
  return cache[key];
13545
13545
  }
13546
13546
 
13547
- const NEBULA_VERSION_HASH = "b434";
13547
+ const NEBULA_VERSION_HASH = "b727";
13548
13548
  ClassNameGenerator.configure(componentName => {
13549
13549
  return "njs-".concat(NEBULA_VERSION_HASH, "-").concat(componentName.replace('Mui', ''));
13550
13550
  });
@@ -13776,7 +13776,7 @@
13776
13776
  const appRef = React$1.createRef();
13777
13777
  const element = document.createElement('div');
13778
13778
  element.style.display = 'none';
13779
- element.setAttribute('data-nebulajs-version', "5.3.0");
13779
+ element.setAttribute('data-nebulajs-version', "5.4.1");
13780
13780
  element.setAttribute('data-app-id', app.id);
13781
13781
  document.body.appendChild(element);
13782
13782
  if (context) {
@@ -19082,6 +19082,8 @@
19082
19082
  whiteSpace: 'nowrap',
19083
19083
  textAlign: 'center',
19084
19084
  border: 0,
19085
+ borderTopStyle: 'solid',
19086
+ borderLeftStyle: 'solid',
19085
19087
  '&::before, &::after': {
19086
19088
  content: '""',
19087
19089
  alignSelf: 'center'
@@ -19092,7 +19094,8 @@
19092
19094
  }) => _extends$6({}, ownerState.children && ownerState.orientation !== 'vertical' && {
19093
19095
  '&::before, &::after': {
19094
19096
  width: '100%',
19095
- borderTop: `thin solid ${(theme.vars || theme).palette.divider}`
19097
+ borderTop: `thin solid ${(theme.vars || theme).palette.divider}`,
19098
+ borderTopStyle: 'inherit'
19096
19099
  }
19097
19100
  }), ({
19098
19101
  theme,
@@ -19101,7 +19104,8 @@
19101
19104
  flexDirection: 'column',
19102
19105
  '&::before, &::after': {
19103
19106
  height: '100%',
19104
- borderLeft: `thin solid ${(theme.vars || theme).palette.divider}`
19107
+ borderLeft: `thin solid ${(theme.vars || theme).palette.divider}`,
19108
+ borderLeftStyle: 'inherit'
19105
19109
  }
19106
19110
  }), ({
19107
19111
  ownerState
@@ -28421,7 +28425,7 @@
28421
28425
  boxShadow: 'inset 0 0 0 2px rgb(2, 117, 217)'
28422
28426
  }
28423
28427
  }));
28424
- function ListBoxSearch(_ref2) {
28428
+ function ListBoxSearch(_ref2, ref) {
28425
28429
  let {
28426
28430
  popoverOpen,
28427
28431
  selections,
@@ -28583,7 +28587,7 @@
28583
28587
  abortSearch();
28584
28588
  focusOnInput();
28585
28589
  };
28586
- const onKeyDownClearSearch = async e => {
28590
+ const onKeyDownClearSearch = e => {
28587
28591
  const container = e.currentTarget.closest('.listbox-container');
28588
28592
  switch (e.key) {
28589
28593
  case 'Enter':
@@ -28606,6 +28610,11 @@
28606
28610
  e.stopPropagation();
28607
28611
  return undefined;
28608
28612
  };
28613
+ reactExports.useImperativeHandle(ref, () => ({
28614
+ focus() {
28615
+ focusOnInput();
28616
+ }
28617
+ }));
28609
28618
  if (!visible || searchEnabled === false) {
28610
28619
  return null;
28611
28620
  }
@@ -28653,6 +28662,7 @@
28653
28662
  }
28654
28663
  });
28655
28664
  }
28665
+ var ListBoxSearch$1 = reactExports.forwardRef(ListBoxSearch);
28656
28666
 
28657
28667
  /* eslint no-underscore-dangle: 0 */
28658
28668
  function createAppSelections(_ref) {
@@ -31185,13 +31195,19 @@
31185
31195
  components,
31186
31196
  checkboxes: checkboxesOption,
31187
31197
  selectDisabled = () => false,
31188
- flags
31198
+ flags,
31199
+ sortCriteria = [{
31200
+ qSortByState: 1,
31201
+ qSortByAscii: 1,
31202
+ qSortByNumeric: 1,
31203
+ qSortByLoadOrder: 1
31204
+ }]
31189
31205
  } = _ref;
31190
31206
  const isMasterDim = Boolean(fieldName === null || fieldName === void 0 ? void 0 : fieldName.qLibraryId);
31191
31207
  const open = show && Boolean(alignTo.current);
31192
31208
  const [listCount, setListCount] = reactExports.useState(0);
31193
31209
  const theme = useTheme$2();
31194
- const searchContainerRef = reactExports.useRef();
31210
+ const searchInputRef = reactExports.useRef();
31195
31211
  const [model] = useSessionModel({
31196
31212
  qInfo: {
31197
31213
  qType: 'njsListbox'
@@ -31206,12 +31222,7 @@
31206
31222
  qHeight: 0
31207
31223
  }],
31208
31224
  qDef: {
31209
- qSortCriterias: [{
31210
- qSortByState: 1,
31211
- qSortByAscii: 1,
31212
- qSortByNumeric: 1,
31213
- qSortByLoadOrder: 1
31214
- }],
31225
+ qSortCriterias: sortCriteria,
31215
31226
  qFieldDefs: isMasterDim ? undefined : [fieldName]
31216
31227
  },
31217
31228
  qLibraryId: isMasterDim ? fieldName.qLibraryId : undefined
@@ -31274,8 +31285,7 @@
31274
31285
  selections
31275
31286
  });
31276
31287
  const onCtrlF = () => {
31277
- const input = searchContainerRef.current.querySelector('input');
31278
- input === null || input === void 0 || input.focus();
31288
+ searchInputRef.current.focus();
31279
31289
  };
31280
31290
  const hasSelections$1 = hasSelections(layout);
31281
31291
  return /*#__PURE__*/React$1.createElement(Popover, {
@@ -31349,9 +31359,9 @@
31349
31359
  }, /*#__PURE__*/React$1.createElement("div", {
31350
31360
  ref: moreAlignTo
31351
31361
  }), /*#__PURE__*/React$1.createElement(Grid, {
31352
- item: true,
31353
- ref: searchContainerRef
31354
- }, /*#__PURE__*/React$1.createElement(ListBoxSearch, {
31362
+ item: true
31363
+ }, /*#__PURE__*/React$1.createElement(ListBoxSearch$1, {
31364
+ ref: searchInputRef,
31355
31365
  popoverOpen: open,
31356
31366
  styles: styles,
31357
31367
  visible: true,
@@ -33308,18 +33318,6 @@
33308
33318
  selectDisabled = () => false,
33309
33319
  flags
33310
33320
  } = options;
33311
-
33312
- // Hook that will trigger update when used in useEffects.
33313
- // Modified from: https://medium.com/@teh_builder/ref-objects-inside-useeffect-hooks-eb7c15198780
33314
- const useRefWithCallback = () => {
33315
- const [ref, setInternalRef] = reactExports.useState({});
33316
- const setRef = reactExports.useCallback(node => {
33317
- setInternalRef({
33318
- current: node
33319
- });
33320
- }, [setInternalRef]);
33321
- return [ref, setRef];
33322
- };
33323
33321
  const theme = useTheme$2();
33324
33322
  const {
33325
33323
  translator,
@@ -33343,8 +33341,8 @@
33343
33341
  appLayout: app === null || app === void 0 ? void 0 : app.layout
33344
33342
  });
33345
33343
  const containerRef = reactExports.useRef();
33344
+ const searchInputRef = reactExports.useRef();
33346
33345
  const [containerRectRef, containerRect] = useRect$1();
33347
- const [searchContainer, searchContainerRef] = useRefWithCallback();
33348
33346
  const [showToolbar, setShowToolbar] = reactExports.useState(false);
33349
33347
  const [showSearch, setShowSearch] = reactExports.useState(false);
33350
33348
  const hovering = reactExports.useRef(false);
@@ -33430,16 +33428,6 @@
33430
33428
  }
33431
33429
  };
33432
33430
  }, [toolbar, selections, isPopover]);
33433
- reactExports.useEffect(() => {
33434
- if (!searchContainer || !searchContainer.current) {
33435
- return;
33436
- }
33437
- // Focus search field on toggle-show or when focusSearch is true.
33438
- if (search && focusSearch || search === 'toggle' && showSearch) {
33439
- const input = searchContainer.current.querySelector('input');
33440
- input && input.focus();
33441
- }
33442
- }, [searchContainer && searchContainer.current, showSearch, search, focusSearch]);
33443
33431
  const {
33444
33432
  wildCardSearch,
33445
33433
  searchEnabled,
@@ -33466,11 +33454,10 @@
33466
33454
  if (search === 'toggle') {
33467
33455
  handleShowSearch();
33468
33456
  } else {
33469
- const input = searchContainer.current.querySelector('input');
33470
- input === null || input === void 0 || input.focus();
33457
+ searchInputRef.current.focus();
33471
33458
  }
33472
33459
  };
33473
- const shouldAutoFocus = searchVisible && search === 'toggle';
33460
+ const shouldAutoFocus = searchVisible && (search === 'toggle' || focusSearch);
33474
33461
 
33475
33462
  // Add a container padding for grid mode to harmonize with the grid item margins (should sum to 8px).
33476
33463
  const isGridMode = (layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.dataLayout) === 'grid';
@@ -33537,9 +33524,9 @@
33537
33524
  role: "region",
33538
33525
  "aria-label": translator.get('Listbox.ResultFilterLabel')
33539
33526
  }, /*#__PURE__*/React$1.createElement(Grid, {
33540
- item: true,
33541
- ref: searchContainerRef
33542
- }, /*#__PURE__*/React$1.createElement(ListBoxSearch, {
33527
+ item: true
33528
+ }, /*#__PURE__*/React$1.createElement(ListBoxSearch$1, {
33529
+ ref: searchInputRef,
33543
33530
  selections: selections,
33544
33531
  selectionState: selectionState$1,
33545
33532
  model: model,
@@ -34165,7 +34152,8 @@
34165
34152
  stateName: stateName,
34166
34153
  autoFocus: options.autoFocus,
34167
34154
  components: options.components,
34168
- flags: flags
34155
+ flags: flags,
34156
+ sortCriteria: options.sortCriteria
34169
34157
  });
34170
34158
  }
34171
34159
 
@@ -36299,7 +36287,8 @@
36299
36287
  nebbie,
36300
36288
  focusHandler,
36301
36289
  emitter,
36302
- onMount
36290
+ onMount,
36291
+ navigation
36303
36292
  } = _ref5;
36304
36293
  try {
36305
36294
  const snType = await getType({
@@ -36313,7 +36302,8 @@
36313
36302
  selections,
36314
36303
  nebbie,
36315
36304
  focusHandler,
36316
- emitter
36305
+ emitter,
36306
+ navigation
36317
36307
  });
36318
36308
  if (sn) {
36319
36309
  dispatch({
@@ -36351,7 +36341,8 @@
36351
36341
  initialError,
36352
36342
  onMount,
36353
36343
  currentId,
36354
- emitter
36344
+ emitter,
36345
+ navigation
36355
36346
  } = _ref6;
36356
36347
  const {
36357
36348
  app,
@@ -36481,7 +36472,8 @@
36481
36472
  nebbie,
36482
36473
  focusHandler: focusHandler.current,
36483
36474
  emitter,
36484
- onMount
36475
+ onMount,
36476
+ navigation
36485
36477
  });
36486
36478
  };
36487
36479
 
@@ -36656,7 +36648,8 @@
36656
36648
  initialSnPlugins,
36657
36649
  onMount,
36658
36650
  emitter,
36659
- initialError
36651
+ initialError,
36652
+ navigation
36660
36653
  } = _ref;
36661
36654
  const {
36662
36655
  root
@@ -36672,7 +36665,8 @@
36672
36665
  initialSnPlugins: initialSnPlugins,
36673
36666
  initialError: initialError,
36674
36667
  onMount: onMount,
36675
- emitter: emitter
36668
+ emitter: emitter,
36669
+ navigation: navigation
36676
36670
  }), element, currentId);
36677
36671
  const unmount = () => {
36678
36672
  root.remove(portal);
@@ -37888,7 +37882,6 @@
37888
37882
  /**
37889
37883
  * Gets the embed instance used.
37890
37884
  * @entry
37891
- * @experimental
37892
37885
  * @since 1.7.0
37893
37886
  * @returns {Embed} The embed instance used.
37894
37887
  * @example
@@ -37929,6 +37922,22 @@
37929
37922
  return useInternalContext('deviceType');
37930
37923
  }
37931
37924
 
37925
+ /**
37926
+ * Gets the navigation api to control sheet navigation. When useNavigation is used in Sense, it returns Sense.navigation.
37927
+ * @entry
37928
+ * @experimental
37929
+ * @since 5.4.0
37930
+ * @returns {Navigation} navigation api.
37931
+ * @example
37932
+ * import { useNavigation } from "@nebula.js/stardust";
37933
+ * // ...
37934
+ * const navigation = useNavigation();
37935
+ * const [activeSheetId, setActiveSheetId] = useState(navigation?.getCurrentSheetId() || "");
37936
+ */
37937
+ function useNavigation() {
37938
+ return useInternalContext('navigation');
37939
+ }
37940
+
37932
37941
  /**
37933
37942
  * Gets the array of plugins provided when rendering the visualization.
37934
37943
  * @entry
@@ -38254,7 +38263,6 @@
38254
38263
  *
38255
38264
  * Used to update properties and get a new layout without triggering onInitialRender.
38256
38265
  * @entry
38257
- * @experimental
38258
38266
  * @returns {RenderState} The render state.
38259
38267
  * @example
38260
38268
  * import { useRenderState } from '@nebula.js/stardust';
@@ -38291,7 +38299,6 @@
38291
38299
  /**
38292
38300
  * Gets an event emitter instance for the visualization.
38293
38301
  * @entry
38294
- * @experimental
38295
38302
  * @returns {Emitter}
38296
38303
  * @example
38297
38304
  * // In a Nebula visualization
@@ -38315,7 +38322,6 @@
38315
38322
  }
38316
38323
 
38317
38324
  /**
38318
- * @experimental
38319
38325
  * @interface Keyboard
38320
38326
  * @property {boolean} enabled Whether or not Nebula handles keyboard navigation or not.
38321
38327
  * @property {boolean} active Set to true when the chart is activated, ie a user tabs to the chart and presses Enter or Space.
@@ -38506,6 +38512,7 @@
38506
38512
  deviceType: galaxy.deviceType,
38507
38513
  theme: undefined,
38508
38514
  translator: galaxy.translator,
38515
+ navigation: opts.navigation,
38509
38516
  // --- dynamic values ---
38510
38517
  layout: {},
38511
38518
  appLayout: {},
@@ -39036,6 +39043,7 @@
39036
39043
  let {
39037
39044
  model,
39038
39045
  halo,
39046
+ navigation,
39039
39047
  initialError,
39040
39048
  onDestroy = async () => {}
39041
39049
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -39277,7 +39285,8 @@
39277
39285
  initialSnPlugins,
39278
39286
  initialError,
39279
39287
  onMount,
39280
- emitter
39288
+ emitter,
39289
+ navigation
39281
39290
  });
39282
39291
  return mounted;
39283
39292
  },
@@ -39372,11 +39381,12 @@
39372
39381
  }
39373
39382
 
39374
39383
  /* eslint no-underscore-dangle:0 */
39375
- async function init(model, optional, halo, initialError) {
39376
- let onDestroy = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : async () => {};
39384
+ async function init(model, optional, halo, navigation, initialError) {
39385
+ let onDestroy = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : async () => {};
39377
39386
  const api = viz({
39378
39387
  model,
39379
39388
  halo,
39389
+ navigation,
39380
39390
  initialError,
39381
39391
  onDestroy
39382
39392
  });
@@ -39438,7 +39448,8 @@
39438
39448
  options,
39439
39449
  plugins,
39440
39450
  element,
39441
- extendProperties
39451
+ extendProperties,
39452
+ navigation
39442
39453
  } = _ref;
39443
39454
  let mergedProps = {};
39444
39455
  const children = [];
@@ -39494,7 +39505,7 @@
39494
39505
  options,
39495
39506
  plugins,
39496
39507
  element
39497
- }, halo, error, onDestroy);
39508
+ }, halo, navigation, error, onDestroy);
39498
39509
  }
39499
39510
 
39500
39511
  /**
@@ -39608,7 +39619,7 @@
39608
39619
  /** @type {'njs-sheet'} */
39609
39620
  className: 'njs-sheet'
39610
39621
  };
39611
- function getCellRenderer(cell, halo, initialSnOptions, initialSnPlugins, initialError, onMount) {
39622
+ function getCellRenderer(cell, halo, initialSnOptions, initialSnPlugins, initialError, onMount, navigation) {
39612
39623
  const {
39613
39624
  x,
39614
39625
  y,
@@ -39622,7 +39633,8 @@
39622
39633
  width: "".concat(width, "%"),
39623
39634
  height: "".concat(height, "%"),
39624
39635
  position: 'absolute'
39625
- }
39636
+ },
39637
+ key: cell.model.id
39626
39638
  }, /*#__PURE__*/React$1.createElement(Cell, {
39627
39639
  ref: cell.cellRef,
39628
39640
  halo: halo,
@@ -39631,7 +39643,8 @@
39631
39643
  initialSnOptions: initialSnOptions,
39632
39644
  initialSnPlugins: initialSnPlugins,
39633
39645
  initialError: initialError,
39634
- onMount: onMount
39646
+ onMount: onMount,
39647
+ navigation: navigation
39635
39648
  }));
39636
39649
  }
39637
39650
  function getBounds(pos, columns, rows) {
@@ -39645,18 +39658,22 @@
39645
39658
  height: pos.rowspan / rows * 100
39646
39659
  };
39647
39660
  }
39648
- function Sheet(_ref) {
39661
+ const Sheet = reactExports.forwardRef((_ref, ref) => {
39662
+ var _navigation$setCurren;
39649
39663
  let {
39650
- model,
39664
+ model: inputModel,
39651
39665
  halo,
39652
39666
  initialSnOptions,
39653
39667
  initialSnPlugins,
39654
39668
  initialError,
39655
- onMount
39669
+ onMount,
39670
+ unmount,
39671
+ navigation
39656
39672
  } = _ref;
39657
39673
  const {
39658
39674
  root
39659
39675
  } = halo;
39676
+ const [model, setModel] = reactExports.useState(inputModel);
39660
39677
  const [layout] = useLayout$1(model);
39661
39678
  const {
39662
39679
  theme: themeName,
@@ -39666,7 +39683,7 @@
39666
39683
  const [bgColor, setBgColor] = reactExports.useState(undefined);
39667
39684
  const [bgImage, setBgImage] = reactExports.useState(undefined);
39668
39685
  const [deepHash, setDeepHash] = reactExports.useState('');
39669
-
39686
+ navigation === null || navigation === void 0 || (_navigation$setCurren = navigation.setCurrentSheetId) === null || _navigation$setCurren === void 0 || _navigation$setCurren.call(navigation, model.id);
39670
39687
  /// For each object
39671
39688
  reactExports.useEffect(() => {
39672
39689
  if (layout) {
@@ -39677,8 +39694,8 @@
39677
39694
  setDeepHash(hash);
39678
39695
  const fetchObjects = async () => {
39679
39696
  /*
39680
- Need to always fetch and evaluate everything as the sheet need to support multiple instances of the same object?
39681
- No, there is no way to add the same chart twice, so the optimization should be worth it.
39697
+ Need to always fetch and evaluate everything as the sheet need to support multiple instances of the same object?
39698
+ No, there is no way to add the same chart twice, so the optimization should be worth it.
39682
39699
  */
39683
39700
 
39684
39701
  // Clear the cell list
@@ -39722,16 +39739,29 @@
39722
39739
  fetchObjects();
39723
39740
  }
39724
39741
  }, [layout]);
39725
- const cellRenderers = reactExports.useMemo(() => cells ? cells.map(c => getCellRenderer(c, halo, initialSnOptions, initialSnPlugins, initialError, c.mounted)) : [], [cells]);
39742
+ reactExports.useEffect(() => {
39743
+ const onModelClose = () => {
39744
+ model.removeListener('closed', onModelClose);
39745
+ unmount();
39746
+ };
39747
+ model.on('closed', onModelClose);
39748
+ return () => model.removeListener('closed', onModelClose);
39749
+ }, [model]);
39750
+ const cellRenderers = reactExports.useMemo(() => cells ? cells.map(c => getCellRenderer(c, halo, initialSnOptions, initialSnPlugins, initialError, c.mounted, navigation)) : [], [cells]);
39726
39751
  reactExports.useEffect(() => {
39727
39752
  const bgComp = layout !== null && layout !== void 0 && layout.components ? layout.components.find(comp => comp.key === 'general') : null;
39728
39753
  setBgColor(resolveBgColor(bgComp, halo.public.theme));
39729
39754
  setBgImage(resolveBgImage(bgComp, halo.app));
39730
39755
  }, [layout, halo.public.theme, halo.app, themeName]);
39731
39756
 
39757
+ // Expose sheet ref api
39758
+ reactExports.useImperativeHandle(ref, () => ({
39759
+ setModel
39760
+ }), []);
39761
+
39732
39762
  /* TODO
39733
- - sheet title + bg + logo etc + as option
39734
- - sheet exposed classnames for theming
39763
+ - sheet title + bg + logo etc + as option
39764
+ - sheet exposed classnames for theming
39735
39765
  */
39736
39766
 
39737
39767
  const height = !layout || Number.isNaN(layout.height) ? '100%' : "".concat(Number(layout.height), "%");
@@ -39756,7 +39786,7 @@
39756
39786
  backgroundPosition: bgImage && bgImage.pos
39757
39787
  }
39758
39788
  }, cellRenderers);
39759
- }
39789
+ });
39760
39790
 
39761
39791
  function glue(_ref) {
39762
39792
  let {
@@ -39766,26 +39796,29 @@
39766
39796
  initialSnOptions,
39767
39797
  initialSnPlugins,
39768
39798
  onMount,
39769
- initialError
39799
+ initialError,
39800
+ navigation
39770
39801
  } = _ref;
39771
39802
  const {
39772
39803
  root
39773
39804
  } = halo;
39774
39805
  const sheetRef = React$1.createRef();
39775
- const portal = ReactDOM.createPortal( /*#__PURE__*/React$1.createElement(Sheet, {
39806
+ let portal;
39807
+ const unmount = () => {
39808
+ root.remove(portal);
39809
+ };
39810
+ portal = ReactDOM.createPortal( /*#__PURE__*/React$1.createElement(Sheet, {
39776
39811
  ref: sheetRef,
39777
39812
  halo: halo,
39778
39813
  model: model,
39779
39814
  initialSnOptions: initialSnOptions,
39780
39815
  initialSnPlugins: initialSnPlugins,
39781
39816
  initialError: initialError,
39782
- onMount: onMount
39817
+ onMount: onMount,
39818
+ unmount: unmount,
39819
+ navigation: navigation
39783
39820
  }), element, model.id);
39784
- const unmount = () => {
39785
- root.remove(portal);
39786
- model.removeListener('closed', unmount);
39787
- };
39788
- model.on('closed', unmount);
39821
+ navigation.setSheetRef(sheetRef);
39789
39822
  root.add(portal);
39790
39823
  return [unmount, sheetRef];
39791
39824
  }
@@ -39795,6 +39828,7 @@
39795
39828
  let {
39796
39829
  model,
39797
39830
  halo,
39831
+ navigation,
39798
39832
  initialError,
39799
39833
  onDestroy = async () => {}
39800
39834
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -39855,6 +39889,13 @@
39855
39889
  * @type {string}
39856
39890
  */
39857
39891
  model,
39892
+ /**
39893
+ * The navigation api to control sheet navigation.
39894
+ * @experimental
39895
+ * @since 5.4.0
39896
+ * @type {Navigation}
39897
+ */
39898
+ navigation,
39858
39899
  /**
39859
39900
  * Destroys the sheet and removes it from the the DOM.
39860
39901
  * @example
@@ -39886,7 +39927,8 @@
39886
39927
  initialSnOptions,
39887
39928
  initialSnPlugins,
39888
39929
  initialError,
39889
- onMount
39930
+ onMount,
39931
+ navigation
39890
39932
  });
39891
39933
  return mounted;
39892
39934
  },
@@ -39919,11 +39961,12 @@
39919
39961
  }
39920
39962
 
39921
39963
  /* eslint no-underscore-dangle:0 */
39922
- async function initSheet(model, optional, halo, initialError) {
39923
- let onDestroy = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : async () => {};
39964
+ async function initSheet(model, optional, halo, navigation, initialError) {
39965
+ let onDestroy = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : async () => {};
39924
39966
  const api = sheet({
39925
39967
  model,
39926
39968
  halo,
39969
+ navigation,
39927
39970
  initialError,
39928
39971
  onDestroy
39929
39972
  });
@@ -39939,12 +39982,115 @@
39939
39982
  return api;
39940
39983
  }
39941
39984
 
39985
+ function createNavigationApi(halo, store, model) {
39986
+ var _galaxy$anything;
39987
+ const {
39988
+ galaxy
39989
+ } = halo.public;
39990
+ if ((_galaxy$anything = galaxy.anything) !== null && _galaxy$anything !== void 0 && (_galaxy$anything = _galaxy$anything.sense) !== null && _galaxy$anything !== void 0 && _galaxy$anything.navigation) {
39991
+ var _galaxy$anything2;
39992
+ return (_galaxy$anything2 = galaxy.anything) === null || _galaxy$anything2 === void 0 || (_galaxy$anything2 = _galaxy$anything2.sense) === null || _galaxy$anything2 === void 0 ? void 0 : _galaxy$anything2.navigation;
39993
+ }
39994
+ const State = {
39995
+ model
39996
+ };
39997
+
39998
+ /**
39999
+ * @class Navigation
40000
+ * @description The navigation api instance.
40001
+ * @implements Emitter
40002
+ * @experimental
40003
+ * @since 5.4.0
40004
+ * @example
40005
+ * const navigation = useNavigation();
40006
+ * //...
40007
+ * useEffect(() => {
40008
+ * const onSheetChanged = () => {
40009
+ * // do something
40010
+ * };
40011
+ * if (navigation?.addListener) {
40012
+ * navigation.addListener("sheetChanged", onSheetChanged);
40013
+ * }
40014
+ * return () => {
40015
+ * if (navigation?.removeListener) {
40016
+ * navigation.removeListener("sheetChanged", onSheetChanged);
40017
+ * }
40018
+ * };
40019
+ * }, [navigation]);
40020
+ *
40021
+ * const onSheetClick = (sheetId: string) => {
40022
+ * navigation?.goToSheet(sheetId);
40023
+ * };
40024
+ */
40025
+ const navigationAPI = /** @lends Navigation# */{
40026
+ /**
40027
+ * Navigate to the supplied sheet and emit 'sheetChanged' event if the target sheet Id is valid.
40028
+ * This allows a navigation object to synchronize its current sheet item with the active sheet.
40029
+ * @experimental
40030
+ * @since 5.4.0
40031
+ * @param {string} sheetId Id of the sheet to navigate to
40032
+ */
40033
+ goToSheet: async sheetId => {
40034
+ var _State$sheetRef, _State$sheetRef$setMo;
40035
+ if (!State.sheetRef) {
40036
+ return;
40037
+ }
40038
+ const {
40039
+ modelStore,
40040
+ rpcRequestModelStore
40041
+ } = store;
40042
+ const key = "".concat(sheetId);
40043
+ let rpc = rpcRequestModelStore.get(key);
40044
+ if (!rpc) {
40045
+ rpc = halo.app.getObject(sheetId);
40046
+ rpcRequestModelStore.set(key, rpc);
40047
+ }
40048
+ let newModel;
40049
+ try {
40050
+ newModel = await rpc;
40051
+ if (newModel.genericType !== 'sheet') {
40052
+ return;
40053
+ }
40054
+ } catch (e) {
40055
+ return;
40056
+ }
40057
+ modelStore.set(key, newModel);
40058
+ (_State$sheetRef = State.sheetRef) === null || _State$sheetRef === void 0 || (_State$sheetRef = _State$sheetRef.current) === null || _State$sheetRef === void 0 || (_State$sheetRef$setMo = _State$sheetRef.setModel) === null || _State$sheetRef$setMo === void 0 || _State$sheetRef$setMo.call(_State$sheetRef, newModel);
40059
+ State.model = newModel;
40060
+ navigationAPI.emit('sheetChanged');
40061
+ },
40062
+ /**
40063
+ * @private
40064
+ * Set the sheet ref
40065
+ * @param {object} sheetRef sheet ref object
40066
+ */
40067
+ setSheetRef: sheetRef => {
40068
+ State.sheetRef = sheetRef;
40069
+ },
40070
+ /**
40071
+ * Return the current sheet id
40072
+ * @experimental
40073
+ * @since 5.4.0
40074
+ * @returns {string|false} The current sheet Id. false means there is no current sheet.
40075
+ */
40076
+ getCurrentSheetId: () => {
40077
+ if (State.model) {
40078
+ return State.model.id;
40079
+ }
40080
+ return false;
40081
+ }
40082
+ };
40083
+ eventmixin(navigationAPI);
40084
+ return navigationAPI;
40085
+ }
40086
+
39942
40087
  async function getObject(_ref, halo, store) {
39943
40088
  let {
39944
40089
  id,
39945
40090
  options,
39946
40091
  plugins,
39947
- element
40092
+ element,
40093
+ navigation: inputNavigation
39948
40094
  } = _ref;
39949
40095
  const {
39950
40096
  modelStore,
@@ -39958,18 +40104,19 @@
39958
40104
  }
39959
40105
  const model = await rpc;
39960
40106
  modelStore.set(key, model);
40107
+ const navigation = inputNavigation || (model.genericType === 'sheet' ? createNavigationApi(halo, store, model) : undefined);
39961
40108
  if (model.genericType === 'sheet') {
39962
40109
  return initSheet(model, {
39963
40110
  options,
39964
40111
  plugins,
39965
40112
  element
39966
- }, halo);
40113
+ }, halo, navigation);
39967
40114
  }
39968
40115
  return init(model, {
39969
40116
  options,
39970
40117
  plugins,
39971
40118
  element
39972
- }, halo);
40119
+ }, halo, navigation);
39973
40120
  }
39974
40121
 
39975
40122
  function flagsFn () {
@@ -42405,6 +42552,7 @@
42405
42552
  exports.useLayout = useLayout;
42406
42553
  exports.useMemo = useMemo;
42407
42554
  exports.useModel = useModel;
42555
+ exports.useNavigation = useNavigation;
42408
42556
  exports.useOptions = useOptions;
42409
42557
  exports.usePlugins = usePlugins;
42410
42558
  exports.usePromise = usePromise;