@makolabs/ripple 0.0.1-dev.55 → 0.0.1-dev.57

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/dist/index.d.ts CHANGED
@@ -201,6 +201,8 @@ export type TableProps<T extends DataRow = any> = {
201
201
  bordered?: boolean;
202
202
  striped?: boolean;
203
203
  pageSize?: number;
204
+ currentPage?: number;
205
+ totalItems?: number;
204
206
  selectable?: boolean;
205
207
  selected?: T[];
206
208
  class?: ClassValue;
@@ -212,12 +214,21 @@ export type TableProps<T extends DataRow = any> = {
212
214
  thclass?: ClassValue;
213
215
  tdclass?: ClassValue;
214
216
  footerclass?: ClassValue;
217
+ paginationclass?: ClassValue;
215
218
  onrowclick?: (row: T, index: number) => void;
216
219
  onsort?: (sortState: SortState) => void;
217
220
  onselect?: (selected: T[]) => void;
221
+ onpagechange?: (page: number) => void;
218
222
  rowclass?: (row: T, index: number) => ClassValue;
219
223
  loading?: boolean;
220
224
  expandedContent?: Snippet<[T]>;
225
+ pagination?: boolean;
226
+ showPagination?: boolean;
227
+ showPageSize?: boolean;
228
+ pageSizeOptions?: number[];
229
+ onpagesizechange?: (pageSize: number) => void;
230
+ paginationPosition?: 'top' | 'bottom' | 'both';
231
+ paginationTemplate?: 'simple' | 'full';
221
232
  };
222
233
  export type BreadcrumbItem = {
223
234
  label: string;
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { cn } from '../../helper/cls.js';
3
- import { table } from './table.js';
3
+ import { table } from './table';
4
4
  import type { TableProps, SortDirection, SortState } from '../../index.js';
5
5
 
6
6
  let {
@@ -9,11 +9,15 @@
9
9
  bordered = true,
10
10
  striped = false,
11
11
  pageSize = 10,
12
+ currentPage: externalCurrentPage,
13
+ totalItems,
12
14
  selectable = false,
13
15
  selected = $bindable([]),
14
- onrowclick = () => {},
16
+ onrowclick,
15
17
  onsort = () => {},
16
18
  onselect = () => {},
19
+ onpagechange,
20
+ onpagesizechange,
17
21
  class: classname = '',
18
22
  wrapperclass: wrapperClass = '',
19
23
  tableclass: tableClass = '',
@@ -23,17 +27,40 @@
23
27
  thclass: thClass = '',
24
28
  tdclass: tdClass = '',
25
29
  footerclass: footerClass = '',
30
+ paginationclass: paginationClass = '',
26
31
  rowclass = () => '',
27
32
  loading = false,
28
- expandedContent
33
+ expandedContent,
34
+ pagination = true,
35
+ showPagination = true,
36
+ showPageSize = false,
37
+ pageSizeOptions = [5, 10, 25, 50, 100],
38
+ paginationPosition = 'bottom',
39
+ paginationTemplate = 'full'
29
40
  }: TableProps<any> = $props();
30
41
 
31
42
  let sortColumn = $state('');
32
43
  let sortDirection = $state<SortDirection>(null);
33
- let currentPage = $state(1);
44
+ let internalCurrentPage = $state(externalCurrentPage || 1);
45
+ let internalPageSize = $state(pageSize);
34
46
 
35
- // Pagination is automatically determined by pageSize
36
- const pagination = $derived(pageSize > 0 && data.length > pageSize);
47
+ // Use external current page if provided
48
+ $effect(() => {
49
+ if (externalCurrentPage !== undefined) {
50
+ internalCurrentPage = externalCurrentPage;
51
+ }
52
+ });
53
+
54
+ // Pagination is automatically determined by pageSize and pagination prop
55
+ const showPaginationControls = $derived(
56
+ pagination &&
57
+ showPagination &&
58
+ (data.length > internalPageSize || totalItems > internalPageSize)
59
+ );
60
+
61
+ // Calculate total items and pages
62
+ const effectiveTotalItems = $derived(totalItems !== undefined ? totalItems : data.length);
63
+ const totalPages = $derived(Math.ceil(effectiveTotalItems / internalPageSize));
37
64
 
38
65
  const {
39
66
  base: baseClass,
@@ -65,13 +92,28 @@
65
92
  const thClasses = $derived(cn(thBaseClass(), thClass));
66
93
  const tdClasses = $derived(cn(tdBaseClass(), tdClass));
67
94
  const footerClasses = $derived(cn(footerBaseClass(), footerClass));
95
+ const paginationClasses = $derived(cn(paginationBaseClass(), paginationClass));
68
96
  const emptyStateClasses = $derived(emptyStateBaseClass());
69
97
 
70
98
  // Handle pagination
71
- const totalPages = $derived(Math.ceil(data.length / pageSize));
72
- const paginatedData = $derived(
73
- pagination ? data.slice((currentPage - 1) * pageSize, currentPage * pageSize) : data
74
- );
99
+ function getPaginatedData() {
100
+ // If no pagination or all data fits on one page, return all data
101
+ if (!pagination || data.length <= internalPageSize) {
102
+ return data;
103
+ }
104
+
105
+ // If external data source might be handling pagination
106
+ if (totalItems !== undefined) {
107
+ // If data.length is less than or equal to pageSize, assume it's already paginated
108
+ if (data.length <= internalPageSize) {
109
+ return data;
110
+ }
111
+ }
112
+
113
+ // Otherwise, handle pagination internally
114
+ const startIndex = (internalCurrentPage - 1) * internalPageSize;
115
+ return data.slice(startIndex, startIndex + internalPageSize);
116
+ }
75
117
 
76
118
  // Handle sorting
77
119
  function toggleSort(column: string) {
@@ -115,29 +157,265 @@
115
157
  }
116
158
 
117
159
  function handleRowClick(row: any, index: number) {
118
- onrowclick(row, index);
160
+ onrowclick?.(row, index);
161
+ }
162
+
163
+ function goToFirstPage() {
164
+ if (internalCurrentPage !== 1) {
165
+ internalCurrentPage = 1;
166
+ onpagechange?.(internalCurrentPage);
167
+ }
168
+ }
169
+
170
+ function goToLastPage() {
171
+ if (internalCurrentPage !== totalPages) {
172
+ internalCurrentPage = totalPages;
173
+ onpagechange?.(internalCurrentPage);
174
+ }
119
175
  }
120
176
 
121
177
  function nextPage() {
122
- if (currentPage < totalPages) {
123
- currentPage++;
178
+ if (internalCurrentPage < totalPages) {
179
+ internalCurrentPage++;
180
+ onpagechange?.(internalCurrentPage);
124
181
  }
125
182
  }
126
183
 
127
184
  function prevPage() {
128
- if (currentPage > 1) {
129
- currentPage--;
185
+ if (internalCurrentPage > 1) {
186
+ internalCurrentPage--;
187
+ onpagechange?.(internalCurrentPage);
130
188
  }
131
189
  }
132
190
 
133
191
  function goToPage(page: number) {
134
- if (page >= 1 && page <= totalPages) {
135
- currentPage = page;
192
+ if (page >= 1 && page <= totalPages && page !== internalCurrentPage) {
193
+ internalCurrentPage = page;
194
+ onpagechange?.(internalCurrentPage);
195
+ }
196
+ }
197
+
198
+ function handlePageSizeChange(event: Event) {
199
+ const select = event.target as HTMLSelectElement;
200
+ const newPageSize = parseInt(select.value, 10);
201
+ internalPageSize = newPageSize;
202
+
203
+ // Adjust current page if it would exceed the new total pages
204
+ const newTotalPages = Math.ceil(effectiveTotalItems / newPageSize);
205
+ if (internalCurrentPage > newTotalPages) {
206
+ internalCurrentPage = newTotalPages || 1;
207
+ }
208
+
209
+ onpagesizechange?.(newPageSize);
210
+ onpagechange?.(internalCurrentPage);
211
+ }
212
+
213
+ function getPageNumbers(): number[] {
214
+ const pages: number[] = [];
215
+ const maxPages = 5;
216
+ const halfMax = Math.floor(maxPages / 2);
217
+
218
+ let start = Math.max(1, internalCurrentPage - halfMax);
219
+ let end = Math.min(totalPages, start + maxPages - 1);
220
+
221
+ if (end - start + 1 < maxPages) {
222
+ start = Math.max(1, end - maxPages + 1);
223
+ }
224
+
225
+ for (let i = start; i <= end; i++) {
226
+ pages.push(i);
136
227
  }
228
+
229
+ return pages;
137
230
  }
138
231
  </script>
139
232
 
140
233
  <div class={baseClasses}>
234
+ {#if showPaginationControls && (paginationPosition === 'top' || paginationPosition === 'both')}
235
+ <div class={footerClasses}>
236
+ <div class={paginationClasses}>
237
+ <div class="flex items-center gap-2">
238
+ {#if showPageSize}
239
+ <div class="flex items-center gap-2">
240
+ <label for="table-page-size" class="text-default-500 text-sm">Show</label>
241
+ <select
242
+ id="table-page-size"
243
+ class="border-default-200 rounded-md border px-2 py-1 text-sm"
244
+ value={internalPageSize}
245
+ onchange={handlePageSizeChange}
246
+ >
247
+ {#each pageSizeOptions as option}
248
+ <option value={option}>{option}</option>
249
+ {/each}
250
+ </select>
251
+ <span class="text-default-500 text-sm">entries</span>
252
+ </div>
253
+ {/if}
254
+ <span class="text-default-500 text-sm">
255
+ Showing {Math.min(
256
+ (internalCurrentPage - 1) * internalPageSize + 1,
257
+ effectiveTotalItems
258
+ )}
259
+ to {Math.min(internalCurrentPage * internalPageSize, effectiveTotalItems)} of {effectiveTotalItems}
260
+ entries
261
+ </span>
262
+ </div>
263
+
264
+ <div class="flex items-center gap-1">
265
+ {#if paginationTemplate === 'full'}
266
+ <!-- First page button -->
267
+ <button
268
+ type="button"
269
+ class={cn(
270
+ 'relative inline-flex items-center rounded-md px-2 py-1 text-sm font-medium',
271
+ internalCurrentPage === 1
272
+ ? 'text-default-300 cursor-not-allowed'
273
+ : 'text-default-700 hover:bg-default-100'
274
+ )}
275
+ onclick={goToFirstPage}
276
+ disabled={internalCurrentPage === 1}
277
+ aria-label="First page"
278
+ >
279
+ <!-- Double Chevron Left SVG -->
280
+ <svg
281
+ xmlns="http://www.w3.org/2000/svg"
282
+ width="16"
283
+ height="16"
284
+ viewBox="0 0 24 24"
285
+ fill="none"
286
+ stroke="currentColor"
287
+ stroke-width="2"
288
+ stroke-linecap="round"
289
+ stroke-linejoin="round"
290
+ class="h-4 w-4"
291
+ >
292
+ <path d="m11 17-5-5 5-5"></path>
293
+ <path d="m18 17-5-5 5-5"></path>
294
+ </svg>
295
+ </button>
296
+ {/if}
297
+
298
+ <!-- Previous page button -->
299
+ <button
300
+ type="button"
301
+ class={cn(
302
+ 'relative inline-flex items-center rounded-md px-2 py-1 text-sm font-medium',
303
+ internalCurrentPage === 1
304
+ ? 'text-default-300 cursor-not-allowed'
305
+ : 'text-default-700 hover:bg-default-100'
306
+ )}
307
+ onclick={prevPage}
308
+ disabled={internalCurrentPage === 1}
309
+ aria-label="Previous page"
310
+ >
311
+ <!-- Chevron Left SVG -->
312
+ <svg
313
+ xmlns="http://www.w3.org/2000/svg"
314
+ width="16"
315
+ height="16"
316
+ viewBox="0 0 24 24"
317
+ fill="none"
318
+ stroke="currentColor"
319
+ stroke-width="2"
320
+ stroke-linecap="round"
321
+ stroke-linejoin="round"
322
+ class="h-4 w-4"
323
+ >
324
+ <path d="m15 18-6-6 6-6"></path>
325
+ </svg>
326
+ </button>
327
+
328
+ <!-- Page numbers -->
329
+ {#if paginationTemplate === 'full'}
330
+ {#each getPageNumbers() as pageNum}
331
+ <button
332
+ type="button"
333
+ class={cn(
334
+ 'relative inline-flex items-center rounded-md px-3 py-1 text-sm font-medium',
335
+ internalCurrentPage === pageNum
336
+ ? 'bg-primary-100 text-primary-700'
337
+ : 'text-default-700 hover:bg-default-100'
338
+ )}
339
+ onclick={() => goToPage(pageNum)}
340
+ aria-label={`Page ${pageNum}`}
341
+ aria-current={internalCurrentPage === pageNum ? 'page' : undefined}
342
+ >
343
+ {pageNum}
344
+ </button>
345
+ {/each}
346
+ {:else}
347
+ <span class="text-default-500 px-2 text-sm">
348
+ Page {internalCurrentPage} of {totalPages}
349
+ </span>
350
+ {/if}
351
+
352
+ <!-- Next page button -->
353
+ <button
354
+ type="button"
355
+ class={cn(
356
+ 'relative inline-flex items-center rounded-md px-2 py-1 text-sm font-medium',
357
+ internalCurrentPage === totalPages
358
+ ? 'text-default-300 cursor-not-allowed'
359
+ : 'text-default-700 hover:bg-default-100'
360
+ )}
361
+ onclick={nextPage}
362
+ disabled={internalCurrentPage === totalPages}
363
+ aria-label="Next page"
364
+ >
365
+ <!-- Chevron Right SVG -->
366
+ <svg
367
+ xmlns="http://www.w3.org/2000/svg"
368
+ width="16"
369
+ height="16"
370
+ viewBox="0 0 24 24"
371
+ fill="none"
372
+ stroke="currentColor"
373
+ stroke-width="2"
374
+ stroke-linecap="round"
375
+ stroke-linejoin="round"
376
+ class="h-4 w-4"
377
+ >
378
+ <path d="m9 18 6-6-6-6"></path>
379
+ </svg>
380
+ </button>
381
+
382
+ {#if paginationTemplate === 'full'}
383
+ <!-- Last page button -->
384
+ <button
385
+ type="button"
386
+ class={cn(
387
+ 'relative inline-flex items-center rounded-md px-2 py-1 text-sm font-medium',
388
+ internalCurrentPage === totalPages
389
+ ? 'text-default-300 cursor-not-allowed'
390
+ : 'text-default-700 hover:bg-default-100'
391
+ )}
392
+ onclick={goToLastPage}
393
+ disabled={internalCurrentPage === totalPages}
394
+ aria-label="Last page"
395
+ >
396
+ <!-- Double Chevron Right SVG -->
397
+ <svg
398
+ xmlns="http://www.w3.org/2000/svg"
399
+ width="16"
400
+ height="16"
401
+ viewBox="0 0 24 24"
402
+ fill="none"
403
+ stroke="currentColor"
404
+ stroke-width="2"
405
+ stroke-linecap="round"
406
+ stroke-linejoin="round"
407
+ class="h-4 w-4"
408
+ >
409
+ <path d="m13 17 5-5-5-5"></path>
410
+ <path d="m6 17 5-5-5-5"></path>
411
+ </svg>
412
+ </button>
413
+ {/if}
414
+ </div>
415
+ </div>
416
+ </div>
417
+ {/if}
418
+
141
419
  <div class={wrapperClasses}>
142
420
  <table class={tableClasses}>
143
421
  <thead class={theadClasses}>
@@ -260,7 +538,7 @@
260
538
  </div>
261
539
  </td>
262
540
  </tr>
263
- {:else if paginatedData.length === 0}
541
+ {:else if getPaginatedData().length === 0}
264
542
  <tr>
265
543
  <td
266
544
  colspan={selectable ? columns.length + 1 : columns.length}
@@ -270,13 +548,12 @@
270
548
  </td>
271
549
  </tr>
272
550
  {:else}
273
- {#each paginatedData as row, rowIndex (rowIndex)}
551
+ {#each getPaginatedData() as row, rowIndex}
274
552
  <tr
275
- class={cn(
276
- trClasses,
277
- rowclass(row, rowIndex),
278
- selectable && isRowSelected(row) && 'bg-primary-100'
279
- )}
553
+ class={cn(trClasses, rowclass(row, rowIndex), {
554
+ 'bg-primary-100': selectable && isRowSelected(row),
555
+ 'cursor-pointer': onrowclick
556
+ })}
280
557
  onclick={() => handleRowClick(row, rowIndex)}
281
558
  aria-selected={selectable && isRowSelected(row)}
282
559
  >
@@ -326,91 +603,186 @@
326
603
  </table>
327
604
  </div>
328
605
 
329
- {#if pagination && totalPages > 1}
606
+ {#if showPaginationControls && (paginationPosition === 'bottom' || paginationPosition === 'both')}
330
607
  <div class={footerClasses}>
331
- <div class={paginationBaseClass()}>
608
+ <div class={paginationClasses}>
332
609
  <div class="flex items-center gap-2">
610
+ {#if showPageSize}
611
+ <div class="flex items-center gap-2">
612
+ <label for="table-page-size-bottom" class="text-default-500 text-sm">Show</label>
613
+ <select
614
+ id="table-page-size-bottom"
615
+ class="border-default-200 rounded-md border px-2 py-1 text-sm"
616
+ value={internalPageSize}
617
+ onchange={handlePageSizeChange}
618
+ >
619
+ {#each pageSizeOptions as option}
620
+ <option value={option}>{option}</option>
621
+ {/each}
622
+ </select>
623
+ <span class="text-default-500 text-sm">entries</span>
624
+ </div>
625
+ {/if}
333
626
  <span class="text-default-500 text-sm">
334
- Showing {Math.min((currentPage - 1) * pageSize + 1, data.length)}
335
- to {Math.min(currentPage * pageSize, data.length)} of {data.length} entries
627
+ Showing {Math.min(
628
+ (internalCurrentPage - 1) * internalPageSize + 1,
629
+ effectiveTotalItems
630
+ )}
631
+ to {Math.min(internalCurrentPage * internalPageSize, effectiveTotalItems)} of {effectiveTotalItems}
632
+ entries
336
633
  </span>
337
634
  </div>
338
635
 
339
636
  <div class="flex items-center gap-1">
637
+ {#if paginationTemplate === 'full'}
638
+ <!-- First page button -->
639
+ <button
640
+ type="button"
641
+ class={cn(
642
+ 'relative inline-flex items-center rounded-md px-2 py-1 text-sm font-medium',
643
+ internalCurrentPage === 1
644
+ ? 'text-default-300 cursor-not-allowed'
645
+ : 'text-default-700 hover:bg-default-100'
646
+ )}
647
+ onclick={goToFirstPage}
648
+ disabled={internalCurrentPage === 1}
649
+ aria-label="First page"
650
+ >
651
+ <!-- Double Chevron Left SVG -->
652
+ <svg
653
+ xmlns="http://www.w3.org/2000/svg"
654
+ width="16"
655
+ height="16"
656
+ viewBox="0 0 24 24"
657
+ fill="none"
658
+ stroke="currentColor"
659
+ stroke-width="2"
660
+ stroke-linecap="round"
661
+ stroke-linejoin="round"
662
+ class="h-4 w-4"
663
+ >
664
+ <path d="m11 17-5-5 5-5"></path>
665
+ <path d="m18 17-5-5 5-5"></path>
666
+ </svg>
667
+ </button>
668
+ {/if}
669
+
670
+ <!-- Previous page button -->
340
671
  <button
341
672
  type="button"
342
673
  class={cn(
343
674
  'relative inline-flex items-center rounded-md px-2 py-1 text-sm font-medium',
344
- currentPage === 1
675
+ internalCurrentPage === 1
345
676
  ? 'text-default-300 cursor-not-allowed'
346
677
  : 'text-default-700 hover:bg-default-100'
347
678
  )}
348
679
  onclick={prevPage}
349
- disabled={currentPage === 1}
680
+ disabled={internalCurrentPage === 1}
350
681
  aria-label="Previous page"
351
682
  >
683
+ <!-- Chevron Left SVG -->
352
684
  <svg
353
685
  xmlns="http://www.w3.org/2000/svg"
354
- viewBox="0 0 20 20"
355
- fill="currentColor"
356
- class="h-5 w-5"
686
+ width="16"
687
+ height="16"
688
+ viewBox="0 0 24 24"
689
+ fill="none"
690
+ stroke="currentColor"
691
+ stroke-width="2"
692
+ stroke-linecap="round"
693
+ stroke-linejoin="round"
694
+ class="h-4 w-4"
357
695
  >
358
- <path
359
- d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z"
360
- />
696
+ <path d="m15 18-6-6 6-6"></path>
361
697
  </svg>
362
698
  </button>
363
699
 
364
- <!--eslint-disable-next-line @typescript-eslint/no-unused-vars-->
365
- {#each Array(Math.min(5, totalPages)) as _, i (i)}
366
- {@const pageNum =
367
- currentPage <= 3
368
- ? i + 1
369
- : currentPage >= totalPages - 2
370
- ? totalPages - 4 + i
371
- : currentPage - 2 + i}
372
-
373
- {#if pageNum > 0 && pageNum <= totalPages}
700
+ <!-- Page numbers -->
701
+ {#if paginationTemplate === 'full'}
702
+ {#each getPageNumbers() as pageNum}
374
703
  <button
375
704
  type="button"
376
705
  class={cn(
377
706
  'relative inline-flex items-center rounded-md px-3 py-1 text-sm font-medium',
378
- currentPage === pageNum
707
+ internalCurrentPage === pageNum
379
708
  ? 'bg-primary-100 text-primary-700'
380
709
  : 'text-default-700 hover:bg-default-100'
381
710
  )}
382
711
  onclick={() => goToPage(pageNum)}
383
712
  aria-label={`Page ${pageNum}`}
384
- aria-current={currentPage === pageNum ? 'page' : undefined}
713
+ aria-current={internalCurrentPage === pageNum ? 'page' : undefined}
385
714
  >
386
715
  {pageNum}
387
716
  </button>
388
- {/if}
389
- {/each}
717
+ {/each}
718
+ {:else}
719
+ <span class="text-default-500 px-2 text-sm">
720
+ Page {internalCurrentPage} of {totalPages}
721
+ </span>
722
+ {/if}
390
723
 
724
+ <!-- Next page button -->
391
725
  <button
392
726
  type="button"
393
727
  class={cn(
394
728
  'relative inline-flex items-center rounded-md px-2 py-1 text-sm font-medium',
395
- currentPage === totalPages
729
+ internalCurrentPage === totalPages
396
730
  ? 'text-default-300 cursor-not-allowed'
397
731
  : 'text-default-700 hover:bg-default-100'
398
732
  )}
399
733
  onclick={nextPage}
400
- disabled={currentPage === totalPages}
734
+ disabled={internalCurrentPage === totalPages}
401
735
  aria-label="Next page"
402
736
  >
737
+ <!-- Chevron Right SVG -->
403
738
  <svg
404
739
  xmlns="http://www.w3.org/2000/svg"
405
- viewBox="0 0 20 20"
406
- fill="currentColor"
407
- class="h-5 w-5"
740
+ width="16"
741
+ height="16"
742
+ viewBox="0 0 24 24"
743
+ fill="none"
744
+ stroke="currentColor"
745
+ stroke-width="2"
746
+ stroke-linecap="round"
747
+ stroke-linejoin="round"
748
+ class="h-4 w-4"
408
749
  >
409
- <path
410
- d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z"
411
- />
750
+ <path d="m9 18 6-6-6-6"></path>
412
751
  </svg>
413
752
  </button>
753
+
754
+ {#if paginationTemplate === 'full'}
755
+ <!-- Last page button -->
756
+ <button
757
+ type="button"
758
+ class={cn(
759
+ 'relative inline-flex items-center rounded-md px-2 py-1 text-sm font-medium',
760
+ internalCurrentPage === totalPages
761
+ ? 'text-default-300 cursor-not-allowed'
762
+ : 'text-default-700 hover:bg-default-100'
763
+ )}
764
+ onclick={goToLastPage}
765
+ disabled={internalCurrentPage === totalPages}
766
+ aria-label="Last page"
767
+ >
768
+ <!-- Double Chevron Right SVG -->
769
+ <svg
770
+ xmlns="http://www.w3.org/2000/svg"
771
+ width="16"
772
+ height="16"
773
+ viewBox="0 0 24 24"
774
+ fill="none"
775
+ stroke="currentColor"
776
+ stroke-width="2"
777
+ stroke-linecap="round"
778
+ stroke-linejoin="round"
779
+ class="h-4 w-4"
780
+ >
781
+ <path d="m13 17 5-5-5-5"></path>
782
+ <path d="m6 17 5-5-5-5"></path>
783
+ </svg>
784
+ </button>
785
+ {/if}
414
786
  </div>
415
787
  </div>
416
788
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makolabs/ripple",
3
- "version": "0.0.1-dev.55",
3
+ "version": "0.0.1-dev.57",
4
4
  "description": "Simple Svelte 5 powered component library ✨",
5
5
  "repository": {
6
6
  "type": "git",