@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.
package/core/esm/dev.js CHANGED
@@ -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
  */
@@ -5251,7 +5251,7 @@ function GlobalStyles(props) {
5251
5251
  }
5252
5252
 
5253
5253
  /**
5254
- * @mui/styled-engine v5.16.4
5254
+ * @mui/styled-engine v5.16.6
5255
5255
  *
5256
5256
  * @license MIT
5257
5257
  * This source code is licensed under the MIT license found in the
@@ -9081,7 +9081,7 @@ function create$3(definition) {
9081
9081
  return cache[key];
9082
9082
  }
9083
9083
 
9084
- const NEBULA_VERSION_HASH = "b434";
9084
+ const NEBULA_VERSION_HASH = "b727";
9085
9085
  ClassNameGenerator.configure(componentName => {
9086
9086
  return "njs-".concat(NEBULA_VERSION_HASH, "-").concat(componentName.replace('Mui', ''));
9087
9087
  });
@@ -9313,7 +9313,7 @@ function boot(_ref2) {
9313
9313
  const appRef = React__default.createRef();
9314
9314
  const element = document.createElement('div');
9315
9315
  element.style.display = 'none';
9316
- element.setAttribute('data-nebulajs-version', "5.3.0");
9316
+ element.setAttribute('data-nebulajs-version', "5.4.1");
9317
9317
  element.setAttribute('data-app-id', app.id);
9318
9318
  document.body.appendChild(element);
9319
9319
  if (context) {
@@ -15669,7 +15669,7 @@ const StyledIconButton = styled(IconButton)(() => ({
15669
15669
  boxShadow: 'inset 0 0 0 2px rgb(2, 117, 217)'
15670
15670
  }
15671
15671
  }));
15672
- function ListBoxSearch(_ref2) {
15672
+ function ListBoxSearch(_ref2, ref) {
15673
15673
  let {
15674
15674
  popoverOpen,
15675
15675
  selections,
@@ -15831,7 +15831,7 @@ function ListBoxSearch(_ref2) {
15831
15831
  abortSearch();
15832
15832
  focusOnInput();
15833
15833
  };
15834
- const onKeyDownClearSearch = async e => {
15834
+ const onKeyDownClearSearch = e => {
15835
15835
  const container = e.currentTarget.closest('.listbox-container');
15836
15836
  switch (e.key) {
15837
15837
  case 'Enter':
@@ -15854,6 +15854,11 @@ function ListBoxSearch(_ref2) {
15854
15854
  e.stopPropagation();
15855
15855
  return undefined;
15856
15856
  };
15857
+ useImperativeHandle$1(ref, () => ({
15858
+ focus() {
15859
+ focusOnInput();
15860
+ }
15861
+ }));
15857
15862
  if (!visible || searchEnabled === false) {
15858
15863
  return null;
15859
15864
  }
@@ -15901,6 +15906,7 @@ function ListBoxSearch(_ref2) {
15901
15906
  }
15902
15907
  });
15903
15908
  }
15909
+ var ListBoxSearch$1 = forwardRef(ListBoxSearch);
15904
15910
 
15905
15911
  /* eslint no-underscore-dangle: 0 */
15906
15912
  function createAppSelections(_ref) {
@@ -18433,13 +18439,19 @@ function ListBoxPopover(_ref) {
18433
18439
  components,
18434
18440
  checkboxes: checkboxesOption,
18435
18441
  selectDisabled = () => false,
18436
- flags
18442
+ flags,
18443
+ sortCriteria = [{
18444
+ qSortByState: 1,
18445
+ qSortByAscii: 1,
18446
+ qSortByNumeric: 1,
18447
+ qSortByLoadOrder: 1
18448
+ }]
18437
18449
  } = _ref;
18438
18450
  const isMasterDim = Boolean(fieldName === null || fieldName === void 0 ? void 0 : fieldName.qLibraryId);
18439
18451
  const open = show && Boolean(alignTo.current);
18440
18452
  const [listCount, setListCount] = useState$1(0);
18441
18453
  const theme = useTheme$1();
18442
- const searchContainerRef = useRef();
18454
+ const searchInputRef = useRef();
18443
18455
  const [model] = useSessionModel({
18444
18456
  qInfo: {
18445
18457
  qType: 'njsListbox'
@@ -18454,12 +18466,7 @@ function ListBoxPopover(_ref) {
18454
18466
  qHeight: 0
18455
18467
  }],
18456
18468
  qDef: {
18457
- qSortCriterias: [{
18458
- qSortByState: 1,
18459
- qSortByAscii: 1,
18460
- qSortByNumeric: 1,
18461
- qSortByLoadOrder: 1
18462
- }],
18469
+ qSortCriterias: sortCriteria,
18463
18470
  qFieldDefs: isMasterDim ? undefined : [fieldName]
18464
18471
  },
18465
18472
  qLibraryId: isMasterDim ? fieldName.qLibraryId : undefined
@@ -18522,8 +18529,7 @@ function ListBoxPopover(_ref) {
18522
18529
  selections
18523
18530
  });
18524
18531
  const onCtrlF = () => {
18525
- const input = searchContainerRef.current.querySelector('input');
18526
- input === null || input === void 0 || input.focus();
18532
+ searchInputRef.current.focus();
18527
18533
  };
18528
18534
  const hasSelections$1 = hasSelections(layout);
18529
18535
  return /*#__PURE__*/React__default.createElement(Popover, {
@@ -18597,9 +18603,9 @@ function ListBoxPopover(_ref) {
18597
18603
  }, /*#__PURE__*/React__default.createElement("div", {
18598
18604
  ref: moreAlignTo
18599
18605
  }), /*#__PURE__*/React__default.createElement(Grid, {
18600
- item: true,
18601
- ref: searchContainerRef
18602
- }, /*#__PURE__*/React__default.createElement(ListBoxSearch, {
18606
+ item: true
18607
+ }, /*#__PURE__*/React__default.createElement(ListBoxSearch$1, {
18608
+ ref: searchInputRef,
18603
18609
  popoverOpen: open,
18604
18610
  styles: styles,
18605
18611
  visible: true,
@@ -20556,18 +20562,6 @@ function ListBoxInline(_ref3) {
20556
20562
  selectDisabled = () => false,
20557
20563
  flags
20558
20564
  } = options;
20559
-
20560
- // Hook that will trigger update when used in useEffects.
20561
- // Modified from: https://medium.com/@teh_builder/ref-objects-inside-useeffect-hooks-eb7c15198780
20562
- const useRefWithCallback = () => {
20563
- const [ref, setInternalRef] = useState$1({});
20564
- const setRef = useCallback(node => {
20565
- setInternalRef({
20566
- current: node
20567
- });
20568
- }, [setInternalRef]);
20569
- return [ref, setRef];
20570
- };
20571
20565
  const theme = useTheme$1();
20572
20566
  const {
20573
20567
  translator,
@@ -20591,8 +20585,8 @@ function ListBoxInline(_ref3) {
20591
20585
  appLayout: app === null || app === void 0 ? void 0 : app.layout
20592
20586
  });
20593
20587
  const containerRef = useRef();
20588
+ const searchInputRef = useRef();
20594
20589
  const [containerRectRef, containerRect] = useRect$1();
20595
- const [searchContainer, searchContainerRef] = useRefWithCallback();
20596
20590
  const [showToolbar, setShowToolbar] = useState$1(false);
20597
20591
  const [showSearch, setShowSearch] = useState$1(false);
20598
20592
  const hovering = useRef(false);
@@ -20678,16 +20672,6 @@ function ListBoxInline(_ref3) {
20678
20672
  }
20679
20673
  };
20680
20674
  }, [toolbar, selections, isPopover]);
20681
- useEffect$1(() => {
20682
- if (!searchContainer || !searchContainer.current) {
20683
- return;
20684
- }
20685
- // Focus search field on toggle-show or when focusSearch is true.
20686
- if (search && focusSearch || search === 'toggle' && showSearch) {
20687
- const input = searchContainer.current.querySelector('input');
20688
- input && input.focus();
20689
- }
20690
- }, [searchContainer && searchContainer.current, showSearch, search, focusSearch]);
20691
20675
  const {
20692
20676
  wildCardSearch,
20693
20677
  searchEnabled,
@@ -20714,11 +20698,10 @@ function ListBoxInline(_ref3) {
20714
20698
  if (search === 'toggle') {
20715
20699
  handleShowSearch();
20716
20700
  } else {
20717
- const input = searchContainer.current.querySelector('input');
20718
- input === null || input === void 0 || input.focus();
20701
+ searchInputRef.current.focus();
20719
20702
  }
20720
20703
  };
20721
- const shouldAutoFocus = searchVisible && search === 'toggle';
20704
+ const shouldAutoFocus = searchVisible && (search === 'toggle' || focusSearch);
20722
20705
 
20723
20706
  // Add a container padding for grid mode to harmonize with the grid item margins (should sum to 8px).
20724
20707
  const isGridMode = (layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.dataLayout) === 'grid';
@@ -20785,9 +20768,9 @@ function ListBoxInline(_ref3) {
20785
20768
  role: "region",
20786
20769
  "aria-label": translator.get('Listbox.ResultFilterLabel')
20787
20770
  }, /*#__PURE__*/React__default.createElement(Grid, {
20788
- item: true,
20789
- ref: searchContainerRef
20790
- }, /*#__PURE__*/React__default.createElement(ListBoxSearch, {
20771
+ item: true
20772
+ }, /*#__PURE__*/React__default.createElement(ListBoxSearch$1, {
20773
+ ref: searchInputRef,
20791
20774
  selections: selections,
20792
20775
  selectionState: selectionState$1,
20793
20776
  model: model,
@@ -21413,7 +21396,8 @@ function ListBoxPopoverWrapper(_ref) {
21413
21396
  stateName: stateName,
21414
21397
  autoFocus: options.autoFocus,
21415
21398
  components: options.components,
21416
- flags: flags
21399
+ flags: flags,
21400
+ sortCriteria: options.sortCriteria
21417
21401
  });
21418
21402
  }
21419
21403
 
@@ -23547,7 +23531,8 @@ const loadType = async _ref5 => {
23547
23531
  nebbie,
23548
23532
  focusHandler,
23549
23533
  emitter,
23550
- onMount
23534
+ onMount,
23535
+ navigation
23551
23536
  } = _ref5;
23552
23537
  try {
23553
23538
  const snType = await getType({
@@ -23561,7 +23546,8 @@ const loadType = async _ref5 => {
23561
23546
  selections,
23562
23547
  nebbie,
23563
23548
  focusHandler,
23564
- emitter
23549
+ emitter,
23550
+ navigation
23565
23551
  });
23566
23552
  if (sn) {
23567
23553
  dispatch({
@@ -23599,7 +23585,8 @@ const Cell = forwardRef((_ref6, ref) => {
23599
23585
  initialError,
23600
23586
  onMount,
23601
23587
  currentId,
23602
- emitter
23588
+ emitter,
23589
+ navigation
23603
23590
  } = _ref6;
23604
23591
  const {
23605
23592
  app,
@@ -23729,7 +23716,8 @@ const Cell = forwardRef((_ref6, ref) => {
23729
23716
  nebbie,
23730
23717
  focusHandler: focusHandler.current,
23731
23718
  emitter,
23732
- onMount
23719
+ onMount,
23720
+ navigation
23733
23721
  });
23734
23722
  };
23735
23723
 
@@ -23904,7 +23892,8 @@ function glue$1(_ref) {
23904
23892
  initialSnPlugins,
23905
23893
  onMount,
23906
23894
  emitter,
23907
- initialError
23895
+ initialError,
23896
+ navigation
23908
23897
  } = _ref;
23909
23898
  const {
23910
23899
  root
@@ -23920,7 +23909,8 @@ function glue$1(_ref) {
23920
23909
  initialSnPlugins: initialSnPlugins,
23921
23910
  initialError: initialError,
23922
23911
  onMount: onMount,
23923
- emitter: emitter
23912
+ emitter: emitter,
23913
+ navigation: navigation
23924
23914
  }), element, currentId);
23925
23915
  const unmount = () => {
23926
23916
  root.remove(portal);
@@ -25136,7 +25126,6 @@ function useTheme() {
25136
25126
  /**
25137
25127
  * Gets the embed instance used.
25138
25128
  * @entry
25139
- * @experimental
25140
25129
  * @since 1.7.0
25141
25130
  * @returns {Embed} The embed instance used.
25142
25131
  * @example
@@ -25177,6 +25166,22 @@ function useDeviceType() {
25177
25166
  return useInternalContext('deviceType');
25178
25167
  }
25179
25168
 
25169
+ /**
25170
+ * Gets the navigation api to control sheet navigation. When useNavigation is used in Sense, it returns Sense.navigation.
25171
+ * @entry
25172
+ * @experimental
25173
+ * @since 5.4.0
25174
+ * @returns {Navigation} navigation api.
25175
+ * @example
25176
+ * import { useNavigation } from "@nebula.js/stardust";
25177
+ * // ...
25178
+ * const navigation = useNavigation();
25179
+ * const [activeSheetId, setActiveSheetId] = useState(navigation?.getCurrentSheetId() || "");
25180
+ */
25181
+ function useNavigation() {
25182
+ return useInternalContext('navigation');
25183
+ }
25184
+
25180
25185
  /**
25181
25186
  * Gets the array of plugins provided when rendering the visualization.
25182
25187
  * @entry
@@ -25502,7 +25507,6 @@ function onContextMenu(cb) {
25502
25507
  *
25503
25508
  * Used to update properties and get a new layout without triggering onInitialRender.
25504
25509
  * @entry
25505
- * @experimental
25506
25510
  * @returns {RenderState} The render state.
25507
25511
  * @example
25508
25512
  * import { useRenderState } from '@nebula.js/stardust';
@@ -25539,7 +25543,6 @@ function useRenderState() {
25539
25543
  /**
25540
25544
  * Gets an event emitter instance for the visualization.
25541
25545
  * @entry
25542
- * @experimental
25543
25546
  * @returns {Emitter}
25544
25547
  * @example
25545
25548
  * // In a Nebula visualization
@@ -25563,7 +25566,6 @@ function useEmitter() {
25563
25566
  }
25564
25567
 
25565
25568
  /**
25566
- * @experimental
25567
25569
  * @interface Keyboard
25568
25570
  * @property {boolean} enabled Whether or not Nebula handles keyboard navigation or not.
25569
25571
  * @property {boolean} active Set to true when the chart is activated, ie a user tabs to the chart and presses Enter or Space.
@@ -25754,6 +25756,7 @@ function createWithHooks(generator, opts, galaxy) {
25754
25756
  deviceType: galaxy.deviceType,
25755
25757
  theme: undefined,
25756
25758
  translator: galaxy.translator,
25759
+ navigation: opts.navigation,
25757
25760
  // --- dynamic values ---
25758
25761
  layout: {},
25759
25762
  appLayout: {},
@@ -26284,6 +26287,7 @@ function viz() {
26284
26287
  let {
26285
26288
  model,
26286
26289
  halo,
26290
+ navigation,
26287
26291
  initialError,
26288
26292
  onDestroy = async () => {}
26289
26293
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -26525,7 +26529,8 @@ function viz() {
26525
26529
  initialSnPlugins,
26526
26530
  initialError,
26527
26531
  onMount,
26528
- emitter
26532
+ emitter,
26533
+ navigation
26529
26534
  });
26530
26535
  return mounted;
26531
26536
  },
@@ -26620,11 +26625,12 @@ function viz() {
26620
26625
  }
26621
26626
 
26622
26627
  /* eslint no-underscore-dangle:0 */
26623
- async function init(model, optional, halo, initialError) {
26624
- let onDestroy = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : async () => {};
26628
+ async function init(model, optional, halo, navigation, initialError) {
26629
+ let onDestroy = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : async () => {};
26625
26630
  const api = viz({
26626
26631
  model,
26627
26632
  halo,
26633
+ navigation,
26628
26634
  initialError,
26629
26635
  onDestroy
26630
26636
  });
@@ -26686,7 +26692,8 @@ async function createSessionObject(_ref, halo, store) {
26686
26692
  options,
26687
26693
  plugins,
26688
26694
  element,
26689
- extendProperties
26695
+ extendProperties,
26696
+ navigation
26690
26697
  } = _ref;
26691
26698
  let mergedProps = {};
26692
26699
  const children = [];
@@ -26742,7 +26749,7 @@ async function createSessionObject(_ref, halo, store) {
26742
26749
  options,
26743
26750
  plugins,
26744
26751
  element
26745
- }, halo, error, onDestroy);
26752
+ }, halo, navigation, error, onDestroy);
26746
26753
  }
26747
26754
 
26748
26755
  /**
@@ -26856,7 +26863,7 @@ const SheetElement = {
26856
26863
  /** @type {'njs-sheet'} */
26857
26864
  className: 'njs-sheet'
26858
26865
  };
26859
- function getCellRenderer(cell, halo, initialSnOptions, initialSnPlugins, initialError, onMount) {
26866
+ function getCellRenderer(cell, halo, initialSnOptions, initialSnPlugins, initialError, onMount, navigation) {
26860
26867
  const {
26861
26868
  x,
26862
26869
  y,
@@ -26870,7 +26877,8 @@ function getCellRenderer(cell, halo, initialSnOptions, initialSnPlugins, initial
26870
26877
  width: "".concat(width, "%"),
26871
26878
  height: "".concat(height, "%"),
26872
26879
  position: 'absolute'
26873
- }
26880
+ },
26881
+ key: cell.model.id
26874
26882
  }, /*#__PURE__*/React__default.createElement(Cell, {
26875
26883
  ref: cell.cellRef,
26876
26884
  halo: halo,
@@ -26879,7 +26887,8 @@ function getCellRenderer(cell, halo, initialSnOptions, initialSnPlugins, initial
26879
26887
  initialSnOptions: initialSnOptions,
26880
26888
  initialSnPlugins: initialSnPlugins,
26881
26889
  initialError: initialError,
26882
- onMount: onMount
26890
+ onMount: onMount,
26891
+ navigation: navigation
26883
26892
  }));
26884
26893
  }
26885
26894
  function getBounds(pos, columns, rows) {
@@ -26893,18 +26902,22 @@ function getBounds(pos, columns, rows) {
26893
26902
  height: pos.rowspan / rows * 100
26894
26903
  };
26895
26904
  }
26896
- function Sheet(_ref) {
26905
+ const Sheet = forwardRef((_ref, ref) => {
26906
+ var _navigation$setCurren;
26897
26907
  let {
26898
- model,
26908
+ model: inputModel,
26899
26909
  halo,
26900
26910
  initialSnOptions,
26901
26911
  initialSnPlugins,
26902
26912
  initialError,
26903
- onMount
26913
+ onMount,
26914
+ unmount,
26915
+ navigation
26904
26916
  } = _ref;
26905
26917
  const {
26906
26918
  root
26907
26919
  } = halo;
26920
+ const [model, setModel] = useState$1(inputModel);
26908
26921
  const [layout] = useLayout$1(model);
26909
26922
  const {
26910
26923
  theme: themeName,
@@ -26914,7 +26927,7 @@ function Sheet(_ref) {
26914
26927
  const [bgColor, setBgColor] = useState$1(undefined);
26915
26928
  const [bgImage, setBgImage] = useState$1(undefined);
26916
26929
  const [deepHash, setDeepHash] = useState$1('');
26917
-
26930
+ navigation === null || navigation === void 0 || (_navigation$setCurren = navigation.setCurrentSheetId) === null || _navigation$setCurren === void 0 || _navigation$setCurren.call(navigation, model.id);
26918
26931
  /// For each object
26919
26932
  useEffect$1(() => {
26920
26933
  if (layout) {
@@ -26925,8 +26938,8 @@ function Sheet(_ref) {
26925
26938
  setDeepHash(hash);
26926
26939
  const fetchObjects = async () => {
26927
26940
  /*
26928
- Need to always fetch and evaluate everything as the sheet need to support multiple instances of the same object?
26929
- No, there is no way to add the same chart twice, so the optimization should be worth it.
26941
+ Need to always fetch and evaluate everything as the sheet need to support multiple instances of the same object?
26942
+ No, there is no way to add the same chart twice, so the optimization should be worth it.
26930
26943
  */
26931
26944
 
26932
26945
  // Clear the cell list
@@ -26970,16 +26983,29 @@ function Sheet(_ref) {
26970
26983
  fetchObjects();
26971
26984
  }
26972
26985
  }, [layout]);
26973
- const cellRenderers = useMemo$1(() => cells ? cells.map(c => getCellRenderer(c, halo, initialSnOptions, initialSnPlugins, initialError, c.mounted)) : [], [cells]);
26986
+ useEffect$1(() => {
26987
+ const onModelClose = () => {
26988
+ model.removeListener('closed', onModelClose);
26989
+ unmount();
26990
+ };
26991
+ model.on('closed', onModelClose);
26992
+ return () => model.removeListener('closed', onModelClose);
26993
+ }, [model]);
26994
+ const cellRenderers = useMemo$1(() => cells ? cells.map(c => getCellRenderer(c, halo, initialSnOptions, initialSnPlugins, initialError, c.mounted, navigation)) : [], [cells]);
26974
26995
  useEffect$1(() => {
26975
26996
  const bgComp = layout !== null && layout !== void 0 && layout.components ? layout.components.find(comp => comp.key === 'general') : null;
26976
26997
  setBgColor(resolveBgColor(bgComp, halo.public.theme));
26977
26998
  setBgImage(resolveBgImage(bgComp, halo.app));
26978
26999
  }, [layout, halo.public.theme, halo.app, themeName]);
26979
27000
 
27001
+ // Expose sheet ref api
27002
+ useImperativeHandle$1(ref, () => ({
27003
+ setModel
27004
+ }), []);
27005
+
26980
27006
  /* TODO
26981
- - sheet title + bg + logo etc + as option
26982
- - sheet exposed classnames for theming
27007
+ - sheet title + bg + logo etc + as option
27008
+ - sheet exposed classnames for theming
26983
27009
  */
26984
27010
 
26985
27011
  const height = !layout || Number.isNaN(layout.height) ? '100%' : "".concat(Number(layout.height), "%");
@@ -27004,7 +27030,7 @@ function Sheet(_ref) {
27004
27030
  backgroundPosition: bgImage && bgImage.pos
27005
27031
  }
27006
27032
  }, cellRenderers);
27007
- }
27033
+ });
27008
27034
 
27009
27035
  function glue(_ref) {
27010
27036
  let {
@@ -27014,26 +27040,29 @@ function glue(_ref) {
27014
27040
  initialSnOptions,
27015
27041
  initialSnPlugins,
27016
27042
  onMount,
27017
- initialError
27043
+ initialError,
27044
+ navigation
27018
27045
  } = _ref;
27019
27046
  const {
27020
27047
  root
27021
27048
  } = halo;
27022
27049
  const sheetRef = React__default.createRef();
27023
- const portal = ReactDOM.createPortal( /*#__PURE__*/React__default.createElement(Sheet, {
27050
+ let portal;
27051
+ const unmount = () => {
27052
+ root.remove(portal);
27053
+ };
27054
+ portal = ReactDOM.createPortal( /*#__PURE__*/React__default.createElement(Sheet, {
27024
27055
  ref: sheetRef,
27025
27056
  halo: halo,
27026
27057
  model: model,
27027
27058
  initialSnOptions: initialSnOptions,
27028
27059
  initialSnPlugins: initialSnPlugins,
27029
27060
  initialError: initialError,
27030
- onMount: onMount
27061
+ onMount: onMount,
27062
+ unmount: unmount,
27063
+ navigation: navigation
27031
27064
  }), element, model.id);
27032
- const unmount = () => {
27033
- root.remove(portal);
27034
- model.removeListener('closed', unmount);
27035
- };
27036
- model.on('closed', unmount);
27065
+ navigation.setSheetRef(sheetRef);
27037
27066
  root.add(portal);
27038
27067
  return [unmount, sheetRef];
27039
27068
  }
@@ -27043,6 +27072,7 @@ function sheet() {
27043
27072
  let {
27044
27073
  model,
27045
27074
  halo,
27075
+ navigation,
27046
27076
  initialError,
27047
27077
  onDestroy = async () => {}
27048
27078
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -27103,6 +27133,13 @@ function sheet() {
27103
27133
  * @type {string}
27104
27134
  */
27105
27135
  model,
27136
+ /**
27137
+ * The navigation api to control sheet navigation.
27138
+ * @experimental
27139
+ * @since 5.4.0
27140
+ * @type {Navigation}
27141
+ */
27142
+ navigation,
27106
27143
  /**
27107
27144
  * Destroys the sheet and removes it from the the DOM.
27108
27145
  * @example
@@ -27134,7 +27171,8 @@ function sheet() {
27134
27171
  initialSnOptions,
27135
27172
  initialSnPlugins,
27136
27173
  initialError,
27137
- onMount
27174
+ onMount,
27175
+ navigation
27138
27176
  });
27139
27177
  return mounted;
27140
27178
  },
@@ -27167,11 +27205,12 @@ function sheet() {
27167
27205
  }
27168
27206
 
27169
27207
  /* eslint no-underscore-dangle:0 */
27170
- async function initSheet(model, optional, halo, initialError) {
27171
- let onDestroy = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : async () => {};
27208
+ async function initSheet(model, optional, halo, navigation, initialError) {
27209
+ let onDestroy = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : async () => {};
27172
27210
  const api = sheet({
27173
27211
  model,
27174
27212
  halo,
27213
+ navigation,
27175
27214
  initialError,
27176
27215
  onDestroy
27177
27216
  });
@@ -27187,12 +27226,115 @@ async function initSheet(model, optional, halo, initialError) {
27187
27226
  return api;
27188
27227
  }
27189
27228
 
27229
+ function createNavigationApi(halo, store, model) {
27230
+ var _galaxy$anything;
27231
+ const {
27232
+ galaxy
27233
+ } = halo.public;
27234
+ if ((_galaxy$anything = galaxy.anything) !== null && _galaxy$anything !== void 0 && (_galaxy$anything = _galaxy$anything.sense) !== null && _galaxy$anything !== void 0 && _galaxy$anything.navigation) {
27235
+ var _galaxy$anything2;
27236
+ 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;
27237
+ }
27238
+ const State = {
27239
+ model
27240
+ };
27241
+
27242
+ /**
27243
+ * @class Navigation
27244
+ * @description The navigation api instance.
27245
+ * @implements Emitter
27246
+ * @experimental
27247
+ * @since 5.4.0
27248
+ * @example
27249
+ * const navigation = useNavigation();
27250
+ * //...
27251
+ * useEffect(() => {
27252
+ * const onSheetChanged = () => {
27253
+ * // do something
27254
+ * };
27255
+ * if (navigation?.addListener) {
27256
+ * navigation.addListener("sheetChanged", onSheetChanged);
27257
+ * }
27258
+ * return () => {
27259
+ * if (navigation?.removeListener) {
27260
+ * navigation.removeListener("sheetChanged", onSheetChanged);
27261
+ * }
27262
+ * };
27263
+ * }, [navigation]);
27264
+ *
27265
+ * const onSheetClick = (sheetId: string) => {
27266
+ * navigation?.goToSheet(sheetId);
27267
+ * };
27268
+ */
27269
+ const navigationAPI = /** @lends Navigation# */{
27270
+ /**
27271
+ * Navigate to the supplied sheet and emit 'sheetChanged' event if the target sheet Id is valid.
27272
+ * This allows a navigation object to synchronize its current sheet item with the active sheet.
27273
+ * @experimental
27274
+ * @since 5.4.0
27275
+ * @param {string} sheetId Id of the sheet to navigate to
27276
+ */
27277
+ goToSheet: async sheetId => {
27278
+ var _State$sheetRef, _State$sheetRef$setMo;
27279
+ if (!State.sheetRef) {
27280
+ return;
27281
+ }
27282
+ const {
27283
+ modelStore,
27284
+ rpcRequestModelStore
27285
+ } = store;
27286
+ const key = "".concat(sheetId);
27287
+ let rpc = rpcRequestModelStore.get(key);
27288
+ if (!rpc) {
27289
+ rpc = halo.app.getObject(sheetId);
27290
+ rpcRequestModelStore.set(key, rpc);
27291
+ }
27292
+ let newModel;
27293
+ try {
27294
+ newModel = await rpc;
27295
+ if (newModel.genericType !== 'sheet') {
27296
+ return;
27297
+ }
27298
+ } catch (e) {
27299
+ return;
27300
+ }
27301
+ modelStore.set(key, newModel);
27302
+ (_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);
27303
+ State.model = newModel;
27304
+ navigationAPI.emit('sheetChanged');
27305
+ },
27306
+ /**
27307
+ * @private
27308
+ * Set the sheet ref
27309
+ * @param {object} sheetRef sheet ref object
27310
+ */
27311
+ setSheetRef: sheetRef => {
27312
+ State.sheetRef = sheetRef;
27313
+ },
27314
+ /**
27315
+ * Return the current sheet id
27316
+ * @experimental
27317
+ * @since 5.4.0
27318
+ * @returns {string|false} The current sheet Id. false means there is no current sheet.
27319
+ */
27320
+ getCurrentSheetId: () => {
27321
+ if (State.model) {
27322
+ return State.model.id;
27323
+ }
27324
+ return false;
27325
+ }
27326
+ };
27327
+ eventmixin(navigationAPI);
27328
+ return navigationAPI;
27329
+ }
27330
+
27190
27331
  async function getObject(_ref, halo, store) {
27191
27332
  let {
27192
27333
  id,
27193
27334
  options,
27194
27335
  plugins,
27195
- element
27336
+ element,
27337
+ navigation: inputNavigation
27196
27338
  } = _ref;
27197
27339
  const {
27198
27340
  modelStore,
@@ -27206,18 +27348,19 @@ async function getObject(_ref, halo, store) {
27206
27348
  }
27207
27349
  const model = await rpc;
27208
27350
  modelStore.set(key, model);
27351
+ const navigation = inputNavigation || (model.genericType === 'sheet' ? createNavigationApi(halo, store, model) : undefined);
27209
27352
  if (model.genericType === 'sheet') {
27210
27353
  return initSheet(model, {
27211
27354
  options,
27212
27355
  plugins,
27213
27356
  element
27214
- }, halo);
27357
+ }, halo, navigation);
27215
27358
  }
27216
27359
  return init(model, {
27217
27360
  options,
27218
27361
  plugins,
27219
27362
  element
27220
- }, halo);
27363
+ }, halo, navigation);
27221
27364
  }
27222
27365
 
27223
27366
  function flagsFn () {
@@ -29631,5 +29774,5 @@ const __DO_NOT_USE__ = {
29631
29774
  locale
29632
29775
  };
29633
29776
 
29634
- export { mocker as EnigmaMocker, __DO_NOT_USE__, conversion, index as embed, onContextMenu, onTakeSnapshot, useAction, useApp, useAppLayout, useConstraints, useDeviceType, useEffect, useElement, useEmbed, useEmitter, useGlobal, useImperativeHandle, useInteractionState, useKeyboard, useLayout, useMemo, useModel, useOptions, usePlugins, usePromise, useRect, useRenderState, useSelections, useStaleLayout, useState, useTheme, useTranslator };
29777
+ export { mocker as EnigmaMocker, __DO_NOT_USE__, conversion, index as embed, onContextMenu, onTakeSnapshot, useAction, useApp, useAppLayout, useConstraints, useDeviceType, useEffect, useElement, useEmbed, useEmitter, useGlobal, useImperativeHandle, useInteractionState, useKeyboard, useLayout, useMemo, useModel, useNavigation, useOptions, usePlugins, usePromise, useRect, useRenderState, useSelections, useStaleLayout, useState, useTheme, useTranslator };
29635
29778
  //# sourceMappingURL=dev.js.map