@htlkg/components 0.0.1 → 0.0.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,350 @@
1
+ # useTable Composable
2
+
3
+ Enhanced table state management composable that integrates seamlessly with the hotelinking/ui `uiTable` component.
4
+
5
+ ## Features
6
+
7
+ - ✅ **Pagination**: Full pagination support with page size control
8
+ - ✅ **Sorting**: Multi-column sorting with asc/desc order
9
+ - ✅ **Selection**: Row selection with select all/page functionality
10
+ - ✅ **Filtering**: Smart filters with multiple operators (contains, is, >, <, etc.)
11
+ - ✅ **Column Visibility**: Show/hide columns dynamically
12
+ - ✅ **Event Handlers**: Pre-built handlers for all uiTable events
13
+
14
+ ## Basic Usage
15
+
16
+ ```typescript
17
+ import { useTable } from '@htlkg/components/composables';
18
+
19
+ const table = useTable({
20
+ items: myData,
21
+ pageSize: 10,
22
+ sortKey: 'name',
23
+ sortOrder: 'asc',
24
+ idKey: 'id', // optional, defaults to 'id'
25
+ });
26
+ ```
27
+
28
+ ## Integration with uiTable
29
+
30
+ ```vue
31
+ <template>
32
+ <Table
33
+ :header="tableColumns"
34
+ :items="table.paginatedItems.value"
35
+ :loading="loading"
36
+ :current-page="table.currentPage.value"
37
+ :total-pages="table.totalPages.value"
38
+ :total-items="table.totalItems.value"
39
+ :page-size="table.pageSize.value"
40
+ :ordered-by="table.sortKey.value"
41
+ :order-direction="table.sortOrder.value"
42
+ :hidden-columns="table.hiddenColumns.value"
43
+ :reset-selected="table.resetSelected.value"
44
+ :smart-filter-categories="filterCategories"
45
+ :select-all-items-modal="selectAllModal"
46
+ @change-page="table.handlePageChange"
47
+ @change-page-size="table.handlePageSizeChange"
48
+ @order-by="table.handleOrderBy"
49
+ @smart-filters-sent="table.handleSmartFiltersApplied"
50
+ @smart-filters-cleared="table.handleSmartFiltersCleared"
51
+ @smart-filter-deleted="table.handleSmartFilterDeleted"
52
+ @columns-visibility-changed="table.handleColumnsVisibilityChanged"
53
+ @modal-action="table.handleModalAction"
54
+ />
55
+ </template>
56
+
57
+ <script setup lang="ts">
58
+ import { useTable } from '@htlkg/components/composables';
59
+ import { Table } from '@htlkg/components/data';
60
+
61
+ const table = useTable({
62
+ items: myData,
63
+ pageSize: 10,
64
+ sortKey: 'name',
65
+ sortOrder: 'asc',
66
+ });
67
+ </script>
68
+ ```
69
+
70
+ ## API Reference
71
+
72
+ ### Options
73
+
74
+ ```typescript
75
+ interface UseTableOptions<T> {
76
+ items: T[]; // Array of items to display
77
+ pageSize?: number; // Items per page (default: 10)
78
+ sortKey?: string; // Initial sort column
79
+ sortOrder?: 'asc' | 'desc'; // Initial sort order
80
+ idKey?: string; // Property to use as unique ID (default: 'id')
81
+ }
82
+ ```
83
+
84
+ ### Return Value
85
+
86
+ ```typescript
87
+ interface UseTableReturn<T> {
88
+ // State - Pagination
89
+ currentPage: Ref<number>;
90
+ pageSize: Ref<number>;
91
+ totalPages: ComputedRef<number>;
92
+ totalItems: ComputedRef<number>;
93
+ paginatedItems: ComputedRef<T[]>;
94
+
95
+ // State - Sorting
96
+ sortKey: Ref<string>;
97
+ sortOrder: Ref<'asc' | 'desc'>;
98
+ sortedItems: ComputedRef<T[]>;
99
+
100
+ // State - Selection
101
+ selectedItems: Ref<T[]>;
102
+ selectedItemIds: Ref<Set<string | number>>;
103
+ allSelected: ComputedRef<boolean>;
104
+ someSelected: ComputedRef<boolean>;
105
+
106
+ // State - Filtering
107
+ activeFilters: Ref<SmartFilter[]>;
108
+ filteredItems: ComputedRef<T[]>;
109
+
110
+ // State - Column visibility
111
+ hiddenColumns: Ref<number[]>;
112
+
113
+ // State - Reset
114
+ resetSelected: Ref<boolean>;
115
+
116
+ // Methods - Pagination
117
+ setPage: (page: number) => void;
118
+ setPageSize: (size: number) => void;
119
+ handlePageChange: (page: number) => void;
120
+ handlePageSizeChange: (size: number | string) => void;
121
+
122
+ // Methods - Sorting
123
+ setSorting: (key: string, order?: 'asc' | 'desc') => void;
124
+ handleOrderBy: (event: { value: string; orderDirection: 'asc' | 'desc' }) => void;
125
+
126
+ // Methods - Selection
127
+ selectItem: (item: T) => void;
128
+ deselectItem: (item: T) => void;
129
+ selectAll: () => void;
130
+ selectAllOnPage: () => void;
131
+ clearSelection: () => void;
132
+ isSelected: (item: T) => boolean;
133
+
134
+ // Methods - Filtering
135
+ applyFilters: (filters: SmartFilter[]) => void;
136
+ clearFilters: () => void;
137
+ removeFilter: (index: number) => void;
138
+ handleSmartFiltersApplied: (filters: SmartFilter[]) => void;
139
+ handleSmartFiltersCleared: () => void;
140
+ handleSmartFilterDeleted: (index: number) => void;
141
+
142
+ // Methods - Column visibility
143
+ toggleColumn: (index: number) => void;
144
+ showColumn: (index: number) => void;
145
+ hideColumn: (index: number) => void;
146
+ handleColumnsVisibilityChanged: (event: { index: number; hidden: boolean }) => void;
147
+
148
+ // Methods - Modal actions
149
+ handleModalAction: (event: { modal: string; action: string }) => void;
150
+ }
151
+ ```
152
+
153
+ ### Smart Filters
154
+
155
+ ```typescript
156
+ interface SmartFilter {
157
+ category: string; // Field name to filter on
158
+ operator: string; // Filter operator: 'contains', 'is', '>', '<', '>=', '<='
159
+ value: any; // Filter value
160
+ }
161
+ ```
162
+
163
+ Supported operators:
164
+ - `contains`: String contains (case-insensitive)
165
+ - `is` or `=`: Exact match
166
+ - `>` or `greater`: Greater than (numeric)
167
+ - `<` or `less`: Less than (numeric)
168
+ - `>=` or `greaterOrEqual`: Greater than or equal (numeric)
169
+ - `<=` or `lessOrEqual`: Less than or equal (numeric)
170
+
171
+ ## Examples
172
+
173
+ ### Basic Table with Pagination
174
+
175
+ ```typescript
176
+ const table = useTable({
177
+ items: accounts,
178
+ pageSize: 25,
179
+ });
180
+
181
+ // Use in template
182
+ table.paginatedItems.value // Current page items
183
+ table.currentPage.value // Current page number
184
+ table.totalPages.value // Total pages
185
+ ```
186
+
187
+ ### With Sorting
188
+
189
+ ```typescript
190
+ const table = useTable({
191
+ items: accounts,
192
+ sortKey: 'created_at',
193
+ sortOrder: 'desc',
194
+ });
195
+
196
+ // Programmatic sorting
197
+ table.setSorting('name', 'asc');
198
+
199
+ // Or use the event handler
200
+ @order-by="table.handleOrderBy"
201
+ ```
202
+
203
+ ### With Filtering
204
+
205
+ ```typescript
206
+ const table = useTable({
207
+ items: accounts,
208
+ });
209
+
210
+ // Apply filters programmatically
211
+ table.applyFilters([
212
+ { category: 'name', operator: 'contains', value: 'hotel' },
213
+ { category: 'status', operator: 'is', value: 'active' },
214
+ ]);
215
+
216
+ // Or use the event handlers
217
+ @smart-filters-sent="table.handleSmartFiltersApplied"
218
+ @smart-filters-cleared="table.handleSmartFiltersCleared"
219
+ ```
220
+
221
+ ### With Selection
222
+
223
+ ```typescript
224
+ const table = useTable({
225
+ items: accounts,
226
+ idKey: 'account_id', // Use custom ID field
227
+ });
228
+
229
+ // Check selection state
230
+ table.selectedItems.value // Array of selected items
231
+ table.selectedItemIds.value // Set of selected IDs
232
+ table.allSelected.value // All items selected?
233
+ table.someSelected.value // Some items selected?
234
+
235
+ // Programmatic selection
236
+ table.selectItem(account);
237
+ table.selectAll();
238
+ table.clearSelection();
239
+ ```
240
+
241
+ ### Complete Example
242
+
243
+ ```vue
244
+ <template>
245
+ <div>
246
+ <!-- Stats -->
247
+ <div class="stats">
248
+ <div>Total: {{ table.totalItems.value }}</div>
249
+ <div>Selected: {{ table.selectedItems.value.length }}</div>
250
+ </div>
251
+
252
+ <!-- Table -->
253
+ <Table
254
+ :header="columns"
255
+ :items="tableItems"
256
+ :current-page="table.currentPage.value"
257
+ :total-pages="table.totalPages.value"
258
+ :total-items="table.totalItems.value"
259
+ :page-size="table.pageSize.value"
260
+ :ordered-by="table.sortKey.value"
261
+ :order-direction="table.sortOrder.value"
262
+ :hidden-columns="table.hiddenColumns.value"
263
+ :reset-selected="table.resetSelected.value"
264
+ :smart-filter-categories="filterCategories"
265
+ @change-page="table.handlePageChange"
266
+ @change-page-size="table.handlePageSizeChange"
267
+ @order-by="table.handleOrderBy"
268
+ @smart-filters-sent="table.handleSmartFiltersApplied"
269
+ @smart-filters-cleared="table.handleSmartFiltersCleared"
270
+ @smart-filter-deleted="table.handleSmartFilterDeleted"
271
+ @columns-visibility-changed="table.handleColumnsVisibilityChanged"
272
+ @modal-action="table.handleModalAction"
273
+ />
274
+ </div>
275
+ </template>
276
+
277
+ <script setup lang="ts">
278
+ import { computed } from 'vue';
279
+ import { useTable } from '@htlkg/components/composables';
280
+ import { Table } from '@htlkg/components/data';
281
+
282
+ // Your data
283
+ const accounts = ref([...]);
284
+
285
+ // Initialize table
286
+ const table = useTable({
287
+ items: accounts.value,
288
+ pageSize: 10,
289
+ sortKey: 'name',
290
+ sortOrder: 'asc',
291
+ idKey: 'id',
292
+ });
293
+
294
+ // Transform data for display
295
+ const tableItems = computed(() => {
296
+ return table.paginatedItems.value.map(account => ({
297
+ id: account.id,
298
+ row: [
299
+ account.name,
300
+ { content: account.status, type: 'tag', color: 'green' },
301
+ account.created_at,
302
+ ],
303
+ }));
304
+ });
305
+
306
+ // Table configuration
307
+ const columns = [
308
+ { name: 'Name', value: 'name' },
309
+ { name: 'Status', value: 'status' },
310
+ { name: 'Created', value: 'created_at' },
311
+ ];
312
+
313
+ const filterCategories = [
314
+ {
315
+ id: 'name',
316
+ name: 'Name',
317
+ componentType: 'uiInput',
318
+ defaultProps: { placeholder: 'Search...' },
319
+ },
320
+ ];
321
+ </script>
322
+ ```
323
+
324
+ ## Best Practices
325
+
326
+ 1. **Use computed for items**: Pass reactive data to `useTable` for automatic updates
327
+ 2. **Transform data separately**: Keep raw data in `useTable`, transform for display in computed
328
+ 3. **Custom ID keys**: Use `idKey` option when your items don't have an `id` property
329
+ 4. **Event handlers**: Use the built-in `handle*` methods for seamless uiTable integration
330
+ 5. **Filter logic**: The composable handles AND logic by default; customize if needed
331
+
332
+ ## Migration from Manual State
333
+
334
+ Before:
335
+ ```typescript
336
+ const currentPage = ref(1);
337
+ const pageSize = ref(10);
338
+ const sortKey = ref('name');
339
+ // ... lots of manual state management
340
+ ```
341
+
342
+ After:
343
+ ```typescript
344
+ const table = useTable({
345
+ items: myData,
346
+ pageSize: 10,
347
+ sortKey: 'name',
348
+ });
349
+ // All state and handlers included!
350
+ ```