@nvidia-elements/core 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/accordion/accordion2.js +4 -4
- package/dist/alert/alert-group2.js +1 -1
- package/dist/alert/alert2.js +1 -1
- package/dist/avatar/avatar-group2.js +1 -1
- package/dist/avatar/avatar2.js +1 -1
- package/dist/badge/badge.js +1 -1
- package/dist/badge/badge.js.map +1 -1
- package/dist/badge/badge2.js +1 -1
- package/dist/breadcrumb/breadcrumb.js +1 -1
- package/dist/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/breadcrumb/breadcrumb2.js +1 -1
- package/dist/bundles/index.d.ts +3 -2
- package/dist/bundles/index.js +2 -2
- package/dist/button/button2.js +1 -1
- package/dist/button-group/button-group2.js +1 -1
- package/dist/card/card-content.js +1 -1
- package/dist/card/card-content.js.map +1 -1
- package/dist/card/card-header.js +1 -1
- package/dist/card/card-header.js.map +1 -1
- package/dist/card/card2.js +4 -4
- package/dist/chat-message/chat-message2.js +1 -1
- package/dist/checkbox/checkbox-group2.js +1 -1
- package/dist/checkbox/checkbox2.js +1 -1
- package/dist/color/color2.js +1 -1
- package/dist/combobox/combobox.examples.js.map +1 -1
- package/dist/combobox/combobox2.js +1 -1
- package/dist/copy-button/copy-button2.js +1 -1
- package/dist/copy-button/copy-button2.js.map +1 -1
- package/dist/custom-elements-jsx.d.ts +4 -2
- package/dist/custom-elements-vue.d.ts +4 -2
- package/dist/custom-elements.json +28 -12
- package/dist/data.html.json +6 -4
- package/dist/date/date2.js +1 -1
- package/dist/datetime/datetime2.js +1 -1
- package/dist/dialog/dialog-footer2.js +1 -1
- package/dist/dialog/dialog-header2.js +1 -1
- package/dist/dialog/dialog2.js +1 -1
- package/dist/divider/divider2.js +1 -1
- package/dist/dot/dot2.js +1 -1
- package/dist/drawer/drawer-content2.js +1 -1
- package/dist/drawer/drawer-footer2.js +1 -1
- package/dist/drawer/drawer-header2.js +1 -1
- package/dist/drawer/drawer2.js +1 -1
- package/dist/dropdown/dropdown-footer2.js +1 -1
- package/dist/dropdown/dropdown-header2.js +1 -1
- package/dist/dropdown/dropdown2.js +1 -1
- package/dist/dropdown-group/dropdown-group.js +1 -1
- package/dist/dropdown-group/dropdown-group.js.map +1 -1
- package/dist/dropzone/dropzone.util.js +4 -1
- package/dist/dropzone/dropzone.util.js.map +1 -1
- package/dist/dropzone/dropzone2.js +1 -1
- package/dist/file/file2.js +1 -1
- package/dist/format-datetime/format-datetime2.js +1 -1
- package/dist/format-relative-time/format-relative-time2.js +1 -1
- package/dist/forms/control/control2.js +1 -1
- package/dist/forms/control-group/control-group2.js +1 -1
- package/dist/forms/control-message/control-message2.js +1 -1
- package/dist/forms/utils/states.js.map +1 -1
- package/dist/grid/cell/cell2.js +1 -1
- package/dist/grid/column/column2.js +1 -1
- package/dist/grid/footer/footer2.js +1 -1
- package/dist/grid/grid.examples.js.map +1 -1
- package/dist/grid/grid.examples.json +2 -2
- package/dist/grid/grid2.js +1 -1
- package/dist/grid/header/header2.js +1 -1
- package/dist/grid/placeholder/placeholder2.js +1 -1
- package/dist/grid/row/row2.js +1 -1
- package/dist/icon/icon2.js +2 -2
- package/dist/icon/icons/stop.js +6 -0
- package/dist/icon/icons/stop.js.map +1 -0
- package/dist/icon/icons.d.ts +1 -0
- package/dist/icon/icons.js +1 -0
- package/dist/icon/icons.js.map +1 -1
- package/dist/icon/server.js +1 -0
- package/dist/icon/server.js.map +1 -1
- package/dist/icon-button/icon-button2.js +1 -1
- package/dist/index.js +1 -1
- package/dist/input/input-group2.js +1 -1
- package/dist/input/input2.js +1 -1
- package/dist/internal/controllers/audit.controller.js.map +1 -1
- package/dist/internal/controllers/type-native-popover.controller.js.map +1 -1
- package/dist/internal/controllers/type-ssr.controller.js.map +1 -1
- package/dist/internal/services/global.service.js +1 -1
- package/dist/internal/services/i18n.service.d.ts +1 -1
- package/dist/internal/services/i18n.service.js.map +1 -1
- package/dist/logo/logo2.js +1 -1
- package/dist/menu/menu-item2.js +1 -1
- package/dist/menu/menu2.js +1 -1
- package/dist/month/month2.js +1 -1
- package/dist/notification/notification-group2.js +1 -1
- package/dist/notification/notification2.js +1 -1
- package/dist/page/page-panel/page-panel-content2.js +1 -1
- package/dist/page/page-panel/page-panel-footer2.js +1 -1
- package/dist/page/page-panel/page-panel-header2.js +1 -1
- package/dist/page/page-panel/page-panel2.js +1 -1
- package/dist/page/page2.js +1 -1
- package/dist/page-header/page-header2.js +1 -1
- package/dist/page-loader/page-loader2.js +1 -1
- package/dist/pagination/pagination2.js +1 -1
- package/dist/panel/panel2.js +4 -4
- package/dist/password/password2.js +1 -1
- package/dist/polyfills/index.js +2 -1
- package/dist/polyfills/index.js.map +1 -1
- package/dist/preferences-input/preferences-input2.js +1 -1
- package/dist/preferences-input/preferences-input2.js.map +1 -1
- package/dist/progress-bar/progress-bar.examples.js.map +1 -1
- package/dist/progress-bar/progress-bar.examples.json +1 -1
- package/dist/progress-bar/progress-bar2.js +1 -1
- package/dist/progress-ring/progress-ring2.js +1 -1
- package/dist/progressive-filter-chip/progressive-filter-chip2.js +1 -1
- package/dist/pulse/pulse2.js +1 -1
- package/dist/radio/radio-group2.js +1 -1
- package/dist/radio/radio2.js +1 -1
- package/dist/range/range2.js +1 -1
- package/dist/resize-handle/resize-handle2.js +1 -1
- package/dist/search/search2.js +1 -1
- package/dist/select/select2.js +1 -1
- package/dist/skeleton/skeleton.d.ts +2 -2
- package/dist/skeleton/skeleton2.js +1 -1
- package/dist/skeleton/skeleton2.js.map +1 -1
- package/dist/sort-button/sort-button2.js +1 -1
- package/dist/sparkline/sparkline2.js +1 -1
- package/dist/star-rating/star-rating2.js +1 -1
- package/dist/steps/steps2.js +2 -2
- package/dist/switch/switch-group2.js +1 -1
- package/dist/switch/switch2.js +1 -1
- package/dist/tabs/tabs-group2.js +1 -1
- package/dist/tabs/tabs2.js +2 -2
- package/dist/tag/tag2.js +1 -1
- package/dist/textarea/textarea2.js +1 -1
- package/dist/time/time2.js +1 -1
- package/dist/toast/toast2.js +1 -1
- package/dist/toggletip/toggletip-footer2.js +1 -1
- package/dist/toggletip/toggletip-header2.js +1 -1
- package/dist/toggletip/toggletip2.js +1 -1
- package/dist/toolbar/toolbar.js +1 -1
- package/dist/toolbar/toolbar.js.map +1 -1
- package/dist/toolbar/toolbar2.js +1 -1
- package/dist/tooltip/tooltip2.js +1 -1
- package/dist/tree/tree-node.js +1 -1
- package/dist/tree/tree-node.js.map +1 -1
- package/dist/tree/tree-node2.js +1 -1
- package/dist/tree/tree2.js +1 -1
- package/dist/tree/utils.js.map +1 -1
- package/dist/week/week2.js +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid.examples.js","names":["#group","#loadGroup"],"sources":["../../src/grid/grid.examples.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { LitElement, unsafeCSS, html, nothing } from 'lit';\nimport { state } from 'lit/decorators/state.js';\nimport { getItems, grid } from '../test/demo.js';\nimport layout from '@nvidia-elements/styles/layout.css?inline';\nimport '@nvidia-elements/core/grid/define.js';\nimport '@nvidia-elements/core/badge/define.js'\nimport '@nvidia-elements/core/button/define.js';\nimport '@nvidia-elements/core/card/define.js';\nimport '@nvidia-elements/core/checkbox/define.js';\nimport '@nvidia-elements/core/dropdown/define.js';\nimport '@nvidia-elements/core/icon/define.js';\nimport '@nvidia-elements/core/icon-button/define.js';\nimport '@nvidia-elements/core/tabs/define.js';\nimport '@nvidia-elements/core/menu/define.js';\nimport '@nvidia-elements/core/pagination/define.js';\nimport '@nvidia-elements/core/progress-ring/define.js';\nimport '@nvidia-elements/core/logo/define.js';\nimport '@nvidia-elements/core/page/define.js';\nimport '@nvidia-elements/core/page-header/define.js';\nimport '@nvidia-elements/core/panel/define.js';\nimport '@nvidia-elements/core/radio/define.js';\nimport '@nvidia-elements/core/search/define.js';\nimport '@nvidia-elements/core/sort-button/define.js';\nimport '@nvidia-elements/core/toolbar/define.js';\nimport '@nvidia-elements/core/tooltip/define.js';\nimport '@lit-labs/virtualizer';\n\nexport default {\n title: 'Elements/Data Grid',\n component: 'nve-grid',\n};\n\n/**\n * @summary Basic data grid for tabular data display with columns and rows. Use grids for presenting structured datasets where users need to scan, compare, and analyze information across many columns, such as dashboards, reports, or data management interfaces.\n */\nexport const Default = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary The datagrid follows the ARIA Authoring Practices Guide for standardized keyboard navigation.\n */\nexport const Keynav = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n <nve-grid-column width=\"150px\">Key</nve-grid-column>\n <nve-grid-column>Function</nve-grid-column>\n </nve-grid-header>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Right Arrow</kbd>\n </nve-grid-cell>\n <nve-grid-cell>\n <ul nve-text=\"list\">\n <li>Moves focus one cell to the right.</li>\n <li>If focus is on the right-most cell in the row, focus does not move.</li>\n </ul>\n </nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Left Arrow</kbd>\n </nve-grid-cell>\n <nve-grid-cell>\n <ul nve-text=\"list\">\n <li>Moves focus one cell to the left.</li>\n <li>If focus is on the left-most cell in the row, focus does not move.</li>\n </ul>\n </nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Down Arrow</kbd>\n </nve-grid-cell>\n <nve-grid-cell>\n <ul nve-text=\"list\">\n <li>Moves focus one cell down.</li>\n <li>If focus is on the bottom cell in the column, focus does not move.</li>\n </ul>\n </nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Up Arrow</kbd>\n </nve-grid-cell>\n <nve-grid-cell>\n <ul nve-text=\"list\">\n <li>Moves focus one cell Up.</li>\n <li>If focus is on the top cell in the column, focus does not move.</li>\n </ul>\n </nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Page Down</kbd>\n </nve-grid-cell>\n <nve-grid-cell>\n <ul nve-text=\"list\">\n <li>In example 3, moves focus down five rows, scrolling so the bottom row in the currently visible set of rows becomes the first visible row.</li>\n <li>If focus is in the last row, focus does not move.</li>\n </ul>\n </nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Page Up</kbd>\n </nve-grid-cell>\n <nve-grid-cell>\n <ul nve-text=\"list\">\n <li>In example 3, moves focus up 5 rows, scrolling so the top row in the currently visible set of rows becomes the last visible row.</li>\n <li>If focus is in the first row of the grid, focus does not move.</li>\n </ul>\n </nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Home</kbd>\n </nve-grid-cell>\n <nve-grid-cell>Moves focus to the first cell in the row that contains focus.</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>End</kbd>\n </nve-grid-cell>\n <nve-grid-cell>Moves focus to the last cell in the row that contains focus.</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Control</kbd> + <kbd>Home</kbd>\n </nve-grid-cell>\n <nve-grid-cell>Moves focus to the first cell in the first row.</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Control</kbd> + <kbd>End</kbd>\n </nve-grid-cell>\n <nve-grid-cell>Moves focus to the last cell in the last row.</nve-grid-cell>\n </nve-grid-row>\n</nve-grid>`\n};\n\n/**\n * @summary Multi-select rows with checkboxes for bulk operations. Use multi-select when users need to perform actions on many items at once (like delete, export, or bulk edit), placing checkboxes as the first column and setting the selected attribute for proper accessibility.\n */\nexport const MultiSelect = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n <nve-grid-column width=\"max-content\" position=\"fixed\">\n <nve-checkbox>\n <input type=\"checkbox\" aria-label=\"select all rows\" />\n </nve-checkbox>\n </nve-grid-column>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n <nve-grid-cell>\n <nve-checkbox>\n <input type=\"checkbox\" ?checked=${r === 1} aria-label=\"select row ${r}\" />\n </nve-checkbox>\n </nve-grid-cell>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Use bulk actions for operations on many items. Display only\n * when rows have a selection. Closing bulk actions deselects all selected rows.\n */\nexport const BulkActions = {\n render: () => html`\n<nve-grid style=\"height: 400px\">\n <nve-grid-header>\n <nve-grid-column width=\"max-content\" position=\"fixed\">\n <nve-checkbox>\n <input type=\"checkbox\" aria-label=\"select all rows\" />\n </nve-checkbox>\n </nve-grid-column>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(20).fill('').map((_, r) => html`\n <nve-grid-row .selected=${r === 1}>\n <nve-grid-cell>\n <nve-checkbox>\n <input type=\"checkbox\" ?checked=${r === 1} aria-label=\"select row ${r}\" />\n </nve-checkbox>\n </nve-grid-cell>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n <nve-toolbar status=\"accent\" slot=\"footer\">\n <nve-icon-button container=\"flat\" icon-name=\"cancel\" slot=\"prefix\"></nve-icon-button>\n <p nve-text=\"body\">1 selected</p>\n <nve-button container=\"flat\" interaction=\"destructive\" slot=\"suffix\">delete</nve-button>\n <nve-icon-button container=\"flat\" icon-name=\"more-actions\" slot=\"suffix\"></nve-icon-button>\n </nve-toolbar>\n</nve-grid>\n `\n};\n\n/**\n * @summary A single select datagrid allows users to choose exactly one row\n * from a data table by providing radio buttons in the first column, ensuring\n * only one item has a selection at a time. To enable single select, place `nve-radio`\n * input as the first grid cell of each row. Set `name` attribute on each radio\n * to ensure to associate the same radio group.\n */\nexport const SingleSelect = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n <nve-grid-column width=\"max-content\" position=\"fixed\"></nve-grid-column>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n <nve-grid-cell>\n <nve-radio>\n <input type=\"radio\" ?checked=${r === 1} name=\"single-select\" .value=${`${r}`} aria-label=\"select row ${r}\" />\n </nve-radio>\n </nve-grid-cell>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Row actions enable extra user actions specific to a given row.\n * Place a `nve-icon-button` at the end of the grid row for actions.\n */\nexport const RowAction = {\n render: () => html`\n<nve-dropdown id=\"row-actions-dropdown\" align=\"end\">\n <nve-menu>\n <nve-menu-item>action 1</nve-menu-item>\n <nve-menu-item>action 2</nve-menu-item>\n <nve-menu-item>action 3</nve-menu-item>\n </nve-menu>\n</nve-dropdown>\n<nve-grid>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n <nve-grid-column width=\"max-content\" aria-label=\"additonal actions\" position=\"fixed\"></nve-grid-column>\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n <nve-grid-cell>\n <nve-icon-button id=\"action-${r}\" popovertarget=\"row-actions-dropdown\" container=\"flat\" icon-name=\"more-actions\" aria-label=\"row ${r} actions\"></nve-icon-button>\n </nve-grid-cell>\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Expandable row groups for hierarchical data organization. Use row groups when items have parent-child relationships or nested details (like sessions with uploads, orders with line items), allowing users to progressively disclose details and maintain compact views of large hierarchies.\n */\nexport const RowGroups = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n <nve-grid-column width=\"max-content\" aria-label=\"expand groups\" position=\"fixed\"></nve-grid-column>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n <nve-grid-row>\n <nve-grid-cell>\n <nve-icon-button icon-name=\"caret\" container=\"flat\" direction=\"right\" aria-label=\"view session 2yuecae SSD uploads\"></nve-icon-button>\n </nve-grid-cell>\n <nve-grid-cell>Session: 2yuecae</nve-grid-cell>\n <nve-grid-cell>upload</nve-grid-cell>\n <nve-grid-cell>pending</nve-grid-cell>\n <nve-grid-cell>p3</nve-grid-cell>\n <nve-grid-cell>12/04/22</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row selected>\n <nve-grid-cell>\n <nve-icon-button icon-name=\"caret\" container=\"flat\" direction=\"down\" aria-label=\"view session mvwgh3t SSD uploads\"></nve-icon-button>\n </nve-grid-cell>\n <nve-grid-cell>Session: mvwgh3t</nve-grid-cell>\n <nve-grid-cell>upload</nve-grid-cell>\n <nve-grid-cell>pending</nve-grid-cell>\n <nve-grid-cell>p0</nve-grid-cell>\n <nve-grid-cell>12/11/22</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell></nve-grid-cell>\n <nve-grid-cell>SSD: mvwgh3t</nve-grid-cell>\n <nve-grid-cell>validating</nve-grid-cell>\n <nve-grid-cell>pending</nve-grid-cell>\n <nve-grid-cell>p0</nve-grid-cell>\n <nve-grid-cell>12/11/22</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell></nve-grid-cell>\n <nve-grid-cell>SSD: qudbd8x</nve-grid-cell>\n <nve-grid-cell>uploading</nve-grid-cell>\n <nve-grid-cell>finished</nve-grid-cell>\n <nve-grid-cell>p0</nve-grid-cell>\n <nve-grid-cell>12/11/22</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell></nve-grid-cell>\n <nve-grid-cell>SSD: j8hvikt</nve-grid-cell>\n <nve-grid-cell>queuing</nve-grid-cell>\n <nve-grid-cell>running</nve-grid-cell>\n <nve-grid-cell>p0</nve-grid-cell>\n <nve-grid-cell>12/11/22</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <nve-icon-button icon-name=\"caret\" container=\"flat\" direction=\"right\" aria-label=\"view session bg5ujqp SSD uploads\"></nve-icon-button>\n </nve-grid-cell>\n <nve-grid-cell>Session: bg5ujqp</nve-grid-cell>\n <nve-grid-cell>upload</nve-grid-cell>\n <nve-grid-cell>pending</nve-grid-cell>\n <nve-grid-cell>p1</nve-grid-cell>\n <nve-grid-cell>12/12/22</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <nve-icon-button icon-name=\"caret\" container=\"flat\" direction=\"right\" aria-label=\"view session 6ruehvh SSD uploads\"></nve-icon-button>\n </nve-grid-cell>\n <nve-grid-cell>Session: 6ruehvh</nve-grid-cell>\n <nve-grid-cell>upload</nve-grid-cell>\n <nve-grid-cell>pending</nve-grid-cell>\n <nve-grid-cell>p2</nve-grid-cell>\n <nve-grid-cell>12/09/22</nve-grid-cell>\n </nve-grid-row>\n</nve-grid>\n`\n};\n\n/**\n * @summary The footer displays contextual information or extra user actions such as pagination.\n */\nexport const Footer = {\n render: () => html`\n<nve-grid style=\"height: 400px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(14).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n <nve-grid-footer>\n <p nve-text=\"body\">footer content</p>\n </nve-grid-footer>\n</nve-grid>\n `\n};\n\n/**\n * @summary Use the pagination pattern when working with large data sets\n * that need incremental loading or filtering for performance or useability.\n */\nexport const Pagination = {\n render: () => html`\n<nve-grid style=\"height: 370px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n <nve-grid-footer>\n <nve-pagination value=\"1\" items=\"100\" step=\"10\"></nve-pagination>\n </nve-grid-footer>\n</nve-grid>\n `\n};\n\n/**\n * @summary Fixed-height scrollable grid with persistent header and footer. Use scrollable grids when displaying large datasets where users need to maintain context of column headers and footer controls (like pagination) while scrolling through many rows, improving navigation without losing orientation.\n * @tags test-case\n */\nexport const Scroll = {\n render: () => html`\n<nve-grid style=\"height: 402px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(100).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n <nve-grid-footer>footer</nve-grid-footer>\n</nve-grid>\n `\n};\n\n/**\n * @summary Programmatic scroll control using the grid `scrollTo` API. Use for scroll-to-top buttons, jump-to-row navigation, or restoring scroll position after data refreshes in large datasets.\n */\nexport const ScrollPosition = {\n render: () => html`\n<nve-grid id=\"scroll-position-grid\" style=\"height: 402px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(20).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n <nve-grid-footer>\n <nve-button id=\"scroll-top-button\">scroll top</nve-button>\n </nve-grid-footer>\n</nve-grid>\n<script type=\"module\">\n const grid = document.querySelector('#scroll-position-grid');\n const button = document.querySelector('#scroll-top-button');\n button.addEventListener('click', () => {\n grid.scrollTo({ top: 0, behavior: 'smooth' });\n });\n</script>\n `\n};\n\n/**\n * @summary Using `nve-layout=\"column\"` the grid to fill any remaining space\n * of a parent containing element. This is helpful for preserving the grid\n * height/fill while dynamic content above can freely change.\n * @tags test-case\n */\nexport const FullHeight = {\n render: () => html`\n<section nve-layout=\"column gap:lg\" style=\"height: 500px; padding: var(--nve-ref-size-100); border: 1px solid var(--nve-ref-border-color-emphasis); resize: vertical; overflow: hidden;\">\n <nve-search>\n <input type=\"search\" aria-label=\"search\" placeholder=\"search\" />\n </nve-search>\n <nve-grid style=\"height: 100%; min-height: 0;\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n </nve-grid>\n</section>\n `\n};\n\n/**\n * @summary Create column actions by using the `nve-icon-button` to\n * trigger dropdowns or panels that reveal more actions to the user.\n */\nexport const ColumnAction = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`\n <nve-grid-column>\n column ${i} <nve-icon-button container=\"flat\" popovertarget=\"grid-column-action-dropdown\" icon-name=\"more-actions\" slot=\"actions\"></nve-icon-button>\n </nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n</nve-grid>\n<nve-dropdown id=\"grid-column-action-dropdown\">\n <nve-search rounded>\n <input type=\"search\" placeholder=\"search column\" aria-label=\"search apps\" />\n </nve-search>\n <nve-menu>\n <nve-menu-item><nve-icon name=\"gear\"></nve-icon> settings</nve-menu-item>\n <nve-menu-item><nve-icon name=\"star\"></nve-icon> favorites</nve-menu-item>\n </nve-menu>\n</nve-dropdown>\n `\n};\n\n/**\n * @summary Column width control for responsive grid layouts, enabling flexible content sizing and optimal space usage across different screen sizes.\n */\nexport const ColumnWidth = {\n render: () => html`\n<nve-grid style=\"height: 400px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column width=${i !== 4 ? '300px' : ''}>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n <nve-grid-footer>footer content</nve-grid-footer>\n</nve-grid>\n `\n};\n\n/**\n * @summary Basic grid content display with evenly distributed columns, including standard data presentation and cell content wrapping behavior.\n * @tags test-case\n */\nexport const Content = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Fix columns to any given side, but keep fixed columns from\n * spanning past the half way point of the grid.\n */\nexport const ColumnFixed = {\n render: () => html`\n<nve-grid style=\"height: 400px; max-width: 800px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column position=${i === 0 ? 'fixed' : ''} width=\"200px\">column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Fix many columns to any given side, but keep fixed columns from\n * spanning past the half way point of the grid.\n */\nexport const ColumnMultiFixed = {\n render: () => html`\n<nve-grid style=\"height: 400px; max-width: 800px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column position=${(i === 0) || (i === 4) ? 'fixed' : ''} width=\"200px\">column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Stack and fix many columns to any given side, but keep fixed\n * columns from spanning past the half way point of the grid.\n */\nexport const ColumnStackFixed = {\n render: () => html`\n<nve-grid style=\"height: 400px; max-width: 800px\">\n <nve-grid-header>\n <nve-grid-column position=\"fixed\" width=\"100px\">Column 1</nve-grid-column>\n <nve-grid-column position=\"fixed\" width=\"100px\">Column 2</nve-grid-column>\n <nve-grid-column width=\"200px\">Column 3</nve-grid-column>\n <nve-grid-column width=\"200px\">Column 4</nve-grid-column>\n <nve-grid-column width=\"200px\">Column 5</nve-grid-column>\n <nve-grid-column width=\"200px\">Column 6</nve-grid-column>\n <nve-grid-column position=\"fixed\" width=\"100px\">Column 7</nve-grid-column>\n <nve-grid-column position=\"fixed\" width=\"100px\">Column 8</nve-grid-column>\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(8).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Dynamic column management with programmatic addition and positioning, for flexible grid configuration with evolving data requirements.\n */\nexport const ColumnDynamicFixed = {\n render: () => html`\n<nve-grid id=\"column-dynamic-fixed-grid\" style=\"height: 400px;\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column width=\"200px\" position=${(i === 0) || (i === 4) ? 'fixed' : ''}>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n <nve-grid-footer>\n <nve-button container=\"flat\">add column</nve-button>\n </nve-grid-footer>\n</nve-grid>\n<script type=\"module\">\n const grid = document.querySelector('#column-dynamic-fixed-grid');\n const button = grid.querySelector('nve-button');\n button.addEventListener('click', () => {\n const columns = Array.from(grid.querySelectorAll('nve-grid-column'));\n columns.filter((_ , i) => i !== 0).forEach(column => column.position = null);\n\n // add new column\n const newColumn = document.createElement('nve-grid-column');\n newColumn.position = 'fixed';\n newColumn.width = '200px';\n newColumn.textContent = 'column ' + columns.length;\n grid.querySelector('nve-grid-header').appendChild(newColumn);\n\n // add new cell to each row to the end\n grid.querySelectorAll('nve-grid-row').forEach((row, i) => {\n const cell = document.createElement('nve-grid-cell');\n cell.textContent = 'cell ' + i + '-' + columns.length;\n row.appendChild(cell);\n });\n });\n</script>\n `\n};\n\n/**\n * @summary Center-aligned column content for improved visual balance and data presentation, enhancing readability for numeric and centered data types.\n * @tags test-case\n */\nexport const ColumnAlignCenter = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column column-align=\"center\">column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Right-aligned column content for numeric data and values, providing consistent visual alignment and improved data scanning for financial or metric displays.\n * @tags test-case\n */\nexport const ColumnAlignEnd = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column column-align=\"end\">column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Left-aligned column content for text data and labels, providing consistent visual alignment and improved readability for textual information.\n * @tags test-case\n */\nexport const ColumnAlignStart = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column column-align=\"start\">column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Users can customize their data view through a dropdown menu above the grid, \n * allowing them to show/hide columns and restore default settings for a personalized experience.\n */\nexport const DisplaySettings = {\n render: () => html`\n<div nve-layout=\"column gap:md full\">\n <nve-dropdown closable id=\"column-settings-dropdown\">\n <nve-checkbox-group style=\"width: 175px\">\n <label>Columns</label>\n <nve-checkbox>\n <label>Column 1</label>\n <input type=\"checkbox\" checked />\n </nve-checkbox>\n <nve-checkbox>\n <label>Column 2</label>\n <input type=\"checkbox\" checked />\n </nve-checkbox>\n <nve-checkbox>\n <label>Column 3</label>\n <input type=\"checkbox\" checked />\n </nve-checkbox>\n <nve-checkbox>\n <label>Column 4</label>\n <input type=\"checkbox\" checked />\n </nve-checkbox>\n </nve-checkbox-group>\n <nve-divider></nve-divider>\n <nve-button popovertarget=\"column-settings-dropdown\" popovertargetaction=\"hide\" interaction=\"destructive\" container=\"flat\" style=\"--height: initial\">restore settings</nve-button>\n </nve-dropdown>\n <div nve-layout=\"row gap:sm align:vertical-center\">\n <p nve-text=\"body muted\">1,145 results found</p>\n <nve-button popovertarget=\"column-settings-dropdown\">Display Settings</nve-button>\n </div>\n <nve-grid>\n <nve-grid-header>\n ${Array(4).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(4).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n </nve-grid>\n</div>\n `\n};\n\n/**\n * @summary Sortable columns with visual indicators for data organization. Use sort buttons on columns where sorting is meaningful (dates, numbers, names) to help users find patterns, identify outliers, or locate specific data points, supporting three states: none, ascending, and descending.\n */\nexport const RowSort = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n <nve-grid-column>\n None <nve-sort-button sort=\"none\"></nve-sort-button>\n </nve-grid-column>\n <nve-grid-column>\n Ascending <nve-sort-button sort=\"ascending\"></nve-sort-button>\n </nve-grid-column>\n <nve-grid-column>\n Descending <nve-sort-button sort=\"descending\"></nve-sort-button>\n </nve-grid-column>\n <nve-grid-column>Default</nve-grid-column>\n <nve-grid-column>Default</nve-grid-column>\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/* eslint-disable @nvidia-elements/lint/no-missing-popover-trigger */\n\n/**\n * @summary CSS anchor positioning for tooltips within grid cells, with proper tooltip placement and content visibility in constrained grid environments.\n * @tags test-case\n */\nexport const CSSAnchor = {\n render: () => html`\n <nve-grid style=\"height: 200px;\">\n <nve-grid-header>\n <nve-grid-column>Empty</nve-grid-column>\n </nve-grid-header>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell><span id=\"target\">Target 1</span></nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n </nve-grid>\n <nve-tooltip anchor=\"target\" position=\"right\">My tooltip</nve-tooltip>\n `\n};\n\nclass RowSortDemo extends LitElement {\n @state() private sort: 'none' | 'ascending' | 'descending' = 'none';\n\n static styles = [unsafeCSS(layout)];\n\n get items() {\n if (this.sort === 'ascending') {\n return getItems().sort((a: { field1: { value: string } }, b: { field1: { value: string } }) => a.field1.value.localeCompare(b.field1.value));\n }\n\n if (this.sort === 'descending') {\n return getItems().sort((a: { field1: { value: string } }, b: { field1: { value: string } }) => a.field1.value.localeCompare(b.field1.value)).reverse();\n }\n\n return getItems();\n }\n\n render() {\n return html`\n <nve-grid>\n <nve-grid-header>\n ${Object.entries(this.items[0]).map(([, column], i) => html`\n <nve-grid-column>\n ${column.label} ${i === 0 ? html`<nve-sort-button .sort=${this.sort} @sort=${e => this.sort = e.detail.next}></nve-sort-button>` : nothing}\n </nve-grid-column>`)}\n </nve-grid-header>\n ${this.items.map(row => html`\n <nve-grid-row>\n ${Object.entries(row).map(([, cell]) => html`<nve-grid-cell>${cell.value}</nve-grid-cell> `)}\n </nve-grid-row>`)}\n </nve-grid>\n `\n }\n}\n\ncustomElements.get('row-sort-demo') || customElements.define('row-sort-demo', RowSortDemo);\n\n/**\n * @summary Row sort sorts the rows of the grid.\n * @tags test-case\n */\nexport const RowSortInteractive = {\n render: () => html`<row-sort-demo></row-sort-demo>`\n};\n\nclass InfiniteScrollDemo extends LitElement {\n static styles = [unsafeCSS(layout)];\n\n @state() private rows = this.#group(grid(10000).rows, 100);\n\n @state() private grid: { columns: { id: string; label: string; sort: string }[]; rows: Partial<{ id: string; cells: { id: string; label: string }[] }>[] } = grid(0, 4)\n\n render() {\n return html`\n <nve-grid style=\"height: 400px\" @scrollboxend=${() => this.#loadGroup()}>\n <nve-grid-header>\n ${this.grid.columns.map(column => html`<nve-grid-column>${column.label}</nve-grid-column>`)}\n </nve-grid-header>\n ${this.grid.rows.map(row => html`\n <nve-grid-row>\n ${row.cells.map(cell => html`<nve-grid-cell>${cell.label}</nve-grid-cell> `)}\n </nve-grid-row>`)}\n <nve-grid-footer>\n <p nve-text=\"body\">Items ${this.grid.rows.length} / 10000</p>\n </nve-grid-footer>\n </nve-grid>\n `\n }\n\n connectedCallback() {\n super.connectedCallback();\n this.#loadGroup();\n }\n\n #group(items: object[], size: number) {\n return [...Array(Math.ceil(items.length / size))].map((_, i) => items.slice(size * i, size + size * i));\n }\n\n #loadGroup() {\n const group = this.rows.splice(0, 1)[0];\n if (group) {\n this.grid = { ...this.grid, rows: [...this.grid.rows, ...group] };\n }\n }\n}\n\ncustomElements.get('infinite-scroll-demo') || customElements.define('infinite-scroll-demo', InfiniteScrollDemo);\n\n/**\n * @summary Infinite scroll loads data as the user scrolls down the grid.\n * @tags test-case performance\n */\nexport const PerformanceInfiniteScroll = {\n render: () => html`<infinite-scroll-demo></infinite-scroll-demo>`\n};\n\n/**\n * @summary Datagrid performance is heavily dependent on the content within the grid as well as the host environment.\n * @tags performance\n * @description When rendering large datasets, using the appropriate techniques to maintain good performance matters.\n * - Use pagination or lazy loading to reduce initial render time\n * - Use virtual scroll or batch rendering to improve render performance\n * - Use fixed width columns to improve render performance and reduce layout shift\n * - Avoid duplication of elements within cells, example reuse a single tooltip for all cells vs creating a new tooltip for each cell\n */\nexport const Performance = {\n render: () => html`\n <section id=\"grid-performance-demo\" nve-layout=\"column gap:md full\" style=\"height: 500px;\">\n <nve-button>show large grid</nve-button>\n <p nve-text=\"body muted\">1000 rows, 4000 cells</p>\n </section>\n <script type=\"module\">\n import '@nvidia-elements/core/grid/define.js';\n const section = document.getElementById('grid-performance-demo');\n const button = section.querySelector('nve-button');\n\n button.addEventListener('click', () => {\n const existingGrid = section.querySelector('nve-grid');\n if (existingGrid) {\n existingGrid.remove();\n } else {\n const grid = document.createElement('nve-grid');\n grid.style.setProperty('height', '400px');\n grid.style.setProperty('max-width', '1024px');\n\n const header = document.createElement('nve-grid-header');\n const columns = new Array(4).fill('').map((_, i) => {\n const column = document.createElement('nve-grid-column');\n column.setAttribute('width', '25%');\n column.textContent = 'Column ' + i;\n return column;\n });\n\n const rows = new Array(1000).fill('').map((_, i) => {\n const row = document.createElement('nve-grid-row');\n new Array(4).fill('').forEach((_, c) => {\n const cell = document.createElement('nve-grid-cell');\n cell.textContent = 'Cell ' + i + '-' + c;\n row.appendChild(cell);\n });\n return row;\n });\n\n header.append(...columns);\n grid.appendChild(header);\n grid.append(...rows);\n section.appendChild(grid);\n }\n });\n </script>\n `\n};\n\nclass GridVirtualScrollDemo extends LitElement {\n items = new Array(10000).fill('').map((_i, n) => ({ column: `${n}-0`, column1: `${n}-1`, column2: `${n}-2`, column3: `${n}-3` }));\n\n render() {\n return html`\n <nve-grid>\n <nve-grid-header>\n <nve-grid-column>column</nve-grid-column>\n <nve-grid-column>column</nve-grid-column>\n <nve-grid-column>column</nve-grid-column>\n <nve-grid-column>column</nve-grid-column>\n </nve-grid-header>\n\n <lit-virtualizer style=\"min-height: 350px\" scroller .items=${this.items} .renderItem=${i => html`\n <nve-grid-row style=\"width: 100%\">\n ${Object.keys(i).map(key => html`<nve-grid-cell>${i[key]}</nve-grid-cell>`)}\n </nve-grid-row>`}>\n </lit-virtualizer>\n </nve-grid>\n `;\n }\n}\n\ncustomElements.get('grid-virtual-scroll-demo') || customElements.define('grid-virtual-scroll-demo', GridVirtualScrollDemo);\n\n/**\n * @summary Performance virtual scroll tests the performance of the grid.\n * @tags test-case performance\n */\nexport const PerformanceVirtualScroll = {\n render: () => html`<grid-virtual-scroll-demo></grid-virtual-scroll-demo>`\n};\n\n/**\n * @summary Alternating row background colors for improved scanability. Use striped rows in dense grids or when users frequently scan horizontally across many columns, as the alternating backgrounds help maintain visual alignment and reduce reading errors in wide tables.\n * @tags test-case\n */\nexport const Stripe = {\n render: () => html`\n<nve-grid stripe>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Nest Grid in Cards for UI patterns such as card tab groups. Use\n * the `container=\"flat\"` attribute to enable proper styling of the grid when\n * nested within a card.\n */\nexport const Card = {\n render: () => html`\n<nve-card>\n <nve-card-header>\n <h2 nve-text=\"heading sm bold\">Data Grid</h2>\n <h3 nve-text=\"body muted\">Card Example</h3>\n </nve-card-header>\n <nve-grid container=\"flat\" style=\"height: 325px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(5).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n </nve-grid>\n</nve-card>\n `\n};\n\n/**\n * @summary Grid integrated with tabs for organized data presentation, enabling many data views within a single interface for comprehensive information display.\n * @tags test-case\n */\nexport const CardTabs = {\n render: () => html`\n<nve-card>\n <nve-card-header>\n <h2 nve-text=\"heading sm bold\">Data Grid</h2>\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>\n </nve-card-header>\n <nve-grid container=\"flat\" style=\"height: 325px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n </nve-grid>\n</nve-card>\n `\n};\n\n/**\n * @summary Loading placeholder state with progress indicator. Use grid placeholders during initial data fetching or while loading large datasets, providing visual feedback that content is coming and preventing layout shift when rows populate, improving perceived performance.\n */\nexport const Placeholder = {\n render: () => html`\n<nve-grid style=\"min-height: 400px\">\n <nve-grid-header>\n <nve-grid-column></nve-grid-column>\n </nve-grid-header>\n <nve-grid-placeholder>\n <nve-progress-ring status=\"accent\" size=\"lg\"></nve-progress-ring>\n </nve-grid-placeholder>\n</nve-grid>\n `\n};\n\n/**\n * @summary Full-width grid container for max space use, providing edge-to-edge data display for comprehensive information presentation.\n */\nexport const Full = {\n render: () => html`\n<nve-grid container=\"full\" style=\"height: 400px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Flat container styling for minimal visual weight, providing subtle grid presentation that integrates seamlessly with surrounding content.\n */\nexport const Flat = {\n render: () => html`\n<nve-grid container=\"flat\" style=\"height: 400px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(20).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Different focusable element types within grid cells, with keyboard navigation and accessibility support for interactive content.\n * @tags test-case\n */\nexport const FocusTypes = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n <nve-grid-column>span</nve-grid-column>\n <nve-grid-column>button</nve-grid-column>\n <nve-grid-column>2x buttons</nve-grid-column>\n <nve-grid-column>input</nve-grid-column>\n </nve-grid-header>\n <nve-grid-row>\n <nve-grid-cell>\n <span>span</span>\n </nve-grid-cell>\n <nve-grid-cell>\n <button>button</button>\n </nve-grid-cell>\n <nve-grid-cell>\n <button>button</button>\n <button>button</button>\n </nve-grid-cell>\n <nve-grid-cell>\n <input />\n </nve-grid-cell>\n </nve-grid-row>\n</nve-grid>\n `\n};\n\n/**\n * @summary Use a nve-page-panel when displaying advanced filtering or display\n * settings for the grid. Item detail panels should be open using a action\n * button placed at the end of the grid row.\n */\nexport const PanelDetail = {\n render: () => html`\n<nve-page id=\"grid-panel-demo\">\n <nve-page-header slot=\"header\">\n <nve-logo slot=\"prefix\" size=\"sm\"></nve-logo>\n <h2 nve-text=\"heading\" slot=\"prefix\">Infrastructure</h2>\n </nve-page-header>\n <section nve-layout=\"column gap:md pad:md full\">\n <nve-grid>\n <nve-grid-header>\n ${Array(3).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n <nve-grid-column width=\"max-content\" aria-label=\"details\"></nve-grid-column>\n </nve-grid-header>\n ${Array(10).fill('').map((_, i) => html`\n <nve-grid-row ?selected=${i === 1}>\n ${Array(3).fill('').map((_, c) => html`<nve-grid-cell>cell ${i}-${c}</nve-grid-cell> `)}\n <nve-grid-cell>\n <nve-icon-button container=\"flat\" icon-name=\"expand-details\" value=${i} aria-label=\"view ${i}\"></nve-icon-button>\n </nve-grid-cell>\n </nve-grid-row>\n `)}\n </nve-grid>\n </section>\n <nve-page-panel slot=\"right\" size=\"sm\" expanded closable>\n <nve-page-panel-header>\n <h3 nve-text=\"heading medium sm\">Row 2 Details</h3>\n </nve-page-panel-header>\n <nve-page-panel-content>\n <div nve-layout=\"column gap:md\">\n <div nve-layout=\"column gap:xs\">\n <label nve-text=\"body sm muted\">Task</label>\n <p nve-text=\"eyebrow sm\">Workflow</p>\n </div>\n <div nve-layout=\"column gap:xs\">\n <label nve-text=\"body sm muted\">Status</label>\n <nve-badge status=\"success\">Complete</nve-badge>\n </div>\n <div nve-layout=\"column gap:xs\">\n <label nve-text=\"body sm muted\">Priority</label>\n <nve-badge status=\"pending\">P1</nve-badge>\n </div>\n </div>\n </nve-page-panel-content>\n </nve-page-panel>\n</nve-page>\n<script type=\"module\">\n const page = document.getElementById('grid-panel-demo');\n const grid = page.querySelector('nve-grid');\n const panel = page.querySelector('nve-page-panel');\n const rows = grid.querySelectorAll('nve-grid-row');\n const heading = page.querySelector('nve-page-panel-header h3');\n\n panel.addEventListener('close', () => {\n rows.forEach(row => row.selected = false);\n panel.hidden = true;\n });\n\n grid.addEventListener('click', (e) => {\n if (e.target.localName === 'nve-icon-button') {\n const row = e.target.closest('nve-grid-row');\n rows.forEach(row => row.selected = false);\n panel.hidden = false;\n heading.textContent = 'Row ' + e.target.value + ' Details';\n row.selected = !panel.hidden;\n }\n });\n</script>\n `\n};\n\n/**\n * @summary Panel Grid displays key value type data sets for details of a\n * given item in a collection.\n */\nexport const PanelGrid = {\n render() {\n return html`\n <nve-page>\n <nve-page-header slot=\"header\">\n <nve-logo slot=\"prefix\" size=\"sm\"></nve-logo>\n <h2 nve-text=\"heading\" slot=\"prefix\">Infrastructure</h2>\n </nve-page-header>\n <section nve-layout=\"column gap:md pad:md full\">\n page content\n </section>\n <nve-page-panel slot=\"right\" expanded closable>\n <nve-page-panel-header>\n <h3 nve-text=\"heading medium sm\">Recording</h3>\n </nve-page-panel-header>\n <nve-grid container=\"flat\" stripe>\n <nve-grid-header>\n <nve-grid-column style=\"height: 0; overflow: hidden;\">Key</nve-grid-column>\n <nve-grid-column style=\"height: 0; overflow: hidden;\">Value</nve-grid-column>\n </nve-grid-header>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Session ID</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">123456</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Record Date</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">2023-09-04 11:00</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Tag</p></nve-grid-cell>\n <nve-grid-cell><nve-tag readonly>Production</nve-tag></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Route ID</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">9876123</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Configuration</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">prod-0.1.0</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Duration</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">1:23:34</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Description</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">local test run</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Number of Sensors</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">24</p></nve-grid-cell>\n </nve-grid-row>\n </nve-grid>\n </nve-page-panel>\n </nve-page>\n `;\n }\n}\n\n/**\n * @summary Examples of invalid grid usage patterns for testing and documentation purposes, showing what not to do when implementing grids.\n * @tags anti-pattern\n */\nexport const InvalidDOM = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n <div>invalid</div>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(r === 9 ? 4 : 5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n <span>invalid</span>\n</nve-grid>\n `\n};\n\n/**\n * @summary Examples of invalid grid usage patterns for testing and documentation purposes, showing what not to do when implementing grids.\n * @tags anti-pattern\n */\nexport const Audit = {\n render: () => html`\n<nve-grid style=\"height: 450px\">\n <div hidden></div>\n <nve-grid-header>\n <div hidden></div>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n <div hidden></div>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Do not set the column count to a value that does not match the number of cells in the row.\n * @tags anti-pattern\n */\nexport const InvalidColumnCount = {\n render: () => html`\n<nve-grid>\n <div hidden></div>\n <nve-grid-header>\n <div hidden></div>\n ${Array(4).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(4).fill('').map((_, r) => html`\n <div>\n <nve-grid-row>\n ${Array(3).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n </div>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Ensure column count matches the number of cells in the row to preserve keyboard navigation.\n * @tags test-case\n */\nexport const ValidColumnCount = {\n render: () => html`\n<nve-grid>\n <div hidden></div>\n <nve-grid-header>\n ${Array(4).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(4).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(4).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Use the `nve-sort-button` to add grid row sort.\n * The grid follows the ARIA sort spec and automatically sets the appropriate\n * accessibility related attributes to convey the current sorting state.\n */\nexport const SortVisibility = {\n render: () => html `\n<nve-grid>\n <nve-grid-header>\n <nve-grid-column>\n Column 1 <nve-sort-button sort=\"none\"></nve-sort-button>\n </nve-grid-column>\n <nve-grid-column>\n Column 2 <nve-sort-button sort=\"ascending\"></nve-sort-button>\n </nve-grid-column>\n <nve-grid-column>\n Column 3 <nve-sort-button sort=\"descending\"></nve-sort-button>\n </nve-grid-column>\n <nve-grid-column>Column 4</nve-grid-column>\n </nve-grid-header>\n <nve-grid-row>\n <nve-grid-cell>cell 1-1</nve-grid-cell>\n <nve-grid-cell>cell 1-2</nve-grid-cell>\n <nve-grid-cell>cell 1-3</nve-grid-cell>\n <nve-grid-cell>cell 1-4</nve-grid-cell>\n </nve-grid-row>\n</nve-grid>`\n}\n"],"mappings":";AAGA,IAAA,IAAS"}
|
|
1
|
+
{"version":3,"file":"grid.examples.js","names":["#group","#loadGroup"],"sources":["../../src/grid/grid.examples.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { LitElement, unsafeCSS, html, nothing } from 'lit';\nimport { state } from 'lit/decorators/state.js';\nimport { getItems, grid } from '../test/demo.js';\nimport layout from '@nvidia-elements/styles/layout.css?inline';\nimport '@nvidia-elements/core/grid/define.js';\nimport '@nvidia-elements/core/badge/define.js'\nimport '@nvidia-elements/core/button/define.js';\nimport '@nvidia-elements/core/card/define.js';\nimport '@nvidia-elements/core/checkbox/define.js';\nimport '@nvidia-elements/core/dropdown/define.js';\nimport '@nvidia-elements/core/icon/define.js';\nimport '@nvidia-elements/core/icon-button/define.js';\nimport '@nvidia-elements/core/tabs/define.js';\nimport '@nvidia-elements/core/menu/define.js';\nimport '@nvidia-elements/core/pagination/define.js';\nimport '@nvidia-elements/core/progress-ring/define.js';\nimport '@nvidia-elements/core/logo/define.js';\nimport '@nvidia-elements/core/page/define.js';\nimport '@nvidia-elements/core/page-header/define.js';\nimport '@nvidia-elements/core/panel/define.js';\nimport '@nvidia-elements/core/radio/define.js';\nimport '@nvidia-elements/core/search/define.js';\nimport '@nvidia-elements/core/sort-button/define.js';\nimport '@nvidia-elements/core/toolbar/define.js';\nimport '@nvidia-elements/core/tooltip/define.js';\nimport '@lit-labs/virtualizer';\n\nexport default {\n title: 'Elements/Data Grid',\n component: 'nve-grid',\n};\n\n/**\n * @summary Basic data grid for tabular data display with columns and rows. Use grids for presenting structured datasets where users need to scan, compare, and analyze information across many columns, such as dashboards, reports, or data management interfaces.\n */\nexport const Default = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary The datagrid follows the ARIA Authoring Practices Guide for standardized keyboard navigation.\n */\nexport const Keynav = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n <nve-grid-column width=\"150px\">Key</nve-grid-column>\n <nve-grid-column>Function</nve-grid-column>\n </nve-grid-header>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Right Arrow</kbd>\n </nve-grid-cell>\n <nve-grid-cell>\n <ul nve-text=\"list\">\n <li>Moves focus one cell to the right.</li>\n <li>If focus is on the right-most cell in the row, focus does not move.</li>\n </ul>\n </nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Left Arrow</kbd>\n </nve-grid-cell>\n <nve-grid-cell>\n <ul nve-text=\"list\">\n <li>Moves focus one cell to the left.</li>\n <li>If focus is on the left-most cell in the row, focus does not move.</li>\n </ul>\n </nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Down Arrow</kbd>\n </nve-grid-cell>\n <nve-grid-cell>\n <ul nve-text=\"list\">\n <li>Moves focus one cell down.</li>\n <li>If focus is on the bottom cell in the column, focus does not move.</li>\n </ul>\n </nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Up Arrow</kbd>\n </nve-grid-cell>\n <nve-grid-cell>\n <ul nve-text=\"list\">\n <li>Moves focus one cell Up.</li>\n <li>If focus is on the top cell in the column, focus does not move.</li>\n </ul>\n </nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Page Down</kbd>\n </nve-grid-cell>\n <nve-grid-cell>\n <ul nve-text=\"list\">\n <li>In example 3, moves focus down five rows, scrolling so the bottom row in the currently visible set of rows becomes the first visible row.</li>\n <li>If focus is in the last row, focus does not move.</li>\n </ul>\n </nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Page Up</kbd>\n </nve-grid-cell>\n <nve-grid-cell>\n <ul nve-text=\"list\">\n <li>In example 3, moves focus up 5 rows, scrolling so the top row in the currently visible set of rows becomes the last visible row.</li>\n <li>If focus is in the first row of the grid, focus does not move.</li>\n </ul>\n </nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Home</kbd>\n </nve-grid-cell>\n <nve-grid-cell>Moves focus to the first cell in the row that contains focus.</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>End</kbd>\n </nve-grid-cell>\n <nve-grid-cell>Moves focus to the last cell in the row that contains focus.</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Control</kbd> + <kbd>Home</kbd>\n </nve-grid-cell>\n <nve-grid-cell>Moves focus to the first cell in the first row.</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <kbd>Control</kbd> + <kbd>End</kbd>\n </nve-grid-cell>\n <nve-grid-cell>Moves focus to the last cell in the last row.</nve-grid-cell>\n </nve-grid-row>\n</nve-grid>`\n};\n\n/**\n * @summary Multi-select rows with checkboxes for bulk operations. Use multi-select when users need to perform actions on many items at once (like delete, export, or bulk edit), placing checkboxes as the first column and setting the selected attribute for proper accessibility.\n */\nexport const MultiSelect = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n <nve-grid-column width=\"max-content\" position=\"fixed\">\n <nve-checkbox>\n <input type=\"checkbox\" aria-label=\"select all rows\" />\n </nve-checkbox>\n </nve-grid-column>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n <nve-grid-cell>\n <nve-checkbox>\n <input type=\"checkbox\" ?checked=${r === 1} aria-label=\"select row ${r}\" />\n </nve-checkbox>\n </nve-grid-cell>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Use bulk actions for operations on many items. Display only\n * when rows have a selection. Closing bulk actions deselects all selected rows.\n */\nexport const BulkActions = {\n render: () => html`\n<nve-grid style=\"height: 400px\">\n <nve-grid-header>\n <nve-grid-column width=\"max-content\" position=\"fixed\">\n <nve-checkbox>\n <input type=\"checkbox\" aria-label=\"select all rows\" />\n </nve-checkbox>\n </nve-grid-column>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(20).fill('').map((_, r) => html`\n <nve-grid-row .selected=${r === 1}>\n <nve-grid-cell>\n <nve-checkbox>\n <input type=\"checkbox\" ?checked=${r === 1} aria-label=\"select row ${r}\" />\n </nve-checkbox>\n </nve-grid-cell>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n <nve-toolbar status=\"accent\" slot=\"footer\">\n <nve-icon-button container=\"flat\" icon-name=\"cancel\" slot=\"prefix\"></nve-icon-button>\n <p nve-text=\"body\">1 selected</p>\n <nve-button container=\"flat\" interaction=\"destructive\" slot=\"suffix\">delete</nve-button>\n <nve-icon-button container=\"flat\" icon-name=\"more-actions\" slot=\"suffix\"></nve-icon-button>\n </nve-toolbar>\n</nve-grid>\n `\n};\n\n/**\n * @summary A single select datagrid allows users to choose exactly one row\n * from a data table by providing radio buttons in the first column, ensuring\n * only one item has a selection at a time. To enable single select, place `nve-radio`\n * input as the first grid cell of each row. Set `name` attribute on each radio\n * to ensure to associate the same radio group.\n */\nexport const SingleSelect = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n <nve-grid-column width=\"max-content\" position=\"fixed\"></nve-grid-column>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n <nve-grid-cell>\n <nve-radio>\n <input type=\"radio\" ?checked=${r === 1} name=\"single-select\" .value=${`${r}`} aria-label=\"select row ${r}\" />\n </nve-radio>\n </nve-grid-cell>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Row actions enable extra user actions specific to a given row.\n * Place a `nve-icon-button` at the end of the grid row for actions.\n */\nexport const RowAction = {\n render: () => html`\n<nve-dropdown id=\"row-actions-dropdown\" align=\"end\">\n <nve-menu>\n <nve-menu-item>action 1</nve-menu-item>\n <nve-menu-item>action 2</nve-menu-item>\n <nve-menu-item>action 3</nve-menu-item>\n </nve-menu>\n</nve-dropdown>\n<nve-grid>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n <nve-grid-column width=\"max-content\" aria-label=\"additonal actions\" position=\"fixed\"></nve-grid-column>\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n <nve-grid-cell>\n <nve-icon-button id=\"action-${r}\" popovertarget=\"row-actions-dropdown\" container=\"flat\" icon-name=\"more-actions\" aria-label=\"row ${r} actions\"></nve-icon-button>\n </nve-grid-cell>\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Expandable row groups for hierarchical data organization. Use row groups when items have parent-child relationships or nested details (like sessions with uploads, orders with line items), allowing users to progressively disclose details and maintain compact views of large hierarchies.\n */\nexport const RowGroups = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n <nve-grid-column width=\"max-content\" aria-label=\"expand groups\" position=\"fixed\"></nve-grid-column>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n <nve-grid-row>\n <nve-grid-cell>\n <nve-icon-button icon-name=\"caret\" container=\"flat\" direction=\"right\" aria-label=\"view session 2yuecae SSD uploads\"></nve-icon-button>\n </nve-grid-cell>\n <nve-grid-cell>Session: 2yuecae</nve-grid-cell>\n <nve-grid-cell>upload</nve-grid-cell>\n <nve-grid-cell>pending</nve-grid-cell>\n <nve-grid-cell>p3</nve-grid-cell>\n <nve-grid-cell>12/04/22</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row selected>\n <nve-grid-cell>\n <nve-icon-button icon-name=\"caret\" container=\"flat\" direction=\"down\" aria-label=\"view session mvwgh3t SSD uploads\"></nve-icon-button>\n </nve-grid-cell>\n <nve-grid-cell>Session: mvwgh3t</nve-grid-cell>\n <nve-grid-cell>upload</nve-grid-cell>\n <nve-grid-cell>pending</nve-grid-cell>\n <nve-grid-cell>p0</nve-grid-cell>\n <nve-grid-cell>12/11/22</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell></nve-grid-cell>\n <nve-grid-cell>SSD: mvwgh3t</nve-grid-cell>\n <nve-grid-cell>validating</nve-grid-cell>\n <nve-grid-cell>pending</nve-grid-cell>\n <nve-grid-cell>p0</nve-grid-cell>\n <nve-grid-cell>12/11/22</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell></nve-grid-cell>\n <nve-grid-cell>SSD: qudbd8x</nve-grid-cell>\n <nve-grid-cell>uploading</nve-grid-cell>\n <nve-grid-cell>finished</nve-grid-cell>\n <nve-grid-cell>p0</nve-grid-cell>\n <nve-grid-cell>12/11/22</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell></nve-grid-cell>\n <nve-grid-cell>SSD: j8hvikt</nve-grid-cell>\n <nve-grid-cell>queuing</nve-grid-cell>\n <nve-grid-cell>running</nve-grid-cell>\n <nve-grid-cell>p0</nve-grid-cell>\n <nve-grid-cell>12/11/22</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <nve-icon-button icon-name=\"caret\" container=\"flat\" direction=\"right\" aria-label=\"view session bg5ujqp SSD uploads\"></nve-icon-button>\n </nve-grid-cell>\n <nve-grid-cell>Session: bg5ujqp</nve-grid-cell>\n <nve-grid-cell>upload</nve-grid-cell>\n <nve-grid-cell>pending</nve-grid-cell>\n <nve-grid-cell>p1</nve-grid-cell>\n <nve-grid-cell>12/12/22</nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell>\n <nve-icon-button icon-name=\"caret\" container=\"flat\" direction=\"right\" aria-label=\"view session 6ruehvh SSD uploads\"></nve-icon-button>\n </nve-grid-cell>\n <nve-grid-cell>Session: 6ruehvh</nve-grid-cell>\n <nve-grid-cell>upload</nve-grid-cell>\n <nve-grid-cell>pending</nve-grid-cell>\n <nve-grid-cell>p2</nve-grid-cell>\n <nve-grid-cell>12/09/22</nve-grid-cell>\n </nve-grid-row>\n</nve-grid>\n`\n};\n\n/**\n * @summary The footer displays contextual information or extra user actions such as pagination.\n */\nexport const Footer = {\n render: () => html`\n<nve-grid style=\"height: 400px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(14).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n <nve-grid-footer>\n <p nve-text=\"body\">footer content</p>\n </nve-grid-footer>\n</nve-grid>\n `\n};\n\n/**\n * @summary Use the pagination pattern when working with large data sets\n * that need incremental loading or filtering for performance or useability.\n */\nexport const Pagination = {\n render: () => html`\n<nve-grid style=\"height: 370px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n <nve-grid-footer>\n <nve-pagination value=\"1\" items=\"100\" step=\"10\"></nve-pagination>\n </nve-grid-footer>\n</nve-grid>\n `\n};\n\n/**\n * @summary Fixed-height scrollable grid with persistent header and footer. Use scrollable grids when displaying large datasets where users need to maintain context of column headers and footer controls (like pagination) while scrolling through many rows, improving navigation without losing orientation.\n * @tags test-case\n */\nexport const Scroll = {\n render: () => html`\n<nve-grid style=\"height: 402px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(100).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n <nve-grid-footer>footer</nve-grid-footer>\n</nve-grid>\n `\n};\n\n/**\n * @summary Programmatic scroll control using the grid `scrollTo` API. Use for scroll-to-top buttons, jump-to-row navigation, or restoring scroll position after data refreshes in large datasets.\n */\nexport const ScrollPosition = {\n render: () => html`\n<nve-grid id=\"scroll-position-grid\" style=\"height: 402px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(20).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n <nve-grid-footer>\n <nve-button id=\"scroll-top-button\">scroll top</nve-button>\n </nve-grid-footer>\n</nve-grid>\n<script type=\"module\">\n const grid = document.querySelector('#scroll-position-grid');\n const button = document.querySelector('#scroll-top-button');\n button.addEventListener('click', () => {\n grid.scrollTo({ top: 0, behavior: 'smooth' });\n });\n</script>\n `\n};\n\n/**\n * @summary Using `nve-layout=\"column\"` the grid to fill any remaining space\n * of a parent containing element. This is helpful for preserving the grid\n * height/fill while dynamic content above can freely change.\n * @tags test-case\n */\nexport const FullHeight = {\n render: () => html`\n<section nve-layout=\"column gap:lg\" style=\"height: 500px; padding: var(--nve-ref-size-100); border: 1px solid var(--nve-ref-border-color-emphasis); resize: vertical; overflow: hidden;\">\n <nve-search>\n <input type=\"search\" aria-label=\"search\" placeholder=\"search\" />\n </nve-search>\n <nve-grid style=\"height: 100%; min-height: 0;\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n </nve-grid>\n</section>\n `\n};\n\n/**\n * @summary Create column actions by using the `nve-icon-button` to\n * trigger dropdowns or panels that reveal more actions to the user.\n */\nexport const ColumnAction = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`\n <nve-grid-column>\n column ${i} <nve-icon-button container=\"flat\" popovertarget=\"grid-column-action-dropdown\" icon-name=\"more-actions\" slot=\"actions\"></nve-icon-button>\n </nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n</nve-grid>\n<nve-dropdown id=\"grid-column-action-dropdown\">\n <nve-search rounded>\n <input type=\"search\" placeholder=\"search column\" aria-label=\"search apps\" />\n </nve-search>\n <nve-menu>\n <nve-menu-item><nve-icon name=\"gear\"></nve-icon> settings</nve-menu-item>\n <nve-menu-item><nve-icon name=\"star\"></nve-icon> favorites</nve-menu-item>\n </nve-menu>\n</nve-dropdown>\n `\n};\n\n/**\n * @summary Column width control for responsive grid layouts, enabling flexible content sizing and optimal space usage across different screen sizes.\n */\nexport const ColumnWidth = {\n render: () => html`\n<nve-grid style=\"height: 400px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column width=${i !== 4 ? '300px' : ''}>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n <nve-grid-footer>footer content</nve-grid-footer>\n</nve-grid>\n `\n};\n\n/**\n * @summary Basic grid content display with evenly distributed columns, including standard data presentation and cell content wrapping behavior.\n * @tags test-case\n */\nexport const Content = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Fix columns to any given side, but keep fixed columns from\n * spanning past the half way point of the grid.\n */\nexport const ColumnFixed = {\n render: () => html`\n<nve-grid style=\"height: 400px; max-width: 800px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column position=${i === 0 ? 'fixed' : ''} width=\"200px\">column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Fix many columns to any given side, but keep fixed columns from\n * spanning past the half way point of the grid.\n */\nexport const ColumnMultiFixed = {\n render: () => html`\n<nve-grid style=\"height: 400px; max-width: 800px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column position=${(i === 0) || (i === 4) ? 'fixed' : ''} width=\"200px\">column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Stack and fix many columns to any given side, but keep fixed\n * columns from spanning past the half way point of the grid.\n */\nexport const ColumnStackFixed = {\n render: () => html`\n<nve-grid style=\"height: 400px; max-width: 800px\">\n <nve-grid-header>\n <nve-grid-column position=\"fixed\" width=\"100px\">Column 1</nve-grid-column>\n <nve-grid-column position=\"fixed\" width=\"100px\">Column 2</nve-grid-column>\n <nve-grid-column width=\"200px\">Column 3</nve-grid-column>\n <nve-grid-column width=\"200px\">Column 4</nve-grid-column>\n <nve-grid-column width=\"200px\">Column 5</nve-grid-column>\n <nve-grid-column width=\"200px\">Column 6</nve-grid-column>\n <nve-grid-column position=\"fixed\" width=\"100px\">Column 7</nve-grid-column>\n <nve-grid-column position=\"fixed\" width=\"100px\">Column 8</nve-grid-column>\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(8).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Dynamic column management with programmatic addition and positioning, for flexible grid configuration with evolving data requirements.\n */\nexport const ColumnDynamicFixed = {\n render: () => html`\n<nve-grid id=\"column-dynamic-fixed-grid\" style=\"height: 400px;\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column width=\"200px\" position=${(i === 0) || (i === 4) ? 'fixed' : ''}>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n <nve-grid-footer>\n <nve-button container=\"flat\">add column</nve-button>\n </nve-grid-footer>\n</nve-grid>\n<script type=\"module\">\n const grid = document.querySelector('#column-dynamic-fixed-grid');\n const button = grid.querySelector('nve-button');\n button.addEventListener('click', () => {\n const columns = Array.from(grid.querySelectorAll('nve-grid-column'));\n columns.filter((_ , i) => i !== 0).forEach(column => column.position = null);\n\n // add new column\n const newColumn = document.createElement('nve-grid-column');\n newColumn.position = 'fixed';\n newColumn.width = '200px';\n newColumn.textContent = 'column ' + columns.length;\n grid.querySelector('nve-grid-header').appendChild(newColumn);\n\n // add new cell to each row to the end\n grid.querySelectorAll('nve-grid-row').forEach((row, i) => {\n const cell = document.createElement('nve-grid-cell');\n cell.textContent = 'cell ' + i + '-' + columns.length;\n row.appendChild(cell);\n });\n });\n</script>\n `\n};\n\n/**\n * @summary Center-aligned column content for improved visual balance and data presentation, enhancing readability for numeric and centered data types.\n * @tags test-case\n */\nexport const ColumnAlignCenter = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column column-align=\"center\">column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Right-aligned column content for numeric data and values, providing consistent visual alignment and improved data scanning for financial or metric displays.\n * @tags test-case\n */\nexport const ColumnAlignEnd = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column column-align=\"end\">column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Left-aligned column content for text data and labels, providing consistent visual alignment and improved readability for textual information.\n * @tags test-case\n */\nexport const ColumnAlignStart = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column column-align=\"start\">column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Users can customize their data view through a dropdown menu above the grid, \n * allowing them to show/hide columns and restore default settings for a personalized experience.\n */\nexport const DisplaySettings = {\n render: () => html`\n<div nve-layout=\"column gap:md full\">\n <nve-dropdown closable id=\"column-settings-dropdown\">\n <nve-checkbox-group style=\"width: 175px\">\n <label>Columns</label>\n <nve-checkbox>\n <label>Column 1</label>\n <input type=\"checkbox\" checked />\n </nve-checkbox>\n <nve-checkbox>\n <label>Column 2</label>\n <input type=\"checkbox\" checked />\n </nve-checkbox>\n <nve-checkbox>\n <label>Column 3</label>\n <input type=\"checkbox\" checked />\n </nve-checkbox>\n <nve-checkbox>\n <label>Column 4</label>\n <input type=\"checkbox\" checked />\n </nve-checkbox>\n </nve-checkbox-group>\n <nve-divider></nve-divider>\n <nve-button popovertarget=\"column-settings-dropdown\" popovertargetaction=\"hide\" interaction=\"destructive\" container=\"flat\" style=\"--height: initial\">restore settings</nve-button>\n </nve-dropdown>\n <div nve-layout=\"row gap:sm align:vertical-center\">\n <p nve-text=\"body muted\">1,145 results found</p>\n <nve-button popovertarget=\"column-settings-dropdown\">Display Settings</nve-button>\n </div>\n <nve-grid>\n <nve-grid-header>\n ${Array(4).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(4).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell> `)}\n </nve-grid-row>\n `)}\n </nve-grid>\n</div>\n `\n};\n\n/**\n * @summary Sortable columns with visual indicators for data organization. Use sort buttons on columns where sorting is meaningful (dates, numbers, names) to help users find patterns, identify outliers, or locate specific data points, supporting three states: none, ascending, and descending.\n */\nexport const RowSort = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n <nve-grid-column>\n None <nve-sort-button sort=\"none\"></nve-sort-button>\n </nve-grid-column>\n <nve-grid-column>\n Ascending <nve-sort-button sort=\"ascending\"></nve-sort-button>\n </nve-grid-column>\n <nve-grid-column>\n Descending <nve-sort-button sort=\"descending\"></nve-sort-button>\n </nve-grid-column>\n <nve-grid-column>Default</nve-grid-column>\n <nve-grid-column>Default</nve-grid-column>\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/* eslint-disable @nvidia-elements/lint/no-missing-popover-trigger */\n\n/**\n * @summary CSS anchor positioning for tooltips within grid cells, with proper tooltip placement and content visibility in constrained grid environments.\n * @tags test-case\n */\nexport const CSSAnchor = {\n render: () => html`\n <nve-grid style=\"height: 200px;\">\n <nve-grid-header>\n <nve-grid-column>Empty</nve-grid-column>\n </nve-grid-header>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell><span id=\"target\">Target 1</span></nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n <nve-grid-row><nve-grid-cell>Empty</nve-grid-cell></nve-grid-row>\n </nve-grid>\n <nve-tooltip anchor=\"target\" position=\"right\">My tooltip</nve-tooltip>\n `\n};\n\nclass RowSortDemo extends LitElement {\n @state() private sort: 'none' | 'ascending' | 'descending' = 'none';\n\n static styles = [unsafeCSS(layout)];\n\n get items() {\n if (this.sort === 'ascending') {\n return getItems().sort((a: { field1: { value: string } }, b: { field1: { value: string } }) => a.field1.value.localeCompare(b.field1.value));\n }\n\n if (this.sort === 'descending') {\n return getItems().sort((a: { field1: { value: string } }, b: { field1: { value: string } }) => a.field1.value.localeCompare(b.field1.value)).reverse();\n }\n\n return getItems();\n }\n\n render() {\n return html`\n <nve-grid>\n <nve-grid-header>\n ${Object.entries(this.items[0]).map(([, column], i) => html`\n <nve-grid-column>\n ${column.label} ${i === 0 ? html`<nve-sort-button .sort=${this.sort} @sort=${e => this.sort = e.detail.next}></nve-sort-button>` : nothing}\n </nve-grid-column>`)}\n </nve-grid-header>\n ${this.items.map(row => html`\n <nve-grid-row>\n ${Object.entries(row).map(([, cell]) => html`<nve-grid-cell>${cell.value}</nve-grid-cell> `)}\n </nve-grid-row>`)}\n </nve-grid>\n `\n }\n}\n\ncustomElements.get('row-sort-demo') || customElements.define('row-sort-demo', RowSortDemo);\n\n/**\n * @summary Row sort sorts the rows of the grid.\n * @tags test-case\n */\nexport const RowSortInteractive = {\n render: () => html`<row-sort-demo></row-sort-demo>`\n};\n\nclass InfiniteScrollDemo extends LitElement {\n static styles = [unsafeCSS(layout)];\n\n @state() private rows = this.#group(grid(10000).rows, 100);\n\n @state() private grid: { columns: { id: string; label: string; sort: string }[]; rows: Partial<{ id: string; cells: { id: string; label: string }[] }>[] } = grid(0, 4)\n\n render() {\n return html`\n <nve-grid style=\"height: 400px\" @scrollboxend=${() => this.#loadGroup()}>\n <nve-grid-header>\n ${this.grid.columns.map(column => html`<nve-grid-column>${column.label}</nve-grid-column>`)}\n </nve-grid-header>\n ${this.grid.rows.map(row => html`\n <nve-grid-row>\n ${row.cells.map(cell => html`<nve-grid-cell>${cell.label}</nve-grid-cell> `)}\n </nve-grid-row>`)}\n <nve-grid-footer>\n <p nve-text=\"body\">Items ${this.grid.rows.length} / 10000</p>\n </nve-grid-footer>\n </nve-grid>\n `\n }\n\n connectedCallback() {\n super.connectedCallback();\n this.#loadGroup();\n }\n\n #group(items: object[], size: number) {\n return [...Array(Math.ceil(items.length / size))].map((_, i) => items.slice(size * i, size + size * i));\n }\n\n #loadGroup() {\n const group = this.rows.splice(0, 1)[0];\n if (group) {\n this.grid = { ...this.grid, rows: [...this.grid.rows, ...group] };\n }\n }\n}\n\ncustomElements.get('infinite-scroll-demo') || customElements.define('infinite-scroll-demo', InfiniteScrollDemo);\n\n/**\n * @summary Infinite scroll loads data as the user scrolls down the grid.\n * @tags test-case performance\n */\nexport const PerformanceInfiniteScroll = {\n render: () => html`<infinite-scroll-demo></infinite-scroll-demo>`\n};\n\n/**\n * @summary Datagrid performance is heavily dependent on the content within the grid as well as the host environment.\n * @tags performance\n * @description When rendering large datasets, using the appropriate techniques to maintain good performance matters.\n * - Use pagination or lazy loading to reduce initial render time\n * - Use virtual scroll or batch rendering to improve render performance\n * - Use fixed width columns to improve render performance and reduce layout shift\n * - Avoid duplication of elements within cells, example reuse a single tooltip for all cells vs creating a new tooltip for each cell\n */\nexport const Performance = {\n render: () => html`\n <section id=\"grid-performance-demo\" nve-layout=\"column gap:md full\" style=\"height: 500px;\">\n <nve-button>show large grid</nve-button>\n <p nve-text=\"body muted\">1000 rows, 4000 cells</p>\n </section>\n <script type=\"module\">\n import '@nvidia-elements/core/grid/define.js';\n const section = document.getElementById('grid-performance-demo');\n const button = section.querySelector('nve-button');\n\n button.addEventListener('click', () => {\n const existingGrid = section.querySelector('nve-grid');\n if (existingGrid) {\n existingGrid.remove();\n } else {\n const grid = document.createElement('nve-grid');\n grid.style.setProperty('height', '400px');\n grid.style.setProperty('max-width', '1024px');\n\n const header = document.createElement('nve-grid-header');\n const columns = new Array(4).fill('').map((_, i) => {\n const column = document.createElement('nve-grid-column');\n column.setAttribute('width', '25%');\n column.textContent = 'Column ' + i;\n return column;\n });\n\n const rows = new Array(1000).fill('').map((_, i) => {\n const row = document.createElement('nve-grid-row');\n new Array(4).fill('').forEach((_, c) => {\n const cell = document.createElement('nve-grid-cell');\n cell.textContent = 'Cell ' + i + '-' + c;\n row.appendChild(cell);\n });\n return row;\n });\n\n header.append(...columns);\n grid.appendChild(header);\n grid.append(...rows);\n section.appendChild(grid);\n }\n });\n </script>\n `\n};\n\nclass GridVirtualScrollDemo extends LitElement {\n items = new Array(10000).fill('').map((_i, n) => ({ column: `${n}-0`, column1: `${n}-1`, column2: `${n}-2`, column3: `${n}-3` }));\n\n render() {\n return html`\n <nve-grid>\n <nve-grid-header>\n <nve-grid-column>column</nve-grid-column>\n <nve-grid-column>column</nve-grid-column>\n <nve-grid-column>column</nve-grid-column>\n <nve-grid-column>column</nve-grid-column>\n </nve-grid-header>\n\n <lit-virtualizer style=\"min-height: 350px\" scroller .items=${this.items} .renderItem=${i => html`\n <nve-grid-row style=\"width: 100%\">\n ${Object.keys(i).map(key => html`<nve-grid-cell>${i[key]}</nve-grid-cell>`)}\n </nve-grid-row>`}>\n </lit-virtualizer>\n </nve-grid>\n `;\n }\n}\n\ncustomElements.get('grid-virtual-scroll-demo') || customElements.define('grid-virtual-scroll-demo', GridVirtualScrollDemo);\n\n/**\n * @summary Performance virtual scroll tests the performance of the grid.\n * @tags test-case performance\n */\nexport const PerformanceVirtualScroll = {\n render: () => html`<grid-virtual-scroll-demo></grid-virtual-scroll-demo>`\n};\n\n/**\n * @summary Alternating row background colors for improved scanability. Use striped rows in dense grids or when users frequently scan horizontally across many columns, as the alternating backgrounds help maintain visual alignment and reduce reading errors in wide tables.\n * @tags test-case\n */\nexport const Stripe = {\n render: () => html`\n<nve-grid stripe>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Nest Grid in Cards for UI patterns such as card tab groups. Use\n * the `container=\"flat\"` attribute to enable proper styling of the grid when\n * nested within a card.\n */\nexport const Card = {\n render: () => html`\n<nve-card>\n <nve-card-header>\n <h2 nve-text=\"heading sm bold\">Data Grid</h2>\n <h3 nve-text=\"body muted\">Card Example</h3>\n </nve-card-header>\n <nve-grid container=\"flat\" style=\"height: 325px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(5).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n </nve-grid>\n</nve-card>\n `\n};\n\n/**\n * @summary Grid integrated with tabs for organized data presentation, enabling many data views within a single interface for comprehensive information display.\n * @tags test-case\n */\nexport const CardTabs = {\n render: () => html`\n<nve-card>\n <nve-card-header>\n <h2 nve-text=\"heading sm bold\">Data Grid</h2>\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>\n </nve-card-header>\n <nve-grid container=\"flat\" style=\"height: 325px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n </nve-grid>\n</nve-card>\n `\n};\n\n/**\n * @summary Loading placeholder state with progress indicator. Use grid placeholders during initial data fetching or while loading large datasets, providing visual feedback that content is coming and preventing layout shift when rows populate, improving perceived performance.\n */\nexport const Placeholder = {\n render: () => html`\n<nve-grid style=\"min-height: 400px\">\n <nve-grid-header>\n <nve-grid-column></nve-grid-column>\n </nve-grid-header>\n <nve-grid-placeholder>\n <nve-progress-ring status=\"accent\" size=\"lg\"></nve-progress-ring>\n </nve-grid-placeholder>\n</nve-grid>\n `\n};\n\n/**\n * @summary Full-width grid container for max space use, providing edge-to-edge data display for comprehensive information presentation.\n */\nexport const Full = {\n render: () => html`\n<nve-grid container=\"full\" style=\"height: 400px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Flat container styling for minimal visual weight, providing subtle grid presentation that integrates seamlessly with surrounding content.\n */\nexport const Flat = {\n render: () => html`\n<nve-grid container=\"flat\" style=\"height: 400px\">\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(20).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Different focusable element types within grid cells, with keyboard navigation and accessibility support for interactive content.\n * @tags test-case\n */\nexport const FocusTypes = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n <nve-grid-column>span</nve-grid-column>\n <nve-grid-column>button</nve-grid-column>\n <nve-grid-column>2x buttons</nve-grid-column>\n <nve-grid-column>input</nve-grid-column>\n </nve-grid-header>\n <nve-grid-row>\n <nve-grid-cell>\n <span>span</span>\n </nve-grid-cell>\n <nve-grid-cell>\n <button>button</button>\n </nve-grid-cell>\n <nve-grid-cell>\n <button>button</button>\n <button>button</button>\n </nve-grid-cell>\n <nve-grid-cell>\n <input />\n </nve-grid-cell>\n </nve-grid-row>\n</nve-grid>\n `\n};\n\n/**\n * @summary Use a nve-page-panel when displaying advanced filtering or display\n * settings for the grid. Item detail panels should be open using a action\n * button placed at the end of the grid row.\n */\nexport const PanelDetail = {\n render: () => html`\n<nve-page id=\"grid-panel-demo\">\n <nve-page-header slot=\"header\">\n <nve-logo slot=\"prefix\" size=\"sm\" color=\"brand-green\">NV</nve-logo>\n <h2 nve-text=\"heading\" slot=\"prefix\">Infrastructure</h2>\n </nve-page-header>\n <section nve-layout=\"column gap:md pad:md full\">\n <nve-grid>\n <nve-grid-header>\n ${Array(3).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column> `)}\n <nve-grid-column width=\"max-content\" aria-label=\"details\"></nve-grid-column>\n </nve-grid-header>\n ${Array(10).fill('').map((_, i) => html`\n <nve-grid-row ?selected=${i === 1}>\n ${Array(3).fill('').map((_, c) => html`<nve-grid-cell>cell ${i}-${c}</nve-grid-cell> `)}\n <nve-grid-cell>\n <nve-icon-button container=\"flat\" icon-name=\"expand-details\" value=${i} aria-label=\"view ${i}\"></nve-icon-button>\n </nve-grid-cell>\n </nve-grid-row>\n `)}\n </nve-grid>\n </section>\n <nve-page-panel slot=\"right\" size=\"sm\" expanded closable>\n <nve-page-panel-header>\n <h3 nve-text=\"heading medium sm\">Row 2 Details</h3>\n </nve-page-panel-header>\n <nve-page-panel-content>\n <div nve-layout=\"column gap:md\">\n <div nve-layout=\"column gap:xs\">\n <label nve-text=\"body sm muted\">Task</label>\n <p nve-text=\"label sm\">Workflow</p>\n </div>\n <div nve-layout=\"column gap:xs\">\n <label nve-text=\"body sm muted\">Status</label>\n <nve-badge status=\"success\">Complete</nve-badge>\n </div>\n <div nve-layout=\"column gap:xs\">\n <label nve-text=\"body sm muted\">Priority</label>\n <nve-badge status=\"pending\">P1</nve-badge>\n </div>\n </div>\n </nve-page-panel-content>\n </nve-page-panel>\n</nve-page>\n<script type=\"module\">\n const page = document.getElementById('grid-panel-demo');\n const grid = page.querySelector('nve-grid');\n const panel = page.querySelector('nve-page-panel');\n const rows = grid.querySelectorAll('nve-grid-row');\n const heading = page.querySelector('nve-page-panel-header h3');\n\n panel.addEventListener('close', () => {\n rows.forEach(row => row.selected = false);\n panel.hidden = true;\n });\n\n grid.addEventListener('click', (e) => {\n if (e.target.localName === 'nve-icon-button') {\n const row = e.target.closest('nve-grid-row');\n rows.forEach(row => row.selected = false);\n panel.hidden = false;\n heading.textContent = 'Row ' + e.target.value + ' Details';\n row.selected = !panel.hidden;\n }\n });\n</script>\n `\n};\n\n/**\n * @summary Panel Grid displays key value type data sets for details of a\n * given item in a collection.\n */\nexport const PanelGrid = {\n render() {\n return html`\n <nve-page>\n <nve-page-header slot=\"header\">\n <nve-logo slot=\"prefix\" size=\"sm\" color=\"brand-green\">NV</nve-logo>\n <h2 nve-text=\"heading\" slot=\"prefix\">Infrastructure</h2>\n </nve-page-header>\n <section nve-layout=\"column gap:md pad:md full\">\n page content\n </section>\n <nve-page-panel slot=\"right\" expanded closable>\n <nve-page-panel-header>\n <h3 nve-text=\"heading medium sm\">Recording</h3>\n </nve-page-panel-header>\n <nve-grid container=\"flat\" stripe>\n <nve-grid-header>\n <nve-grid-column style=\"height: 0; overflow: hidden;\">Key</nve-grid-column>\n <nve-grid-column style=\"height: 0; overflow: hidden;\">Value</nve-grid-column>\n </nve-grid-header>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Session ID</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">123456</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Record Date</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">2023-09-04 11:00</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Tag</p></nve-grid-cell>\n <nve-grid-cell><nve-tag readonly>Production</nve-tag></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Route ID</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">9876123</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Configuration</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">prod-0.1.0</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Duration</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">1:23:34</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Description</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">local test run</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Number of Sensors</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">24</p></nve-grid-cell>\n </nve-grid-row>\n </nve-grid>\n </nve-page-panel>\n </nve-page>\n `;\n }\n}\n\n/**\n * @summary Examples of invalid grid usage patterns for testing and documentation purposes, showing what not to do when implementing grids.\n * @tags anti-pattern\n */\nexport const InvalidDOM = {\n render: () => html`\n<nve-grid>\n <nve-grid-header>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n <div>invalid</div>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(r === 9 ? 4 : 5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n <span>invalid</span>\n</nve-grid>\n `\n};\n\n/**\n * @summary Examples of invalid grid usage patterns for testing and documentation purposes, showing what not to do when implementing grids.\n * @tags anti-pattern\n */\nexport const Audit = {\n render: () => html`\n<nve-grid style=\"height: 450px\">\n <div hidden></div>\n <nve-grid-header>\n <div hidden></div>\n ${Array(5).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(10).fill('').map((_, r) => html`\n <nve-grid-row>\n <div hidden></div>\n ${Array(5).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Do not set the column count to a value that does not match the number of cells in the row.\n * @tags anti-pattern\n */\nexport const InvalidColumnCount = {\n render: () => html`\n<nve-grid>\n <div hidden></div>\n <nve-grid-header>\n <div hidden></div>\n ${Array(4).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(4).fill('').map((_, r) => html`\n <div>\n <nve-grid-row>\n ${Array(3).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n </div>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Ensure column count matches the number of cells in the row to preserve keyboard navigation.\n * @tags test-case\n */\nexport const ValidColumnCount = {\n render: () => html`\n<nve-grid>\n <div hidden></div>\n <nve-grid-header>\n ${Array(4).fill('').map((_, i) => html`<nve-grid-column>column ${i}</nve-grid-column>`)}\n </nve-grid-header>\n ${Array(4).fill('').map((_, r) => html`\n <nve-grid-row>\n ${Array(4).fill('').map((_, c) => html`<nve-grid-cell>cell ${r}-${c}</nve-grid-cell>`)}\n </nve-grid-row>\n `)}\n</nve-grid>\n `\n};\n\n/**\n * @summary Use the `nve-sort-button` to add grid row sort.\n * The grid follows the ARIA sort spec and automatically sets the appropriate\n * accessibility related attributes to convey the current sorting state.\n */\nexport const SortVisibility = {\n render: () => html `\n<nve-grid>\n <nve-grid-header>\n <nve-grid-column>\n Column 1 <nve-sort-button sort=\"none\"></nve-sort-button>\n </nve-grid-column>\n <nve-grid-column>\n Column 2 <nve-sort-button sort=\"ascending\"></nve-sort-button>\n </nve-grid-column>\n <nve-grid-column>\n Column 3 <nve-sort-button sort=\"descending\"></nve-sort-button>\n </nve-grid-column>\n <nve-grid-column>Column 4</nve-grid-column>\n </nve-grid-header>\n <nve-grid-row>\n <nve-grid-cell>cell 1-1</nve-grid-cell>\n <nve-grid-cell>cell 1-2</nve-grid-cell>\n <nve-grid-cell>cell 1-3</nve-grid-cell>\n <nve-grid-cell>cell 1-4</nve-grid-cell>\n </nve-grid-row>\n</nve-grid>`\n}\n"],"mappings":";AAGA,IAAA,IAAS"}
|
|
@@ -359,7 +359,7 @@
|
|
|
359
359
|
{
|
|
360
360
|
"id": "core-grid_panel-detail",
|
|
361
361
|
"name": "PanelDetail",
|
|
362
|
-
"template": "<nve-page id=\"grid-panel-demo\">\n <nve-page-header slot=\"header\">\n <nve-logo slot=\"prefix\" size=\"sm\"
|
|
362
|
+
"template": "<nve-page id=\"grid-panel-demo\">\n <nve-page-header slot=\"header\">\n <nve-logo slot=\"prefix\" size=\"sm\" color=\"brand-green\">NV</nve-logo>\n <h2 nve-text=\"heading\" slot=\"prefix\">Infrastructure</h2>\n </nve-page-header>\n <section nve-layout=\"column gap:md pad:md full\">\n <nve-grid>\n <nve-grid-header>\n <nve-grid-column>column 0</nve-grid-column> <nve-grid-column>column 1</nve-grid-column>\n <nve-grid-column>column 2</nve-grid-column>\n <nve-grid-column width=\"max-content\" aria-label=\"details\"></nve-grid-column>\n </nve-grid-header>\n\n <nve-grid-row>\n <nve-grid-cell>cell 0-0</nve-grid-cell> <nve-grid-cell>cell 0-1</nve-grid-cell>\n <nve-grid-cell>cell 0-2</nve-grid-cell>\n <nve-grid-cell>\n <nve-icon-button container=\"flat\" icon-name=\"expand-details\" value=\"0\" aria-label=\"view 0\"></nve-icon-button>\n </nve-grid-cell>\n </nve-grid-row>\n\n <nve-grid-row selected>\n <nve-grid-cell>cell 1-0</nve-grid-cell> <nve-grid-cell>cell 1-1</nve-grid-cell>\n <nve-grid-cell>cell 1-2</nve-grid-cell>\n <nve-grid-cell>\n <nve-icon-button container=\"flat\" icon-name=\"expand-details\" value=\"1\" aria-label=\"view 1\"></nve-icon-button>\n </nve-grid-cell>\n </nve-grid-row>\n\n <nve-grid-row>\n <nve-grid-cell>cell 2-0</nve-grid-cell> <nve-grid-cell>cell 2-1</nve-grid-cell>\n <nve-grid-cell>cell 2-2</nve-grid-cell>\n <nve-grid-cell>\n <nve-icon-button container=\"flat\" icon-name=\"expand-details\" value=\"2\" aria-label=\"view 2\"></nve-icon-button>\n </nve-grid-cell>\n </nve-grid-row>\n\n <nve-grid-row>\n <nve-grid-cell>cell 3-0</nve-grid-cell> <nve-grid-cell>cell 3-1</nve-grid-cell>\n <nve-grid-cell>cell 3-2</nve-grid-cell>\n <nve-grid-cell>\n <nve-icon-button container=\"flat\" icon-name=\"expand-details\" value=\"3\" aria-label=\"view 3\"></nve-icon-button>\n </nve-grid-cell>\n </nve-grid-row>\n\n <nve-grid-row>\n <nve-grid-cell>cell 4-0</nve-grid-cell> <nve-grid-cell>cell 4-1</nve-grid-cell>\n <nve-grid-cell>cell 4-2</nve-grid-cell>\n <nve-grid-cell>\n <nve-icon-button container=\"flat\" icon-name=\"expand-details\" value=\"4\" aria-label=\"view 4\"></nve-icon-button>\n </nve-grid-cell>\n </nve-grid-row>\n\n <nve-grid-row>\n <nve-grid-cell>cell 5-0</nve-grid-cell> <nve-grid-cell>cell 5-1</nve-grid-cell>\n <nve-grid-cell>cell 5-2</nve-grid-cell>\n <nve-grid-cell>\n <nve-icon-button container=\"flat\" icon-name=\"expand-details\" value=\"5\" aria-label=\"view 5\"></nve-icon-button>\n </nve-grid-cell>\n </nve-grid-row>\n\n <nve-grid-row>\n <nve-grid-cell>cell 6-0</nve-grid-cell> <nve-grid-cell>cell 6-1</nve-grid-cell>\n <nve-grid-cell>cell 6-2</nve-grid-cell>\n <nve-grid-cell>\n <nve-icon-button container=\"flat\" icon-name=\"expand-details\" value=\"6\" aria-label=\"view 6\"></nve-icon-button>\n </nve-grid-cell>\n </nve-grid-row>\n\n <nve-grid-row>\n <nve-grid-cell>cell 7-0</nve-grid-cell> <nve-grid-cell>cell 7-1</nve-grid-cell>\n <nve-grid-cell>cell 7-2</nve-grid-cell>\n <nve-grid-cell>\n <nve-icon-button container=\"flat\" icon-name=\"expand-details\" value=\"7\" aria-label=\"view 7\"></nve-icon-button>\n </nve-grid-cell>\n </nve-grid-row>\n\n <nve-grid-row>\n <nve-grid-cell>cell 8-0</nve-grid-cell> <nve-grid-cell>cell 8-1</nve-grid-cell>\n <nve-grid-cell>cell 8-2</nve-grid-cell>\n <nve-grid-cell>\n <nve-icon-button container=\"flat\" icon-name=\"expand-details\" value=\"8\" aria-label=\"view 8\"></nve-icon-button>\n </nve-grid-cell>\n </nve-grid-row>\n\n <nve-grid-row>\n <nve-grid-cell>cell 9-0</nve-grid-cell> <nve-grid-cell>cell 9-1</nve-grid-cell>\n <nve-grid-cell>cell 9-2</nve-grid-cell>\n <nve-grid-cell>\n <nve-icon-button container=\"flat\" icon-name=\"expand-details\" value=\"9\" aria-label=\"view 9\"></nve-icon-button>\n </nve-grid-cell>\n </nve-grid-row>\n </nve-grid>\n </section>\n <nve-page-panel slot=\"right\" size=\"sm\" expanded closable>\n <nve-page-panel-header>\n <h3 nve-text=\"heading medium sm\">Row 2 Details</h3>\n </nve-page-panel-header>\n <nve-page-panel-content>\n <div nve-layout=\"column gap:md\">\n <div nve-layout=\"column gap:xs\">\n <label nve-text=\"body sm muted\">Task</label>\n <p nve-text=\"label sm\">Workflow</p>\n </div>\n <div nve-layout=\"column gap:xs\">\n <label nve-text=\"body sm muted\">Status</label>\n <nve-badge status=\"success\">Complete</nve-badge>\n </div>\n <div nve-layout=\"column gap:xs\">\n <label nve-text=\"body sm muted\">Priority</label>\n <nve-badge status=\"pending\">P1</nve-badge>\n </div>\n </div>\n </nve-page-panel-content>\n </nve-page-panel>\n</nve-page>\n<script type=\"module\">\n const page = document.getElementById(\"grid-panel-demo\");\n const grid = page.querySelector(\"nve-grid\");\n const panel = page.querySelector(\"nve-page-panel\");\n const rows = grid.querySelectorAll(\"nve-grid-row\");\n const heading = page.querySelector(\"nve-page-panel-header h3\");\n panel.addEventListener(\"close\", () => {\n rows.forEach((row) => (row.selected = false));\n panel.hidden = true;\n });\n grid.addEventListener(\"click\", (e) => {\n if (e.target.localName === \"nve-icon-button\") {\n const row = e.target.closest(\"nve-grid-row\");\n rows.forEach((row) => (row.selected = false));\n panel.hidden = false;\n heading.textContent = \"Row \" + e.target.value + \" Details\";\n row.selected = !panel.hidden;\n }\n });\n</script>\n",
|
|
363
363
|
"summary": "Use a nve-page-panel when displaying advanced filtering or display settings for the grid. Item detail panels should be open using a action button placed at the end of the grid row.",
|
|
364
364
|
"description": "",
|
|
365
365
|
"composition": true,
|
|
@@ -368,7 +368,7 @@
|
|
|
368
368
|
{
|
|
369
369
|
"id": "core-grid_panel-grid",
|
|
370
370
|
"name": "PanelGrid",
|
|
371
|
-
"template": "<nve-page>\n <nve-page-header slot=\"header\">\n <nve-logo slot=\"prefix\" size=\"sm\"
|
|
371
|
+
"template": "<nve-page>\n <nve-page-header slot=\"header\">\n <nve-logo slot=\"prefix\" size=\"sm\" color=\"brand-green\">NV</nve-logo>\n <h2 nve-text=\"heading\" slot=\"prefix\">Infrastructure</h2>\n </nve-page-header>\n <section nve-layout=\"column gap:md pad:md full\">page content</section>\n <nve-page-panel slot=\"right\" expanded closable>\n <nve-page-panel-header>\n <h3 nve-text=\"heading medium sm\">Recording</h3>\n </nve-page-panel-header>\n <nve-grid container=\"flat\" stripe>\n <nve-grid-header>\n <nve-grid-column style=\"height: 0; overflow: hidden\">Key</nve-grid-column>\n <nve-grid-column style=\"height: 0; overflow: hidden\">Value</nve-grid-column>\n </nve-grid-header>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Session ID</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">123456</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Record Date</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">2023-09-04 11:00</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Tag</p></nve-grid-cell>\n <nve-grid-cell><nve-tag readonly>Production</nve-tag></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Route ID</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">9876123</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Configuration</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">prod-0.1.0</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Duration</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">1:23:34</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Description</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">local test run</p></nve-grid-cell>\n </nve-grid-row>\n <nve-grid-row>\n <nve-grid-cell><p nve-text=\"label muted\">Number of Sensors</p></nve-grid-cell>\n <nve-grid-cell><p nve-text=\"label\">24</p></nve-grid-cell>\n </nve-grid-row>\n </nve-grid>\n </nve-page-panel>\n</nve-page>\n",
|
|
372
372
|
"summary": "Panel Grid displays key value type data sets for details of a given item in a collection.",
|
|
373
373
|
"description": "",
|
|
374
374
|
"composition": true,
|
package/dist/grid/grid2.js
CHANGED
package/dist/grid/row/row2.js
CHANGED
package/dist/icon/icon2.js
CHANGED
|
@@ -16,7 +16,7 @@ var f = class e extends o {
|
|
|
16
16
|
static {
|
|
17
17
|
this.metadata = {
|
|
18
18
|
tag: "nve-icon",
|
|
19
|
-
version: "0.0.
|
|
19
|
+
version: "0.0.10"
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
static {
|
|
@@ -86,7 +86,7 @@ n([l({
|
|
|
86
86
|
})], f.prototype, "name", void 0), n([d()], f.prototype, "svg", void 0);
|
|
87
87
|
function p(t) {
|
|
88
88
|
if (typeof globalThis.customElements?.get == "function") {
|
|
89
|
-
let n = e(t.metadata.version), r = e("0.0.
|
|
89
|
+
let n = e(t.metadata.version), r = e("0.0.10");
|
|
90
90
|
n.minor <= r.minor && n.major <= r.major && (t._icons = {
|
|
91
91
|
...t._icons,
|
|
92
92
|
...i
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
//#region src/icon/icons/stop.svg?raw
|
|
2
|
+
var e = "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 16 16\"><rect width=\"14\" height=\"14\" fill=\"currentColor\" rx=\"1\" transform=\"matrix(-1 0 0 1 15 1)\"/></svg>";
|
|
3
|
+
//#endregion
|
|
4
|
+
export { e as default };
|
|
5
|
+
|
|
6
|
+
//# sourceMappingURL=stop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.js","names":[],"sources":["../../../src/icon/icons/stop.svg?raw"],"sourcesContent":["export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" fill=\\\"none\\\" viewBox=\\\"0 0 16 16\\\"><rect width=\\\"14\\\" height=\\\"14\\\" fill=\\\"currentColor\\\" rx=\\\"1\\\" transform=\\\"matrix(-1 0 0 1 15 1)\\\"/></svg>\""],"mappings":";AAAA,IAAA,IAAe"}
|
package/dist/icon/icons.d.ts
CHANGED
package/dist/icon/icons.js
CHANGED
|
@@ -245,6 +245,7 @@ var t = {
|
|
|
245
245
|
start: e(() => import("./icons/start.js")),
|
|
246
246
|
"status-offline": e(() => import("./icons/status-offline.js")),
|
|
247
247
|
"status-online": e(() => import("./icons/status-online.js")),
|
|
248
|
+
stop: e(() => import("./icons/stop.js")),
|
|
248
249
|
"stop-sign": e(() => import("./icons/stop-sign.js")),
|
|
249
250
|
stopwatch: e(() => import("./icons/stopwatch.js")),
|
|
250
251
|
strikethrough: e(() => import("./icons/strikethrough.js")),
|