@nova-design-system/nova-react 3.29.0 → 3.30.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.
Files changed (86) hide show
  1. package/dist/cjs/{constants-BReL3Lsa-DpB_ghPF.js → constants-gOKBmbgZ-CSoZ8z-G.js} +5 -0
  2. package/dist/cjs/generated/components.server.js +33 -1
  3. package/dist/cjs/index-DXwd3F_r.js +10391 -0
  4. package/dist/cjs/index.js +7 -1
  5. package/dist/cjs/{nv-accordion-item.entry-D1o0gC5w.js → nv-accordion-item.entry-CTbduehY.js} +3 -3
  6. package/dist/cjs/{nv-accordion.entry-DYJtq9Az.js → nv-accordion.entry-DeaPwIUP.js} +2 -2
  7. package/dist/cjs/{nv-alert.entry-CMtCdHmk.js → nv-alert.entry-B5k8RXXD.js} +8 -8
  8. package/dist/cjs/{nv-avatar.entry-B6e7aG4W.js → nv-avatar.entry-CJh9bGfN.js} +8 -8
  9. package/dist/cjs/{nv-badge_2.entry-RD3j0bJM.js → nv-badge_2.entry-BnPPW4rW.js} +5 -5
  10. package/dist/cjs/{nv-breadcrumb.entry-DgpqY2fr.js → nv-breadcrumb.entry-DS5GJVCJ.js} +2 -2
  11. package/dist/cjs/{nv-breadcrumbs.entry-CZgcDUw5.js → nv-breadcrumbs.entry-CJ835Ba8.js} +2 -2
  12. package/dist/cjs/{nv-button.entry-DR9NaRxG.js → nv-button.entry-8U0o_X3d.js} +7 -7
  13. package/dist/cjs/{nv-buttongroup.entry-qO8r7WqG.js → nv-buttongroup.entry-D5I5d9y0.js} +2 -2
  14. package/dist/cjs/{nv-calendar.entry-DRlv3Xph.js → nv-calendar.entry-C0ggIM3A.js} +9 -9
  15. package/dist/cjs/{nv-col.entry-B7utJttP.js → nv-col.entry-tIk723nS.js} +2 -2
  16. package/dist/cjs/{nv-datagrid.entry-digYmlnA.js → nv-datagrid.entry-Cal_usTi.js} +8 -8
  17. package/dist/cjs/{nv-datagridcolumn.entry-UwaDi-Hr.js → nv-datagridcolumn.entry-BLbpwW7Q.js} +2 -2
  18. package/dist/cjs/{nv-datetest.entry-BJtWaM2T.js → nv-datetest.entry-NQzySOox.js} +2 -2
  19. package/dist/cjs/{nv-datetimetest.entry-WaNPcHxh.js → nv-datetimetest.entry-Br6j4eAR.js} +1 -1
  20. package/dist/cjs/{nv-dialog.entry-BI_mFT2G.js → nv-dialog.entry-GTDQJaoQ.js} +3 -3
  21. package/dist/cjs/{nv-dialogfooter_2.entry-DU2ClBUR.js → nv-dialogfooter_2.entry-CHY36NHl.js} +6 -6
  22. package/dist/cjs/{nv-drawer.entry-BKF4CyOt.js → nv-drawer.entry-C-TZDi4-.js} +3 -3
  23. package/dist/cjs/{nv-drawerfooter_2.entry-BSyUs7_4.js → nv-drawerfooter_2.entry-DTY4qAnd.js} +6 -6
  24. package/dist/cjs/{nv-fieldcheckbox.entry-l5FWToQi.js → nv-fieldcheckbox.entry-Qf4gdEnq.js} +5 -5
  25. package/dist/cjs/{nv-fielddate.entry-BfviesNp.js → nv-fielddate.entry-D1aJmKbh.js} +7 -7
  26. package/dist/cjs/{nv-fielddaterange.entry-BvDkPLXG.js → nv-fielddaterange.entry-Vc-gHwf8.js} +7 -7
  27. package/dist/cjs/{nv-fielddropdown.entry-B-nYjuMt.js → nv-fielddropdown.entry-BVVsM71m.js} +5 -5
  28. package/dist/cjs/{nv-fielddropdownitem.entry-Dxqyb9DN.js → nv-fielddropdownitem.entry-DTRonCZJ.js} +2 -2
  29. package/dist/cjs/{nv-fieldmultiselect.entry-CgO1RP0W.js → nv-fieldmultiselect.entry-Cvsh_jn7.js} +1 -1
  30. package/dist/cjs/{nv-fieldnumber.entry-stgdLi7x.js → nv-fieldnumber.entry-jVFZ0wj3.js} +5 -5
  31. package/dist/cjs/{nv-fieldpassword.entry-CHA3JAUd.js → nv-fieldpassword.entry-CQKbWqMe.js} +5 -5
  32. package/dist/cjs/{nv-fieldradio.entry-DHavVjB-.js → nv-fieldradio.entry-FPGOqFBo.js} +4 -4
  33. package/dist/cjs/{nv-fieldselect.entry-Dq5AsOFt.js → nv-fieldselect.entry-DJmW4pff.js} +6 -6
  34. package/dist/cjs/{nv-fieldslider.entry-SlF3BBUW.js → nv-fieldslider.entry-D71HjSto.js} +4 -4
  35. package/dist/cjs/{nv-fieldtext.entry-BYCc8SyD.js → nv-fieldtext.entry-BxgbvxEW.js} +5 -5
  36. package/dist/cjs/{nv-fieldtextarea.entry-96JCOb9L.js → nv-fieldtextarea.entry-BDS37zhJ.js} +4 -4
  37. package/dist/cjs/{nv-fieldtime.entry-BdzjxkaK.js → nv-fieldtime.entry-DkWokxdT.js} +44 -44
  38. package/dist/cjs/{nv-icon.entry-CSRxi6BH.js → nv-icon.entry-CUemAv89.js} +8 -8
  39. package/dist/cjs/{nv-iconbutton_2.entry-BtDxwMFD.js → nv-iconbutton_2.entry-BLdJr3QV.js} +3 -3
  40. package/dist/cjs/{nv-menu.entry-aX39SPH8.js → nv-menu.entry-z4cDNCeX.js} +2 -2
  41. package/dist/cjs/{nv-menuitem.entry-DzSp52G2.js → nv-menuitem.entry-4XdONuGl.js} +2 -2
  42. package/dist/cjs/{nv-notification-bullet.entry-D2yOXj46.js → nv-notification-bullet.entry-B1EK4G_X.js} +1 -1
  43. package/dist/cjs/{nv-notification.entry-BRXHbtT8.js → nv-notification.entry-BBAQ72f7.js} +19 -19
  44. package/dist/cjs/{nv-notificationcontainer.entry-YNIM2_ah.js → nv-notificationcontainer.entry-CtFunFA9.js} +2 -2
  45. package/dist/cjs/{nv-pagination-nav.entry-uY1nT9aT.js → nv-pagination-nav.entry-DbzEBjoa.js} +2 -2
  46. package/dist/cjs/{nv-paginationtable.entry-mr5KYXVC.js → nv-paginationtable.entry-DRGsk0DH.js} +19 -3
  47. package/dist/cjs/{nv-popover.entry-_9ARKM70.js → nv-popover.entry-w9o3Y_vT.js} +2 -2
  48. package/dist/cjs/{nv-row.entry-BMQvcqlU.js → nv-row.entry-Cop4QB1Y.js} +2 -2
  49. package/dist/cjs/nv-sidebar.entry-96HyTMt9.js +355 -0
  50. package/dist/cjs/{nv-sidebarcontent.entry-llnRwVuj.js → nv-sidebarcontent.entry-RCkZZp9I.js} +2 -2
  51. package/dist/cjs/{nv-sidebardivider.entry--rQv8d5T.js → nv-sidebardivider.entry-DY25WqI7.js} +2 -2
  52. package/dist/cjs/{nv-sidebarfooter.entry-C5R0sUI_.js → nv-sidebarfooter.entry-9BFpNPLP.js} +2 -2
  53. package/dist/cjs/{nv-sidebargroup.entry-DdrpLbU7.js → nv-sidebargroup.entry-Cj52DXba.js} +2 -2
  54. package/dist/cjs/{nv-sidebarheader.entry-HuBPIsyf.js → nv-sidebarheader.entry-_WZgNwoi.js} +2 -2
  55. package/dist/cjs/{nv-sidebarlogo.entry-TZNPoqnA.js → nv-sidebarlogo.entry-4Zy6k3V5.js} +2 -2
  56. package/dist/cjs/{nv-sidebarnavitem.entry-BWc3mF5I.js → nv-sidebarnavitem.entry-fQ9sqxDj.js} +3 -3
  57. package/dist/cjs/{nv-sidebarnavsubitem.entry-DekANwO8.js → nv-sidebarnavsubitem.entry-1iBobkME.js} +2 -2
  58. package/dist/cjs/{nv-split.entry-BOwOB8FW.js → nv-split.entry-Dfzpge0r.js} +2 -2
  59. package/dist/cjs/{nv-stack.entry-CaTiSLGN.js → nv-stack.entry-BnCput1S.js} +2 -2
  60. package/dist/cjs/nv-statusindicator.entry-ClPHcTkz.js +42 -0
  61. package/dist/cjs/{nv-table.entry-LFZaS0Dy.js → nv-table.entry-DsllD6Bz.js} +3 -3
  62. package/dist/cjs/{nv-tableheader.entry-CK50S8xW.js → nv-tableheader.entry-AWCKrpLj.js} +2 -2
  63. package/dist/cjs/nv-tag.entry-BwENpoSV.js +85 -0
  64. package/dist/cjs/{nv-timetest.entry-A9elKwkf.js → nv-timetest.entry-BQsV7Qb2.js} +2 -2
  65. package/dist/cjs/{nv-toggle.entry-BGu-6rEs.js → nv-toggle.entry-a0tSJ6GE.js} +3 -3
  66. package/dist/cjs/{nv-togglebutton.entry-BzAcBOgN.js → nv-togglebutton.entry-CT8fZr74.js} +2 -2
  67. package/dist/cjs/{nv-togglebuttongroup.entry-CIWp7IXc.js → nv-togglebuttongroup.entry-BN7WkQ_L.js} +2 -2
  68. package/dist/cjs/{nv-tooltip.entry-CoGkSHpv.js → nv-tooltip.entry-xpFqRgZM.js} +2 -2
  69. package/dist/components/NvDatatable/NvDatatable.js +176 -59
  70. package/dist/components/NvDatatable/expandState.js +8 -0
  71. package/dist/components/NvDatatable/expandState.test.js +41 -0
  72. package/dist/components/NvDatatable/paginationState.js +9 -0
  73. package/dist/components/NvDatatable/paginationState.test.js +84 -0
  74. package/dist/generated/components.js +20 -1
  75. package/dist/generated/components.server.js +31 -1
  76. package/dist/types/components/NvDatatable/NvDatatable.d.ts +1 -1
  77. package/dist/types/components/NvDatatable/expandState.d.ts +5 -0
  78. package/dist/types/components/NvDatatable/expandState.test.d.ts +1 -0
  79. package/dist/types/components/NvDatatable/paginationState.d.ts +9 -0
  80. package/dist/types/components/NvDatatable/paginationState.test.d.ts +1 -0
  81. package/dist/types/components/NvDatatable/types.d.ts +16 -1
  82. package/dist/types/generated/components.d.ts +12 -1
  83. package/dist/types/generated/components.server.d.ts +12 -1
  84. package/package.json +1 -1
  85. package/dist/cjs/index-DgKzi_Pd.js +0 -10208
  86. package/dist/cjs/nv-sidebar.entry-C4HTjJmz.js +0 -181
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-DgKzi_Pd.js');
3
+ var index = require('./index-DXwd3F_r.js');
4
4
  require('@stencil/react-output-target/runtime');
5
5
  require('react');
6
6
  require('react-dom');
@@ -62,7 +62,7 @@ const NvTableheader = class {
62
62
  /****************************************************************************/
63
63
  //#region RENDER
64
64
  render() {
65
- return (index.h(index.Host, { key: '962f555a02b3035148c5915ae7493c68c0202cc7', role: "columnheader", "aria-sort": this.ariaSort, tabindex: this.sortable ? 0 : undefined, onKeyDown: this.handleKeyDown.bind(this), onClick: this.cycleSortDirection.bind(this) }, index.h("slot", { key: '0e69da3d4e2eb8ad01060f51d5043ffc14380415' }), this.sortable && (index.h("span", { key: 'a9b5ff97552d142cc3e1becc14a34ebab1f3092d', class: "sort-icon-wrap", "aria-hidden": "true" }, index.h("nv-iconbutton", { key: '76f832eba2b57f244dbce597668f493a918cf599', disableTabindex: true, name: "arrow-up", size: "xs", emphasis: this.sortDirection === 'none' ? 'lower' : 'low',
65
+ return (index.h(index.Host, { key: '1edf4d679b60517b8fdc239a1bc9e91fc55990ab', role: "columnheader", "aria-sort": this.ariaSort, tabindex: this.sortable ? 0 : undefined, onKeyDown: this.handleKeyDown.bind(this), onClick: this.cycleSortDirection.bind(this) }, index.h("slot", { key: '33d9ae13cbae6d34cf374bc626bc616c57e43322' }), this.sortable && (index.h("span", { key: '61e15b2af831a97051590e31369b42774f13ae53', class: "sort-icon-wrap", "aria-hidden": "true" }, index.h("nv-iconbutton", { key: 'e8cefc8559de91c2e892547b56eb51d5bc103c1c', disableTabindex: true, name: "arrow-up", size: "xs", emphasis: this.sortDirection === 'none' ? 'lower' : 'low',
66
66
  // prevent mousedown from selecting text
67
67
  onMouseDown: (e) => e.preventDefault(), class: {
68
68
  'is-none': this.sortDirection === 'none',
@@ -0,0 +1,85 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-DXwd3F_r.js');
4
+ var clsxChV9xqsO = require('./clsx-ChV9xqsO-BtxeOLZW.js');
5
+ require('@stencil/react-output-target/runtime');
6
+ require('react');
7
+ require('react-dom');
8
+
9
+ const nvTagCss = () => `nv-tag{display:inline-flex;align-items:center;gap:var(--tag-gap-x);padding:0 var(--tag-padding-x);border-radius:var(--tag-border-radius);border:1px solid;overflow:hidden;font-family:var(--font-family-default), var(--font-family-fallback), sans-serif;font-size:var(--font-size-xs);font-weight:var(--font-weight-medium-emphasis);line-height:var(--line-height-xs);height:var(--tag-height);width:fit-content;vertical-align:middle}nv-tag.has-dismiss{padding-right:0}nv-tag.tag-orange{color:var(--color-rainbow-2-text);background-color:var(--color-rainbow-2-background);border-color:var(--color-rainbow-2-border-light)}nv-tag.tag-orange nv-icon{color:var(--color-rainbow-2-icon)}nv-tag.tag-orange .nv-tag-content:focus,nv-tag.tag-orange .nv-tag-content:focus-within{outline:none}nv-tag.tag-orange .nv-tag-content:focus-visible,nv-tag.tag-orange .nv-tag-content:has(:focus-visible){outline:calc(var(--focus-outline-stroke) * 1) solid var(--color-rainbow-2-text);outline-offset:calc(var(--focus-outline-offset) * 0.2)}nv-tag.tag-crimson{color:var(--color-rainbow-6-text);background-color:var(--color-rainbow-6-background);border-color:var(--color-rainbow-6-border-light)}nv-tag.tag-crimson nv-icon{color:var(--color-rainbow-6-icon)}nv-tag.tag-crimson .nv-tag-content:focus,nv-tag.tag-crimson .nv-tag-content:focus-within{outline:none}nv-tag.tag-crimson .nv-tag-content:focus-visible,nv-tag.tag-crimson .nv-tag-content:has(:focus-visible){outline:calc(var(--focus-outline-stroke) * 1) solid var(--color-rainbow-6-text);outline-offset:calc(var(--focus-outline-offset) * 0.2)}nv-tag.tag-yellow{color:var(--color-rainbow-3-text);background-color:var(--color-rainbow-3-background);border-color:var(--color-rainbow-3-border-light)}nv-tag.tag-yellow nv-icon{color:var(--color-rainbow-3-icon)}nv-tag.tag-yellow .nv-tag-content:focus,nv-tag.tag-yellow .nv-tag-content:focus-within{outline:none}nv-tag.tag-yellow .nv-tag-content:focus-visible,nv-tag.tag-yellow .nv-tag-content:has(:focus-visible){outline:calc(var(--focus-outline-stroke) * 1) solid var(--color-rainbow-3-text);outline-offset:calc(var(--focus-outline-offset) * 0.2)}nv-tag.tag-red{color:var(--color-rainbow-4-text);background-color:var(--color-rainbow-4-background);border-color:var(--color-rainbow-4-border-light)}nv-tag.tag-red nv-icon{color:var(--color-rainbow-4-icon)}nv-tag.tag-red .nv-tag-content:focus,nv-tag.tag-red .nv-tag-content:focus-within{outline:none}nv-tag.tag-red .nv-tag-content:focus-visible,nv-tag.tag-red .nv-tag-content:has(:focus-visible){outline:calc(var(--focus-outline-stroke) * 1) solid var(--color-rainbow-4-text);outline-offset:calc(var(--focus-outline-offset) * 0.2)}nv-tag.tag-blue{color:var(--color-rainbow-8-text);background-color:var(--color-rainbow-8-background);border-color:var(--color-rainbow-8-border-light)}nv-tag.tag-blue nv-icon{color:var(--color-rainbow-8-icon)}nv-tag.tag-blue .nv-tag-content:focus,nv-tag.tag-blue .nv-tag-content:focus-within{outline:none}nv-tag.tag-blue .nv-tag-content:focus-visible,nv-tag.tag-blue .nv-tag-content:has(:focus-visible){outline:calc(var(--focus-outline-stroke) * 1) solid var(--color-rainbow-8-text);outline-offset:calc(var(--focus-outline-offset) * 0.2)}nv-tag.tag-amber{color:var(--color-rainbow-1-text);background-color:var(--color-rainbow-1-background);border-color:var(--color-rainbow-1-border-light)}nv-tag.tag-amber nv-icon{color:var(--color-rainbow-1-icon)}nv-tag.tag-amber .nv-tag-content:focus,nv-tag.tag-amber .nv-tag-content:focus-within{outline:none}nv-tag.tag-amber .nv-tag-content:focus-visible,nv-tag.tag-amber .nv-tag-content:has(:focus-visible){outline:calc(var(--focus-outline-stroke) * 1) solid var(--color-rainbow-1-text);outline-offset:calc(var(--focus-outline-offset) * 0.2)}nv-tag.tag-green{color:var(--color-rainbow-7-text);background-color:var(--color-rainbow-7-background);border-color:var(--color-rainbow-7-border-light)}nv-tag.tag-green nv-icon{color:var(--color-rainbow-7-icon)}nv-tag.tag-green .nv-tag-content:focus,nv-tag.tag-green .nv-tag-content:focus-within{outline:none}nv-tag.tag-green .nv-tag-content:focus-visible,nv-tag.tag-green .nv-tag-content:has(:focus-visible){outline:calc(var(--focus-outline-stroke) * 1) solid var(--color-rainbow-7-text);outline-offset:calc(var(--focus-outline-offset) * 0.2)}nv-tag.tag-turquoise{color:var(--color-rainbow-5-text);background-color:var(--color-rainbow-5-background);border-color:var(--color-rainbow-5-border-light)}nv-tag.tag-turquoise nv-icon{color:var(--color-rainbow-5-icon)}nv-tag.tag-turquoise .nv-tag-content:focus,nv-tag.tag-turquoise .nv-tag-content:focus-within{outline:none}nv-tag.tag-turquoise .nv-tag-content:focus-visible,nv-tag.tag-turquoise .nv-tag-content:has(:focus-visible){outline:calc(var(--focus-outline-stroke) * 1) solid var(--color-rainbow-5-text);outline-offset:calc(var(--focus-outline-offset) * 0.2)}nv-tag.tag-lime{color:var(--color-rainbow-9-text);background-color:var(--color-rainbow-9-background);border-color:var(--color-rainbow-9-border-light)}nv-tag.tag-lime nv-icon{color:var(--color-rainbow-9-icon)}nv-tag.tag-lime .nv-tag-content:focus,nv-tag.tag-lime .nv-tag-content:focus-within{outline:none}nv-tag.tag-lime .nv-tag-content:focus-visible,nv-tag.tag-lime .nv-tag-content:has(:focus-visible){outline:calc(var(--focus-outline-stroke) * 1) solid var(--color-rainbow-9-text);outline-offset:calc(var(--focus-outline-offset) * 0.2)}nv-tag.tag-grey{color:var(--color-rainbow-10-text);background-color:var(--color-rainbow-10-background);border-color:var(--color-rainbow-10-border-light)}nv-tag.tag-grey nv-icon{color:var(--color-rainbow-10-icon)}nv-tag.tag-grey .nv-tag-content:focus,nv-tag.tag-grey .nv-tag-content:focus-within{outline:none}nv-tag.tag-grey .nv-tag-content:focus-visible,nv-tag.tag-grey .nv-tag-content:has(:focus-visible){outline:calc(var(--focus-outline-stroke) * 1) solid var(--color-rainbow-10-text);outline-offset:calc(var(--focus-outline-offset) * 0.2)}nv-tag .nv-tag-leading{display:contents}nv-tag .nv-tag-label{white-space:nowrap}nv-tag .nv-tag-content{display:inline-flex;align-items:center;gap:var(--tag-gap-x);color:inherit;text-decoration:none;border-radius:var(--tag-border-radius)}nv-tag.is-link .nv-tag-content{cursor:pointer}nv-tag.is-link .nv-tag-content:hover{text-decoration:underline}nv-tag .nv-tag-dismiss{padding:0;margin:0;line-height:0;border:none;background:none;cursor:pointer;color:inherit;display:inline-flex;align-items:center;justify-content:center;width:var(--tag-height);height:var(--tag-height);border-radius:0;appearance:none}nv-tag .nv-tag-dismiss:focus,nv-tag .nv-tag-dismiss:focus-within{outline:none}nv-tag .nv-tag-dismiss:focus-visible{border-radius:0;box-shadow:inset 0 0 0 var(--focus-outline-stroke) var(--color-focus-brand)}nv-tag .nv-tag-dismiss:hover{background-color:var(--color-interaction-container-neutral-background-hover);mix-blend-mode:multiply}nv-tag .nv-tag-dismiss:disabled{opacity:var(--opacity-disabled);pointer-events:none;cursor:default}nv-tag nv-icon>svg{width:var(--spacing-3);height:var(--spacing-3);stroke-width:1.2px}`;
10
+
11
+ const NvTag = class {
12
+ constructor(hostRef) {
13
+ index.registerInstance(this, hostRef);
14
+ this.dismissed = index.createEvent(this, "dismissed", 3);
15
+ /****************************************************************************/
16
+ //#region PROPERTIES
17
+ /**
18
+ * The color variant of the tag.
19
+ */
20
+ this.color = 'grey';
21
+ /**
22
+ * Whether the tag can be dismissed.
23
+ */
24
+ this.dismissible = false;
25
+ /**
26
+ * The browsing context for the link.
27
+ */
28
+ this.target = '_self';
29
+ /**
30
+ * Whether the dismiss button is disabled.
31
+ */
32
+ this.disabled = false;
33
+ //#endregion EVENTS
34
+ /****************************************************************************/
35
+ //#region METHODS
36
+ /**
37
+ * Handles the dismiss button click.
38
+ * @param {MouseEvent} event - The click event.
39
+ */
40
+ this.handleDismiss = (event) => {
41
+ event.stopPropagation();
42
+ this.dismissed.emit({ label: this.label });
43
+ };
44
+ }
45
+ //#endregion METHODS
46
+ /****************************************************************************/
47
+ //#region RENDER
48
+ /**
49
+ * Renders the tag content (icon + label).
50
+ * @returns {unknown} The tag content JSX.
51
+ */
52
+ renderContent() {
53
+ return [
54
+ index.h("span", { class: "nv-tag-leading", "aria-hidden": "true" }, index.h("slot", { name: "leading-icon" })),
55
+ index.h("span", { class: "nv-tag-label" }, this.label),
56
+ ];
57
+ }
58
+ /**
59
+ * Computes the rel attribute for the anchor.
60
+ * @returns {string | undefined} The computed rel value.
61
+ */
62
+ computeRel() {
63
+ if (this.href == null)
64
+ return undefined;
65
+ if (this.rel)
66
+ return this.rel;
67
+ if (this.target === '_blank')
68
+ return 'noopener noreferrer';
69
+ return undefined;
70
+ }
71
+ render() {
72
+ const isLink = this.href != null;
73
+ const TagContent = isLink ? 'a' : 'span';
74
+ const anchorProps = isLink
75
+ ? { href: this.href, target: this.target, rel: this.computeRel() }
76
+ : {};
77
+ return (index.h(index.Host, { key: '91f8ca597d894aaa486f1323e85b5f41a20cd964', class: clsxChV9xqsO.clsx(`tag-${this.color}`, {
78
+ 'has-dismiss': this.dismissible,
79
+ 'is-link': isLink,
80
+ }) }, index.h(TagContent, { key: 'fb92a9c11d119770e9cea1091a9a3efcd988a132', class: "nv-tag-content", ...anchorProps }, this.renderContent()), this.dismissible && (index.h("button", { key: '8d66bfae4867b83bc24ea316237fb64347fd494b', class: "nv-tag-dismiss", type: "button", "aria-label": this.label ? `Remove ${this.label}` : undefined, disabled: this.disabled, onClick: this.handleDismiss }, index.h("nv-icon", { key: 'd271fc3152cfe7bcca19b372f2bf313b339e9c37', name: "x", size: "xs" })))));
81
+ }
82
+ };
83
+ NvTag.style = nvTagCss();
84
+
85
+ exports.nv_tag = NvTag;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-DgKzi_Pd.js');
3
+ var index = require('./index-DXwd3F_r.js');
4
4
  var novaDatetimeCyL2J6O4 = require('./nova-datetime-CyL2J6O4-0Y9g3rfI.js');
5
5
  require('@stencil/react-output-target/runtime');
6
6
  require('react');
@@ -67,7 +67,7 @@ const NvTimetest = class {
67
67
  /****************************************************************************/
68
68
  //#region RENDER
69
69
  render() {
70
- return (index.h(index.Host, { key: '85d3773d49a180e5bc9b5bc0962cc3b709a474b0' }, index.h("label", { key: 'c0d5c262578e6aa1555ded8c542e2eef7e42d491' }, "Start:", index.h("input", { key: '31fe9447be14efd87aab1161dbc01593a30328dc', type: "time", step: "1", value: this.value?.start ?? '', onInput: this.handleStartChange })), index.h("label", { key: '0959b432f53169c425765b94c098ca5ecc8d6ede' }, "End:", index.h("input", { key: 'ccc50a80dfea2ab7eb627d11840dd5626ca25f88', type: "time", step: "1", value: this.value?.end ?? '', onInput: this.handleEndChange })), index.h("slot", { key: 'd4c6a017d41102a245e1f8472d676bc866382c00' })));
70
+ return (index.h(index.Host, { key: 'c9c68e93ef3e0ab01e06918f707c89a6b7bd650b' }, index.h("label", { key: '418d4bea5711e9db888650aff9e8b89bc0945710' }, "Start:", index.h("input", { key: '15eeee721a64b4c2811814c7d3c7303c84dfb071', type: "time", step: "1", value: this.value?.start ?? '', onInput: this.handleStartChange })), index.h("label", { key: 'e21457f05d522370ed8dccbb228b20207fe0b973' }, "End:", index.h("input", { key: '856e9a1bce12c51c49c1f666e37d4b8d0d878960', type: "time", step: "1", value: this.value?.end ?? '', onInput: this.handleEndChange })), index.h("slot", { key: '983319380ff04eaaca09a0ffcd9f50523f235580' })));
71
71
  }
72
72
  };
73
73
  NvTimetest.style = nvTimetestCss();
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-DgKzi_Pd.js');
3
+ var index = require('./index-DXwd3F_r.js');
4
4
  var clsxChV9xqsO = require('./clsx-ChV9xqsO-BtxeOLZW.js');
5
5
  var v4BdYh22OP = require('./v4-BdYh22OP-C1vaJ4yP.js');
6
6
  require('@stencil/react-output-target/runtime');
@@ -66,8 +66,8 @@ const NvToggle = class {
66
66
  /****************************************************************************/
67
67
  //#region RENDER
68
68
  render() {
69
- return (index.h(index.Host, { key: '39ad1374bbf8cd5393a99dc4c18fa28091dc5e90', class: clsxChV9xqsO.clsx(this.labelPlacement === 'before' && 'label-placement-before') }, index.h("div", { key: '3a8be2405404975398f1a0dae05c0855b913245f', class: "input-container" }, index.h("input", { key: 'b589b9faa5801f99e698d0e664e0a35779a1271f', type: "checkbox", id: this.inputId, name: this.name, autocomplete: "off", value: this.value, checked: Boolean(this.checked), disabled: this.disabled || this.readonly, readonly: this.readonly })), index.h("div", { key: 'a3308782b02b1c0eca3d6a1b87509674b9bc5c13', class: "text-container" }, (this.label || this.el.querySelector('[slot="label"]')) && (index.h("label", { key: '854b2ffe7bf61423512154ffe8b3b0351a2950a4', htmlFor: this.inputId, class: clsxChV9xqsO.clsx(this.hideLabel && 'visually-hidden') }, index.h("slot", { key: '933bf88b7841f3b2ed24c3bb86fb24159eaac900', name: "label" }, this.label))), (this.description ||
70
- this.el.querySelector('[slot="description"]')) && (index.h("div", { key: '5a04358d1be3b935239bb23e1466cc22ed2f3b48', class: "description" }, index.h("slot", { key: 'f5c1513eff6ee42bc171b0088baec634f8458197', name: "description" }, this.description))))));
69
+ return (index.h(index.Host, { key: 'b2bf7956fbe102ff780e87bc731c8d558a6890fe', class: clsxChV9xqsO.clsx(this.labelPlacement === 'before' && 'label-placement-before') }, index.h("div", { key: '920b35e98be9f6ef90489a84307e6588c192e4c3', class: "input-container" }, index.h("input", { key: 'ae627fc038ca204d9e79d9643ba4e946a16fa76d', type: "checkbox", id: this.inputId, name: this.name, autocomplete: "off", value: this.value, checked: Boolean(this.checked), disabled: this.disabled || this.readonly, readonly: this.readonly })), index.h("div", { key: '9c5c0ebba6f24aa9f0556b2c86d823b43c8dd142', class: "text-container" }, (this.label || this.el.querySelector('[slot="label"]')) && (index.h("label", { key: 'c33b7d589cbc142dd5a318e78ebfbd97f17867c1', htmlFor: this.inputId, class: clsxChV9xqsO.clsx(this.hideLabel && 'visually-hidden') }, index.h("slot", { key: 'b45490d577602efb5782aa0952112a28a063e167', name: "label" }, this.label))), (this.description ||
70
+ this.el.querySelector('[slot="description"]')) && (index.h("div", { key: '5526f29f5f90c89c82c41ceb48e3ccc2d2454e2f', class: "description" }, index.h("slot", { key: '2ed5c8330514c7f6bb180483e8289228e84dcfa0', name: "description" }, this.description))))));
71
71
  }
72
72
  static get formAssociated() { return true; }
73
73
  get el() { return index.getElement(this); }
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-DgKzi_Pd.js');
3
+ var index = require('./index-DXwd3F_r.js');
4
4
  require('@stencil/react-output-target/runtime');
5
5
  require('react');
6
6
  require('react-dom');
@@ -57,7 +57,7 @@ const NvTogglebutton = class {
57
57
  /****************************************************************************/
58
58
  //#region RENDER
59
59
  render() {
60
- return (index.h(index.Host, { key: '8e700d38ba155b977d4efa0d9e01b41e73fc4413', role: "button", tabindex: "0", "aria-pressed": String(this.active), onClick: this.handleClick }, index.h("slot", { key: '92427015839f98b0d9238b8df6af8e08ee511153' })));
60
+ return (index.h(index.Host, { key: '0e5895e17effeef2164efdb6a0b414bb40fde21e', role: "button", tabindex: "0", "aria-pressed": String(this.active), onClick: this.handleClick }, index.h("slot", { key: '9a7c2370e6ad8a7442fd9a7c3d4a172a41037103' })));
61
61
  }
62
62
  get el() { return index.getElement(this); }
63
63
  };
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-DgKzi_Pd.js');
3
+ var index = require('./index-DXwd3F_r.js');
4
4
  require('@stencil/react-output-target/runtime');
5
5
  require('react');
6
6
  require('react-dom');
@@ -156,7 +156,7 @@ const NvTogglebuttongroup = class {
156
156
  /****************************************************************************/
157
157
  //#region RENDER
158
158
  render() {
159
- return (index.h(index.Host, { key: '2026cb95db8b57f2a1cd4ea53608f336843b63fe' }, index.h("slot", { key: '5c06ab59d6c99e789c3a1c3a8a4842a0772ca3a2' })));
159
+ return (index.h(index.Host, { key: '4428416f62c5e5f0713089cf7601babd5ee43161' }, index.h("slot", { key: '549cab50def8d37f072f83af0eea1bb4b55fe3e2' })));
160
160
  }
161
161
  get el() { return index.getElement(this); }
162
162
  static get watchers() { return {
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-DgKzi_Pd.js');
3
+ var index = require('./index-DXwd3F_r.js');
4
4
  require('@stencil/react-output-target/runtime');
5
5
  require('react');
6
6
  require('react-dom');
@@ -52,7 +52,7 @@ const NvTooltip = class {
52
52
  /****************************************************************************/
53
53
  //#region RENDER
54
54
  render() {
55
- return (index.h(index.Host, { key: '8285fbb412cb45cc7baf2936f0405c0438395c8d' }, index.h("nv-popover", { key: '29d70e9baa826de35d2cdca88f48610d70ec55e4', ref: el => (this.popoverElement = el), triggerMode: "hover", hasArrow: true, placement: this.placement, strategy: this.strategy, groupName: 'tooltip', enterDelay: this.enterDelay, onOpenChanged: e => this.openChanged.emit(e.detail) }, index.h("p", { key: 'a9c907fa96f9c4108a8d84cec53981218c060811', slot: "content" }, this.message), index.h("slot", { key: 'af1b7ac8069071fe2d41e925f1c0090f8b6aaab5', name: "content" })), index.h("slot", { key: 'e5d3c6d16fb7e4a682b66e0016d9e4e30e5647e0', ref: el => (this.defaultSlot = el) })));
55
+ return (index.h(index.Host, { key: '6eccd65d55ddfaba863959cd49dd9f404a0f0790' }, index.h("nv-popover", { key: '9be6e361b11d259b1b8f7b006c41bb62e69141b9', ref: el => (this.popoverElement = el), triggerMode: "hover", hasArrow: true, placement: this.placement, strategy: this.strategy, groupName: 'tooltip', enterDelay: this.enterDelay, onOpenChanged: e => this.openChanged.emit(e.detail) }, index.h("p", { key: 'a8ac3ddeb4ec1e4fe93bf5344ef35a0712fc60c3', slot: "content" }, this.message), index.h("slot", { key: '67f9e9c245910c5f0e4e0e515872a332f9065055', name: "content" })), index.h("slot", { key: '453d0a071793edcdba9fd100bb0161d70c82a506', ref: el => (this.defaultSlot = el) })));
56
56
  }
57
57
  get el() { return index.getElement(this); }
58
58
  };
@@ -1,13 +1,15 @@
1
1
  import React, { useMemo, useState, useEffect, useRef, useCallback, } from 'react';
2
- import { flexRender, getCoreRowModel, getPaginationRowModel, getSortedRowModel, getFilteredRowModel, useReactTable, } from '@tanstack/react-table';
3
- import { NvTable, NvTableheader, NvPaginationtable, NvFieldcheckbox, } from '../../generated/components';
2
+ import { flexRender, getCoreRowModel, getPaginationRowModel, getSortedRowModel, getFilteredRowModel, getExpandedRowModel, useReactTable, } from '@tanstack/react-table';
3
+ import { NvTable, NvTableheader, NvPaginationtable, NvFieldcheckbox, NvIconbutton, } from '../../generated/components';
4
4
  import { defineCustomElement as defineNvPaginationtable } from '@nova-design-system/nova-webcomponents/dist/components/nv-paginationtable.js';
5
5
  if (typeof window !== 'undefined' &&
6
6
  !customElements.get('nv-paginationtable')) {
7
7
  defineNvPaginationtable();
8
8
  }
9
9
  import { applyRowSelection, applySelectAllSelection, shouldIgnoreSelectAllEvent, } from './selectionState';
10
- function NvDatatable({ mode = 'client', columns, rows, pagination, sorting, filtering, selection, renderPagination, renderFiltering, onRowClick, stickyHeader, ...htmlProps }) {
10
+ import { shouldShowExpandedContent } from './expandState';
11
+ import { resolvePaginationRowCount } from './paginationState';
12
+ function NvDatatable({ mode = 'client', columns, rows, pagination, sorting, filtering, selection, renderPagination, renderFiltering, onRowClick, expandable, stickyHeader, ...htmlProps }) {
11
13
  const areSetsEqual = useCallback((a, b) => {
12
14
  if (a.size !== b.size) {
13
15
  return false;
@@ -24,7 +26,7 @@ function NvDatatable({ mode = 'client', columns, rows, pagination, sorting, filt
24
26
  pageIndex: 0,
25
27
  pageSize: pagination?.initialPageSize || 10,
26
28
  });
27
- const [sortingState, setSortingState] = useState(sorting?.sortState || []);
29
+ const [sortingState, setSortingState] = useState(sorting?.sortState ?? sorting?.initialSortState ?? []);
28
30
  const [globalFilterState, setGlobalFilterState] = useState(filtering?.filterState);
29
31
  const [selectedRowIdsState, setSelectedRowIdsState] = useState(() => new Set(selection?.selectedRowIds ?? []));
30
32
  const selectedRowIdsRef = useRef(new Set(selection?.selectedRowIds ?? []));
@@ -32,6 +34,14 @@ function NvDatatable({ mode = 'client', columns, rows, pagination, sorting, filt
32
34
  const selectionEnabled = selectionMode !== 'none';
33
35
  const selectAllEnabled = selection?.enableSelectAll ?? true;
34
36
  const rowClickEnabled = typeof onRowClick === 'function';
37
+ const hasExpandable = !!expandable;
38
+ const isCollapsible = expandable?.collapsible ?? false;
39
+ const [expandedState, setExpandedState] = useState(expandable?.expandedState ?? {});
40
+ useEffect(() => {
41
+ if (expandable?.expandedState !== undefined) {
42
+ setExpandedState(expandable.expandedState);
43
+ }
44
+ }, [expandable?.expandedState]);
35
45
  const getSelectionRowId = useCallback((row) => selection?.getRowId?.(row) ?? '', [selection]);
36
46
  const lastRowRef = useRef(null);
37
47
  const selectAllIntentRef = useRef(false);
@@ -140,29 +150,66 @@ function NvDatatable({ mode = 'client', columns, rows, pagination, sorting, filt
140
150
  }
141
151
  return columnDef;
142
152
  });
143
- if (!selectionEnabled) {
144
- return dataColumns;
145
- }
146
- const selectionColumn = {
147
- id: '__selection__',
148
- header: '',
149
- size: selection?.checkboxColumnWidth ?? 48,
150
- enableResizing: false,
151
- enableSorting: false,
152
- cell: () => null,
153
- };
154
- return [selectionColumn, ...dataColumns];
155
- }, [columns, sorting, selectionEnabled, selection?.checkboxColumnWidth]);
153
+ const prefixColumns = [];
154
+ const isCombinedColumn = selectionEnabled && isCollapsible;
155
+ if (isCombinedColumn) {
156
+ prefixColumns.push({
157
+ id: '__selection_expand__',
158
+ header: '',
159
+ size: (selection?.checkboxColumnWidth ?? 48) +
160
+ (expandable?.toggleColumnWidth ?? 48),
161
+ enableResizing: false,
162
+ enableSorting: false,
163
+ cell: () => null,
164
+ });
165
+ }
166
+ else {
167
+ if (selectionEnabled) {
168
+ prefixColumns.push({
169
+ id: '__selection__',
170
+ header: '',
171
+ size: selection?.checkboxColumnWidth ?? 48,
172
+ enableResizing: false,
173
+ enableSorting: false,
174
+ cell: () => null,
175
+ });
176
+ }
177
+ if (isCollapsible) {
178
+ prefixColumns.push({
179
+ id: '__expand__',
180
+ header: '',
181
+ size: expandable?.toggleColumnWidth ?? 48,
182
+ enableResizing: false,
183
+ enableSorting: false,
184
+ cell: () => null,
185
+ });
186
+ }
187
+ }
188
+ return [...prefixColumns, ...dataColumns];
189
+ }, [
190
+ columns,
191
+ sorting,
192
+ selectionEnabled,
193
+ selection?.checkboxColumnWidth,
194
+ isCollapsible,
195
+ expandable?.toggleColumnWidth,
196
+ ]);
156
197
  const tableConfig = useMemo(() => {
198
+ const tableState = {};
199
+ if (sorting) {
200
+ tableState.sorting = sorting.sortState || sortingState;
201
+ }
202
+ if (filtering) {
203
+ tableState.globalFilter = globalFilterState;
204
+ }
205
+ if (isCollapsible) {
206
+ tableState.expanded = expandable?.expandedState ?? expandedState;
207
+ }
157
208
  const baseConfig = {
158
209
  data: rows,
159
210
  columns: tableColumns,
160
211
  getCoreRowModel: getCoreRowModel(),
161
212
  ...(sorting && {
162
- state: {
163
- sorting: sorting.sortState || sortingState,
164
- ...(filtering && { globalFilter: globalFilterState }),
165
- },
166
213
  onSortingChange: mode === 'server'
167
214
  ? (updater) => {
168
215
  const newSort = typeof updater === 'function'
@@ -182,10 +229,6 @@ function NvDatatable({ mode = 'client', columns, rows, pagination, sorting, filt
182
229
  getSortedRowModel: mode === 'client' ? getSortedRowModel() : undefined,
183
230
  }),
184
231
  ...(filtering && {
185
- state: {
186
- ...(sorting && { sorting: sorting.sortState || sortingState }),
187
- globalFilter: globalFilterState,
188
- },
189
232
  onGlobalFilterChange: (updater) => {
190
233
  const newFilter = typeof updater === 'function'
191
234
  ? updater(globalFilterState)
@@ -198,6 +241,20 @@ function NvDatatable({ mode = 'client', columns, rows, pagination, sorting, filt
198
241
  globalFilterFn: filtering.globalFilterFn,
199
242
  getFilteredRowModel: mode === 'client' ? getFilteredRowModel() : undefined,
200
243
  }),
244
+ ...(isCollapsible && {
245
+ getExpandedRowModel: getExpandedRowModel(),
246
+ getRowCanExpand: expandable?.getRowCanExpand
247
+ ? (row) => expandable.getRowCanExpand(row.original)
248
+ : () => true,
249
+ onExpandedChange: (updater) => {
250
+ const newExpanded = typeof updater === 'function'
251
+ ? updater(expandedState)
252
+ : updater;
253
+ setExpandedState(newExpanded);
254
+ expandable?.onExpandedChange?.(newExpanded);
255
+ },
256
+ }),
257
+ ...(Object.keys(tableState).length > 0 && { state: tableState }),
201
258
  };
202
259
  if (!pagination) {
203
260
  return baseConfig;
@@ -243,6 +300,9 @@ function NvDatatable({ mode = 'client', columns, rows, pagination, sorting, filt
243
300
  sortingState,
244
301
  filtering,
245
302
  globalFilterState,
303
+ isCollapsible,
304
+ expandable,
305
+ expandedState,
246
306
  mode,
247
307
  ]);
248
308
  const table = useReactTable(tableConfig);
@@ -436,9 +496,14 @@ function NvDatatable({ mode = 'client', columns, rows, pagination, sorting, filt
436
496
  return null;
437
497
  }
438
498
  const pageCount = table.getPageCount();
439
- const rowCount = mode === 'server' && !pagination.infinite
440
- ? pagination.totalRowCount || rows.length
441
- : rows.length;
499
+ const rowCount = resolvePaginationRowCount({
500
+ mode,
501
+ isInfinite: !!pagination.infinite,
502
+ hasFiltering: !!filtering,
503
+ totalRowCount: pagination.totalRowCount,
504
+ rowsLength: rows.length,
505
+ filteredRowsLength: table.getFilteredRowModel().rows.length,
506
+ });
442
507
  const api = {
443
508
  pageIndex: tablePaginationState.pageIndex,
444
509
  pageSize: tablePaginationState.pageSize,
@@ -557,23 +622,32 @@ function NvDatatable({ mode = 'client', columns, rows, pagination, sorting, filt
557
622
  }
558
623
  } }));
559
624
  }, [getSelectionRowId, isRowSelected, setRowSelection]);
625
+ const renderExpandToggle = useCallback((row, rowIndex) => {
626
+ const isExpanded = row.getIsExpanded();
627
+ const canExpand = row.getCanExpand();
628
+ const expandedContentId = `datatable-expanded-content-${rowIndex}`;
629
+ if (!canExpand) {
630
+ return null;
631
+ }
632
+ return (React.createElement(NvIconbutton, { "data-testid": `datatable-row-${rowIndex}-expand-toggle`, "aria-expanded": isExpanded ? 'true' : 'false', "aria-controls": expandedContentId, "aria-label": isExpanded
633
+ ? `Collapse row ${rowIndex + 1}`
634
+ : `Expand row ${rowIndex + 1}`, onClick: (e) => {
635
+ e.stopPropagation();
636
+ row.toggleExpanded();
637
+ }, name: isExpanded ? 'chevron-down' : 'chevron-right', size: "sm", emphasis: "lower" }));
638
+ }, []);
560
639
  return (React.createElement(React.Fragment, null,
561
640
  filteringAPI && renderFiltering && renderFiltering(filteringAPI),
562
641
  React.createElement(NvTable, { ...htmlProps },
563
642
  React.createElement("table", { "data-row-click-enabled": rowClickEnabled ? 'true' : 'false' },
564
643
  React.createElement("thead", { "data-sticky-top": stickyHeader ? 'true' : undefined }, table.getHeaderGroups().map((headerGroup) => (React.createElement("tr", { key: headerGroup.id }, headerGroup.headers.map((header) => {
565
644
  const isSelectionHeader = header.id === '__selection__';
645
+ const isExpandHeader = header.id === '__expand__';
646
+ const isCombinedHeader = header.id === '__selection_expand__';
647
+ const isSpecialHeader = isSelectionHeader || isExpandHeader || isCombinedHeader;
566
648
  const canSort = header.column.getCanSort();
567
649
  const sortDirection = header.column.getIsSorted();
568
- return (React.createElement("th", { key: header.id, "data-testid": isSelectionHeader
569
- ? 'datatable-header-selection'
570
- : `datatable-header-${header.id}`, style: {
571
- width: header.column.columnDef.size + 'px',
572
- }, "data-no-resize": isSelectionHeader
573
- ? true
574
- : header.column.columnDef.enableResizing
575
- ? null
576
- : true }, isSelectionHeader ? (selectionMode === 'multiple' && selectAllEnabled ? (React.createElement("div", { className: "flex items-center justify-center" },
650
+ const renderSelectAllCheckbox = selectionMode === 'multiple' && selectAllEnabled ? (React.createElement("div", { className: "flex items-center justify-center" },
577
651
  React.createElement(NvFieldcheckbox, { "data-testid": "datatable-select-all-checkbox", checked: selectAllState === 'checked', indeterminate: selectAllState === 'indeterminate', label: "Select all rows", hideLabel: true, onPointerDownCapture: () => {
578
652
  if (selectAllIntentResetTimerRef.current) {
579
653
  clearTimeout(selectAllIntentResetTimerRef.current);
@@ -591,7 +665,20 @@ function NvDatatable({ mode = 'client', columns, rows, pagination, sorting, filt
591
665
  finally {
592
666
  selectAllIntentRef.current = false;
593
667
  }
594
- } }))) : null) : (React.createElement(NvTableheader, { sortable: canSort ? true : undefined, sortDirection: sortDirection || (canSort ? 'none' : undefined), onSortDirectionChanged: canSort
668
+ } }))) : null;
669
+ return (React.createElement("th", { key: header.id, "data-testid": isSelectionHeader
670
+ ? 'datatable-header-selection'
671
+ : isExpandHeader
672
+ ? 'datatable-header-expand'
673
+ : isCombinedHeader
674
+ ? 'datatable-header-selection-expand'
675
+ : `datatable-header-${header.id}`, style: {
676
+ width: header.column.columnDef.size + 'px',
677
+ }, "data-no-resize": isSpecialHeader
678
+ ? true
679
+ : header.column.columnDef.enableResizing
680
+ ? null
681
+ : true }, isSelectionHeader ? (renderSelectAllCheckbox) : isCombinedHeader ? (renderSelectAllCheckbox) : isExpandHeader ? null : (React.createElement(NvTableheader, { sortable: canSort ? true : undefined, sortDirection: sortDirection || (canSort ? 'none' : undefined), onSortDirectionChanged: canSort
595
682
  ? header.column.getToggleSortingHandler()
596
683
  : undefined }, header.isPlaceholder
597
684
  ? null
@@ -600,28 +687,58 @@ function NvDatatable({ mode = 'client', columns, rows, pagination, sorting, filt
600
687
  React.createElement("tbody", null, tableRows.map((row, index) => {
601
688
  const isLastRow = isInfiniteScroll && index === tableRows.length - 1;
602
689
  const stableRowKey = getSelectionRowId(row.original) || row.id;
603
- return (React.createElement("tr", { key: stableRowKey, "data-testid": `datatable-row-${index}`, ref: isLastRow ? lastRowRef : undefined, className: rowClickEnabled ? 'nv-datatable-row-clickable' : undefined, tabIndex: rowClickEnabled ? 0 : undefined, onClick: rowClickEnabled
604
- ? () => onRowClick?.({ row: row.original, rowIndex: index })
605
- : undefined, onKeyDown: rowClickEnabled
606
- ? (event) => {
607
- if (event.currentTarget !== event.target) {
608
- return;
609
- }
610
- if (event.key === 'Enter' || event.key === ' ') {
611
- event.preventDefault();
612
- onRowClick?.({
613
- row: row.original,
614
- rowIndex: index,
615
- });
690
+ const expandedContent = hasExpandable
691
+ ? expandable.renderExpandedContent({
692
+ row: row.original,
693
+ rowIndex: index,
694
+ })
695
+ : null;
696
+ const hasContent = expandedContent != null;
697
+ const showExpanded = shouldShowExpandedContent({
698
+ hasContent,
699
+ isCollapsible,
700
+ isExpanded: isCollapsible ? row.getIsExpanded() : false,
701
+ });
702
+ const expandedContentId = `datatable-expanded-content-${index}`;
703
+ const totalColumnCount = row.getVisibleCells().length;
704
+ return (React.createElement(React.Fragment, { key: stableRowKey },
705
+ React.createElement("tr", { "data-testid": `datatable-row-${index}`, "data-selected": isRowSelected(row.original) ? '' : undefined, ref: isLastRow ? lastRowRef : undefined, className: rowClickEnabled ? 'nv-datatable-row-clickable' : undefined, tabIndex: rowClickEnabled ? 0 : undefined, onClick: rowClickEnabled
706
+ ? () => onRowClick?.({
707
+ row: row.original,
708
+ rowIndex: index,
709
+ })
710
+ : undefined, onKeyDown: rowClickEnabled
711
+ ? (event) => {
712
+ if (event.currentTarget !== event.target) {
713
+ return;
714
+ }
715
+ if (event.key === 'Enter' || event.key === ' ') {
716
+ event.preventDefault();
717
+ onRowClick?.({
718
+ row: row.original,
719
+ rowIndex: index,
720
+ });
721
+ }
616
722
  }
617
- }
618
- : undefined }, row.getVisibleCells().map((cell) => (React.createElement("td", { key: cell.id, "data-testid": cell.column.id === '__selection__'
619
- ? 'datatable-cell-selection'
620
- : `datatable-cell-${cell.column.id}`, onClick: cell.column.id === '__selection__'
621
- ? (event) => event.stopPropagation()
622
- : undefined }, cell.column.id === '__selection__'
623
- ? renderRowSelectionCheckbox(row.original, index)
624
- : flexRender(cell.column.columnDef.cell, cell.getContext()))))));
723
+ : undefined }, row.getVisibleCells().map((cell) => {
724
+ const isCombinedCell = cell.column.id === '__selection_expand__';
725
+ const isSelectionCell = cell.column.id === '__selection__';
726
+ const isExpandCell = cell.column.id === '__expand__';
727
+ return (React.createElement("td", { key: cell.id, "data-testid": isSelectionCell
728
+ ? 'datatable-cell-selection'
729
+ : isExpandCell
730
+ ? 'datatable-cell-expand'
731
+ : isCombinedCell
732
+ ? 'datatable-cell-selection-expand'
733
+ : `datatable-cell-${cell.column.id}`, onClick: isSelectionCell || isExpandCell || isCombinedCell
734
+ ? (event) => event.stopPropagation()
735
+ : undefined }, isSelectionCell ? (renderRowSelectionCheckbox(row.original, index)) : isExpandCell ? (renderExpandToggle(row, index)) : isCombinedCell ? (React.createElement("div", { className: "flex items-center justify-center gap-1" },
736
+ renderRowSelectionCheckbox(row.original, index),
737
+ renderExpandToggle(row, index))) : (flexRender(cell.column.columnDef.cell, cell.getContext()))));
738
+ })),
739
+ showExpanded && (React.createElement("tr", { className: "nv-datatable-expanded-row", "data-testid": `datatable-expanded-row-${index}`, id: expandedContentId, role: "region", "aria-label": `Expanded content for row ${index + 1}` },
740
+ React.createElement("td", { colSpan: totalColumnCount },
741
+ React.createElement("div", { className: "nv-datatable-expanded-content" }, expandedContent))))));
625
742
  })))),
626
743
  paginationAPI &&
627
744
  (renderPagination
@@ -0,0 +1,8 @@
1
+ export function shouldShowExpandedContent(params) {
2
+ const { hasContent, isCollapsible, isExpanded } = params;
3
+ if (!hasContent)
4
+ return false;
5
+ if (!isCollapsible)
6
+ return true;
7
+ return isExpanded;
8
+ }
@@ -0,0 +1,41 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { shouldShowExpandedContent } from './expandState';
3
+ describe('expandState', () => {
4
+ describe('shouldShowExpandedContent', () => {
5
+ it('returns false when there is no content', () => {
6
+ expect(shouldShowExpandedContent({
7
+ hasContent: false,
8
+ isCollapsible: false,
9
+ isExpanded: false,
10
+ })).toBe(false);
11
+ });
12
+ it('returns false when there is no content even if expanded', () => {
13
+ expect(shouldShowExpandedContent({
14
+ hasContent: false,
15
+ isCollapsible: true,
16
+ isExpanded: true,
17
+ })).toBe(false);
18
+ });
19
+ it('returns true when has content and not collapsible', () => {
20
+ expect(shouldShowExpandedContent({
21
+ hasContent: true,
22
+ isCollapsible: false,
23
+ isExpanded: false,
24
+ })).toBe(true);
25
+ });
26
+ it('returns false when collapsible and not expanded', () => {
27
+ expect(shouldShowExpandedContent({
28
+ hasContent: true,
29
+ isCollapsible: true,
30
+ isExpanded: false,
31
+ })).toBe(false);
32
+ });
33
+ it('returns true when collapsible and expanded', () => {
34
+ expect(shouldShowExpandedContent({
35
+ hasContent: true,
36
+ isCollapsible: true,
37
+ isExpanded: true,
38
+ })).toBe(true);
39
+ });
40
+ });
41
+ });
@@ -0,0 +1,9 @@
1
+ export function resolvePaginationRowCount(opts) {
2
+ if (opts.mode === 'server' && !opts.isInfinite) {
3
+ return opts.totalRowCount || opts.rowsLength;
4
+ }
5
+ if (opts.mode === 'client' && opts.hasFiltering) {
6
+ return opts.filteredRowsLength;
7
+ }
8
+ return opts.rowsLength;
9
+ }