@lazhus/kg-ui 0.2.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.
Files changed (70) hide show
  1. package/README.md +128 -0
  2. package/custom-elements.json +3815 -0
  3. package/dist/components/kg-accordion-item.js +117 -0
  4. package/dist/components/kg-accordion.js +32 -0
  5. package/dist/components/kg-button.js +241 -0
  6. package/dist/components/kg-card.js +129 -0
  7. package/dist/components/kg-checkbox.js +147 -0
  8. package/dist/components/kg-colorpicker.js +240 -0
  9. package/dist/components/kg-column.js +48 -0
  10. package/dist/components/kg-datagrid.js +428 -0
  11. package/dist/components/kg-datepicker.js +650 -0
  12. package/dist/components/kg-divider.js +118 -0
  13. package/dist/components/kg-drawer.js +178 -0
  14. package/dist/components/kg-file-upload.js +274 -0
  15. package/dist/components/kg-grid.js +46 -0
  16. package/dist/components/kg-image.js +100 -0
  17. package/dist/components/kg-input.js +318 -0
  18. package/dist/components/kg-loader.js +175 -0
  19. package/dist/components/kg-modal.js +165 -0
  20. package/dist/components/kg-progress.js +82 -0
  21. package/dist/components/kg-radio-group.js +75 -0
  22. package/dist/components/kg-radio.js +121 -0
  23. package/dist/components/kg-row.js +42 -0
  24. package/dist/components/kg-select.js +331 -0
  25. package/dist/components/kg-skeleton.js +108 -0
  26. package/dist/components/kg-slider.js +196 -0
  27. package/dist/components/kg-spinner.js +79 -0
  28. package/dist/components/kg-stepper.js +214 -0
  29. package/dist/components/kg-switch.js +106 -0
  30. package/dist/components/kg-tab-panel.js +35 -0
  31. package/dist/components/kg-tabs.js +158 -0
  32. package/dist/components/kg-text.js +141 -0
  33. package/dist/components/kg-textarea.js +162 -0
  34. package/dist/components/kg-toast.js +200 -0
  35. package/dist/index.js +68 -0
  36. package/dist/kg-ui.css +1 -0
  37. package/package.json +57 -0
  38. package/types/components/kg-accordion-item.d.ts +25 -0
  39. package/types/components/kg-accordion.d.ts +22 -0
  40. package/types/components/kg-button.d.ts +34 -0
  41. package/types/components/kg-card.d.ts +31 -0
  42. package/types/components/kg-checkbox.d.ts +28 -0
  43. package/types/components/kg-colorpicker.d.ts +28 -0
  44. package/types/components/kg-column.d.ts +20 -0
  45. package/types/components/kg-datagrid.d.ts +55 -0
  46. package/types/components/kg-datepicker.d.ts +43 -0
  47. package/types/components/kg-divider.d.ts +34 -0
  48. package/types/components/kg-drawer.d.ts +31 -0
  49. package/types/components/kg-file-upload.d.ts +40 -0
  50. package/types/components/kg-grid.d.ts +20 -0
  51. package/types/components/kg-image.d.ts +40 -0
  52. package/types/components/kg-input.d.ts +34 -0
  53. package/types/components/kg-loader.d.ts +31 -0
  54. package/types/components/kg-modal.d.ts +31 -0
  55. package/types/components/kg-progress.d.ts +37 -0
  56. package/types/components/kg-radio-group.d.ts +25 -0
  57. package/types/components/kg-radio.d.ts +25 -0
  58. package/types/components/kg-row.d.ts +20 -0
  59. package/types/components/kg-select.d.ts +37 -0
  60. package/types/components/kg-skeleton.d.ts +34 -0
  61. package/types/components/kg-slider.d.ts +40 -0
  62. package/types/components/kg-spinner.d.ts +28 -0
  63. package/types/components/kg-stepper.d.ts +31 -0
  64. package/types/components/kg-switch.d.ts +28 -0
  65. package/types/components/kg-tab-panel.d.ts +28 -0
  66. package/types/components/kg-tabs.d.ts +25 -0
  67. package/types/components/kg-text.d.ts +31 -0
  68. package/types/components/kg-textarea.d.ts +43 -0
  69. package/types/components/kg-toast.d.ts +28 -0
  70. package/types/index.d.ts +335 -0
@@ -0,0 +1,428 @@
1
+ import { LitElement as d, css as c, html as r } from "lit";
2
+ import "lit/directives/class-map.js";
3
+ import "./kg-checkbox.js";
4
+ import "./kg-radio.js";
5
+ import { unsafeHTML as l } from "lit/directives/unsafe-html.js";
6
+ import "./kg-button.js";
7
+ import "./kg-skeleton.js";
8
+ class h extends d {
9
+ static properties = {
10
+ columns: { type: Array },
11
+ // [{ label: 'Name', field: 'name', width: '100px', align: 'left', sortable: true }]
12
+ data: { type: Array },
13
+ loading: { type: Boolean },
14
+ striped: { type: Boolean },
15
+ bordered: { type: Boolean },
16
+ hover: { type: Boolean },
17
+ selectable: { type: Boolean },
18
+ selectionMode: { type: String, attribute: "selection-mode" },
19
+ // 'single' | 'multiple', default 'multiple'
20
+ selectedRows: { type: Array, state: !0 },
21
+ // Sorting
22
+ sortable: { type: Boolean },
23
+ // Global sort enable/disable
24
+ _sortColumn: { type: String, state: !0 },
25
+ _sortDirection: { type: String, state: !0 },
26
+ // 'asc' | 'desc'
27
+ // Pagination
28
+ pagination: { type: Boolean },
29
+ pageSize: { type: Number, attribute: "page-size" },
30
+ _currentPage: { type: Number, state: !0 }
31
+ };
32
+ static styles = c`
33
+ :host {
34
+ display: block;
35
+ width: 100%;
36
+ font-family: inherit;
37
+ color: var(--kg-text);
38
+ --datagrid-border: var(--kg-border, #e2e8f0);
39
+ --datagrid-header-bg: var(--kg-surface, #f8fafc);
40
+ --datagrid-selected-bg: rgba(var(--kg-primary-rgb, 65, 171, 52), 0.08);
41
+ }
42
+
43
+ .wrapper {
44
+ display: flex;
45
+ flex-direction: column;
46
+ gap: 1rem;
47
+ width: 100%;
48
+ }
49
+
50
+ .table-container {
51
+ width: 100%;
52
+ overflow-x: auto;
53
+ border: 1px solid var(--datagrid-border);
54
+ border-radius: var(--kg-radius-md, 8px);
55
+ background: var(--kg-bg);
56
+ }
57
+
58
+ table {
59
+ width: 100%;
60
+ border-collapse: collapse;
61
+ text-align: left;
62
+ font-size: 0.9rem;
63
+ }
64
+
65
+ thead {
66
+ background-color: var(--datagrid-header-bg);
67
+ border-bottom: 2px solid var(--datagrid-border);
68
+ }
69
+
70
+ th {
71
+ padding: 12px 16px;
72
+ font-weight: 600;
73
+ color: var(--kg-text-muted);
74
+ white-space: nowrap;
75
+ user-select: none;
76
+ transition: background 0.2s;
77
+ overflow: hidden;
78
+ text-overflow: ellipsis;
79
+ }
80
+
81
+ th.sortable {
82
+ cursor: pointer;
83
+ }
84
+
85
+ th.sortable:hover {
86
+ background-color: rgba(0,0,0,0.03);
87
+ color: var(--kg-text);
88
+ }
89
+
90
+ td {
91
+ padding: 12px 16px;
92
+ border-bottom: 1px solid var(--datagrid-border);
93
+ transition: background 0.2s;
94
+ overflow: hidden;
95
+ text-overflow: ellipsis;
96
+ white-space: nowrap;
97
+ }
98
+
99
+ tr:last-child td {
100
+ border-bottom: none;
101
+ }
102
+
103
+ /* Modifiers */
104
+ :host([striped]) tbody tr:nth-child(even) {
105
+ background-color: var(--kg-surface);
106
+ }
107
+
108
+ :host([bordered]) td, :host([bordered]) th {
109
+ border-right: 1px solid var(--datagrid-border);
110
+ }
111
+
112
+ :host([bordered]) td:last-child, :host([bordered]) th:last-child {
113
+ border-right: none;
114
+ }
115
+
116
+ tbody tr {
117
+ transition: background-color 0.2s;
118
+ }
119
+
120
+ :host([hover]) tbody tr:hover {
121
+ background-color: var(--datagrid-hover-bg, rgba(0, 0, 0, 0.04));
122
+ }
123
+
124
+ /* Selection */
125
+ .checkbox-cell {
126
+ width: 48px;
127
+ text-align: center;
128
+ padding: 0 8px;
129
+ }
130
+
131
+ /* kg-checkbox and kg-radio handle their own sizing and cursor */
132
+
133
+ tr.selected {
134
+ background-color: var(--datagrid-selected-bg) !important;
135
+ }
136
+
137
+ /* Alignment */
138
+ .align-left { text-align: left; }
139
+ .align-center { text-align: center; }
140
+ .align-right { text-align: right; }
141
+
142
+ /* Empty State */
143
+ .empty-state {
144
+ padding: 3rem;
145
+ text-align: center;
146
+ color: var(--kg-text-muted);
147
+ }
148
+
149
+ /* Sort Icons */
150
+ .sort-icon {
151
+ display: inline-block;
152
+ margin-left: 4px;
153
+ vertical-align: middle;
154
+ opacity: 0.3;
155
+ font-size: 0.8em;
156
+ }
157
+
158
+ th.sortable:hover .sort-icon {
159
+ opacity: 0.7;
160
+ }
161
+
162
+ th.active-sort .sort-icon {
163
+ opacity: 1;
164
+ color: var(--kg-primary);
165
+ }
166
+
167
+ /* Pagination */
168
+ .pagination-footer {
169
+ display: flex;
170
+ align-items: center;
171
+ justify-content: space-between;
172
+ padding: 1rem 0;
173
+ gap: 1rem;
174
+ flex-wrap: wrap;
175
+ border-top: 1px solid var(--datagrid-border);
176
+ margin-top: -1px; /* Overlap with table border if needed, or keeping it separate */
177
+ }
178
+
179
+ .pagination-info {
180
+ font-size: 0.85rem;
181
+ color: var(--kg-text-muted);
182
+ font-weight: 500;
183
+ }
184
+
185
+ .pagination-controls {
186
+ display: flex;
187
+ align-items: center;
188
+ gap: 0.25rem;
189
+ }
190
+
191
+
192
+ `;
193
+ constructor() {
194
+ super(), this.columns = [], this.data = [], this.loading = !1, this.striped = !1, this.bordered = !1, this.hover = !0, this.selectable = !1, this.selectionMode = "multiple", this.selectedRows = [], this.sortable = !1, this.pagination = !1, this.pageSize = 10, this._currentPage = 1, this._sortColumn = null, this._sortDirection = null;
195
+ }
196
+ _handleSelectAll(e) {
197
+ if (!this.selectable || this.selectionMode === "single") return;
198
+ e.detail.checked ? this.selectedRows = [...this.data] : this.selectedRows = [], this._emitSelectionChange();
199
+ }
200
+ _handleRowSelect(e, t) {
201
+ if (this.selectable)
202
+ if (t.stopPropagation(), this.selectionMode === "single")
203
+ this._isSelected(e) || (this.selectedRows = [e], this._emitSelectionChange());
204
+ else {
205
+ let s;
206
+ t.type === "change" && t.detail !== void 0 && t.detail.checked !== void 0 ? s = t.detail.checked : s = !this._isSelected(e), s ? this.selectedRows = [...this.selectedRows, e] : this.selectedRows = this.selectedRows.filter((o) => o !== e), this._emitSelectionChange();
207
+ }
208
+ }
209
+ _isSelected(e) {
210
+ return this.selectedRows.includes(e);
211
+ }
212
+ _emitSelectionChange() {
213
+ this.dispatchEvent(new CustomEvent("selection-change", {
214
+ detail: { selectedRows: this.selectedRows },
215
+ bubbles: !0,
216
+ composed: !0
217
+ }));
218
+ }
219
+ _handleSort(e) {
220
+ !e.sortable && !this.sortable || (this._sortColumn === e.field ? this._sortDirection = this._sortDirection === "asc" ? "desc" : "asc" : (this._sortColumn = e.field, this._sortDirection = "asc"), this.dispatchEvent(new CustomEvent("sort", {
221
+ detail: { column: this._sortColumn, direction: this._sortDirection },
222
+ bubbles: !0,
223
+ composed: !0
224
+ })));
225
+ }
226
+ _getProcessedData() {
227
+ let e = [...this.data];
228
+ if (this._sortColumn && e.sort((t, s) => {
229
+ const o = t[this._sortColumn], n = s[this._sortColumn];
230
+ return o < n ? this._sortDirection === "asc" ? -1 : 1 : o > n ? this._sortDirection === "asc" ? 1 : -1 : 0;
231
+ }), this.pagination) {
232
+ const t = (this._currentPage - 1) * this.pageSize, s = t + this.pageSize;
233
+ return {
234
+ data: e.slice(t, s),
235
+ total: e.length
236
+ };
237
+ }
238
+ return { data: e, total: e.length };
239
+ }
240
+ _changePage(e) {
241
+ if (e < 1) return;
242
+ const t = this.data.length, s = Math.ceil(t / this.pageSize);
243
+ e > s || (this._currentPage = e, this.dispatchEvent(new CustomEvent("page-change", {
244
+ detail: { page: this._currentPage, pageSize: this.pageSize },
245
+ bubbles: !0,
246
+ composed: !0
247
+ })));
248
+ }
249
+ _renderCellContent(e, t) {
250
+ if (!e.render)
251
+ return t[e.field];
252
+ const s = e.render(t);
253
+ return typeof s == "string" ? l(s) : s;
254
+ }
255
+ _renderHeaderContent(e) {
256
+ if (e.headerRender) {
257
+ const t = e.headerRender(e);
258
+ return typeof t == "string" ? l(t) : t;
259
+ }
260
+ return e.label;
261
+ }
262
+ render() {
263
+ const { data: e, total: t } = this._getProcessedData(), s = this.pagination ? Math.ceil(t / this.pageSize) : 1, o = this.data.length > 0 && this.selectedRows.length === this.data.length, n = this.selectionMode === "single";
264
+ return r`
265
+ <div class="wrapper">
266
+ <div class="table-container">
267
+ <table>
268
+ <thead>
269
+ <tr>
270
+ ${this.selectable ? r`
271
+ <th class="checkbox-cell">
272
+ ${n ? "" : r`
273
+ <kg-checkbox
274
+ .checked="${o}"
275
+ @change="${this._handleSelectAll}"
276
+ ></kg-checkbox>
277
+ `}
278
+ </th>
279
+ ` : ""}
280
+
281
+ ${this.columns.map((i) => r`
282
+ <th
283
+ class="${i.sortable || this.sortable ? "sortable" : ""} ${i.align ? `align-${i.align}` : ""} ${this._sortColumn === i.field ? "active-sort" : ""}"
284
+ style="${i.width ? `width: ${i.width}; min-width: ${i.width}; max-width: ${i.width};` : ""}"
285
+ @click="${() => this._handleSort(i)}"
286
+ >
287
+ ${this._renderHeaderContent(i)}
288
+ ${i.sortable || this.sortable ? r`
289
+ <span class="sort-icon">
290
+ ${this._sortColumn === i.field ? this._sortDirection === "asc" ? "▲" : "▼" : "⇅"}
291
+ </span>
292
+ ` : ""}
293
+ </th>
294
+ `)}
295
+ </tr>
296
+ </thead>
297
+ <tbody>
298
+ ${this.loading ? r`
299
+ ${Array.from({ length: this.pagination && this.pageSize ? this.pageSize : 5 }).map(() => r`
300
+ <tr>
301
+ ${this.selectable ? r`
302
+ <td class="checkbox-cell">
303
+ <kg-skeleton variant="rect" width="16px" height="16px" style="border-radius: 4px; display: inline-block;"></kg-skeleton>
304
+ </td>
305
+ ` : ""}
306
+ ${this.columns.map(() => r`
307
+ <td>
308
+ <kg-skeleton variant="text" width="${Math.floor(Math.random() * 50 + 40)}%" height="1rem"></kg-skeleton>
309
+ </td>
310
+ `)}
311
+ </tr>
312
+ `)}
313
+ ` : e.length === 0 ? r`
314
+ <tr>
315
+ <td colspan="${this.columns.length + (this.selectable ? 1 : 0)}" class="empty-state">
316
+ Veri bulunamadı.
317
+ </td>
318
+ </tr>
319
+ ` : e.map((i) => r`
320
+ <tr
321
+ class="${this._isSelected(i) ? "selected" : ""}"
322
+ @click="${(a) => this._handleRowSelect(i, a)}"
323
+ >
324
+ ${this.selectable ? r`
325
+ <td class="checkbox-cell">
326
+ ${n ? r`
327
+ <kg-radio
328
+ .checked="${this._isSelected(i)}"
329
+ style="pointer-events: none;"
330
+ ></kg-radio>
331
+ ` : r`
332
+ <kg-checkbox
333
+ .checked="${this._isSelected(i)}"
334
+ @change="${(a) => this._handleRowSelect(i, a)}"
335
+ @click="${(a) => a.stopPropagation()}"
336
+ ></kg-checkbox>
337
+ `}
338
+ </td>
339
+ ` : ""}
340
+
341
+ ${this.columns.map((a) => r`
342
+ <td class="${a.align ? `align-${a.align}` : ""}">
343
+ ${this._renderCellContent(a, i)}
344
+ </td>
345
+ `)}
346
+ </tr>
347
+ `)}
348
+ </tbody>
349
+ </table>
350
+ </div>
351
+
352
+ ${this.pagination && t > 0 ? r`
353
+ <div class="pagination-footer">
354
+ <div class="pagination-info">
355
+ Toplam <strong>${t}</strong> kayıttan <strong>${(this._currentPage - 1) * this.pageSize + 1} - ${Math.min(this._currentPage * this.pageSize, t)}</strong> arası gösteriliyor
356
+ </div>
357
+ <div class="pagination-controls">
358
+ <!-- First Page -->
359
+ <kg-button
360
+ ?disabled="${this._currentPage === 1}"
361
+ @click="${() => this._changePage(1)}"
362
+ text
363
+ color="secondary"
364
+ size="medium"
365
+ square
366
+ >
367
+ <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 17l-5-5 5-5M18 17l-5-5 5-5"/></svg>
368
+ </kg-button>
369
+
370
+ <!-- Previous Page -->
371
+ <kg-button
372
+ ?disabled="${this._currentPage === 1}"
373
+ @click="${() => this._changePage(this._currentPage - 1)}"
374
+ text
375
+ color="secondary"
376
+ size="medium"
377
+ square
378
+ >
379
+ <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><path d="M15 18l-6-6 6-6"/></svg>
380
+ </kg-button>
381
+
382
+ <!-- Page Numbers -->
383
+ ${Array.from({ length: s }, (i, a) => a + 1).map((i) => r`
384
+ <kg-button
385
+ @click="${() => this._changePage(i)}"
386
+ color="${this._currentPage === i ? "primary" : "secondary"}"
387
+ ?text="${this._currentPage !== i}"
388
+ size="medium"
389
+ square
390
+ >
391
+ ${i}
392
+ </kg-button>
393
+ `)}
394
+
395
+ <!-- Next Page -->
396
+ <kg-button
397
+ ?disabled="${this._currentPage === s}"
398
+ @click="${() => this._changePage(this._currentPage + 1)}"
399
+ text
400
+ color="secondary"
401
+ size="medium"
402
+ square
403
+ >
404
+ <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 18l6-6-6-6"/></svg>
405
+ </kg-button>
406
+
407
+ <!-- Last Page -->
408
+ <kg-button
409
+ ?disabled="${this._currentPage === s}"
410
+ @click="${() => this._changePage(s)}"
411
+ text
412
+ color="secondary"
413
+ size="medium"
414
+ square
415
+ >
416
+ <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><path d="M13 17l5-5-5-5M6 17l5-5-5-5"/></svg>
417
+ </kg-button>
418
+ </div>
419
+ </div>
420
+ ` : ""}
421
+ </div>
422
+ `;
423
+ }
424
+ }
425
+ customElements.define("kg-datagrid", h);
426
+ export {
427
+ h as kgdatagrid
428
+ };