@prioticket/design-system-web 1.2.0 → 1.3.0-beta.2

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.
@@ -0,0 +1,559 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("lit"),l=require("lit/decorators.js"),u=require("lit/directives/repeat.js"),g=require("lit/directives/class-map.js");require("./pd-icon.cjs.js");require("./pd-checkbox.cjs.js");require("./pd-text-field.cjs.js");require("./pd-icon-button.cjs.js");require("./pd-select.cjs.js");require("./pd-menu-item.cjs.js");var b=Object.defineProperty,m=Object.getOwnPropertyDescriptor,d=(p,e,t,a)=>{for(var r=a>1?void 0:a?m(e,t):e,n=p.length-1,i;n>=0;n--)(i=p[n])&&(r=(a?i(e,t,r):i(r))||r);return a&&r&&b(e,t,r),r};exports.PdTable=class extends o.LitElement{constructor(){super(...arguments),this.columns=[],this.data=[],this.rowKey=(e,t)=>{const a=e.id;return a!=null?String(a):`__idx_${t}`},this.selectable=!1,this.sortable=!1,this.pagination=!1,this.pageSize=10,this.pageIndex=0,this.totalItems=0,this.draggableRows=!1,this.draggableColumns=!1,this.loading=!1,this.clearSelectionOnDataChange=!1,this.currencyCode="EUR",this.pageSizeOptions=[5,10,25,50,100],this._sortColumn=null,this._sortDirection="asc",this._selectedRowKeys=new Set,this._draggedRowIndex=null,this._dragOverRowIndex=null,this._isDragHandleGrabbed=!1,this._draggedColumnIndex=null,this._dragOverColumnIndex=null,this._displayDataCache=[],this._displayDataCacheKey="",this._uniqueId=Math.random().toString(36).substring(2,9)}get _isServerSidePagination(){return this.totalItems>0}get _totalCount(){return this._isServerSidePagination?this.totalItems:this.data.length}get _totalPages(){return Math.ceil(this._totalCount/this.pageSize)}get _displayData(){const e=this._computeCacheKey();if(e===this._displayDataCacheKey)return this._displayDataCache;let t=[...this.data];if(this.sortable&&this._sortColumn&&(t=this._sortData(t)),this.pagination&&!this._isServerSidePagination&&this.data.length>this.pageSize){const a=this.pageIndex*this.pageSize,r=a+this.pageSize;t=t.slice(a,r)}return this._displayDataCacheKey=e,this._displayDataCache=t,t}willUpdate(e){super.willUpdate(e),e.has("data")&&this.clearSelectionOnDataChange&&(this._selectedRowKeys=new Set),(e.has("data")||e.has("pageSize"))&&this.pageIndex>=this._totalPages&&this._totalPages>0&&(this.pageIndex=this._totalPages-1)}_computeCacheKey(){let e="empty";if(this.data.length>0){const t=this.rowKey(this.data[0],0),a=this.rowKey(this.data[this.data.length-1],this.data.length-1),r=this.data.length>2?this.rowKey(this.data[Math.floor(this.data.length/2)],Math.floor(this.data.length/2)):"";e=`${this.data.length}-${t}-${r}-${a}`}return`${e}|${this._sortColumn}|${this._sortDirection}|${this.pageIndex}|${this.pageSize}|${this.totalItems}`}_sortData(e){const t=this._sortColumn,a=this._sortDirection;return[...e].sort((r,n)=>{const i=r[t],s=n[t];if(i==null&&s==null)return 0;if(i==null)return a==="asc"?1:-1;if(s==null)return a==="asc"?-1:1;if(typeof i=="number"&&typeof s=="number")return a==="asc"?i-s:s-i;if(i instanceof Date&&s instanceof Date)return a==="asc"?i.getTime()-s.getTime():s.getTime()-i.getTime();const h=String(i).toLowerCase(),c=String(s).toLowerCase();return h<c?a==="asc"?-1:1:h>c?a==="asc"?1:-1:0})}_getRowKey(e,t){return this.rowKey(e,t)}_getActualDataIndex(e){return this.data.indexOf(e)}_isColumnSortable(e){return e.sortable!==void 0?e.sortable:this.sortable}_getColumnAlignment(e){return e.align?e.align:e.type==="number"||e.type==="currency"?"right":e.type==="boolean"?"center":"left"}_getColspan(){return this.columns.length+(this.selectable?1:0)+(this.draggableRows?1:0)}_handleSort(e){if(!this._isColumnSortable(e))return;const t=this._sortColumn===e.id&&this._sortDirection==="asc"?"desc":"asc";this._sortColumn=e.id,this._sortDirection=t,this.dispatchEvent(new CustomEvent("pd-table-sort",{detail:{columnId:e.id,direction:t},bubbles:!0,composed:!0}))}_handleHeaderKeyDown(e,t){(e.key==="Enter"||e.key===" ")&&(e.preventDefault(),this._handleSort(t))}_handleSelectAll(e){const t=e.target,a=new Set;t.checked&&this.data.forEach((r,n)=>{a.add(this._getRowKey(r,n))}),this._selectedRowKeys=a,this._emitSelectionChange()}_handleSelectRow(e,t,a){const r=this._getRowKey(e,t),n=new Set(this._selectedRowKeys);a?n.add(r):n.delete(r),this._selectedRowKeys=n,this._emitSelectionChange()}_emitSelectionChange(){const e=this.data.filter((t,a)=>this._selectedRowKeys.has(this._getRowKey(t,a)));this.dispatchEvent(new CustomEvent("pd-table-selection-change",{detail:{selectedKeys:Array.from(this._selectedRowKeys),selectedRows:e},bubbles:!0,composed:!0}))}_handleRowClick(e,t){this.dispatchEvent(new CustomEvent("pd-table-row-click",{detail:{row:e,index:t},bubbles:!0,composed:!0}))}_handleCellChange(e,t,a,r){const n=r.target,i=e[a.id];let s=n.value;if(a.type==="number"||a.type==="currency"){const h=parseFloat(n.value);s=isNaN(h)?null:h}this.dispatchEvent(new CustomEvent("pd-table-cell-change",{detail:{row:e,rowIndex:t,columnId:a.id,value:s,previousValue:i},bubbles:!0,composed:!0}))}_onDragStart(e,t){if(!this.draggableRows||!this._isDragHandleGrabbed){e.preventDefault();return}this._draggedRowIndex=t,e.dataTransfer&&(e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",String(t))),requestAnimationFrame(()=>{e.target.classList.add("dragging")})}_onDragOver(e,t){!this.draggableRows||this._draggedRowIndex===null||(e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="move"),this._dragOverRowIndex!==t&&(this._dragOverRowIndex=t))}_onDragEnd(e){this._resetDragState(),e.target.classList.remove("dragging")}_onDrop(e,t){if(e.preventDefault(),!this.draggableRows||this._draggedRowIndex===null)return;const a=this._draggedRowIndex;a!==t&&(this._sortColumn=null,this._sortDirection="asc",this.dispatchEvent(new CustomEvent("pd-table-row-reorder",{detail:{fromIndex:a,toIndex:t,item:this.data[a]},bubbles:!0,composed:!0}))),this._resetDragState()}_resetDragState(){this._draggedRowIndex=null,this._dragOverRowIndex=null,this._isDragHandleGrabbed=!1}_handleDragHandleMouseDown(){this._isDragHandleGrabbed=!0}_handleDragHandleMouseUp(){this._isDragHandleGrabbed=!1}_handleDragHandleKeyDown(e,t){e.key==="ArrowUp"&&t>0?(e.preventDefault(),this._emitReorder(t,t-1)):e.key==="ArrowDown"&&t<this.data.length-1&&(e.preventDefault(),this._emitReorder(t,t+1))}_emitReorder(e,t){this._sortColumn=null,this._sortDirection="asc",this.dispatchEvent(new CustomEvent("pd-table-row-reorder",{detail:{fromIndex:e,toIndex:t,item:this.data[e]},bubbles:!0,composed:!0}))}_onColumnDragStart(e,t){if(!this.draggableColumns){e.preventDefault();return}this._draggedColumnIndex=t,e.dataTransfer&&(e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",`column:${t}`)),requestAnimationFrame(()=>{e.target.classList.add("column-dragging")})}_onColumnDragOver(e,t){!this.draggableColumns||this._draggedColumnIndex===null||(e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="move"),this._dragOverColumnIndex!==t&&(this._dragOverColumnIndex=t))}_onColumnDragEnd(e){this._resetColumnDragState(),e.target.classList.remove("column-dragging")}_onColumnDrop(e,t){if(e.preventDefault(),!this.draggableColumns||this._draggedColumnIndex===null)return;const a=this._draggedColumnIndex;a!==t&&this.dispatchEvent(new CustomEvent("pd-table-column-reorder",{detail:{fromIndex:a,toIndex:t,column:this.columns[a]},bubbles:!0,composed:!0})),this._resetColumnDragState()}_resetColumnDragState(){this._draggedColumnIndex=null,this._dragOverColumnIndex=null}_handleColumnHeaderKeyDown(e,t){this.draggableColumns&&(e.key==="ArrowLeft"&&t>0?(e.preventDefault(),this._emitColumnReorder(t,t-1)):e.key==="ArrowRight"&&t<this.columns.length-1&&(e.preventDefault(),this._emitColumnReorder(t,t+1)))}_emitColumnReorder(e,t){this.dispatchEvent(new CustomEvent("pd-table-column-reorder",{detail:{fromIndex:e,toIndex:t,column:this.columns[e]},bubbles:!0,composed:!0}))}_handlePageChange(e){e<0||e>=this._totalPages||(this.pageIndex=e,this.dispatchEvent(new CustomEvent("pd-table-page-change",{detail:{pageIndex:e,pageSize:this.pageSize},bubbles:!0,composed:!0})))}_handlePageSizeChange(e){const t=e.target,a=parseInt(t.value,10);this.pageSize=a,this.pageIndex=0,this.dispatchEvent(new CustomEvent("pd-table-page-change",{detail:{pageIndex:0,pageSize:a},bubbles:!0,composed:!0}))}_renderHeader(){const e=this.data.length>0&&this._selectedRowKeys.size===this.data.length,t=this._selectedRowKeys.size>0&&this._selectedRowKeys.size<this.data.length;return o.html`
2
+ <thead>
3
+ <tr role="row">
4
+ ${this.draggableRows?o.html`
5
+ <th class="drag-handle-header" role="columnheader" aria-label="Reorder">
6
+ <span class="visually-hidden">Reorder</span>
7
+ </th>
8
+ `:o.nothing}
9
+
10
+ ${this.selectable?o.html`
11
+ <th class="checkbox-cell" role="columnheader">
12
+ <pd-checkbox
13
+ aria-label="Select all rows"
14
+ ?checked=${e}
15
+ ?indeterminate=${t}
16
+ @change=${this._handleSelectAll}
17
+ ></pd-checkbox>
18
+ </th>
19
+ `:o.nothing}
20
+
21
+ ${this.columns.map((a,r)=>this._renderHeaderCell(a,r))}
22
+ </tr>
23
+ </thead>
24
+ `}_renderHeaderCell(e,t){const a=this._isColumnSortable(e),r=this._getColumnAlignment(e),n=this._sortColumn===e.id,i=this._draggedColumnIndex===t,s=this._dragOverColumnIndex===t&&!i,h=n?this._sortDirection==="asc"?"ascending":"descending":"none";return o.html`
25
+ <th
26
+ role="columnheader"
27
+ class=${g.classMap({sortable:a,sorted:n,[`align-${r}`]:!0,"column-draggable":this.draggableColumns,"column-dragging":i,"column-drag-over":s})}
28
+ style=${e.width?`width: ${e.width};`:""}${e.minWidth?` min-width: ${e.minWidth};`:""}
29
+ aria-sort=${a?h:o.nothing}
30
+ tabindex=${a||this.draggableColumns?"0":o.nothing}
31
+ draggable=${this.draggableColumns?"true":"false"}
32
+ @click=${()=>this._handleSort(e)}
33
+ @keydown=${c=>{this._handleHeaderKeyDown(c,e),this._handleColumnHeaderKeyDown(c,t)}}
34
+ @dragstart=${c=>this._onColumnDragStart(c,t)}
35
+ @dragover=${c=>this._onColumnDragOver(c,t)}
36
+ @drop=${c=>this._onColumnDrop(c,t)}
37
+ @dragend=${c=>this._onColumnDragEnd(c)}
38
+ >
39
+ <div class=${g.classMap({"header-content":!0,[`align-${r}`]:!0})}>
40
+ ${this.draggableColumns?o.html`
41
+ <pd-icon
42
+ class="column-drag-handle"
43
+ name="drag_indicator"
44
+ size="small"
45
+ aria-hidden="true"
46
+ ></pd-icon>
47
+ `:o.nothing}
48
+ <span class="header-text">${e.header}</span>
49
+ ${a?o.html`
50
+ <pd-icon
51
+ class=${g.classMap({"sort-icon":!0,"sort-icon-visible":n,"sort-icon-desc":n&&this._sortDirection==="desc"})}
52
+ name="arrow_upward"
53
+ size="small"
54
+ aria-hidden="true"
55
+ ></pd-icon>
56
+ `:o.nothing}
57
+ </div>
58
+ </th>
59
+ `}_renderCell(e,t,a){if(a.cellTemplate)return a.cellTemplate(e,t);const r=e[a.id];if(a.editable)return this._renderEditableCell(e,t,a,r);switch(a.type){case"currency":return this._formatCurrency(r,a.currencyCode);case"number":return this._formatNumber(r);case"date":return this._formatDate(r);case"boolean":return this._renderBoolean(r);default:return r!=null?String(r):""}}_renderEditableCell(e,t,a,r){const n=a.type==="number"||a.type==="currency"?"number":"text";return o.html`
60
+ <pd-text-field
61
+ type=${n}
62
+ .value=${r!=null?String(r):""}
63
+ aria-label="${a.header}"
64
+ @change=${i=>this._handleCellChange(e,t,a,i)}
65
+ @click=${i=>i.stopPropagation()}
66
+ style="width: 100%;"
67
+ ></pd-text-field>
68
+ `}_formatCurrency(e,t){const a=Number(e);if(e==null||isNaN(a))return String(e??"");const r=t||this.currencyCode;try{return a.toLocaleString(this.locale,{style:"currency",currency:r})}catch{return a.toLocaleString(this.locale)}}_formatNumber(e){const t=Number(e);return e==null||isNaN(t)?String(e??""):t.toLocaleString(this.locale)}_formatDate(e){if(e==null)return"";const t=e instanceof Date?e:new Date(String(e));return isNaN(t.getTime())?String(e):t.toLocaleDateString(this.locale)}_renderBoolean(e){const t=!!e;return o.html`
69
+ <pd-icon
70
+ name=${t?"check":"close"}
71
+ size="small"
72
+ aria-label=${t?"Yes":"No"}
73
+ class=${g.classMap({"boolean-true":t,"boolean-false":!t})}
74
+ ></pd-icon>
75
+ `}_renderRow(e,t){const a=this._getRowKey(e,t),r=this._selectedRowKeys.has(a),n=this._draggedRowIndex===t,i=this._dragOverRowIndex===t&&!n;return o.html`
76
+ <tr
77
+ role="row"
78
+ class=${g.classMap({selected:r,draggable:this.draggableRows,dragging:n,"drag-over":i})}
79
+ aria-selected=${this.selectable?String(r):o.nothing}
80
+ draggable=${this.draggableRows?"true":"false"}
81
+ @dragstart=${s=>this._onDragStart(s,t)}
82
+ @dragover=${s=>this._onDragOver(s,t)}
83
+ @drop=${s=>this._onDrop(s,t)}
84
+ @dragend=${s=>this._onDragEnd(s)}
85
+ @click=${()=>this._handleRowClick(e,t)}
86
+ >
87
+ ${this.draggableRows?o.html`
88
+ <td class="drag-handle-cell" role="cell">
89
+ <pd-icon
90
+ name="drag_indicator"
91
+ size="small"
92
+ class="drag-handle"
93
+ tabindex="0"
94
+ role="button"
95
+ aria-label="Drag to reorder row. Use arrow keys to move up or down."
96
+ @mousedown=${this._handleDragHandleMouseDown}
97
+ @mouseup=${this._handleDragHandleMouseUp}
98
+ @keydown=${s=>this._handleDragHandleKeyDown(s,t)}
99
+ ></pd-icon>
100
+ </td>
101
+ `:o.nothing}
102
+
103
+ ${this.selectable?o.html`
104
+ <td class="checkbox-cell" role="cell">
105
+ <pd-checkbox
106
+ aria-label="Select row"
107
+ ?checked=${r}
108
+ @change=${s=>{const h=s.target;this._handleSelectRow(e,t,h.checked)}}
109
+ @click=${s=>s.stopPropagation()}
110
+ ></pd-checkbox>
111
+ </td>
112
+ `:o.nothing}
113
+
114
+ ${this.columns.map(s=>o.html`
115
+ <td
116
+ role="cell"
117
+ class=${g.classMap({[`align-${this._getColumnAlignment(s)}`]:!0,editable:!!s.editable})}
118
+ >
119
+ ${this._renderCell(e,t,s)}
120
+ </td>
121
+ `)}
122
+ </tr>
123
+ `}_renderEmptyState(){return o.html`
124
+ <tr class="state-row">
125
+ <td colspan=${this._getColspan()} class="no-data">
126
+ <slot name="no-data">
127
+ <div class="empty-state">
128
+ <pd-icon name="inbox" size="large" aria-hidden="true"></pd-icon>
129
+ <span>No data available</span>
130
+ </div>
131
+ </slot>
132
+ </td>
133
+ </tr>
134
+ `}_renderLoadingState(){return o.html`
135
+ <tr class="state-row">
136
+ <td colspan=${this._getColspan()} class="loading-cell">
137
+ <slot name="loading">
138
+ <div class="loading-state">
139
+ <span>Loading...</span>
140
+ </div>
141
+ </slot>
142
+ </td>
143
+ </tr>
144
+ `}_renderPagination(){if(!this.pagination)return o.nothing;const e=this._totalCount,t=e===0?0:this.pageIndex*this.pageSize+1,a=Math.min((this.pageIndex+1)*this.pageSize,e),r=this.pageIndex===0,n=this.pageIndex>=this._totalPages-1||e===0;return o.html`
145
+ <nav class="pagination" aria-label="Table pagination">
146
+ <div class="pagination-info" aria-live="polite" aria-atomic="true">
147
+ <span class="pagination-range">${t}–${a}</span>
148
+ <span class="pagination-total">of ${e}</span>
149
+ </div>
150
+
151
+ <div class="pagination-controls" role="group" aria-label="Pagination controls">
152
+ <pd-icon-button
153
+ icon="first_page"
154
+ aria-label="First page"
155
+ ?disabled=${r}
156
+ @click=${()=>this._handlePageChange(0)}
157
+ ></pd-icon-button>
158
+ <pd-icon-button
159
+ icon="chevron_left"
160
+ aria-label="Previous page"
161
+ ?disabled=${r}
162
+ @click=${()=>this._handlePageChange(this.pageIndex-1)}
163
+ ></pd-icon-button>
164
+ <pd-icon-button
165
+ icon="chevron_right"
166
+ aria-label="Next page"
167
+ ?disabled=${n}
168
+ @click=${()=>this._handlePageChange(this.pageIndex+1)}
169
+ ></pd-icon-button>
170
+ <pd-icon-button
171
+ icon="last_page"
172
+ aria-label="Last page"
173
+ ?disabled=${n}
174
+ @click=${()=>this._handlePageChange(this._totalPages-1)}
175
+ ></pd-icon-button>
176
+ </div>
177
+
178
+ <div class="items-per-page">
179
+ <label id="page-size-label-${this._uniqueId}">Items per page:</label>
180
+ <pd-select
181
+ aria-labelledby="page-size-label-${this._uniqueId}"
182
+ .value=${this.pageSize.toString()}
183
+ @change=${this._handlePageSizeChange}
184
+ >
185
+ ${this.pageSizeOptions.map(i=>o.html`
186
+ <pd-menu-item value=${String(i)}>${i}</pd-menu-item>
187
+ `)}
188
+ </pd-select>
189
+ </div>
190
+ </nav>
191
+ `}render(){const e=this._displayData,t=e.length===0&&!this.loading;return o.html`
192
+ <div class="table-wrapper">
193
+ <div class="table-container">
194
+ <table
195
+ role="grid"
196
+ aria-busy=${this.loading?"true":"false"}
197
+ aria-rowcount=${this._totalCount}
198
+ >
199
+ ${this._renderHeader()}
200
+ <tbody>
201
+ ${this.loading?this._renderLoadingState():o.nothing}
202
+ ${t?this._renderEmptyState():o.nothing}
203
+ ${this.loading?o.nothing:u.repeat(e,a=>{const r=this._getActualDataIndex(a);return this._getRowKey(a,r)},a=>{const r=this._getActualDataIndex(a);return this._renderRow(a,r)})}
204
+ </tbody>
205
+ </table>
206
+ </div>
207
+ ${this._renderPagination()}
208
+ </div>
209
+ `}clearSelection(){this._selectedRowKeys=new Set,this._emitSelectionChange()}selectByKeys(e){this._selectedRowKeys=new Set(e.map(t=>String(t))),this._emitSelectionChange()}selectAll(){const e=this.data.map((t,a)=>this._getRowKey(t,a));this._selectedRowKeys=new Set(e),this._emitSelectionChange()}getSelectedRows(){return this.data.filter((e,t)=>this._selectedRowKeys.has(this._getRowKey(e,t)))}getSelectedKeys(){return Array.from(this._selectedRowKeys)}clearSort(){this._sortColumn=null,this._sortDirection="asc"}setSort(e,t="asc"){this._sortColumn=e,this._sortDirection=t}goToPage(e){this._handlePageChange(e)}invalidateCache(){this._displayDataCacheKey=""}};exports.PdTable.styles=o.css`
210
+ :host {
211
+ display: block;
212
+
213
+ /* Customizable CSS custom properties */
214
+ --pd-table-header-bg: var(--md-sys-color-surface);
215
+ --pd-table-header-hover-bg: var(--md-sys-color-surface-container-highest);
216
+ --pd-table-row-bg: var(--md-sys-color-surface);
217
+ --pd-table-row-hover-bg: var(--md-sys-color-surface-container-low);
218
+ --pd-table-row-selected-bg: var(--md-sys-color-secondary-container);
219
+ --pd-table-row-selected-color: var(--md-sys-color-on-secondary-container);
220
+ --pd-table-border-color: var(--md-sys-color-outline-variant);
221
+ --pd-table-cell-padding: 12px 16px;
222
+ --pd-table-row-height: 52px;
223
+ --pd-table-header-height: 56px;
224
+
225
+ font-family: var(--md-sys-typescale-body-medium-font, inherit);
226
+ }
227
+
228
+ /* Visually hidden but accessible */
229
+ .visually-hidden {
230
+ position: absolute;
231
+ width: 1px;
232
+ height: 1px;
233
+ padding: 0;
234
+ margin: -1px;
235
+ overflow: hidden;
236
+ clip: rect(0, 0, 0, 0);
237
+ white-space: nowrap;
238
+ border: 0;
239
+ }
240
+
241
+ /* Container */
242
+ .table-container {
243
+ width: 100%;
244
+ overflow-x: auto;
245
+ border: 1px solid var(--pd-table-border-color);
246
+ border-radius: var(--md-sys-shape-corner-medium, 12px);
247
+ background: var(--pd-table-row-bg);
248
+ }
249
+
250
+ table {
251
+ width: 100%;
252
+ border-collapse: collapse;
253
+ border-spacing: 0;
254
+ }
255
+
256
+ /* Header Styles */
257
+ th {
258
+ background-color: var(--pd-table-header-bg);
259
+ color: var(--md-sys-color-on-surface);
260
+ font-weight: var(--md-sys-typescale-label-large-weight, 500);
261
+ font-size: var(--md-sys-typescale-label-large-size, 14px);
262
+ text-align: left;
263
+ padding: var(--pd-table-cell-padding);
264
+ white-space: nowrap;
265
+ user-select: none;
266
+ border-bottom: 1px solid var(--pd-table-border-color);
267
+ height: var(--pd-table-header-height);
268
+ box-sizing: border-box;
269
+ position: relative;
270
+ }
271
+
272
+ th.sortable {
273
+ cursor: pointer;
274
+ transition: background-color 0.15s ease;
275
+ }
276
+
277
+ th.sortable:hover {
278
+ background-color: var(--pd-table-header-hover-bg);
279
+ }
280
+
281
+ th.sortable:focus-visible {
282
+ outline: 2px solid var(--md-sys-color-primary);
283
+ outline-offset: -2px;
284
+ border-radius: 4px;
285
+ }
286
+
287
+ .header-content {
288
+ display: inline-flex;
289
+ align-items: center;
290
+ gap: 4px;
291
+ min-height: 20px;
292
+ }
293
+
294
+ .header-content.align-right {
295
+ float: right;
296
+ }
297
+
298
+ .header-content.align-center {
299
+ justify-content: center;
300
+ width: 100%;
301
+ }
302
+
303
+ .header-content.align-left {
304
+ justify-content: flex-start;
305
+ }
306
+
307
+ .header-text {
308
+ overflow: hidden;
309
+ text-overflow: ellipsis;
310
+ }
311
+
312
+ /* Sort Icon */
313
+ .sort-icon {
314
+ opacity: 0;
315
+ transition: opacity 0.15s ease, transform 0.2s ease;
316
+ transform: rotate(0deg);
317
+ flex-shrink: 0;
318
+ }
319
+
320
+ th.sortable:hover .sort-icon {
321
+ opacity: 0.4;
322
+ }
323
+
324
+ .sort-icon-visible {
325
+ opacity: 1 !important;
326
+ }
327
+
328
+ .sort-icon-desc {
329
+ transform: rotate(180deg);
330
+ }
331
+
332
+ /* Cell Styles */
333
+ td {
334
+ padding: var(--pd-table-cell-padding);
335
+ color: var(--md-sys-color-on-surface);
336
+ font-size: var(--md-sys-typescale-body-medium-size, 14px);
337
+ border-bottom: none;
338
+ background: var(--pd-table-row-bg);
339
+ height: var(--pd-table-row-height);
340
+ box-sizing: border-box;
341
+ vertical-align: middle;
342
+ }
343
+
344
+ /* Row States */
345
+ tbody tr {
346
+ transition: background-color 0.1s ease;
347
+ }
348
+
349
+ tbody tr:not(.state-row):hover td {
350
+ background-color: var(--pd-table-row-hover-bg);
351
+ }
352
+
353
+ tr.selected td {
354
+ background-color: var(--pd-table-row-selected-bg);
355
+ color: var(--pd-table-row-selected-color);
356
+ }
357
+
358
+ tr.selected:hover td {
359
+ background-color: var(--pd-table-row-selected-bg);
360
+ filter: brightness(0.97);
361
+ }
362
+
363
+ /* Row Drag States */
364
+ tr.draggable {
365
+ cursor: default;
366
+ }
367
+
368
+ tr.dragging {
369
+ opacity: 0.5;
370
+ }
371
+
372
+ tr.dragging td {
373
+ background: var(--md-sys-color-surface-container-high);
374
+ }
375
+
376
+ tr.drag-over td {
377
+ box-shadow: inset 0 2px 0 0 var(--md-sys-color-primary);
378
+ }
379
+
380
+ /* Column Drag States */
381
+ th.column-draggable {
382
+ cursor: grab;
383
+ user-select: none;
384
+ }
385
+
386
+ th.column-draggable:active {
387
+ cursor: grabbing;
388
+ }
389
+
390
+ th.column-dragging {
391
+ opacity: 0.5;
392
+ background: var(--md-sys-color-surface-container-high) !important;
393
+ }
394
+
395
+ th.column-drag-over {
396
+ box-shadow: inset 2px 0 0 0 var(--md-sys-color-primary);
397
+ }
398
+
399
+ .column-drag-handle {
400
+ color: var(--md-sys-color-on-surface-variant);
401
+ margin-right: 4px;
402
+ flex-shrink: 0;
403
+ opacity: 0.6;
404
+ transition: opacity 0.15s ease;
405
+ }
406
+
407
+ th.column-draggable:hover .column-drag-handle {
408
+ opacity: 1;
409
+ }
410
+
411
+ /* Alignment */
412
+ .align-left { text-align: left; }
413
+ .align-center { text-align: center; }
414
+ .align-right { text-align: right; }
415
+
416
+ /* Special Cells */
417
+ .checkbox-cell {
418
+ width: 52px;
419
+ padding: 0 8px;
420
+ text-align: center;
421
+ }
422
+
423
+ .drag-handle-cell {
424
+ width: 44px;
425
+ padding: 0 8px;
426
+ text-align: center;
427
+ }
428
+
429
+ .drag-handle {
430
+ cursor: grab;
431
+ color: var(--md-sys-color-on-surface-variant);
432
+ border-radius: 4px;
433
+ padding: 4px;
434
+ }
435
+
436
+ .drag-handle:hover {
437
+ background-color: var(--md-sys-color-surface-container-high);
438
+ }
439
+
440
+ .drag-handle:focus-visible {
441
+ outline: 2px solid var(--md-sys-color-primary);
442
+ outline-offset: 2px;
443
+ }
444
+
445
+ .drag-handle-header {
446
+ width: 44px;
447
+ }
448
+
449
+ /* Boolean Icons */
450
+ .boolean-true {
451
+ color: var(--md-sys-color-primary);
452
+ }
453
+
454
+ .boolean-false {
455
+ color: var(--md-sys-color-outline);
456
+ }
457
+
458
+ /* Empty & Loading States */
459
+ .no-data,
460
+ .loading-cell {
461
+ text-align: center;
462
+ padding: 48px 16px;
463
+ color: var(--md-sys-color-on-surface-variant);
464
+ }
465
+
466
+ .empty-state,
467
+ .loading-state {
468
+ display: flex;
469
+ flex-direction: column;
470
+ align-items: center;
471
+ gap: 12px;
472
+ }
473
+
474
+ .empty-state pd-icon {
475
+ color: var(--md-sys-color-outline);
476
+ }
477
+
478
+ /* Pagination */
479
+ .pagination {
480
+ display: flex;
481
+ align-items: center;
482
+ justify-content: space-between;
483
+ padding: 12px 16px;
484
+ gap: 16px;
485
+ color: var(--md-sys-color-on-surface);
486
+ font-size: var(--md-sys-typescale-label-large-size, 14px);
487
+ border-top: 1px solid var(--pd-table-border-color);
488
+ flex-wrap: wrap;
489
+ }
490
+
491
+ .pagination-info {
492
+ flex: 1;
493
+ min-width: 100px;
494
+ }
495
+
496
+ .pagination-range {
497
+ font-weight: 500;
498
+ }
499
+
500
+ .pagination-total {
501
+ color: var(--md-sys-color-on-surface-variant);
502
+ }
503
+
504
+ .pagination-controls {
505
+ display: flex;
506
+ gap: 4px;
507
+ flex: 1;
508
+ justify-content: center;
509
+ }
510
+
511
+ .items-per-page {
512
+ display: flex;
513
+ align-items: center;
514
+ gap: 8px;
515
+ flex: 1;
516
+ justify-content: flex-end;
517
+ }
518
+
519
+ .items-per-page label {
520
+ color: var(--md-sys-color-on-surface-variant);
521
+ }
522
+
523
+ .items-per-page pd-select {
524
+ min-width: 72px;
525
+ }
526
+
527
+ /* Editable Cell Styling */
528
+ td.editable {
529
+ padding: 4px 8px;
530
+ }
531
+
532
+ pd-text-field {
533
+ --md-filled-text-field-container-color: transparent;
534
+ --md-filled-text-field-active-indicator-color: transparent;
535
+ --md-filled-text-field-hover-active-indicator-color: var(--md-sys-color-primary);
536
+ --md-filled-text-field-input-text-font: inherit;
537
+ }
538
+
539
+ /* Responsive */
540
+ @media (max-width: 600px) {
541
+ .pagination {
542
+ flex-direction: column;
543
+ gap: 12px;
544
+ padding: 12px;
545
+ }
546
+
547
+ .pagination-info,
548
+ .pagination-controls,
549
+ .items-per-page {
550
+ flex: none;
551
+ width: 100%;
552
+ justify-content: center;
553
+ }
554
+
555
+ .items-per-page {
556
+ justify-content: space-between;
557
+ }
558
+ }
559
+ `;d([l.property({type:Array})],exports.PdTable.prototype,"columns",2);d([l.property({type:Array})],exports.PdTable.prototype,"data",2);d([l.property({attribute:!1})],exports.PdTable.prototype,"rowKey",2);d([l.property({type:Boolean})],exports.PdTable.prototype,"selectable",2);d([l.property({type:Boolean})],exports.PdTable.prototype,"sortable",2);d([l.property({type:Boolean})],exports.PdTable.prototype,"pagination",2);d([l.property({type:Number})],exports.PdTable.prototype,"pageSize",2);d([l.property({type:Number})],exports.PdTable.prototype,"pageIndex",2);d([l.property({type:Number})],exports.PdTable.prototype,"totalItems",2);d([l.property({type:Boolean,attribute:"draggable-rows"})],exports.PdTable.prototype,"draggableRows",2);d([l.property({type:Boolean,attribute:"draggable-columns"})],exports.PdTable.prototype,"draggableColumns",2);d([l.property({type:Boolean})],exports.PdTable.prototype,"loading",2);d([l.property({type:Boolean,attribute:"clear-selection-on-data-change"})],exports.PdTable.prototype,"clearSelectionOnDataChange",2);d([l.property({type:String,attribute:"currency-code"})],exports.PdTable.prototype,"currencyCode",2);d([l.property({type:String})],exports.PdTable.prototype,"locale",2);d([l.property({type:Array,attribute:"page-size-options"})],exports.PdTable.prototype,"pageSizeOptions",2);d([l.state()],exports.PdTable.prototype,"_sortColumn",2);d([l.state()],exports.PdTable.prototype,"_sortDirection",2);d([l.state()],exports.PdTable.prototype,"_selectedRowKeys",2);d([l.state()],exports.PdTable.prototype,"_draggedRowIndex",2);d([l.state()],exports.PdTable.prototype,"_dragOverRowIndex",2);d([l.state()],exports.PdTable.prototype,"_isDragHandleGrabbed",2);d([l.state()],exports.PdTable.prototype,"_draggedColumnIndex",2);d([l.state()],exports.PdTable.prototype,"_dragOverColumnIndex",2);exports.PdTable=d([l.customElement("pd-table")],exports.PdTable);