|
6 | 6 | <meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
7 | 7 | <title>Grid</title>
|
8 | 8 | <script type="module" src="./common.js"></script>
|
| 9 | + <style> |
| 10 | + body { |
| 11 | + font-family: var(--lumo-font-family); |
| 12 | + padding: 20px; |
| 13 | + } |
| 14 | + |
| 15 | + h2 { |
| 16 | + margin-top: 40px; |
| 17 | + margin-bottom: 20px; |
| 18 | + color: var(--lumo-header-text-color); |
| 19 | + } |
| 20 | + |
| 21 | + vaadin-grid { |
| 22 | + margin-bottom: 40px; |
| 23 | + height: 400px; |
| 24 | + } |
| 25 | + |
| 26 | + /* Header and footer slot styles */ |
| 27 | + [part="header"] { |
| 28 | + background: var(--lumo-contrast-5pct); |
| 29 | + border-bottom: 1px solid var(--lumo-contrast-10pct); |
| 30 | + padding: var(--lumo-space-s) var(--lumo-space-m); |
| 31 | + gap: var(--lumo-space-m); |
| 32 | + } |
| 33 | + |
| 34 | + [part="footer"] { |
| 35 | + background: var(--lumo-contrast-5pct); |
| 36 | + border-top: 1px solid var(--lumo-contrast-10pct); |
| 37 | + padding: var(--lumo-space-xs) var(--lumo-space-m); |
| 38 | + font-size: var(--lumo-font-size-s); |
| 39 | + color: var(--lumo-secondary-text-color); |
| 40 | + gap: var(--lumo-space-s); |
| 41 | + } |
| 42 | + |
| 43 | + .flex-grow { |
| 44 | + flex: 1; |
| 45 | + } |
| 46 | + </style> |
9 | 47 | </head>
|
10 | 48 | <body>
|
| 49 | + <h1>Grid Examples</h1> |
11 | 50 | <script type="module">
|
12 | 51 | import '@vaadin/grid/all-imports';
|
13 | 52 | import '@vaadin/tooltip';
|
| 53 | + import '@vaadin/button'; |
| 54 | + import '@vaadin/text-field'; |
| 55 | + import '@vaadin/icon'; |
| 56 | + import '@vaadin/icons'; |
| 57 | + </script> |
| 58 | + |
| 59 | + <h2>Grid with Header and Footer Slots (Flex Layout)</h2> |
| 60 | + <vaadin-grid id="header-footer-grid"> |
| 61 | + <!-- Multiple elements directly in header slot using flex layout --> |
| 62 | + <vaadin-icon slot="header" icon="vaadin:grid-h" style="color: var(--lumo-primary-color);"></vaadin-icon> |
| 63 | + <strong slot="header">User Management</strong> |
| 64 | + <span slot="header" class="flex-grow"></span> |
| 65 | + <vaadin-text-field slot="header" placeholder="Search users..." clear-button-visible style="width: 250px;"> |
| 66 | + <vaadin-icon slot="prefix" icon="vaadin:search"></vaadin-icon> |
| 67 | + </vaadin-text-field> |
| 68 | + <vaadin-button slot="header" theme="primary"> |
| 69 | + <vaadin-icon icon="vaadin:plus" slot="prefix"></vaadin-icon> |
| 70 | + Add User |
| 71 | + </vaadin-button> |
| 72 | + |
| 73 | + <vaadin-grid-selection-column></vaadin-grid-selection-column> |
| 74 | + <vaadin-grid-column path="name" header="Name"></vaadin-grid-column> |
| 75 | + <vaadin-grid-column path="email" header="Email"></vaadin-grid-column> |
| 76 | + <vaadin-grid-column path="role" header="Role"></vaadin-grid-column> |
| 77 | + <vaadin-grid-column path="status" header="Status"></vaadin-grid-column> |
| 78 | + |
| 79 | + <!-- Multiple elements in footer --> |
| 80 | + <span slot="footer">Total: <strong id="user-count">0</strong> users</span> |
| 81 | + <span slot="footer" class="flex-grow"></span> |
| 82 | + <span slot="footer">Selected: <strong id="selected-count">0</strong></span> |
| 83 | + <span slot="footer" style="margin-left: var(--lumo-space-xl);">Last updated: <span id="update-time">Never</span></span> |
| 84 | + </vaadin-grid> |
| 85 | + |
| 86 | + <h2>Grid with Toolbar Actions</h2> |
| 87 | + <vaadin-grid id="toolbar-grid"> |
| 88 | + <!-- Header with title and actions --> |
| 89 | + <h3 slot="header" style="margin: 0;">Products</h3> |
| 90 | + <div slot="header" style="margin-left: auto; display: flex; gap: var(--lumo-space-s);"> |
| 91 | + <vaadin-button theme="tertiary"> |
| 92 | + <vaadin-icon icon="vaadin:download" slot="prefix"></vaadin-icon> |
| 93 | + Export |
| 94 | + </vaadin-button> |
| 95 | + <vaadin-button theme="tertiary"> |
| 96 | + <vaadin-icon icon="vaadin:upload" slot="prefix"></vaadin-icon> |
| 97 | + Import |
| 98 | + </vaadin-button> |
| 99 | + <vaadin-button theme="error tertiary"> |
| 100 | + <vaadin-icon icon="vaadin:trash" slot="prefix"></vaadin-icon> |
| 101 | + Delete |
| 102 | + </vaadin-button> |
| 103 | + </div> |
| 104 | + |
| 105 | + <vaadin-grid-selection-column></vaadin-grid-selection-column> |
| 106 | + <vaadin-grid-filter-column path="product" header="Product"></vaadin-grid-filter-column> |
| 107 | + <vaadin-grid-filter-column path="category" header="Category"></vaadin-grid-filter-column> |
| 108 | + <vaadin-grid-column path="price" header="Price"></vaadin-grid-column> |
| 109 | + <vaadin-grid-column path="stock" header="Stock"></vaadin-grid-column> |
| 110 | + |
| 111 | + <!-- Footer with status indicator --> |
| 112 | + <span slot="footer" style="display: flex; align-items: center; gap: var(--lumo-space-xs);"> |
| 113 | + <span style="width: 8px; height: 8px; background: var(--lumo-success-color); border-radius: 50%;"></span> |
| 114 | + All systems operational |
| 115 | + </span> |
| 116 | + <span slot="footer" style="margin-left: auto;"> |
| 117 | + Showing <strong id="product-count">0</strong> of <strong id="product-total">0</strong> products |
| 118 | + </span> |
| 119 | + </vaadin-grid> |
| 120 | + |
| 121 | + <h2>Original Tree Grid Example</h2> |
| 122 | + <vaadin-grid id="tree-grid" item-id-path="name"> |
| 123 | + <vaadin-grid-selection-column auto-select frozen drag-select></vaadin-grid-selection-column> |
| 124 | + <vaadin-grid-tree-column frozen path="name" width="200px" flex-shrink="0"></vaadin-grid-tree-column> |
| 125 | + <vaadin-grid-column path="name" width="200px" flex-shrink="0"></vaadin-grid-column> |
| 126 | + <vaadin-grid-column path="name" width="200px" flex-shrink="0"></vaadin-grid-column> |
| 127 | + <vaadin-grid-column path="name" width="200px" flex-shrink="0"></vaadin-grid-column> |
14 | 128 |
|
15 |
| - const grid = document.querySelector('vaadin-grid'); |
| 129 | + <vaadin-tooltip slot="tooltip" hover-delay="500" hide-delay="500"></vaadin-tooltip> |
| 130 | + </vaadin-grid> |
16 | 131 |
|
17 |
| - grid.dataProvider = ({ parentItem, page, pageSize }, cb) => { |
| 132 | + <script type="module"> |
| 133 | + // Sample data for header-footer grid |
| 134 | + const users = [ |
| 135 | + { name: 'John Smith', email: '[email protected]', role: 'Administrator', status: 'Active' }, |
| 136 | + { name: 'Jane Doe', email: '[email protected]', role: 'Editor', status: 'Active' }, |
| 137 | + { name: 'Bob Johnson', email: '[email protected]', role: 'Viewer', status: 'Inactive' }, |
| 138 | + { name: 'Alice Williams', email: '[email protected]', role: 'Editor', status: 'Active' }, |
| 139 | + { name: 'Charlie Brown', email: '[email protected]', role: 'Viewer', status: 'Active' }, |
| 140 | + { name: 'Diana Prince', email: '[email protected]', role: 'Administrator', status: 'Active' }, |
| 141 | + { name: 'Edward Norton', email: '[email protected]', role: 'Editor', status: 'Active' }, |
| 142 | + { name: 'Fiona Green', email: '[email protected]', role: 'Viewer', status: 'Inactive' }, |
| 143 | + ]; |
| 144 | + |
| 145 | + const headerFooterGrid = document.querySelector('#header-footer-grid'); |
| 146 | + headerFooterGrid.items = users; |
| 147 | + document.querySelector('#user-count').textContent = users.length; |
| 148 | + document.querySelector('#update-time').textContent = new Date().toLocaleTimeString(); |
| 149 | + |
| 150 | + // Update selected count |
| 151 | + headerFooterGrid.addEventListener('selected-items-changed', (e) => { |
| 152 | + document.querySelector('#selected-count').textContent = e.detail.value.length; |
| 153 | + }); |
| 154 | + |
| 155 | + // Handle search |
| 156 | + const searchField = headerFooterGrid.querySelector('vaadin-text-field[slot="header"]'); |
| 157 | + searchField.addEventListener('value-changed', (e) => { |
| 158 | + const searchTerm = e.detail.value.toLowerCase(); |
| 159 | + if (searchTerm) { |
| 160 | + headerFooterGrid.items = users.filter( |
| 161 | + (user) => |
| 162 | + user.name.toLowerCase().includes(searchTerm) || |
| 163 | + user.email.toLowerCase().includes(searchTerm) || |
| 164 | + user.role.toLowerCase().includes(searchTerm), |
| 165 | + ); |
| 166 | + } else { |
| 167 | + headerFooterGrid.items = users; |
| 168 | + } |
| 169 | + document.querySelector('#user-count').textContent = headerFooterGrid.items.length; |
| 170 | + }); |
| 171 | + |
| 172 | + // Sample data for toolbar grid |
| 173 | + const products = [ |
| 174 | + { product: 'Laptop Pro', category: 'Electronics', price: '$1,299', stock: 45 }, |
| 175 | + { product: 'Wireless Mouse', category: 'Accessories', price: '$29', stock: 120 }, |
| 176 | + { product: 'USB-C Cable', category: 'Accessories', price: '$19', stock: 200 }, |
| 177 | + { product: 'Monitor 27"', category: 'Electronics', price: '$399', stock: 30 }, |
| 178 | + { product: 'Keyboard Mechanical', category: 'Accessories', price: '$79', stock: 85 }, |
| 179 | + { product: 'Webcam HD', category: 'Electronics', price: '$99', stock: 60 }, |
| 180 | + { product: 'Desk Lamp LED', category: 'Office', price: '$49', stock: 95 }, |
| 181 | + { product: 'Office Chair', category: 'Furniture', price: '$299', stock: 25 }, |
| 182 | + { product: 'Standing Desk', category: 'Furniture', price: '$599', stock: 15 }, |
| 183 | + { product: 'Headphones', category: 'Electronics', price: '$149', stock: 70 }, |
| 184 | + ]; |
| 185 | + |
| 186 | + const toolbarGrid = document.querySelector('#toolbar-grid'); |
| 187 | + toolbarGrid.items = products; |
| 188 | + document.querySelector('#product-count').textContent = products.length; |
| 189 | + document.querySelector('#product-total').textContent = products.length; |
| 190 | + |
| 191 | + // Original tree grid setup |
| 192 | + const treeGrid = document.querySelector('#tree-grid'); |
| 193 | + treeGrid.dataProvider = ({ parentItem, page, pageSize }, cb) => { |
18 | 194 | // Let's have 100 root-level items and 5 items on every child level
|
19 | 195 | const levelSize = parentItem ? 5 : 100;
|
20 | 196 |
|
|
30 | 206 | cb(pageItems, levelSize);
|
31 | 207 | };
|
32 | 208 |
|
33 |
| - const tooltip = document.querySelector('[slot="tooltip"]'); |
| 209 | + const tooltip = treeGrid.querySelector('[slot="tooltip"]'); |
34 | 210 | tooltip.generator = ({ column, item }) => {
|
35 | 211 | return column && column.path && item ? `Tooltip ${column.path} ${item.name}` : '';
|
36 | 212 | };
|
37 | 213 | </script>
|
38 |
| - |
39 |
| - <vaadin-grid item-id-path="name"> |
40 |
| - <vaadin-grid-selection-column auto-select frozen drag-select></vaadin-grid-selection-column> |
41 |
| - <vaadin-grid-tree-column frozen path="name" width="200px" flex-shrink="0"></vaadin-grid-tree-column> |
42 |
| - <vaadin-grid-column path="name" width="200px" flex-shrink="0"></vaadin-grid-column> |
43 |
| - <vaadin-grid-column path="name" width="200px" flex-shrink="0"></vaadin-grid-column> |
44 |
| - <vaadin-grid-column path="name" width="200px" flex-shrink="0"></vaadin-grid-column> |
45 |
| - |
46 |
| - <vaadin-tooltip slot="tooltip" hover-delay="500" hide-delay="500"></vaadin-tooltip> |
47 |
| - </vaadin-grid> |
48 | 214 | </body>
|
49 | 215 | </html>
|
0 commit comments