@nvidia-elements/core 2.17.1 → 2.18.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 (142) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/accordion/accordion2.js +4 -4
  3. package/dist/alert/alert-group2.js +1 -1
  4. package/dist/alert/alert2.js +1 -1
  5. package/dist/avatar/avatar-group2.js +1 -1
  6. package/dist/avatar/avatar2.js +1 -1
  7. package/dist/badge/badge2.js +1 -1
  8. package/dist/breadcrumb/breadcrumb2.js +1 -1
  9. package/dist/bundles/index.d.ts +33 -1
  10. package/dist/bundles/index.js +8 -8
  11. package/dist/button/button2.js +1 -1
  12. package/dist/button-group/button-group2.js +1 -1
  13. package/dist/card/card2.js +4 -4
  14. package/dist/chat-message/chat-message2.js +1 -1
  15. package/dist/checkbox/checkbox-group2.js +1 -1
  16. package/dist/checkbox/checkbox2.js +1 -1
  17. package/dist/color/color2.js +1 -1
  18. package/dist/combobox/combobox2.js +1 -1
  19. package/dist/copy-button/copy-button2.js +1 -1
  20. package/dist/custom-elements-jsx.d.ts +25 -1
  21. package/dist/custom-elements-vue.d.ts +25 -1
  22. package/dist/custom-elements.json +177 -1
  23. package/dist/data.html.json +12 -1
  24. package/dist/date/date2.js +1 -1
  25. package/dist/datetime/datetime2.js +1 -1
  26. package/dist/dialog/dialog-footer2.js +1 -1
  27. package/dist/dialog/dialog-header2.js +1 -1
  28. package/dist/dialog/dialog2.js +1 -1
  29. package/dist/divider/divider2.js +1 -1
  30. package/dist/dot/dot2.js +1 -1
  31. package/dist/drag-handle/drag-handle2.js +1 -1
  32. package/dist/drawer/drawer-content2.js +1 -1
  33. package/dist/drawer/drawer-footer2.js +1 -1
  34. package/dist/drawer/drawer-header2.js +1 -1
  35. package/dist/drawer/drawer2.js +1 -1
  36. package/dist/dropdown/dropdown-footer2.js +1 -1
  37. package/dist/dropdown/dropdown-header2.js +1 -1
  38. package/dist/dropdown/dropdown2.js +1 -1
  39. package/dist/dropdown-group/dropdown-group.js +1 -1
  40. package/dist/dropzone/dropzone2.js +1 -1
  41. package/dist/file/file2.js +1 -1
  42. package/dist/format-bytes/format-bytes2.js +1 -1
  43. package/dist/format-datetime/format-datetime2.js +1 -1
  44. package/dist/format-number/format-number2.js +1 -1
  45. package/dist/format-relative-time/format-relative-time2.js +1 -1
  46. package/dist/format-truncate/format-truncate2.js +1 -1
  47. package/dist/forms/control/control2.js +1 -1
  48. package/dist/forms/control-group/control-group2.js +1 -1
  49. package/dist/forms/control-message/control-message2.js +1 -1
  50. package/dist/gauge/gauge2.js +1 -1
  51. package/dist/grid/cell/cell2.js +1 -1
  52. package/dist/grid/column/column2.js +1 -1
  53. package/dist/grid/footer/footer2.js +1 -1
  54. package/dist/grid/grid2.js +1 -1
  55. package/dist/grid/header/header2.js +1 -1
  56. package/dist/grid/placeholder/placeholder2.js +1 -1
  57. package/dist/grid/row/row2.js +1 -1
  58. package/dist/icon/icon2.js +2 -2
  59. package/dist/icon-button/icon-button2.js +1 -1
  60. package/dist/iframe/iframe2.js +1 -1
  61. package/dist/index.js +1 -1
  62. package/dist/input/input-group2.js +1 -1
  63. package/dist/input/input2.js +1 -1
  64. package/dist/internal/controllers/keynav-list.controller.d.ts +2 -0
  65. package/dist/internal/controllers/keynav-list.controller.js +8 -0
  66. package/dist/internal/controllers/keynav-list.controller.js.map +1 -1
  67. package/dist/internal/services/global.service.js +1 -1
  68. package/dist/logo/logo2.js +1 -1
  69. package/dist/menu/menu-group2.js +1 -1
  70. package/dist/menu/menu-item2.js +1 -1
  71. package/dist/menu/menu2.js +1 -1
  72. package/dist/month/month2.js +1 -1
  73. package/dist/notification/notification-group2.js +1 -1
  74. package/dist/notification/notification2.js +1 -1
  75. package/dist/page/page-panel/page-panel-content2.js +1 -1
  76. package/dist/page/page-panel/page-panel-footer2.js +1 -1
  77. package/dist/page/page-panel/page-panel-header2.js +1 -1
  78. package/dist/page/page-panel/page-panel2.js +1 -1
  79. package/dist/page/page2.js +1 -1
  80. package/dist/page-header/page-header2.js +1 -1
  81. package/dist/page-loader/page-loader2.js +1 -1
  82. package/dist/pagination/pagination2.js +1 -1
  83. package/dist/panel/panel2.js +4 -4
  84. package/dist/password/password2.js +1 -1
  85. package/dist/preferences-input/preferences-input2.js +1 -1
  86. package/dist/progress-bar/progress-bar2.js +1 -1
  87. package/dist/progress-dot/progress-dot2.js +1 -1
  88. package/dist/progress-ring/progress-ring2.js +1 -1
  89. package/dist/progressive-filter-chip/progressive-filter-chip2.js +1 -1
  90. package/dist/pulse/pulse2.js +1 -1
  91. package/dist/radio/radio-group2.js +1 -1
  92. package/dist/radio/radio2.js +1 -1
  93. package/dist/range/range2.js +1 -1
  94. package/dist/resize-handle/resize-handle2.js +1 -1
  95. package/dist/search/search2.js +1 -1
  96. package/dist/select/select2.js +1 -1
  97. package/dist/skeleton/skeleton2.js +1 -1
  98. package/dist/sort-button/sort-button2.js +1 -1
  99. package/dist/sparkline/sparkline2.js +1 -1
  100. package/dist/star-rating/star-rating2.js +1 -1
  101. package/dist/steps/steps2.js +2 -2
  102. package/dist/switch/switch-group2.js +1 -1
  103. package/dist/switch/switch2.js +1 -1
  104. package/dist/tabs/define.d.ts +2 -1
  105. package/dist/tabs/define.js +2 -1
  106. package/dist/tabs/define.js.map +1 -1
  107. package/dist/tabs/index.d.ts +1 -0
  108. package/dist/tabs/index.js +2 -1
  109. package/dist/tabs/tabs-group2.js +19 -18
  110. package/dist/tabs/tabs-group2.js.map +1 -1
  111. package/dist/tabs/tabs-item-group.d.ts +29 -0
  112. package/dist/tabs/tabs-item-group.js +6 -0
  113. package/dist/tabs/tabs-item-group.js.map +1 -0
  114. package/dist/tabs/tabs-item-group2.js +34 -0
  115. package/dist/tabs/tabs-item-group2.js.map +1 -0
  116. package/dist/tabs/tabs-item.js +1 -1
  117. package/dist/tabs/tabs-item.js.map +1 -1
  118. package/dist/tabs/tabs.d.ts +5 -1
  119. package/dist/tabs/tabs.examples.js.map +1 -1
  120. package/dist/tabs/tabs.examples.json +24 -6
  121. package/dist/tabs/tabs.global.js +1 -1
  122. package/dist/tabs/tabs.global.js.map +1 -1
  123. package/dist/tabs/tabs.js +1 -1
  124. package/dist/tabs/tabs.js.map +1 -1
  125. package/dist/tabs/tabs2.js +76 -34
  126. package/dist/tabs/tabs2.js.map +1 -1
  127. package/dist/tabs/utils.d.ts +4 -0
  128. package/dist/tabs/utils.js +18 -0
  129. package/dist/tabs/utils.js.map +1 -0
  130. package/dist/tag/tag2.js +1 -1
  131. package/dist/textarea/textarea2.js +1 -1
  132. package/dist/time/time2.js +1 -1
  133. package/dist/toast/toast2.js +1 -1
  134. package/dist/toggletip/toggletip-footer2.js +1 -1
  135. package/dist/toggletip/toggletip-header2.js +1 -1
  136. package/dist/toggletip/toggletip2.js +1 -1
  137. package/dist/toolbar/toolbar2.js +1 -1
  138. package/dist/tooltip/tooltip2.js +1 -1
  139. package/dist/tree/tree-node2.js +1 -1
  140. package/dist/tree/tree2.js +1 -1
  141. package/dist/week/week2.js +1 -1
  142. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.examples.js","names":[],"sources":["../../src/tabs/tabs.examples.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { html } from 'lit';\nimport '@nvidia-elements/core/tabs/define.js';\nimport '@nvidia-elements/core/button/define.js';\nimport '@nvidia-elements/core/card/define.js';\nimport '@nvidia-elements/core/dot/define.js';\nimport '@nvidia-elements/core/icon/define.js';\n\nexport default {\n title: 'Elements/Tabs',\n component: 'nve-tabs'\n};\n\n/**\n * @summary Tabs group component for organizing content into selectable sections with disabled state support.\n */\nexport const Default = {\n render: () => html`\n<nve-tabs-group id=\"tab-group-default\">\n <nve-tabs>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group-default\" value=\"overview\">Overview</nve-tabs-item>\n <nve-tabs-item selected command=\"--toggle\" commandfor=\"tab-group-default\" value=\"details\">Details</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group-default\" value=\"settings\">Settings</nve-tabs-item>\n </nve-tabs>\n <div slot=\"overview\">\n overview content\n </div>\n <div slot=\"details\">\n details content\n </div>\n <div slot=\"settings\">\n settings content\n </div>\n</nve-tabs-group>`\n};\n\n\n/**\n * @summary Borderless tabs variant for minimal visual styling without border emphasis.\n * @tags test-case\n */\nexport const BorderlessTabs = {\n render: () => html`\n<nve-tabs borderless behavior-select>\n <nve-tabs-item selected>Tab 1</nve-tabs-item>\n <nve-tabs-item>Tab 2</nve-tabs-item>\n <nve-tabs-item>Tab 3 </nve-tabs-item>\n <nve-tabs-item disabled>Disabled</nve-tabs-item>\n <nve-tabs-item>Tab 5</nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Tabs with custom border background styling for brand-specific visual customization.\n * @tags test-case\n */\nexport const BorderBackground = {\n render: () => html`\n<nve-tabs behavior-select style=\"--indicator-background: var(--nve-ref-color-brand-green-900); --indicator-border-radius: none;\">\n <nve-tabs-item selected>\n Tab 1\n </nve-tabs-item>\n <nve-tabs-item>\n Tab 2\n </nve-tabs-item>\n <nve-tabs-item>\n Tab 3\n </nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Tabs with notification dots for indicating unread content or alerts within tab sections.\n */\nexport const WithDots = {\n render: () => html`\n<nve-tabs behavior-select>\n <nve-tabs-item>Tab 1</nve-tabs-item>\n <nve-tabs-item>Tab 2</nve-tabs-item>\n <nve-tabs-item>Tab 3 </nve-tabs-item>\n <nve-tabs-item selected>\n Tab 4\n <nve-dot aria-label=\"10 notifications\">10</nve-dot>\n </nve-tabs-item>\n <nve-tabs-item>Tab 5</nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Vertical tabs layout for sidebar navigation and vertical content organization patterns.\n */\nexport const VerticalTabs = {\n render: () => html`\n<nve-tabs vertical behavior-select style=\"width: 250px\">\n <nve-tabs-item selected>Tab 1</nve-tabs-item>\n <nve-tabs-item>Tab 2</nve-tabs-item>\n <nve-tabs-item>Tab 3</nve-tabs-item>\n <nve-tabs-item disabled>Disabled</nve-tabs-item>\n <nve-tabs-item>Tab 5</nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Borderless vertical tabs with icons for enhanced visual navigation and minimal styling.\n * @tags test-case\n */\nexport const BorderlessVerticalTabs = {\n render: () => html`\n<nve-tabs vertical borderless behavior-select style=\"width: 250px\">\n <nve-tabs-item>\n <nve-icon name=\"gear\"></nve-icon> Tab 1\n </nve-tabs-item>\n <nve-tabs-item>\n <nve-icon name=\"person\"></nve-icon> Tab 2\n </nve-tabs-item>\n <nve-tabs-item selected>\n <nve-icon name=\"beaker\"></nve-icon> Tab 3\n </nve-tabs-item>\n <nve-tabs-item>\n <nve-icon name=\"add-grid\"></nve-icon> Tab 4\n </nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Stateless tabs for external state management without built-in selection behavior.\n */\nexport const StatelessTabs = {\n render: () => html`\n<nve-tabs>\n <nve-tabs-item selected>Tab 1</nve-tabs-item>\n <nve-tabs-item>Tab 2</nve-tabs-item>\n <nve-tabs-item>Tab 3</nve-tabs-item>\n <nve-tabs-item>Tab 4</nve-tabs-item>\n <nve-tabs-item disabled>Disabled</nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Tabs with link navigation for routing-based tab switching and page navigation.\n */\nexport const Links = {\n render: () => html`\n<nve-tabs>\n <nve-tabs-item selected>\n <a href=\"#links\">Tab 1</a>\n </nve-tabs-item>\n <nve-tabs-item>\n <a href=\"#links\">Tab 2</a>\n </nve-tabs-item>\n <nve-tabs-item>\n <a href=\"#links\">Tab 3</a>\n </nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Tabs with overflow handling for managing large numbers of tabs with scrolling behavior.\n * @tags test-case\n */\nexport const OverflowTabs = {\n render: () => html`\n<nve-tabs behavior-select>\n <nve-tabs-item selected>Tab 1</nve-tabs-item>\n <nve-tabs-item>Tab 2</nve-tabs-item>\n <nve-tabs-item>Tab 3</nve-tabs-item>\n <nve-tabs-item>Tab 4</nve-tabs-item>\n <nve-tabs-item>Tab 5</nve-tabs-item>\n <nve-tabs-item>Tab 6</nve-tabs-item>\n <nve-tabs-item>Tab 7</nve-tabs-item>\n <nve-tabs-item>Tab 8</nve-tabs-item>\n <nve-tabs-item>Tab 9</nve-tabs-item>\n <nve-tabs-item>Tab 10</nve-tabs-item>\n <nve-tabs-item>Tab 11</nve-tabs-item>\n <nve-tabs-item>Tab 12</nve-tabs-item>\n <nve-tabs-item>Tab 13</nve-tabs-item>\n <nve-tabs-item>Tab 14</nve-tabs-item>\n <nve-tabs-item>Tab 15</nve-tabs-item>\n <nve-tabs-item>Tab 16</nve-tabs-item>\n <nve-tabs-item>Tab 17</nve-tabs-item>\n <nve-tabs-item>Tab 18</nve-tabs-item>\n <nve-tabs-item>Tab 19</nve-tabs-item>\n <nve-tabs-item>Tab 20</nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Tabs selection state and a popover working together without any CSS Anchor Positioning collisions.\n * @tags test-case\n */\nexport const WithTooltips = {\n render: () => html`\n<nve-tooltip id=\"tab1\">Tooltip for tab 1</nve-tooltip>\n<nve-tooltip id=\"tab2\">Tooltip for tab 2</nve-tooltip>\n<nve-tooltip id=\"tab3\">Tooltip for tab 3</nve-tooltip>\n<nve-tabs behavior-select>\n <nve-tabs-item selected popovertarget=\"tab1\">Tab 1</nve-tabs-item>\n <nve-tabs-item popovertarget=\"tab2\">Tab 2</nve-tabs-item>\n <nve-tabs-item id=\"tab-item-3\" popovertarget=\"tab3\">Tab 3</nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Group tabs with slot-matched panels and structured card content when one selected value should control both the tab state and revealed details.\n */\nexport const GroupPanels = {\n render: () => html`\n<nve-tabs-group id=\"tab-group\">\n <nve-tabs>\n <nve-tabs-item selected command=\"--toggle\" commandfor=\"tab-group\" value=\"overview\">Overview</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group\" value=\"details\">Details</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group\" value=\"settings\">Settings</nve-tabs-item>\n </nve-tabs>\n <div slot=\"overview\">\n <nve-card style=\"width: 100%; min-width: 320px;\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Overview</h2>\n <p nve-text=\"body sm muted\">High-level release status and current priorities.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Status</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Ready for review</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Audience</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Design and product owners</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Next step</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Validate the tab labels and panel order</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n <div slot=\"details\">\n <nve-card style=\"width: 100%; min-width: 320px;\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Details</h2>\n <p nve-text=\"body sm muted\">Supporting context for teams that need implementation specifics.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Owner</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Elements design system</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Coverage</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Unit, SSR, and accessibility checks</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Focus</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Selection sync and panel wiring</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n <div slot=\"settings\">\n <nve-card style=\"width: 100%; min-width: 320px;\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Settings</h2>\n <p nve-text=\"body sm muted\">Configuration notes for authors and downstream consumers.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Selection</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Controlled by the active tab value</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Panels</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Matched by slot name</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Actions</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">External buttons can drive the same group</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n</nve-tabs-group>`\n};\n\n/**\n * @summary Tab group with vertical tab strip at inline-start beside slot-matched panels for sidebar-style settings and details layouts in LTR.\n */\nexport const GroupVerticalPanels = {\n render: () => html`\n<nve-tabs-group id=\"tab-group-vertical-start\" alignment=\"start\">\n <nve-tabs vertical style=\"width: 250px\">\n <nve-tabs-item selected command=\"--toggle\" commandfor=\"tab-group-vertical-start\" value=\"overview\">Overview</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group-vertical-start\" value=\"details\">Details</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group-vertical-start\" value=\"settings\">Settings</nve-tabs-item>\n </nve-tabs>\n <div slot=\"overview\" style=\"width: 100%; min-width: 320px;\">\n <nve-card style=\"width: 100%\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Overview</h2>\n <p nve-text=\"body sm muted\">High-level release status and current priorities.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Status</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Ready for review</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Audience</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Design and product owners</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Next step</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Validate the tab labels and panel order</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n <div slot=\"details\" style=\"width: 100%; min-width: 320px;\">\n <nve-card style=\"width: 100%\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Details</h2>\n <p nve-text=\"body sm muted\">Supporting context for teams that need implementation specifics.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Owner</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Elements design system</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Coverage</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Unit, SSR, and accessibility checks</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Focus</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Selection sync and panel wiring</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n <div slot=\"settings\" style=\"width: 100%; min-width: 320px;\">\n <nve-card style=\"width: 100%\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Settings</h2>\n <p nve-text=\"body sm muted\">Configuration notes for authors and downstream consumers.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Selection</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Controlled by the active tab value</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Panels</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Matched by slot name</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Actions</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">External buttons can drive the same group</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n</nve-tabs-group>`\n};\n\n/**\n * @summary Tab group with vertical tab strip at inline-end beside slot-matched panels when the tab rail should sit on the opposite side from inline-start sidebars.\n */\nexport const GroupVerticalEnd = {\n render: () => html`\n<nve-tabs-group id=\"tab-group-vertical-end\" alignment=\"end\">\n <nve-tabs vertical style=\"width: 250px\">\n <nve-tabs-item selected command=\"--toggle\" commandfor=\"tab-group-vertical-end\" value=\"overview\">Overview</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group-vertical-end\" value=\"details\">Details</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group-vertical-end\" value=\"settings\">Settings</nve-tabs-item>\n </nve-tabs>\n <div slot=\"overview\" style=\"width: 100%; min-width: 320px;\">\n <nve-card style=\"width: 100%\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Overview</h2>\n <p nve-text=\"body sm muted\">High-level release status and current priorities.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Status</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Ready for review</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Audience</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Design and product owners</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Next step</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Validate the tab labels and panel order</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n <div slot=\"details\" style=\"width: 100%; min-width: 320px;\">\n <nve-card style=\"width: 100%\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Details</h2>\n <p nve-text=\"body sm muted\">Supporting context for teams that need implementation specifics.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Owner</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Elements design system</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Coverage</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Unit, SSR, and accessibility checks</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Focus</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Selection sync and panel wiring</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n <div slot=\"settings\" style=\"width: 100%; min-width: 320px;\">\n <nve-card style=\"width: 100%\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Settings</h2>\n <p nve-text=\"body sm muted\">Configuration notes for authors and downstream consumers.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Selection</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Controlled by the active tab value</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Panels</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Matched by slot name</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Actions</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">External buttons can drive the same group</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n</nve-tabs-group>`\n};\n\n/**\n * @summary Drive the same tabs group from external buttons when layouts need tabs and secondary actions to stay in sync with structured panel content.\n */\nexport const ExternalControls = {\n render: () => html`\n<div nve-layout=\"column gap:lg\">\n <nve-tabs-group id=\"tab-group-controls\">\n <nve-tabs>\n <nve-tabs-item selected command=\"--toggle\" commandfor=\"tab-group-controls\" value=\"overview\">Overview</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group-controls\" value=\"details\">Details</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group-controls\" value=\"settings\">Settings</nve-tabs-item>\n </nve-tabs>\n <div slot=\"overview\">\n <nve-card style=\"width: 100%; min-width: 320px;\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Overview</h2>\n <p nve-text=\"body sm muted\">Quick status for the current tab group.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">State</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Overview is active</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Signal</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Use this tab for a summary of the current workflow</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Tip</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Pair it with external controls for quick switching</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n <div slot=\"details\">\n <nve-card style=\"width: 100%; min-width: 320px;\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Details</h2>\n <p nve-text=\"body sm muted\">Deeper context for follow-up tasks and implementation notes.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">State</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Details are available on demand</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Signal</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Use this tab when readers need extra context</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Tip</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Keep the content specific to the selected tab</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n <div slot=\"settings\">\n <nve-card style=\"width: 100%; min-width: 320px;\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Settings</h2>\n <p nve-text=\"body sm muted\">Preferences and coordination notes for the shared tab group.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">State</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Settings remain in sync with the selected value</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Signal</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Useful for configuration and admin actions</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Tip</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Use external buttons when the layout needs extra actions</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n </nve-tabs-group>\n\n <div nve-layout=\"row gap:xs\">\n <nve-button command=\"--toggle\" commandfor=\"tab-group-controls\" value=\"overview\">overview</nve-button>\n <nve-button command=\"--toggle\" commandfor=\"tab-group-controls\" value=\"details\">details</nve-button>\n <nve-button command=\"--toggle\" commandfor=\"tab-group-controls\" value=\"settings\">settings</nve-button>\n </div>\n</div>`\n};\n"],"mappings":";AAGA,IAAA,IAAS"}
1
+ {"version":3,"file":"tabs.examples.js","names":[],"sources":["../../src/tabs/tabs.examples.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { html } from 'lit';\nimport '@nvidia-elements/core/tabs/define.js';\nimport '@nvidia-elements/core/button/define.js';\nimport '@nvidia-elements/core/card/define.js';\nimport '@nvidia-elements/core/dot/define.js';\nimport '@nvidia-elements/core/icon/define.js';\nimport '@nvidia-elements/core/icon-button/define.js';\nimport '@nvidia-elements/core/dropdown/define.js';\nimport '@nvidia-elements/core/menu/define.js';\n\nexport default {\n title: 'Elements/Tabs',\n component: 'nve-tabs'\n};\n\n/**\n * @summary Tabs group component for organizing content into selectable sections with disabled state support.\n */\nexport const Default = {\n render: () => html`\n<nve-tabs-group id=\"tab-group-default\">\n <nve-tabs>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group-default\" value=\"overview\">Overview</nve-tabs-item>\n <nve-tabs-item selected command=\"--toggle\" commandfor=\"tab-group-default\" value=\"details\">Details</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group-default\" value=\"settings\">Settings</nve-tabs-item>\n </nve-tabs>\n <div slot=\"overview\">\n overview content\n </div>\n <div slot=\"details\">\n details content\n </div>\n <div slot=\"settings\">\n settings content\n </div>\n</nve-tabs-group>`\n};\n\n/**\n * @summary Borderless tabs variant for minimal visual styling without border emphasis.\n * @tags test-case\n */\nexport const BorderlessTabs = {\n render: () => html`\n<nve-tabs borderless behavior-select>\n <nve-tabs-item selected>Tab 1</nve-tabs-item>\n <nve-tabs-item>Tab 2</nve-tabs-item>\n <nve-tabs-item>Tab 3 </nve-tabs-item>\n <nve-tabs-item disabled>Disabled</nve-tabs-item>\n <nve-tabs-item>Tab 5</nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Tabs with custom border background styling for brand-specific visual customization.\n * @tags test-case\n */\nexport const BorderBackground = {\n render: () => html`\n<nve-tabs behavior-select style=\"--indicator-background: var(--nve-ref-color-brand-green-900); --indicator-border-radius: none;\">\n <nve-tabs-item selected>\n Tab 1\n </nve-tabs-item>\n <nve-tabs-item>\n Tab 2\n </nve-tabs-item>\n <nve-tabs-item>\n Tab 3\n </nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Add icons and notification indicators around tab labels.\n * @description Add Icons before tab labels and Dots after them using the `prefix` and `suffix` slots.\n */\nexport const PrefixAndSuffix = {\n render: () => html`\n<nve-tabs behavior-select>\n <nve-tabs-item selected>\n <nve-icon slot=\"prefix\" name=\"home\" aria-hidden=\"true\"></nve-icon>\n Overview\n <nve-dot slot=\"suffix\" aria-label=\"10 notifications\">10</nve-dot>\n </nve-tabs-item>\n <nve-tabs-item>\n <nve-icon slot=\"prefix\" name=\"beaker\" aria-hidden=\"true\"></nve-icon>\n Experiments\n </nve-tabs-item>\n <nve-tabs-item>\n <nve-icon slot=\"prefix\" name=\"gear\" aria-hidden=\"true\"></nve-icon>\n Settings\n <nve-dot slot=\"suffix\" status=\"accent\" size=\"sm\" aria-hidden=\"true\"></nve-dot>\n </nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Vertical tabs layout for sidebar navigation and vertical content organization patterns.\n */\nexport const VerticalTabs = {\n render: () => html`\n<nve-tabs vertical behavior-select style=\"width: 250px\">\n <nve-tabs-item selected>Tab 1</nve-tabs-item>\n <nve-tabs-item>Tab 2</nve-tabs-item>\n <nve-tabs-item>Tab 3</nve-tabs-item>\n <nve-tabs-item disabled>Disabled</nve-tabs-item>\n <nve-tabs-item>Tab 5</nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Borderless vertical tabs with icons for enhanced visual navigation and minimal styling.\n * @tags test-case\n */\nexport const BorderlessVerticalTabs = {\n render: () => html`\n<nve-tabs vertical borderless behavior-select style=\"width: 250px\">\n <nve-tabs-item>\n <nve-icon name=\"gear\"></nve-icon> Tab 1\n </nve-tabs-item>\n <nve-tabs-item>\n <nve-icon name=\"person\"></nve-icon> Tab 2\n </nve-tabs-item>\n <nve-tabs-item selected>\n <nve-icon name=\"beaker\"></nve-icon> Tab 3\n </nve-tabs-item>\n <nve-tabs-item>\n <nve-icon name=\"add-grid\"></nve-icon> Tab 4\n </nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Stateless tabs for external state management without built-in selection behavior.\n */\nexport const StatelessTabs = {\n render: () => html`\n<nve-tabs>\n <nve-tabs-item selected>Tab 1</nve-tabs-item>\n <nve-tabs-item>Tab 2</nve-tabs-item>\n <nve-tabs-item>Tab 3</nve-tabs-item>\n <nve-tabs-item>Tab 4</nve-tabs-item>\n <nve-tabs-item disabled>Disabled</nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Tabs with link navigation for routing-based tab switching and page navigation.\n */\nexport const Links = {\n render: () => html`\n<nve-tabs>\n <nve-tabs-item selected>\n <a href=\"#links\">Tab 1</a>\n </nve-tabs-item>\n <nve-tabs-item>\n <a href=\"#links\">Tab 2</a>\n </nve-tabs-item>\n <nve-tabs-item>\n <a href=\"#links\">Tab 3</a>\n </nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Tabs with overflow handling for managing large numbers of tabs with scrolling behavior.\n * @tags test-case\n */\nexport const OverflowTabs = {\n render: () => html`\n<nve-tabs behavior-select>\n <nve-tabs-item selected>Tab 1</nve-tabs-item>\n <nve-tabs-item>Tab 2</nve-tabs-item>\n <nve-tabs-item>Tab 3</nve-tabs-item>\n <nve-tabs-item>Tab 4</nve-tabs-item>\n <nve-tabs-item>Tab 5</nve-tabs-item>\n <nve-tabs-item>Tab 6</nve-tabs-item>\n <nve-tabs-item>Tab 7</nve-tabs-item>\n <nve-tabs-item>Tab 8</nve-tabs-item>\n <nve-tabs-item>Tab 9</nve-tabs-item>\n <nve-tabs-item>Tab 10</nve-tabs-item>\n <nve-tabs-item>Tab 11</nve-tabs-item>\n <nve-tabs-item>Tab 12</nve-tabs-item>\n <nve-tabs-item>Tab 13</nve-tabs-item>\n <nve-tabs-item>Tab 14</nve-tabs-item>\n <nve-tabs-item>Tab 15</nve-tabs-item>\n <nve-tabs-item>Tab 16</nve-tabs-item>\n <nve-tabs-item>Tab 17</nve-tabs-item>\n <nve-tabs-item>Tab 18</nve-tabs-item>\n <nve-tabs-item>Tab 19</nve-tabs-item>\n <nve-tabs-item>Tab 20</nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Tabs selection state and a popover working together without any CSS Anchor Positioning collisions.\n * @tags test-case\n */\nexport const WithTooltips = {\n render: () => html`\n<nve-tooltip id=\"tab1\">Tooltip for tab 1</nve-tooltip>\n<nve-tooltip id=\"tab2\">Tooltip for tab 2</nve-tooltip>\n<nve-tooltip id=\"tab3\">Tooltip for tab 3</nve-tooltip>\n<nve-tabs behavior-select>\n <nve-tabs-item selected popovertarget=\"tab1\">Tab 1</nve-tabs-item>\n <nve-tabs-item popovertarget=\"tab2\">Tab 2</nve-tabs-item>\n <nve-tabs-item id=\"tab-item-3\" popovertarget=\"tab3\">Tab 3</nve-tabs-item>\n</nve-tabs>`\n};\n\n/**\n * @summary Group tabs with slot-matched panels and structured card content when one selected value should control both the tab state and revealed details.\n */\nexport const GroupPanels = {\n render: () => html`\n<nve-tabs-group id=\"tab-group\">\n <nve-tabs>\n <nve-tabs-item selected command=\"--toggle\" commandfor=\"tab-group\" value=\"overview\">Overview</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group\" value=\"details\">Details</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group\" value=\"settings\">Settings</nve-tabs-item>\n </nve-tabs>\n <div slot=\"overview\">\n <nve-card style=\"width: 100%; min-width: 320px;\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Overview</h2>\n <p nve-text=\"body sm muted\">High-level release status and current priorities.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Status</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Ready for review</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Audience</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Design and product owners</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Next step</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Validate the tab labels and panel order</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n <div slot=\"details\">\n <nve-card style=\"width: 100%; min-width: 320px;\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Details</h2>\n <p nve-text=\"body sm muted\">Supporting context for teams that need implementation specifics.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Owner</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Elements design system</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Coverage</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Unit, SSR, and accessibility checks</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Focus</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Selection sync and panel wiring</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n <div slot=\"settings\">\n <nve-card style=\"width: 100%; min-width: 320px;\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Settings</h2>\n <p nve-text=\"body sm muted\">Configuration notes for authors and downstream consumers.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Selection</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Controlled by the active tab value</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Panels</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Matched by slot name</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Actions</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">External buttons can drive the same group</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n</nve-tabs-group>`\n};\n\n/**\n * @summary Tab group with vertical tab strip at inline-start beside slot-matched panels for sidebar-style settings and details layouts in LTR.\n */\nexport const GroupVerticalPanels = {\n render: () => html`\n<nve-tabs-group id=\"tab-group-vertical-start\" alignment=\"start\">\n <nve-tabs vertical style=\"width: 250px\">\n <nve-tabs-item selected command=\"--toggle\" commandfor=\"tab-group-vertical-start\" value=\"overview\">Overview</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group-vertical-start\" value=\"details\">Details</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group-vertical-start\" value=\"settings\">Settings</nve-tabs-item>\n </nve-tabs>\n <div slot=\"overview\" style=\"width: 100%; min-width: 320px;\">\n <nve-card style=\"width: 100%\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Overview</h2>\n <p nve-text=\"body sm muted\">High-level release status and current priorities.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Status</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Ready for review</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Audience</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Design and product owners</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Next step</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Validate the tab labels and panel order</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n <div slot=\"details\" style=\"width: 100%; min-width: 320px;\">\n <nve-card style=\"width: 100%\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Details</h2>\n <p nve-text=\"body sm muted\">Supporting context for teams that need implementation specifics.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Owner</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Elements design system</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Coverage</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Unit, SSR, and accessibility checks</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Focus</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Selection sync and panel wiring</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n <div slot=\"settings\" style=\"width: 100%; min-width: 320px;\">\n <nve-card style=\"width: 100%\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Settings</h2>\n <p nve-text=\"body sm muted\">Configuration notes for authors and downstream consumers.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Selection</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Controlled by the active tab value</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Panels</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Matched by slot name</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Actions</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">External buttons can drive the same group</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n</nve-tabs-group>`\n};\n\n/**\n * @summary Tab group with vertical tab strip at inline-end beside slot-matched panels when the tab rail should sit on the opposite side from inline-start sidebars.\n */\nexport const GroupVerticalEnd = {\n render: () => html`\n<nve-tabs-group id=\"tab-group-vertical-end\" alignment=\"end\">\n <nve-tabs vertical style=\"width: 250px\">\n <nve-tabs-item selected command=\"--toggle\" commandfor=\"tab-group-vertical-end\" value=\"overview\">Overview</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group-vertical-end\" value=\"details\">Details</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group-vertical-end\" value=\"settings\">Settings</nve-tabs-item>\n </nve-tabs>\n <div slot=\"overview\" style=\"width: 100%; min-width: 320px;\">\n <nve-card style=\"width: 100%\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Overview</h2>\n <p nve-text=\"body sm muted\">High-level release status and current priorities.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Status</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Ready for review</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Audience</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Design and product owners</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Next step</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Validate the tab labels and panel order</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n <div slot=\"details\" style=\"width: 100%; min-width: 320px;\">\n <nve-card style=\"width: 100%\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Details</h2>\n <p nve-text=\"body sm muted\">Supporting context for teams that need implementation specifics.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Owner</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Elements design system</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Coverage</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Unit, SSR, and accessibility checks</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Focus</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Selection sync and panel wiring</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n <div slot=\"settings\" style=\"width: 100%; min-width: 320px;\">\n <nve-card style=\"width: 100%\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Settings</h2>\n <p nve-text=\"body sm muted\">Configuration notes for authors and downstream consumers.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Selection</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Controlled by the active tab value</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Panels</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Matched by slot name</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Actions</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">External buttons can drive the same group</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n</nve-tabs-group>`\n};\n\n/**\n * @summary Drive the same tabs group from external buttons when layouts need tabs and secondary actions to stay in sync with structured panel content.\n */\nexport const ExternalControls = {\n render: () => html`\n<div nve-layout=\"column gap:lg\">\n <nve-tabs-group id=\"tab-group-controls\">\n <nve-tabs>\n <nve-tabs-item selected command=\"--toggle\" commandfor=\"tab-group-controls\" value=\"overview\">Overview</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group-controls\" value=\"details\">Details</nve-tabs-item>\n <nve-tabs-item command=\"--toggle\" commandfor=\"tab-group-controls\" value=\"settings\">Settings</nve-tabs-item>\n </nve-tabs>\n <div slot=\"overview\">\n <nve-card style=\"width: 100%; min-width: 320px;\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Overview</h2>\n <p nve-text=\"body sm muted\">Quick status for the current tab group.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">State</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Overview is active</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Signal</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Use this tab for a summary of the current workflow</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Tip</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Pair it with external controls for quick switching</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n <div slot=\"details\">\n <nve-card style=\"width: 100%; min-width: 320px;\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Details</h2>\n <p nve-text=\"body sm muted\">Deeper context for follow-up tasks and implementation notes.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">State</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Details are available on demand</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Signal</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Use this tab when readers need extra context</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Tip</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Keep the content specific to the selected tab</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n <div slot=\"settings\">\n <nve-card style=\"width: 100%; min-width: 320px;\">\n <nve-card-header>\n <div nve-layout=\"column gap:xs\">\n <h2 nve-text=\"heading sm bold\">Settings</h2>\n <p nve-text=\"body sm muted\">Preferences and coordination notes for the shared tab group.</p>\n </div>\n </nve-card-header>\n <nve-card-content>\n <dl nve-layout=\"grid gap:sm\">\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">State</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Settings remain in sync with the selected value</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Signal</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Useful for configuration and admin actions</dd>\n <dt nve-layout=\"span:4\" nve-text=\"body muted medium\">Tip</dt>\n <dd nve-layout=\"span:8\" nve-text=\"body\">Use external buttons when the layout needs extra actions</dd>\n </dl>\n </nve-card-content>\n </nve-card>\n </div>\n </nve-tabs-group>\n\n <div nve-layout=\"row gap:xs\">\n <nve-button command=\"--toggle\" commandfor=\"tab-group-controls\" value=\"overview\">overview</nve-button>\n <nve-button command=\"--toggle\" commandfor=\"tab-group-controls\" value=\"details\">details</nve-button>\n <nve-button command=\"--toggle\" commandfor=\"tab-group-controls\" value=\"settings\">settings</nve-button>\n </div>\n</div>`\n};\n\n/**\n * @summary Close a tab with an application-owned button.\n * @description Add a labeled Icon Button to the `suffix` slot of a Tabs Item Group and handle its click to close the tab. Use arrow keys to focus a tab, then Tab to reach its actions.\n */\nexport const ItemGroupAction = {\n render: () => html`\n<nve-tabs behavior-select>\n <nve-tabs-item id=\"workspace-overview\" selected>Overview</nve-tabs-item>\n <nve-tabs-item-group id=\"workspace-experiment\">\n <nve-tabs-item>Experiment</nve-tabs-item>\n <nve-icon-button id=\"close-experiment\" slot=\"suffix\" icon-name=\"cancel\" size=\"sm\" container=\"flat\" aria-label=\"Close experiment\"></nve-icon-button>\n </nve-tabs-item-group>\n</nve-tabs>\n<script type=\"module\">\n const overview = document.querySelector('#workspace-overview');\n document.querySelector('#close-experiment').addEventListener('click', () => {\n document.querySelector('#workspace-experiment').remove();\n overview.selected = true;\n overview.focus();\n });\n</script>`\n};\n\n/**\n * @summary Open a tab's actions menu from a suffix button without selecting the tab.\n * @description Add an Icon Button to open a Dropdown beside the tab strip.\n */\nexport const ItemGroupMenu = {\n render: () => html`\n<nve-tabs behavior-select>\n <nve-tabs-item selected>Overview</nve-tabs-item>\n <nve-tabs-item-group>\n <nve-tabs-item>Experiment</nve-tabs-item>\n <nve-icon-button slot=\"suffix\" icon-name=\"more-actions\" size=\"sm\" container=\"flat\" aria-label=\"Experiment actions\" aria-haspopup=\"menu\" popovertarget=\"experiment-actions\"></nve-icon-button>\n </nve-tabs-item-group>\n</nve-tabs>\n<nve-dropdown id=\"experiment-actions\">\n <nve-menu>\n <nve-menu-item>Rename</nve-menu-item>\n <nve-menu-item>Duplicate</nve-menu-item>\n </nve-menu>\n</nve-dropdown>`\n};\n"],"mappings":";AAGA,IAAA,IAAS"}
@@ -34,12 +34,12 @@
34
34
  ]
35
35
  },
36
36
  {
37
- "id": "tabs-with-dots",
38
- "name": "WithDots",
39
- "template": "<nve-tabs behavior-select>\n <nve-tabs-item>Tab 1</nve-tabs-item>\n <nve-tabs-item>Tab 2</nve-tabs-item>\n <nve-tabs-item>Tab 3 </nve-tabs-item>\n <nve-tabs-item selected>\n Tab 4\n <nve-dot aria-label=\"10 notifications\">10</nve-dot>\n </nve-tabs-item>\n <nve-tabs-item>Tab 5</nve-tabs-item>\n</nve-tabs>\n",
40
- "summary": "Tabs with notification dots for indicating unread content or alerts within tab sections.",
41
- "description": "",
42
- "composition": false,
37
+ "id": "tabs-prefix-and-suffix",
38
+ "name": "PrefixAndSuffix",
39
+ "template": "<nve-tabs behavior-select>\n <nve-tabs-item selected>\n <nve-icon slot=\"prefix\" name=\"home\" aria-hidden=\"true\"></nve-icon>\n Overview\n <nve-dot slot=\"suffix\" aria-label=\"10 notifications\">10</nve-dot>\n </nve-tabs-item>\n <nve-tabs-item>\n <nve-icon slot=\"prefix\" name=\"beaker\" aria-hidden=\"true\"></nve-icon>\n Experiments\n </nve-tabs-item>\n <nve-tabs-item>\n <nve-icon slot=\"prefix\" name=\"gear\" aria-hidden=\"true\"></nve-icon>\n Settings\n <nve-dot slot=\"suffix\" status=\"accent\" size=\"sm\" aria-hidden=\"true\"></nve-dot>\n </nve-tabs-item>\n</nve-tabs>\n",
40
+ "summary": "Add icons and notification indicators around tab labels.",
41
+ "description": "Add Icons before tab labels and Dots after them using the `prefix` and `suffix` slots.",
42
+ "composition": true,
43
43
  "tags": []
44
44
  },
45
45
  {
@@ -137,6 +137,24 @@
137
137
  "description": "",
138
138
  "composition": true,
139
139
  "tags": []
140
+ },
141
+ {
142
+ "id": "tabs-item-group-action",
143
+ "name": "ItemGroupAction",
144
+ "template": "<nve-tabs behavior-select>\n <nve-tabs-item id=\"workspace-overview\" selected>Overview</nve-tabs-item>\n <nve-tabs-item-group id=\"workspace-experiment\">\n <nve-tabs-item>Experiment</nve-tabs-item>\n <nve-icon-button id=\"close-experiment\" slot=\"suffix\" icon-name=\"cancel\" size=\"sm\" container=\"flat\" aria-label=\"Close experiment\"></nve-icon-button>\n </nve-tabs-item-group>\n</nve-tabs>\n<script type=\"module\">\n const overview = document.querySelector(\"#workspace-overview\");\n document.querySelector(\"#close-experiment\").addEventListener(\"click\", () => {\n document.querySelector(\"#workspace-experiment\").remove();\n overview.selected = true;\n overview.focus();\n });\n</script>\n",
145
+ "summary": "Close a tab with an application-owned button.",
146
+ "description": "Add a labeled Icon Button to the `suffix` slot of a Tabs Item Group and handle its click to close the tab. Use arrow keys to focus a tab, then Tab to reach its actions.",
147
+ "composition": false,
148
+ "tags": []
149
+ },
150
+ {
151
+ "id": "tabs-item-group-menu",
152
+ "name": "ItemGroupMenu",
153
+ "template": "<nve-tabs behavior-select>\n <nve-tabs-item selected>Overview</nve-tabs-item>\n <nve-tabs-item-group>\n <nve-tabs-item>Experiment</nve-tabs-item>\n <nve-icon-button slot=\"suffix\" icon-name=\"more-actions\" size=\"sm\" container=\"flat\" aria-label=\"Experiment actions\" aria-haspopup=\"menu\" popovertarget=\"experiment-actions\"></nve-icon-button>\n </nve-tabs-item-group>\n</nve-tabs>\n<nve-dropdown id=\"experiment-actions\">\n <nve-menu>\n <nve-menu-item>Rename</nve-menu-item>\n <nve-menu-item>Duplicate</nve-menu-item>\n </nve-menu>\n</nve-dropdown>\n",
154
+ "summary": "Open a tab's actions menu from a suffix button without selecting the tab.",
155
+ "description": "Add an Icon Button to open a Dropdown beside the tab strip.",
156
+ "composition": true,
157
+ "tags": []
140
158
  }
141
159
  ]
142
160
  }
@@ -1,5 +1,5 @@
1
1
  //#region src/tabs/tabs.global.css?inline
2
- var e = "nve-tabs{--indicator-background: var(--nve-sys-accent-secondary-background);--indicator-height: var(--nve-ref-border-width-xl);--indicator-border-radius: var(--nve-ref-border-radius-sm);&:after{background:var(--indicator-background);height:var(--indicator-height);border-radius:var(--indicator-border-radius);position:fixed;display:block;content:\"\";width:anchor-size(width);transition:left var(--nve-ref-animation-duration-150) var(--nve-ref-animation-easing-100);position-anchor:--selected;top:calc(anchor(bottom) - var(--indicator-height));left:anchor(left);z-index:-1}&[borderless]:after{display:none!important}}nve-tabs[vertical]{&:after{width:var(--indicator-height);height:anchor-size(height);transition:top var(--nve-ref-animation-duration-150) var(--nve-ref-animation-easing-100);top:anchor(top)}}nve-tabs-item{&[selected]{anchor-name:--selected}}";
2
+ var e = "nve-tabs{anchor-scope:--selected,--selected-group;--indicator-background: var(--nve-sys-accent-secondary-background);--indicator-height: var(--nve-ref-border-width-xl);--indicator-border-radius: var(--nve-ref-border-radius-sm);&:after{background:var(--indicator-background);height:var(--indicator-height);border-radius:var(--indicator-border-radius);position:fixed;display:block;content:\"\";width:anchor-size(width);transition:left var(--nve-ref-animation-duration-150) var(--nve-ref-animation-easing-100);position-anchor:--selected;top:calc(anchor(bottom) - var(--indicator-height));left:anchor(left);z-index:-1}&[borderless]:after{display:none!important}}nve-tabs[vertical]{&:after{width:var(--indicator-height);height:anchor-size(height);transition:top var(--nve-ref-animation-duration-150) var(--nve-ref-animation-easing-100);top:anchor(top)}}nve-tabs[vertical]:dir(rtl):after{left:auto;right:anchor(right)}nve-tabs-item[selected]{anchor-name:--selected}nve-tabs-item-group:has(>nve-tabs-item[selected]){anchor-name:--selected-group}nve-tabs:has(>nve-tabs-item-group>nve-tabs-item[selected]):after{position-anchor:--selected-group}";
3
3
  //#endregion
4
4
  export { e as default };
5
5
 
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.global.js","names":[],"sources":["../../src/tabs/tabs.global.css?inline"],"sourcesContent":["/* SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */\n/* SPDX-License-Identifier: Apache-2.0 */\n\nnve-tabs {\n --indicator-background: var(--nve-sys-accent-secondary-background);\n --indicator-height: var(--nve-ref-border-width-xl);\n --indicator-border-radius: var(--nve-ref-border-radius-sm);\n\n &::after {\n background: var(--indicator-background);\n height: var(--indicator-height);\n border-radius: var(--indicator-border-radius);\n position: fixed;\n display: block;\n content: '';\n width: anchor-size(width);\n transition: left var(--nve-ref-animation-duration-150) var(--nve-ref-animation-easing-100);\n position-anchor: --selected;\n top: calc(anchor(bottom) - var(--indicator-height));\n left: anchor(left);\n z-index: -1;\n }\n\n &[borderless]::after {\n display: none !important;\n }\n}\n\nnve-tabs[vertical] {\n &::after {\n width: var(--indicator-height);\n height: anchor-size(height);\n transition: top var(--nve-ref-animation-duration-150) var(--nve-ref-animation-easing-100);\n top: anchor(top);\n }\n}\n\nnve-tabs-item {\n &[selected] {\n anchor-name: --selected;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"tabs.global.js","names":[],"sources":["../../src/tabs/tabs.global.css?inline"],"sourcesContent":["/* SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */\n/* SPDX-License-Identifier: Apache-2.0 */\n\nnve-tabs {\n anchor-scope: --selected, --selected-group;\n --indicator-background: var(--nve-sys-accent-secondary-background);\n --indicator-height: var(--nve-ref-border-width-xl);\n --indicator-border-radius: var(--nve-ref-border-radius-sm);\n\n &::after {\n background: var(--indicator-background);\n height: var(--indicator-height);\n border-radius: var(--indicator-border-radius);\n position: fixed;\n display: block;\n content: '';\n width: anchor-size(width);\n transition: left var(--nve-ref-animation-duration-150) var(--nve-ref-animation-easing-100);\n position-anchor: --selected;\n top: calc(anchor(bottom) - var(--indicator-height));\n left: anchor(left);\n z-index: -1;\n }\n\n &[borderless]::after {\n display: none !important;\n }\n}\n\nnve-tabs[vertical] {\n &::after {\n width: var(--indicator-height);\n height: anchor-size(height);\n transition: top var(--nve-ref-animation-duration-150) var(--nve-ref-animation-easing-100);\n top: anchor(top);\n }\n}\n\nnve-tabs[vertical]:dir(rtl)::after {\n left: auto;\n right: anchor(right);\n}\n\nnve-tabs-item[selected] {\n anchor-name: --selected;\n}\n\nnve-tabs-item-group:has(> nve-tabs-item[selected]) {\n anchor-name: --selected-group;\n}\n\nnve-tabs:has(> nve-tabs-item-group > nve-tabs-item[selected])::after {\n position-anchor: --selected-group;\n}\n"],"mappings":""}
package/dist/tabs/tabs.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/tabs/tabs.css?inline
2
- var e = ":host{--gap: var(--nve-ref-space-xs)}[internal-host]{display:flex;flex-direction:row;gap:var(--gap);overflow-x:auto;white-space:nowrap;scrollbar-color:var(--nve-sys-scrollbar-thumb-color) var(--nve-sys-scrollbar-track-color);scrollbar-width:var(--nve-sys-scrollbar-width)}:host([vertical]){--gap: var(--nve-ref-space-xxxs)}:host([vertical]) [internal-host]{flex-direction:column}:host([vertical]) ::slotted(nve-tabs-item){--border-inset: 0 8px 0 8px;--width: calc(100% - 8px) }:host([vertical]) ::slotted(nve-tabs-item:state(selected)){--nve-sys-interaction-state-ratio: var(--nve-sys-interaction-state-ratio-hover)}::slotted(nve-tabs-item){white-space:nowrap}";
2
+ var e = ":host{--gap: var(--nve-ref-space-xs)}[internal-host]{display:flex;flex-direction:row;gap:var(--gap);overflow-x:auto;white-space:nowrap;scrollbar-color:var(--nve-sys-scrollbar-thumb-color) var(--nve-sys-scrollbar-track-color);scrollbar-width:var(--nve-sys-scrollbar-width)}:host([vertical]){--gap: var(--nve-ref-space-xxxs)}:host([vertical]) [internal-host]{flex-direction:column}:host([vertical]) ::slotted(:is(nve-tabs-item,nve-tabs-item-group)){--border-inset: 0 8px 0 8px;--width: calc(100% - 8px) }:host([vertical]) ::slotted(nve-tabs-item:state(selected)){--nve-sys-interaction-state-ratio: var(--nve-sys-interaction-state-ratio-hover)}:host([vertical]) ::slotted(nve-tabs-item-group:has(> nve-tabs-item[selected])){--_tabs-group-interaction-state-ratio: var(--nve-sys-interaction-state-ratio-hover)}::slotted(:is(nve-tabs-item,nve-tabs-item-group)){white-space:nowrap}";
3
3
  //#endregion
4
4
  export { e as default };
5
5
 
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.js","names":[],"sources":["../../src/tabs/tabs.css?inline"],"sourcesContent":["/* SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */\n/* SPDX-License-Identifier: Apache-2.0 */\n\n:host {\n --gap: var(--nve-ref-space-xs);\n}\n\n[internal-host] {\n display: flex;\n flex-direction: row;\n gap: var(--gap);\n overflow-x: auto;\n white-space: nowrap;\n scrollbar-color: var(--nve-sys-scrollbar-thumb-color) var(--nve-sys-scrollbar-track-color);\n scrollbar-width: var(--nve-sys-scrollbar-width);\n}\n\n:host([vertical]) {\n --gap: var(--nve-ref-space-xxxs);\n}\n\n:host([vertical]) [internal-host] {\n flex-direction: column;\n}\n\n:host([vertical]) ::slotted(nve-tabs-item) {\n --border-inset: 0 8px 0 8px;\n --width: calc(100% - 8px);\n}\n\n:host([vertical]) ::slotted(nve-tabs-item:state(selected)) {\n --nve-sys-interaction-state-ratio: var(--nve-sys-interaction-state-ratio-hover);\n}\n\n::slotted(nve-tabs-item) {\n white-space: nowrap;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"tabs.js","names":[],"sources":["../../src/tabs/tabs.css?inline"],"sourcesContent":["/* SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */\n/* SPDX-License-Identifier: Apache-2.0 */\n\n:host {\n --gap: var(--nve-ref-space-xs);\n}\n\n[internal-host] {\n display: flex;\n flex-direction: row;\n gap: var(--gap);\n overflow-x: auto;\n white-space: nowrap;\n scrollbar-color: var(--nve-sys-scrollbar-thumb-color) var(--nve-sys-scrollbar-track-color);\n scrollbar-width: var(--nve-sys-scrollbar-width);\n}\n\n:host([vertical]) {\n --gap: var(--nve-ref-space-xxxs);\n}\n\n:host([vertical]) [internal-host] {\n flex-direction: column;\n}\n\n:host([vertical]) ::slotted(:is(nve-tabs-item, nve-tabs-item-group)) {\n --border-inset: 0 8px 0 8px;\n --width: calc(100% - 8px);\n}\n\n:host([vertical]) ::slotted(nve-tabs-item:state(selected)) {\n --nve-sys-interaction-state-ratio: var(--nve-sys-interaction-state-ratio-hover);\n}\n\n:host([vertical]) ::slotted(nve-tabs-item-group:has(> nve-tabs-item[selected])) {\n --_tabs-group-interaction-state-ratio: var(--nve-sys-interaction-state-ratio-hover);\n}\n\n::slotted(:is(nve-tabs-item, nve-tabs-item-group)) {\n white-space: nowrap;\n}\n"],"mappings":""}
@@ -1,31 +1,32 @@
1
1
  import { audit as e } from "../internal/controllers/audit.controller.js";
2
2
  import { appendAnchorName as t, appendRootNodeStyle as n, removeAnchorName as r } from "../internal/utils/dom.js";
3
- import { keyNavigationList as i } from "../internal/controllers/keynav-list.controller.js";
3
+ import { KeyNavigationListController as i } from "../internal/controllers/keynav-list.controller.js";
4
4
  import { attachInternals as a } from "../internal/utils/a11y.js";
5
5
  import { stateSelected as o } from "../internal/controllers/state-selected.controller.js";
6
6
  import { useStyles as s } from "../internal/styles/index.js";
7
7
  import c from "../_virtual/_@oxc-project_runtime@0.147.0/helpers/esm/decorate.js";
8
- import l from "./tabs.global.js";
9
- import u from "./tabs-item.js";
10
- import d from "./tabs.js";
11
- import { LitElement as f, html as p } from "lit";
12
- import { property as m } from "lit/decorators/property.js";
13
- import { ButtonFormControlMixin as h } from "@nvidia-elements/forms/mixins";
14
- import { queryAssignedElements as g } from "lit/decorators/query-assigned-elements.js";
8
+ import { getTabItems as l, isTabItemTabbable as u } from "./utils.js";
9
+ import d from "./tabs.global.js";
10
+ import f from "./tabs-item.js";
11
+ import p from "./tabs.js";
12
+ import { LitElement as m, html as h } from "lit";
13
+ import { property as g } from "lit/decorators/property.js";
14
+ import { ButtonFormControlMixin as _ } from "@nvidia-elements/forms/mixins";
15
+ import { queryAssignedElements as v } from "lit/decorators/query-assigned-elements.js";
15
16
  //#region src/tabs/tabs.ts
16
- var _ = class extends h(f) {
17
+ var y = class extends _(m) {
17
18
  static {
18
- this.styles = s([u]);
19
+ this.styles = s([f]);
19
20
  }
20
21
  static {
21
22
  this.metadata = {
22
23
  tag: "nve-tabs-item",
23
- version: "2.17.1",
24
- parents: ["nve-tabs"]
24
+ version: "2.18.0",
25
+ parents: ["nve-tabs", "nve-tabs-item-group"]
25
26
  };
26
27
  }
27
28
  render() {
28
- return p`<div internal-host focus-within><slot></slot></div>`;
29
+ return h`<div internal-host focus-within><slot name="prefix"></slot><div id="label"><slot></slot></div><slot name="suffix"></slot></div>`;
29
30
  }
30
31
  constructor() {
31
32
  super(), this.selected = !1, this.type = "button";
@@ -37,62 +38,103 @@ var _ = class extends h(f) {
37
38
  super.updated(e), e.has("selected") && (this.selected ? t(this, "--selected") : r(this, "--selected"));
38
39
  }
39
40
  };
40
- c([m({
41
+ c([g({
41
42
  type: Boolean,
42
43
  reflect: !0
43
- })], _.prototype, "selected", void 0), _ = c([e(), o()], _);
44
- var v = class extends f {
44
+ })], y.prototype, "selected", void 0), y = c([e(), o()], y);
45
+ var b = class extends m {
45
46
  constructor(...e) {
46
- super(...e), this.vertical = !1, this.borderless = !1, this.behaviorSelect = !1, this.#t = (e) => {
47
- this.#e(e.target);
47
+ super(...e), this.vertical = !1, this.borderless = !1, this.behaviorSelect = !1, this.#t = new i(this), this.#n = [], this.#a = (e) => {
48
+ e.some((e) => e.type === "childList" || e.attributeName === "slot") ? this.#o() : e.some((e) => this.#e.some((t) => t.contains(e.target))) && this.#s();
49
+ }, this.#o = async () => {
50
+ let e = this.#e;
51
+ if (e.length === this.#n.length && e.every((e, t) => e === this.#n[t])) {
52
+ this.#s();
53
+ return;
54
+ }
55
+ let t = this.#n;
56
+ this.#n = e, await Promise.all(e.map((e) => e.updateComplete)), e === this.#n && (this.#t.refreshItems(t), this.#s());
57
+ }, this.#l = (e) => {
58
+ let t = e.composedPath(), n = this.#e.find((e) => t.includes(e));
59
+ n && this.#c(n);
48
60
  };
49
61
  }
50
62
  static {
51
- this.styles = s([d]);
63
+ this.styles = s([p]);
52
64
  }
53
65
  static {
54
66
  this.metadata = {
55
67
  tag: "nve-tabs",
56
- version: "2.17.1",
57
- children: ["nve-tabs-item"]
68
+ version: "2.18.0",
69
+ children: ["nve-tabs-item", "nve-tabs-item-group"]
58
70
  };
59
71
  }
60
72
  get keynavListConfig() {
61
- let e = this.items;
73
+ let e = this.#e;
62
74
  return {
63
75
  items: e,
64
76
  initialItem: e.find((e) => e.selected),
65
- layout: this.vertical ? "vertical" : "horizontal"
77
+ layout: this.vertical ? "vertical" : "horizontal",
78
+ dir: getComputedStyle(this).direction
66
79
  };
67
80
  }
68
- #e(e) {
69
- !this.behaviorSelect || !e.matches("nve-tabs-item") || e.disabled || (this.keynavListConfig.items.forEach((e) => e.selected = !1), e.selected = !0);
81
+ get #e() {
82
+ return l(this.entries ?? []);
70
83
  }
84
+ #t;
85
+ #n;
86
+ #r;
71
87
  render() {
72
- return p`<div internal-host><slot></slot></div>`;
88
+ return h`<div internal-host><slot @slotchange="${this.#o}"></slot></div>`;
73
89
  }
74
90
  connectedCallback() {
75
- super.connectedCallback(), n(this, l), a(this), this._internals.role = "tablist", this.addEventListener("click", this.#t);
91
+ super.connectedCallback(), n(this, d), a(this), this._internals.role = "tablist", this.addEventListener("click", this.#l), this.#i(), this.hasUpdated && this.#s();
76
92
  }
77
93
  disconnectedCallback() {
78
- super.disconnectedCallback(), this.removeEventListener("click", this.#t);
94
+ super.disconnectedCallback(), this.removeEventListener("click", this.#l), this.#r?.disconnect();
95
+ }
96
+ firstUpdated() {
97
+ this.#r = new MutationObserver(this.#a), this.#i();
79
98
  }
80
- #t;
81
99
  updated(e) {
82
100
  super.updated(e), this._internals.ariaOrientation = this.vertical ? "vertical" : "horizontal";
83
101
  }
102
+ #i() {
103
+ this.#r?.observe(this, {
104
+ childList: !0,
105
+ subtree: !0,
106
+ attributes: !0,
107
+ attributeFilter: [
108
+ "tabindex",
109
+ "href",
110
+ "slot"
111
+ ]
112
+ });
113
+ }
114
+ #a;
115
+ #o;
116
+ #s() {
117
+ this.querySelectorAll(":scope > nve-tabs-item-group").forEach((e) => {
118
+ let t = l([e])[0];
119
+ e.accessoryTabEnabled = !!t && u(t);
120
+ });
121
+ }
122
+ #c(e) {
123
+ !this.behaviorSelect || !e.matches("nve-tabs-item") || e.disabled || (this.keynavListConfig.items.forEach((e) => e.selected = !1), e.selected = !0);
124
+ }
125
+ #l;
84
126
  };
85
- c([m({
127
+ c([g({
86
128
  type: Boolean,
87
129
  reflect: !0
88
- })], v.prototype, "vertical", void 0), c([m({
130
+ })], b.prototype, "vertical", void 0), c([g({
89
131
  type: Boolean,
90
132
  reflect: !0
91
- })], v.prototype, "borderless", void 0), c([m({
133
+ })], b.prototype, "borderless", void 0), c([g({
92
134
  type: Boolean,
93
135
  attribute: "behavior-select"
94
- })], v.prototype, "behaviorSelect", void 0), c([g()], v.prototype, "items", void 0), v = c([e(), i()], v);
136
+ })], b.prototype, "behaviorSelect", void 0), c([v()], b.prototype, "entries", void 0), b = c([e()], b);
95
137
  //#endregion
96
- export { v as Tabs, _ as TabsItem };
138
+ export { b as Tabs, y as TabsItem };
97
139
 
98
140
  //# sourceMappingURL=tabs2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tabs2.js","names":[],"sources":["../../src/tabs/tabs.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { PropertyValues } from 'lit';\nimport { html, LitElement } from 'lit';\nimport { property } from 'lit/decorators/property.js';\nimport { queryAssignedElements } from 'lit/decorators/query-assigned-elements.js';\nimport { ButtonFormControlMixin } from '@nvidia-elements/forms/mixins';\nimport type { KeynavListConfig } from '@nvidia-elements/core/internal';\nimport {\n stateSelected,\n useStyles,\n keyNavigationList,\n attachInternals,\n audit,\n appendRootNodeStyle,\n appendAnchorName,\n removeAnchorName\n} from '@nvidia-elements/core/internal';\nimport globalStyles from './tabs.global.css?inline';\nimport tabsItemStyleSheet from './tabs-item.css?inline';\nimport tabsStyleSheet from './tabs.css?inline';\n\n/**\n * @element nve-tabs-item\n * @description Represents an individual tab within a tablist, providing a selectable button for switching between content views.\n * @documentation https://nvidia.github.io/elements/docs/elements/tabs/\n * @since 0.10.0\n * @entrypoint \\@nvidia-elements/core/tabs\n * @slot - The label displayed for the tab.\n * @cssprop --font-size\n * @cssprop --width\n * @cssprop --padding\n * @cssprop --font-size\n * @cssprop --font-weight\n * @cssprop --border-radius\n * @cssprop --color\n * @cssprop --height\n * @cssprop --cursor\n * @cssprop --text-transform\n * @aria https://www.w3.org/WAI/ARIA/apg/patterns/tabs/\n * @responsive false\n */\n@audit()\n@stateSelected<TabsItem>()\nexport class TabsItem extends ButtonFormControlMixin(LitElement) {\n /**\n * Determines which tab item the user selects, defaults to false.\n */\n @property({ type: Boolean, reflect: true }) selected = false;\n\n static styles = useStyles([tabsItemStyleSheet]);\n\n static readonly metadata = {\n tag: 'nve-tabs-item',\n version: '0.0.0',\n parents: ['nve-tabs']\n };\n\n render() {\n return html`\n <div internal-host focus-within>\n <slot></slot>\n </div>\n `;\n }\n\n constructor() {\n super();\n this.type = 'button';\n }\n\n connectedCallback() {\n super.connectedCallback();\n this._internals.role = 'tab';\n }\n\n updated(props: PropertyValues<this>) {\n super.updated(props);\n\n if (props.has('selected')) {\n if (this.selected) {\n appendAnchorName(this, '--selected');\n } else {\n removeAnchorName(this, '--selected');\n }\n }\n }\n}\n\n/**\n * @element nve-tabs\n * @description Tabs provide a selection UX, typically used for swapping content shown on a page, or within a navigation context.\n * @documentation https://nvidia.github.io/elements/docs/elements/tabs/\n * @since 0.10.0\n * @entrypoint \\@nvidia-elements/core/tabs\n * @slot - default slot for tab-item\n * @cssprop --gap\n * @cssprop --indicator-background\n * @cssprop --indicator-border-radius\n * @cssprop --indicator-height\n * @cssprop --border-inset\n * @aria https://www.w3.org/WAI/ARIA/apg/patterns/tabs/\n * @responsive false\n */\n@audit()\n@keyNavigationList<Tabs>()\nexport class Tabs extends LitElement {\n /**\n * Determines whether the tabs should display in a vertical layout vs. defaulting to horizontal.\n */\n @property({ type: Boolean, reflect: true }) vertical = false;\n\n /**\n * Determines whether the tabs should display a border on selected items vs. defaults to show border.\n */\n @property({ type: Boolean, reflect: true }) borderless = false;\n\n /**\n * Determines whether the tabs should handle selection behavior vs. defaults to off.\n */\n @property({ type: Boolean, attribute: 'behavior-select' }) behaviorSelect = false;\n\n static styles = useStyles([tabsStyleSheet]);\n\n static readonly metadata = {\n tag: 'nve-tabs',\n version: '0.0.0',\n children: ['nve-tabs-item']\n };\n\n /** @private */\n get keynavListConfig(): KeynavListConfig {\n const items = this.items;\n return {\n items,\n initialItem: items.find(item => item.selected),\n layout: this.vertical ? 'vertical' : 'horizontal'\n };\n }\n\n @queryAssignedElements() private items!: TabsItem[];\n\n /** @private */\n declare _internals: ElementInternals;\n\n #selectTab(tabItem: HTMLElement & { matches: Element['matches']; disabled?: boolean; selected?: boolean }) {\n if (!this.behaviorSelect || !tabItem.matches('nve-tabs-item') || tabItem.disabled) {\n return;\n }\n\n this.keynavListConfig.items.forEach((i: HTMLElement) => ((i as TabsItem).selected = false));\n tabItem.selected = true;\n }\n\n render() {\n return html`\n <div internal-host>\n <slot></slot>\n </div>\n `;\n }\n\n connectedCallback() {\n super.connectedCallback();\n appendRootNodeStyle(this, globalStyles);\n attachInternals(this);\n this._internals.role = 'tablist';\n this.addEventListener('click', this.#onClick);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener('click', this.#onClick);\n }\n\n #onClick = (e: Event) => {\n this.#selectTab(e.target as HTMLElement & { matches: Element['matches']; disabled?: boolean; selected?: boolean });\n };\n\n updated(props: PropertyValues<this>) {\n super.updated(props);\n this._internals.ariaOrientation = this.vertical ? 'vertical' : 'horizontal';\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AA6CO,IAAM,IAAN,cAAuB,EAAuB,CAAU,CAAC,CAAC;;EAM/C,KAAA,SAAA,EAAU,CAAC,CAAkB,CAAC;;;EAEnB,KAAA,WAAA;GACzB,KAAK;GACL,SAAS;GACT,SAAS,CAAC,UAAU;EACtB;;CAEA,SAAS;EACP,OAAO,CAAI;CAKb;CAEA,cAAc;EAEZ,AADA,MAAM,GAnB+C,KAAA,WAAA,IAoBrD,KAAK,OAAO;CACd;CAEA,oBAAoB;EAElB,AADA,MAAM,kBAAkB,GACxB,KAAK,WAAW,OAAO;CACzB;CAEA,QAAQ,GAA6B;EAGnC,AAFA,MAAM,QAAQ,CAAK,GAEf,EAAM,IAAI,UAAU,MAClB,KAAK,WACP,EAAiB,MAAM,YAAY,IAEnC,EAAiB,MAAM,YAAY;CAGzC;AACF;AAvCG,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,GAN3C,IAAA,EAAA,CAAA,EAAM,GACN,EAAwB,CAAA,GAAA,CAAA;AA+DlB,IAAM,IAAN,cAAmB,EAAW;;EAqEvB,aAjE2C,KAAA,WAAA,IAKE,KAAA,aAAA,IAKmB,KAAA,iBAAA,IAuDhE,KAAA,MAAA,MAAa;GACvB,KAAK,GAAW,EAAE,MAA+F;EACnH;;;EAvDgB,KAAA,SAAA,EAAU,CAAC,CAAc,CAAC;;;EAEf,KAAA,WAAA;GACzB,KAAK;GACL,SAAS;GACT,UAAU,CAAC,eAAe;EAC5B;;CAGA,IAAI,mBAAqC;EACvC,IAAM,IAAQ,KAAK;EACnB,OAAO;GACL;GACA,aAAa,EAAM,MAAK,MAAQ,EAAK,QAAQ;GAC7C,QAAQ,KAAK,WAAW,aAAa;EACvC;CACF;CAOA,GAAW,GAAgG;EACrG,CAAC,KAAK,kBAAkB,CAAC,EAAQ,QAAQ,eAAe,KAAK,EAAQ,aAIzE,KAAK,iBAAiB,MAAM,SAAS,MAAoB,EAAgB,WAAW,EAAM,GAC1F,EAAQ,WAAW;CACrB;CAEA,SAAS;EACP,OAAO,CAAI;CAKb;CAEA,oBAAoB;EAKlB,AAJA,MAAM,kBAAkB,GACxB,EAAoB,MAAM,CAAY,GACtC,EAAgB,IAAI,GACpB,KAAK,WAAW,OAAO,WACvB,KAAK,iBAAiB,SAAS,KAAK,EAAQ;CAC9C;CAEA,uBAAuB;EAErB,AADA,MAAM,qBAAqB,GAC3B,KAAK,oBAAoB,SAAS,KAAK,EAAQ;CACjD;CAEA;CAIA,QAAQ,GAA6B;EAEnC,AADA,MAAM,QAAQ,CAAK,GACnB,KAAK,WAAW,kBAAkB,KAAK,WAAW,aAAa;CACjE;AACF;AAzEG,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,GAKzC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,cAAA,KAAA,CAAA,GAKzC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,WAAW;AAAkB,CAAC,CAAA,GAAA,EAAA,WAAA,kBAAA,KAAA,CAAA,GAoBxD,EAAA,CAAA,EAAsB,CAAA,GAAA,EAAA,WAAA,SAAA,KAAA,CAAA,GApCxB,IAAA,EAAA,CAAA,EAAM,GACN,EAAwB,CAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"tabs2.js","names":[],"sources":["../../src/tabs/tabs.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { PropertyValues } from 'lit';\nimport { html, LitElement } from 'lit';\nimport { property } from 'lit/decorators/property.js';\nimport { queryAssignedElements } from 'lit/decorators/query-assigned-elements.js';\nimport { ButtonFormControlMixin } from '@nvidia-elements/forms/mixins';\nimport type { KeynavListConfig } from '@nvidia-elements/core/internal';\nimport {\n stateSelected,\n useStyles,\n KeyNavigationListController,\n attachInternals,\n audit,\n appendRootNodeStyle,\n appendAnchorName,\n removeAnchorName\n} from '@nvidia-elements/core/internal';\nimport type { TabsItemGroup } from './tabs-item-group.js';\nimport { getTabItems, isTabItemTabbable } from './utils.js';\nimport globalStyles from './tabs.global.css?inline';\nimport tabsItemStyleSheet from './tabs-item.css?inline';\nimport tabsStyleSheet from './tabs.css?inline';\n\n/**\n * @element nve-tabs-item\n * @description Represents an individual tab within a tablist, providing a selectable button for switching between content views.\n * @documentation https://nvidia.github.io/elements/docs/elements/tabs/\n * @since 0.10.0\n * @entrypoint \\@nvidia-elements/core/tabs\n * @slot - The label displayed for the tab.\n * @slot prefix - Decoration before the label.\n * @slot suffix - Supporting content after the label.\n * @cssprop --gap - Spacing between the label and decoration.\n * @cssprop --font-size\n * @cssprop --width\n * @cssprop --padding\n * @cssprop --font-size\n * @cssprop --font-weight\n * @cssprop --border-radius\n * @cssprop --color\n * @cssprop --height\n * @cssprop --cursor\n * @cssprop --text-transform\n * @aria https://www.w3.org/WAI/ARIA/apg/patterns/tabs/\n * @responsive false\n */\n@audit()\n@stateSelected<TabsItem>()\nexport class TabsItem extends ButtonFormControlMixin(LitElement) {\n /**\n * Determines which tab item the user selects, defaults to false.\n */\n @property({ type: Boolean, reflect: true }) selected = false;\n\n static styles = useStyles([tabsItemStyleSheet]);\n\n static readonly metadata = {\n tag: 'nve-tabs-item',\n version: '0.0.0',\n parents: ['nve-tabs', 'nve-tabs-item-group']\n };\n\n render() {\n return html`\n <div internal-host focus-within>\n <slot name=\"prefix\"></slot>\n <div id=\"label\"><slot></slot></div>\n <slot name=\"suffix\"></slot>\n </div>\n `;\n }\n\n constructor() {\n super();\n this.type = 'button';\n }\n\n connectedCallback() {\n super.connectedCallback();\n this._internals.role = 'tab';\n }\n\n updated(props: PropertyValues<this>) {\n super.updated(props);\n\n if (props.has('selected')) {\n if (this.selected) {\n appendAnchorName(this, '--selected');\n } else {\n removeAnchorName(this, '--selected');\n }\n }\n }\n}\n\n/**\n * @element nve-tabs\n * @description Tabs provide a selection UX, typically used for swapping content shown on a page, or within a navigation context.\n * @documentation https://nvidia.github.io/elements/docs/elements/tabs/\n * @since 0.10.0\n * @entrypoint \\@nvidia-elements/core/tabs\n * @slot - default slot for tab-item\n * @cssprop --gap\n * @cssprop --indicator-background\n * @cssprop --indicator-border-radius\n * @cssprop --indicator-height\n * @cssprop --border-inset\n * @aria https://www.w3.org/WAI/ARIA/apg/patterns/tabs/\n * @responsive false\n */\n@audit()\nexport class Tabs extends LitElement {\n /**\n * Determines whether the tabs should display in a vertical layout vs. defaulting to horizontal.\n */\n @property({ type: Boolean, reflect: true }) vertical = false;\n\n /**\n * Determines whether the tabs should display a border on selected items vs. defaults to show border.\n */\n @property({ type: Boolean, reflect: true }) borderless = false;\n\n /**\n * Determines whether the tabs should handle selection behavior vs. defaults to off.\n */\n @property({ type: Boolean, attribute: 'behavior-select' }) behaviorSelect = false;\n\n static styles = useStyles([tabsStyleSheet]);\n\n static readonly metadata = {\n tag: 'nve-tabs',\n version: '0.0.0',\n children: ['nve-tabs-item', 'nve-tabs-item-group']\n };\n\n /** @private */\n get keynavListConfig(): KeynavListConfig {\n const items = this.#items;\n return {\n items,\n initialItem: items.find(item => item.selected),\n layout: this.vertical ? 'vertical' : 'horizontal',\n dir: getComputedStyle(this).direction\n };\n }\n\n @queryAssignedElements() private entries!: HTMLElement[];\n\n get #items(): TabsItem[] {\n return getTabItems(this.entries ?? []);\n }\n\n #keynavController = new KeyNavigationListController(this);\n #knownItems: TabsItem[] = [];\n #itemsObserver?: MutationObserver;\n\n /** @private */\n declare _internals: ElementInternals;\n\n render() {\n return html`\n <div internal-host>\n <slot @slotchange=${this.#syncItems}></slot>\n </div>\n `;\n }\n\n connectedCallback() {\n super.connectedCallback();\n appendRootNodeStyle(this, globalStyles);\n attachInternals(this);\n this._internals.role = 'tablist';\n this.addEventListener('click', this.#onClick);\n this.#observeItems();\n if (this.hasUpdated) this.#syncAccessoryTabState();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener('click', this.#onClick);\n this.#itemsObserver?.disconnect();\n }\n\n firstUpdated() {\n this.#itemsObserver = new MutationObserver(this.#syncFromItems);\n this.#observeItems();\n }\n\n updated(props: PropertyValues<this>) {\n super.updated(props);\n this._internals.ariaOrientation = this.vertical ? 'vertical' : 'horizontal';\n }\n\n #observeItems() {\n this.#itemsObserver?.observe(this, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['tabindex', 'href', 'slot']\n });\n }\n\n #syncFromItems = (records: MutationRecord[]) => {\n if (records.some(record => record.type === 'childList' || record.attributeName === 'slot')) {\n void this.#syncItems();\n } else if (records.some(record => this.#items.some(item => item.contains(record.target)))) {\n this.#syncAccessoryTabState();\n }\n };\n\n #syncItems = async () => {\n const items = this.#items;\n if (items.length === this.#knownItems.length && items.every((item, index) => item === this.#knownItems[index])) {\n this.#syncAccessoryTabState();\n return;\n }\n\n const previousItems = this.#knownItems;\n this.#knownItems = items;\n await Promise.all(items.map(item => item.updateComplete));\n if (items !== this.#knownItems) return;\n\n this.#keynavController.refreshItems(previousItems);\n this.#syncAccessoryTabState();\n };\n\n #syncAccessoryTabState() {\n this.querySelectorAll<TabsItemGroup>(':scope > nve-tabs-item-group').forEach(group => {\n const item = getTabItems([group])[0];\n group.accessoryTabEnabled = !!item && isTabItemTabbable(item);\n });\n }\n\n #selectTab(tabItem: HTMLElement & { matches: Element['matches']; disabled?: boolean; selected?: boolean }) {\n if (!this.behaviorSelect || !tabItem.matches('nve-tabs-item') || tabItem.disabled) {\n return;\n }\n\n this.keynavListConfig.items.forEach((i: HTMLElement) => ((i as TabsItem).selected = false));\n tabItem.selected = true;\n }\n\n #onClick = (event: Event) => {\n const path = event.composedPath();\n const item = this.#items.find(candidate => path.includes(candidate));\n if (item) this.#selectTab(item);\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkDO,IAAM,IAAN,cAAuB,EAAuB,CAAU,CAAC,CAAC;;EAM/C,KAAA,SAAA,EAAU,CAAC,CAAkB,CAAC;;;EAEnB,KAAA,WAAA;GACzB,KAAK;GACL,SAAS;GACT,SAAS,CAAC,YAAY,qBAAqB;EAC7C;;CAEA,SAAS;EACP,OAAO,CAAI;CAOb;CAEA,cAAc;EAEZ,AADA,MAAM,GArB+C,KAAA,WAAA,IAsBrD,KAAK,OAAO;CACd;CAEA,oBAAoB;EAElB,AADA,MAAM,kBAAkB,GACxB,KAAK,WAAW,OAAO;CACzB;CAEA,QAAQ,GAA6B;EAGnC,AAFA,MAAM,QAAQ,CAAK,GAEf,EAAM,IAAI,UAAU,MAClB,KAAK,WACP,EAAiB,MAAM,YAAY,IAEnC,EAAiB,MAAM,YAAY;CAGzC;AACF;AAzCG,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,GAN3C,IAAA,EAAA,CAAA,EAAM,GACN,EAAwB,CAAA,GAAA,CAAA;AAgElB,IAAM,IAAN,cAAmB,EAAW;;EAmIvB,aA/H2C,KAAA,WAAA,IAKE,KAAA,aAAA,IAKmB,KAAA,iBAAA,IA2BxD,KAAA,KAAA,IAAI,EAA4B,IAAI,GAC9B,KAAA,KAAA,CAAC,GAiDT,KAAA,MAAA,MAA8B;GAC9C,AAAI,EAAQ,MAAK,MAAU,EAAO,SAAS,eAAe,EAAO,kBAAkB,MAAM,IACvF,KAAU,GAAW,IACZ,EAAQ,MAAK,MAAU,KAAK,GAAO,MAAK,MAAQ,EAAK,SAAS,EAAO,MAAM,CAAC,CAAC,KACtF,KAAK,GAAuB;EAEhC,GAEa,KAAA,KAAA,YAAY;GACvB,IAAM,IAAQ,KAAK;GACnB,IAAI,EAAM,WAAW,KAAK,GAAY,UAAU,EAAM,OAAO,GAAM,MAAU,MAAS,KAAK,GAAY,EAAM,GAAG;IAC9G,KAAK,GAAuB;IAC5B;GACF;GAEA,IAAM,IAAgB,KAAK;GAC3B,KAAK,KAAc,GACnB,MAAM,QAAQ,IAAI,EAAM,KAAI,MAAQ,EAAK,cAAc,CAAC,GACpD,MAAU,KAAK,OAEnB,KAAK,GAAkB,aAAa,CAAa,GACjD,KAAK,GAAuB;EAC9B,GAkBY,KAAA,MAAA,MAAiB;GAC3B,IAAM,IAAO,EAAM,aAAa,GAC1B,IAAO,KAAK,GAAO,MAAK,MAAa,EAAK,SAAS,CAAS,CAAC;GACnE,AAAI,KAAM,KAAK,GAAW,CAAI;EAChC;;;EAvHgB,KAAA,SAAA,EAAU,CAAC,CAAc,CAAC;;;EAEf,KAAA,WAAA;GACzB,KAAK;GACL,SAAS;GACT,UAAU,CAAC,iBAAiB,qBAAqB;EACnD;;CAGA,IAAI,mBAAqC;EACvC,IAAM,IAAQ,KAAK;EACnB,OAAO;GACL;GACA,aAAa,EAAM,MAAK,MAAQ,EAAK,QAAQ;GAC7C,QAAQ,KAAK,WAAW,aAAa;GACrC,KAAK,iBAAiB,IAAI,CAAC,CAAC;EAC9B;CACF;CAIA,IAAI,KAAqB;EACvB,OAAO,EAAY,KAAK,WAAW,CAAC,CAAC;CACvC;CAEA;CACA;CACA;CAKA,SAAS;EACP,OAAO,CAAI,yCAEa,KAAK,GAAW;CAG1C;CAEA,oBAAoB;EAOlB,AANA,MAAM,kBAAkB,GACxB,EAAoB,MAAM,CAAY,GACtC,EAAgB,IAAI,GACpB,KAAK,WAAW,OAAO,WACvB,KAAK,iBAAiB,SAAS,KAAK,EAAQ,GAC5C,KAAK,GAAc,GACf,KAAK,cAAY,KAAK,GAAuB;CACnD;CAEA,uBAAuB;EAGrB,AAFA,MAAM,qBAAqB,GAC3B,KAAK,oBAAoB,SAAS,KAAK,EAAQ,GAC/C,KAAK,IAAgB,WAAW;CAClC;CAEA,eAAe;EAEb,AADA,KAAK,KAAiB,IAAI,iBAAiB,KAAK,EAAc,GAC9D,KAAK,GAAc;CACrB;CAEA,QAAQ,GAA6B;EAEnC,AADA,MAAM,QAAQ,CAAK,GACnB,KAAK,WAAW,kBAAkB,KAAK,WAAW,aAAa;CACjE;CAEA,KAAgB;EACd,KAAK,IAAgB,QAAQ,MAAM;GACjC,WAAW;GACX,SAAS;GACT,YAAY;GACZ,iBAAiB;IAAC;IAAY;IAAQ;GAAM;EAC9C,CAAC;CACH;CAEA;CAQA;CAgBA,KAAyB;EACvB,KAAK,iBAAgC,8BAA8B,CAAC,CAAC,SAAQ,MAAS;GACpF,IAAM,IAAO,EAAY,CAAC,CAAK,CAAC,CAAC,CAAC;GAClC,EAAM,sBAAsB,CAAC,CAAC,KAAQ,EAAkB,CAAI;EAC9D,CAAC;CACH;CAEA,GAAW,GAAgG;EACrG,CAAC,KAAK,kBAAkB,CAAC,EAAQ,QAAQ,eAAe,KAAK,EAAQ,aAIzE,KAAK,iBAAiB,MAAM,SAAS,MAAoB,EAAgB,WAAW,EAAM,GAC1F,EAAQ,WAAW;CACrB;CAEA;AAKF;AApIG,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,GAKzC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,cAAA,KAAA,CAAA,GAKzC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,WAAW;AAAkB,CAAC,CAAA,GAAA,EAAA,WAAA,kBAAA,KAAA,CAAA,GAqBxD,EAAA,CAAA,EAAsB,CAAA,GAAA,EAAA,WAAA,WAAA,KAAA,CAAA,GApCxB,IAAA,EAAA,CAAA,EAAM,CAAA,GAAA,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { TabsItem } from './tabs.js';
2
+ /** Resolves the tab controls owned by the tab strip, in visual order. */
3
+ export declare function getTabItems(entries: readonly Element[]): TabsItem[];
4
+ export declare function isTabItemTabbable(item: TabsItem): boolean;
@@ -0,0 +1,18 @@
1
+ //#region src/tabs/utils.ts
2
+ function e(e) {
3
+ return e.flatMap((e) => {
4
+ if (e.getAttribute("slot")) return [];
5
+ if (e.localName === "nve-tabs-item") return [e];
6
+ if (e.localName !== "nve-tabs-item-group") return [];
7
+ let t = e.querySelector(":scope > nve-tabs-item:is(:not([slot]), [slot=\"\"])");
8
+ return t ? [t] : [];
9
+ });
10
+ }
11
+ function t(e) {
12
+ let t = e.querySelector(":scope > a:is(:not([slot]), [slot=\"\"])");
13
+ return e.tabIndex >= 0 || !!t && t.matches("[href], [tabindex]") && t.tabIndex >= 0;
14
+ }
15
+ //#endregion
16
+ export { e as getTabItems, t as isTabItemTabbable };
17
+
18
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../src/tabs/utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { TabsItem } from './tabs.js';\n\n/** Resolves the tab controls owned by the tab strip, in visual order. */\nexport function getTabItems(entries: readonly Element[]): TabsItem[] {\n return entries.flatMap(entry => {\n if (entry.getAttribute('slot')) return [];\n if (entry.localName === 'nve-tabs-item') return [entry as TabsItem];\n if (entry.localName !== 'nve-tabs-item-group') return [];\n const item = entry.querySelector<TabsItem>(':scope > nve-tabs-item:is(:not([slot]), [slot=\"\"])');\n return item ? [item] : [];\n });\n}\n\nexport function isTabItemTabbable(item: TabsItem): boolean {\n const anchor = item.querySelector<HTMLAnchorElement>(':scope > a:is(:not([slot]), [slot=\"\"])');\n return item.tabIndex >= 0 || (!!anchor && anchor.matches('[href], [tabindex]') && anchor.tabIndex >= 0);\n}\n"],"mappings":";AAMA,SAAgB,EAAY,GAAyC;CACnE,OAAO,EAAQ,SAAQ,MAAS;EAC9B,IAAI,EAAM,aAAa,MAAM,GAAG,OAAO,CAAC;EACxC,IAAI,EAAM,cAAc,iBAAiB,OAAO,CAAC,CAAiB;EAClE,IAAI,EAAM,cAAc,uBAAuB,OAAO,CAAC;EACvD,IAAM,IAAO,EAAM,cAAwB,sDAAoD;EAC/F,OAAO,IAAO,CAAC,CAAI,IAAI,CAAC;CAC1B,CAAC;AACH;AAEA,SAAgB,EAAkB,GAAyB;CACzD,IAAM,IAAS,EAAK,cAAiC,0CAAwC;CAC7F,OAAO,EAAK,YAAY,KAAM,CAAC,CAAC,KAAU,EAAO,QAAQ,oBAAoB,KAAK,EAAO,YAAY;AACvG"}
package/dist/tag/tag2.js CHANGED
@@ -17,7 +17,7 @@ var p = class extends d(c) {
17
17
  static {
18
18
  this.metadata = {
19
19
  tag: "nve-tag",
20
- version: "2.17.1"
20
+ version: "2.18.0"
21
21
  };
22
22
  }
23
23
  static {
@@ -16,7 +16,7 @@ var i = class extends t {
16
16
  static {
17
17
  this.metadata = {
18
18
  tag: "nve-textarea",
19
- version: "2.17.1"
19
+ version: "2.18.0"
20
20
  };
21
21
  }
22
22
  };
@@ -19,7 +19,7 @@ var l = class extends r {
19
19
  static {
20
20
  this.metadata = {
21
21
  tag: "nve-time",
22
- version: "2.17.1"
22
+ version: "2.18.0"
23
23
  };
24
24
  }
25
25
  static {
@@ -23,7 +23,7 @@ var g = class extends f {
23
23
  static {
24
24
  this.metadata = {
25
25
  tag: "nve-toast",
26
- version: "2.17.1"
26
+ version: "2.18.0"
27
27
  };
28
28
  }
29
29
  static {
@@ -11,7 +11,7 @@ var o = class extends i {
11
11
  static {
12
12
  this.metadata = {
13
13
  tag: "nve-toggletip-footer",
14
- version: "2.17.1",
14
+ version: "2.18.0",
15
15
  parents: ["nve-toggletip"]
16
16
  };
17
17
  }
@@ -11,7 +11,7 @@ var o = class extends i {
11
11
  static {
12
12
  this.metadata = {
13
13
  tag: "nve-toggletip-header",
14
- version: "2.17.1",
14
+ version: "2.18.0",
15
15
  parents: ["nve-toggletip"]
16
16
  };
17
17
  }
@@ -24,7 +24,7 @@ var g = class extends f {
24
24
  static {
25
25
  this.metadata = {
26
26
  tag: "nve-toggletip",
27
- version: "2.17.1"
27
+ version: "2.18.0"
28
28
  };
29
29
  }
30
30
  static {
@@ -21,7 +21,7 @@ var f = class extends c {
21
21
  static {
22
22
  this.metadata = {
23
23
  tag: "nve-toolbar",
24
- version: "2.17.1"
24
+ version: "2.18.0"
25
25
  };
26
26
  }
27
27
  static {
@@ -19,7 +19,7 @@ var d = class extends s {
19
19
  static {
20
20
  this.metadata = {
21
21
  tag: "nve-tooltip",
22
- version: "2.17.1"
22
+ version: "2.18.0"
23
23
  };
24
24
  }
25
25
  render() {
@@ -44,7 +44,7 @@ var E = class extends b {
44
44
  static {
45
45
  this.metadata = {
46
46
  tag: "nve-tree-node",
47
- version: "2.17.1",
47
+ version: "2.18.0",
48
48
  parents: ["nve-tree", "nve-tree-node"]
49
49
  };
50
50
  }
@@ -22,7 +22,7 @@ var m = class extends d {
22
22
  static {
23
23
  this.metadata = {
24
24
  tag: "nve-tree",
25
- version: "2.17.1",
25
+ version: "2.18.0",
26
26
  children: ["nve-tree-node"]
27
27
  };
28
28
  }
@@ -19,7 +19,7 @@ var l = class extends r {
19
19
  static {
20
20
  this.metadata = {
21
21
  tag: "nve-week",
22
- version: "2.17.1"
22
+ version: "2.18.0"
23
23
  };
24
24
  }
25
25
  static {