@juspay/svelte-ui-components 2.80.10 → 2.81.0

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/README.md CHANGED
@@ -91,7 +91,7 @@ This library takes a different approach: **components are unstyled by default**
91
91
  | **ListItem** | Multi-section list row with images, labels, and accordion expansion. | [docs](docs/ListItem.md) |
92
92
  | **Pill** | Compact label/tag for status or categories, optionally clickable with a11y. | [docs](docs/Pill.md) |
93
93
  | **Status** | Full-screen status display for success/failure screens. | [docs](docs/Status.md) |
94
- | **Table** | Sortable data table with sticky headers and per-cell scrolling. | [docs](docs/Table.md) |
94
+ | **Table** | Data table with keyed columns, built-in cell renderers, sorting, pagination and selection. | [docs](docs/Table.md) |
95
95
  | **RelativeTime** | Auto-updating relative time display ("5 minutes ago") with locale support and optional tooltip. | [docs](docs/RelativeTime.md) |
96
96
 
97
97
  ### Feedback & Loading
@@ -0,0 +1,607 @@
1
+ <script lang="ts">
2
+ import { onDestroy } from 'svelte';
3
+ import type { TableCellValue, TableColumn } from './properties';
4
+ import {
5
+ asActionGroupCellData,
6
+ asAvatarStackData,
7
+ asButtonCellData,
8
+ asCompareCellData,
9
+ asInputCellData,
10
+ asInputDataType,
11
+ asJsonObject,
12
+ asLinkCellData,
13
+ asPopupMenuCellData,
14
+ asSelectCellData,
15
+ asTagArrayItems,
16
+ asTagCellData,
17
+ buildAvatarStack,
18
+ cellValueToText
19
+ } from './cellData';
20
+ import Pill from '../Pill/Pill.svelte';
21
+ import Img from '../Img/Img.svelte';
22
+ import IconStack from '../IconStack/IconStack.svelte';
23
+ import Toggle from '../Toggle/Toggle.svelte';
24
+ import Button from '../Button/Button.svelte';
25
+ import Select from '../Select/Select.svelte';
26
+ import Input from '../Input/Input.svelte';
27
+ import Menu from '../Menu/Menu.svelte';
28
+ import trendUpSvg from '../assets/trend-up.svg?raw';
29
+ import trendDownSvg from '../assets/trend-down.svg?raw';
30
+ import copySvg from '../assets/copy.svg?raw';
31
+ import dotsSvg from '../assets/dots-vertical.svg?raw';
32
+
33
+ let {
34
+ column,
35
+ value,
36
+ rowIndex
37
+ }: {
38
+ column: TableColumn;
39
+ value: TableCellValue;
40
+ rowIndex: number;
41
+ } = $props();
42
+
43
+ let copied = $state(false);
44
+ let copyResetTimer: ReturnType<typeof setTimeout> | null = null;
45
+
46
+ onDestroy(() => {
47
+ if (copyResetTimer) {
48
+ clearTimeout(copyResetTimer);
49
+ }
50
+ });
51
+
52
+ // Interactive cells stop click/keydown propagation so a clickable row's
53
+ // onRowClick never mis-fires from within a built-in control — the same
54
+ // pattern Table's own checkbox column uses. Scoped to built-in renderers
55
+ // only; bare cell-snippet consumers keep owning their own propagation.
56
+ const stopClickPropagation = (event: MouseEvent): void => {
57
+ event.stopPropagation();
58
+ };
59
+
60
+ const stopKeydownPropagation = (event: KeyboardEvent): void => {
61
+ event.stopPropagation();
62
+ };
63
+
64
+ const handleCopy = async (url: string): Promise<void> => {
65
+ // SSR / non-secure-context safety: the library renders server-side and as
66
+ // web components, where the clipboard API may be absent.
67
+ if (typeof navigator === 'undefined' || !navigator.clipboard) {
68
+ return;
69
+ }
70
+ try {
71
+ await navigator.clipboard.writeText(url);
72
+ copied = true;
73
+ if (copyResetTimer) {
74
+ clearTimeout(copyResetTimer);
75
+ }
76
+ copyResetTimer = setTimeout(() => {
77
+ copied = false;
78
+ }, 2000);
79
+ } catch {
80
+ copied = false;
81
+ }
82
+ };
83
+ </script>
84
+
85
+ {#if column.type === 'tag'}
86
+ {@const tag = asTagCellData(value)}
87
+ {#if tag}
88
+ <Pill
89
+ text={tag.text}
90
+ classes={tag.classes ?? ''}
91
+ dismissible={tag.dismissible ?? false}
92
+ testId={tag.testId}
93
+ />
94
+ {:else}
95
+ {cellValueToText(value)}
96
+ {/if}
97
+ {:else if column.type === 'text-tag'}
98
+ {@const data = asJsonObject(value) ?? {}}
99
+ {@const tag = asTagCellData(data.tag ?? null)}
100
+ <div class="builtin-text-tag">
101
+ <span class="builtin-primary-text"
102
+ >{typeof data.text === 'string' ? data.text : cellValueToText(value)}</span
103
+ >
104
+ {#if tag}
105
+ <Pill
106
+ text={tag.text}
107
+ classes={tag.classes ?? ''}
108
+ dismissible={tag.dismissible ?? false}
109
+ testId={tag.testId}
110
+ />
111
+ {/if}
112
+ </div>
113
+ {:else if column.type === 'two-line-text'}
114
+ {@const data = asJsonObject(value) ?? {}}
115
+ <div class="builtin-two-line">
116
+ <span class="builtin-primary-text">{typeof data.text1 === 'string' ? data.text1 : '-'}</span>
117
+ <span class="builtin-secondary-text">{typeof data.text2 === 'string' ? data.text2 : '-'}</span>
118
+ </div>
119
+ {:else if column.type === 'icon-label'}
120
+ {@const data = asJsonObject(value) ?? {}}
121
+ {@const icons = Array.isArray(data.icons)
122
+ ? data.icons.filter((iconSrc) => typeof iconSrc === 'string')
123
+ : []}
124
+ <div class="builtin-icon-label">
125
+ {#each icons as iconSrc, iconIndex (`${iconIndex}-${iconSrc}`)}
126
+ <span class="builtin-icon-label-icon">
127
+ <Img src={String(iconSrc)} alt="" fallback="" />
128
+ </span>
129
+ {/each}
130
+ <span>{typeof data.label === 'string' ? data.label : '-'}</span>
131
+ </div>
132
+ {:else if column.type === 'image-two-line-text'}
133
+ {@const data = asJsonObject(value) ?? {}}
134
+ <div class="builtin-image-two-line">
135
+ {#if typeof data.imageUrl === 'string' && data.imageUrl}
136
+ <span class="builtin-thumb">
137
+ <Img
138
+ src={data.imageUrl}
139
+ alt={typeof data.text1 === 'string' ? data.text1 : ''}
140
+ fallback=""
141
+ />
142
+ </span>
143
+ {:else}
144
+ <span class="builtin-thumb builtin-thumb-placeholder"></span>
145
+ {/if}
146
+ <div class="builtin-two-line">
147
+ <span class="builtin-primary-text">{typeof data.text1 === 'string' ? data.text1 : '-'}</span>
148
+ <span class="builtin-secondary-text">{typeof data.text2 === 'string' ? data.text2 : '-'}</span
149
+ >
150
+ </div>
151
+ </div>
152
+ {:else if column.type === 'tag-array'}
153
+ {@const tags = asTagArrayItems(value)}
154
+ {#if tags}
155
+ <div class="builtin-tag-array">
156
+ {#each tags as tag (tag.text)}
157
+ <Pill text={tag.text} classes={tag.classes ?? ''} />
158
+ {/each}
159
+ </div>
160
+ {:else}
161
+ {cellValueToText(value)}
162
+ {/if}
163
+ {:else if column.type === 'avatar-stack'}
164
+ {@const stackData = asAvatarStackData(value)}
165
+ {#if stackData}
166
+ {@const stack = buildAvatarStack(stackData)}
167
+ <div class="builtin-avatar-stack">
168
+ <IconStack icons={stack.icons} />
169
+ {#if stack.rest > 0}
170
+ <span class="builtin-avatar-rest">+{stack.rest}</span>
171
+ {/if}
172
+ </div>
173
+ {:else}
174
+ {cellValueToText(value)}
175
+ {/if}
176
+ {:else if column.type === 'compare'}
177
+ {#if typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' || value === null}
178
+ {cellValueToText(value)}
179
+ {:else}
180
+ {@const compare = asCompareCellData(value)}
181
+ {#if compare}
182
+ <div class="builtin-compare">
183
+ {#if typeof compare.primary === 'string'}
184
+ <span class="builtin-primary-text">{compare.primary}</span>
185
+ {/if}
186
+ {#if typeof compare.comparison === 'string'}
187
+ <span class="builtin-secondary-text">{compare.comparison}</span>
188
+ {/if}
189
+ {#if typeof compare.trendPercent === 'number'}
190
+ {#if compare.trendPercent > 0}
191
+ <span class="builtin-trend builtin-trend-up">
192
+ <!-- eslint-disable svelte/no-at-html-tags -->
193
+ <span class="builtin-trend-icon">{@html trendUpSvg}</span>
194
+ {compare.trendPercent}%
195
+ </span>
196
+ {:else if compare.trendPercent < 0}
197
+ <span class="builtin-trend builtin-trend-down">
198
+ <!-- eslint-disable svelte/no-at-html-tags -->
199
+ <span class="builtin-trend-icon">{@html trendDownSvg}</span>
200
+ {compare.trendPercent}%
201
+ </span>
202
+ {:else}
203
+ <span class="builtin-trend builtin-trend-flat">↔ 0%</span>
204
+ {/if}
205
+ {:else if typeof compare.trendLabel === 'string'}
206
+ <span class="builtin-trend builtin-trend-flat">{compare.trendLabel}</span>
207
+ {/if}
208
+ </div>
209
+ {:else}
210
+ {cellValueToText(value)}
211
+ {/if}
212
+ {/if}
213
+ {:else if column.type === 'toggle'}
214
+ {@const data = asJsonObject(value) ?? {}}
215
+ {@const isChecked = data.checked === true}
216
+ <span
217
+ class="builtin-toggle"
218
+ role="switch"
219
+ aria-checked={isChecked ? 'true' : 'false'}
220
+ aria-label={typeof data.ariaLabel === 'string' ? data.ariaLabel : null}
221
+ data-pw={typeof data.testId === 'string' ? data.testId : null}
222
+ onclick={stopClickPropagation}
223
+ onkeydown={stopKeydownPropagation}
224
+ tabindex={-1}
225
+ >
226
+ <Toggle
227
+ checked={isChecked}
228
+ text=""
229
+ onclick={(newChecked) => column.onToggle?.(rowIndex, newChecked)}
230
+ />
231
+ </span>
232
+ {:else if column.type === 'select'}
233
+ {@const selectData = asSelectCellData(value)}
234
+ {#if selectData}
235
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
236
+ <span
237
+ class="builtin-interactive"
238
+ onclick={stopClickPropagation}
239
+ onkeydown={stopKeydownPropagation}
240
+ >
241
+ <Select
242
+ items={selectData.options}
243
+ value={selectData.selectedId ? [selectData.selectedId] : []}
244
+ placeholder={selectData.placeholder ?? ''}
245
+ disabled={selectData.disabled ?? false}
246
+ testId={selectData.testId}
247
+ onchange={(selectedIds) => {
248
+ if (selectedIds.length > 0) {
249
+ column.onSelect?.(rowIndex, selectedIds[0]);
250
+ }
251
+ }}
252
+ />
253
+ </span>
254
+ {:else}
255
+ {cellValueToText(value)}
256
+ {/if}
257
+ {:else if column.type === 'input'}
258
+ {@const inputData = asInputCellData(value)}
259
+ {#if inputData}
260
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
261
+ <span
262
+ class="builtin-interactive"
263
+ onclick={stopClickPropagation}
264
+ onkeydown={stopKeydownPropagation}
265
+ >
266
+ <Input
267
+ value={inputData.value ?? ''}
268
+ placeholder={inputData.placeholder ?? ''}
269
+ disable={inputData.disabled ?? false}
270
+ testId={inputData.testId ?? ''}
271
+ dataType={asInputDataType(inputData.dataType ?? null)}
272
+ validationPattern={inputData.validationPattern
273
+ ? new RegExp(inputData.validationPattern)
274
+ : null}
275
+ onErrorMessage={inputData.onErrorMessage ?? null}
276
+ actionInput={false}
277
+ onInput={(newValue) => column.onInput?.(rowIndex, newValue)}
278
+ />
279
+ </span>
280
+ {:else}
281
+ {cellValueToText(value)}
282
+ {/if}
283
+ {:else if column.type === 'button'}
284
+ {@const buttonData = asButtonCellData(value)}
285
+ {#if buttonData}
286
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
287
+ <span
288
+ class="builtin-interactive"
289
+ onclick={stopClickPropagation}
290
+ onkeydown={stopKeydownPropagation}
291
+ >
292
+ <Button
293
+ text={buttonData.text}
294
+ disabled={buttonData.disabled ?? false}
295
+ classes={buttonData.classes ?? ''}
296
+ testId={buttonData.testId}
297
+ onclick={() => column.onButtonClick?.(rowIndex)}
298
+ />
299
+ </span>
300
+ {:else}
301
+ {cellValueToText(value)}
302
+ {/if}
303
+ {:else if column.type === 'action-group'}
304
+ {@const actionData = asActionGroupCellData(value)}
305
+ {#if actionData}
306
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
307
+ <span
308
+ class="builtin-interactive builtin-action-group"
309
+ onclick={stopClickPropagation}
310
+ onkeydown={stopKeydownPropagation}
311
+ >
312
+ {#if actionData.primaryButton}
313
+ {@const primary = actionData.primaryButton}
314
+ <Button
315
+ text={primary.text}
316
+ disabled={primary.disabled ?? false}
317
+ classes={primary.classes ?? ''}
318
+ testId={primary.testId}
319
+ onclick={() => column.onPrimaryAction?.(rowIndex)}
320
+ />
321
+ {/if}
322
+ {#if actionData.menuItems && actionData.menuItems.length > 0}
323
+ <Menu
324
+ items={actionData.menuItems.map((item) => ({
325
+ value: item.id,
326
+ label: item.label ?? item.id,
327
+ danger: item.danger,
328
+ separator: item.separator
329
+ }))}
330
+ testId={column.testId && `${column.testId}-menu-${rowIndex}`}
331
+ onselect={(menuItem) => column.onMenuAction?.(rowIndex, menuItem.value)}
332
+ >
333
+ {#snippet trigger()}
334
+ <span class="builtin-icon-button">
335
+ <Button
336
+ ariaLabel="More actions"
337
+ testId={column.testId && `${column.testId}-menu-trigger-${rowIndex}`}
338
+ >
339
+ {#snippet icon()}
340
+ <!-- eslint-disable svelte/no-at-html-tags -->
341
+ <span class="builtin-menu-dots">{@html dotsSvg}</span>
342
+ {/snippet}
343
+ </Button>
344
+ </span>
345
+ {/snippet}
346
+ </Menu>
347
+ {/if}
348
+ </span>
349
+ {:else}
350
+ {cellValueToText(value)}
351
+ {/if}
352
+ {:else if column.type === 'popup-menu'}
353
+ {@const popupData = asPopupMenuCellData(value)}
354
+ {#if popupData}
355
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
356
+ <span
357
+ class="builtin-interactive"
358
+ onclick={stopClickPropagation}
359
+ onkeydown={stopKeydownPropagation}
360
+ >
361
+ <Menu
362
+ items={popupData.items.map((item) => ({
363
+ value: item.id,
364
+ label: item.label ?? item.id,
365
+ danger: item.danger,
366
+ separator: item.separator
367
+ }))}
368
+ testId={column.testId && `${column.testId}-popup-${rowIndex}`}
369
+ onselect={(menuItem) => column.onMenuAction?.(rowIndex, menuItem.value)}
370
+ >
371
+ {#snippet trigger()}
372
+ <span class="builtin-icon-button">
373
+ <Button
374
+ ariaLabel={popupData.ariaLabel ?? 'More actions'}
375
+ testId={column.testId && `${column.testId}-popup-trigger-${rowIndex}`}
376
+ >
377
+ {#snippet icon()}
378
+ <!-- eslint-disable svelte/no-at-html-tags -->
379
+ <span class="builtin-menu-dots">{@html dotsSvg}</span>
380
+ {/snippet}
381
+ </Button>
382
+ </span>
383
+ {/snippet}
384
+ </Menu>
385
+ </span>
386
+ {:else}
387
+ {cellValueToText(value)}
388
+ {/if}
389
+ {:else if column.type === 'link'}
390
+ {@const link = asLinkCellData(value)}
391
+ {#if link}
392
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
393
+ <div class="builtin-link" onclick={stopClickPropagation} onkeydown={stopKeydownPropagation}>
394
+ <a
395
+ href={link.url}
396
+ target="_blank"
397
+ rel="noopener noreferrer"
398
+ class="builtin-link-anchor"
399
+ data-pw={column.testId ? `${column.testId}-link-${rowIndex}` : null}
400
+ >
401
+ {link.label ?? link.url}
402
+ </a>
403
+ {#if link.copyable !== false}
404
+ <span class="builtin-link-copy">
405
+ <Button
406
+ ariaLabel={copied ? 'Link copied' : 'Copy link'}
407
+ testId={column.testId && `${column.testId}-copy-${rowIndex}`}
408
+ onclick={() => handleCopy(link.url)}
409
+ >
410
+ {#snippet icon()}
411
+ <!-- eslint-disable svelte/no-at-html-tags -->
412
+ <span class="builtin-copy-icon">{@html copySvg}</span>
413
+ {/snippet}
414
+ </Button>
415
+ </span>
416
+ {#if copied}
417
+ <span class="builtin-link-copied">Copied</span>
418
+ {/if}
419
+ {/if}
420
+ </div>
421
+ {:else}
422
+ {cellValueToText(value)}
423
+ {/if}
424
+ {:else}
425
+ {cellValueToText(value)}
426
+ {/if}
427
+
428
+ <style>
429
+ .builtin-primary-text {
430
+ display: block;
431
+ font-size: var(--table-cell-primary-font-size, var(--table-content-font-size, 14px));
432
+ color: var(--table-cell-primary-color, var(--table-content-color, #111827));
433
+ }
434
+
435
+ .builtin-secondary-text {
436
+ display: block;
437
+ font-size: var(--table-cell-secondary-font-size, 12px);
438
+ color: var(--table-cell-secondary-color, #6b7280);
439
+ }
440
+
441
+ .builtin-two-line,
442
+ .builtin-compare {
443
+ display: flex;
444
+ flex-direction: column;
445
+ gap: var(--table-cell-line-gap, 2px);
446
+ }
447
+
448
+ .builtin-text-tag {
449
+ display: flex;
450
+ align-items: center;
451
+ gap: var(--table-cell-inline-gap, 8px);
452
+ }
453
+
454
+ .builtin-icon-label {
455
+ display: flex;
456
+ align-items: center;
457
+ gap: var(--table-cell-inline-gap, 8px);
458
+ }
459
+
460
+ .builtin-icon-label-icon :global(img),
461
+ .builtin-icon-label-icon :global(svg) {
462
+ width: var(--table-cell-icon-size, 16px);
463
+ height: var(--table-cell-icon-size, 16px);
464
+ display: block;
465
+ }
466
+
467
+ .builtin-image-two-line {
468
+ display: flex;
469
+ align-items: center;
470
+ gap: var(--table-cell-inline-gap, 8px);
471
+ }
472
+
473
+ .builtin-thumb {
474
+ display: inline-flex;
475
+ width: var(--table-cell-thumb-size, 32px);
476
+ height: var(--table-cell-thumb-size, 32px);
477
+ border-radius: var(--table-cell-thumb-radius, var(--radius, 4px));
478
+ overflow: hidden;
479
+ flex-shrink: 0;
480
+ }
481
+
482
+ .builtin-thumb :global(img) {
483
+ width: 100%;
484
+ height: 100%;
485
+ object-fit: cover;
486
+ }
487
+
488
+ .builtin-thumb-placeholder {
489
+ background-color: var(--table-cell-thumb-placeholder-background, #f3f4f6);
490
+ }
491
+
492
+ .builtin-tag-array {
493
+ display: flex;
494
+ flex-wrap: wrap;
495
+ gap: var(--table-tag-array-gap, 4px);
496
+ }
497
+
498
+ .builtin-avatar-stack {
499
+ display: flex;
500
+ align-items: center;
501
+ gap: var(--table-cell-inline-gap, 8px);
502
+ }
503
+
504
+ .builtin-avatar-rest {
505
+ font-size: var(--table-cell-secondary-font-size, 12px);
506
+ color: var(--table-cell-secondary-color, #6b7280);
507
+ }
508
+
509
+ .builtin-trend {
510
+ display: inline-flex;
511
+ align-items: center;
512
+ gap: var(--table-trend-gap, 4px);
513
+ font-size: var(--table-cell-secondary-font-size, 12px);
514
+ }
515
+
516
+ .builtin-trend-up {
517
+ color: var(--table-trend-up-color, #16a34a);
518
+ }
519
+
520
+ .builtin-trend-down {
521
+ color: var(--table-trend-down-color, #dc2626);
522
+ }
523
+
524
+ .builtin-trend-flat {
525
+ color: var(--table-trend-flat-color, #6b7280);
526
+ }
527
+
528
+ .builtin-trend-icon :global(svg) {
529
+ width: var(--table-trend-icon-size, 12px);
530
+ height: var(--table-trend-icon-size, 12px);
531
+ display: block;
532
+ }
533
+
534
+ .builtin-toggle {
535
+ display: inline-flex;
536
+ align-items: center;
537
+ }
538
+
539
+ .builtin-interactive {
540
+ display: inline-flex;
541
+ align-items: center;
542
+ min-width: 0;
543
+ }
544
+
545
+ .builtin-action-group {
546
+ gap: var(--table-cell-inline-gap, 8px);
547
+ }
548
+
549
+ .builtin-icon-button {
550
+ --button-color: transparent;
551
+ --button-border: none;
552
+ --button-padding: 2px;
553
+ --button-margin: 0;
554
+ --button-width: fit-content;
555
+ --button-height: fit-content;
556
+ --button-text-color: var(--table-cell-icon-button-color, #6b7280);
557
+ --button-hover-color: var(--table-cell-icon-button-hover-background, rgba(0, 0, 0, 0.05));
558
+ display: inline-flex;
559
+ }
560
+
561
+ .builtin-menu-dots :global(svg) {
562
+ width: var(--table-cell-icon-size, 16px);
563
+ height: var(--table-cell-icon-size, 16px);
564
+ display: block;
565
+ }
566
+
567
+ .builtin-link {
568
+ display: flex;
569
+ align-items: center;
570
+ gap: var(--table-cell-inline-gap, 8px);
571
+ min-width: 0;
572
+ }
573
+
574
+ .builtin-link-anchor {
575
+ color: var(--table-link-color, #2563eb);
576
+ text-decoration: var(--table-link-decoration, underline);
577
+ overflow: hidden;
578
+ text-overflow: ellipsis;
579
+ white-space: nowrap;
580
+ min-width: 0;
581
+ }
582
+
583
+ .builtin-link-copy {
584
+ --button-color: transparent;
585
+ --button-border: none;
586
+ --button-padding: 2px;
587
+ --button-margin: 0;
588
+ --button-width: fit-content;
589
+ --button-height: fit-content;
590
+ --button-text-color: var(--table-link-copy-color, #6b7280);
591
+ --button-hover-color: var(--table-link-copy-hover-background, rgba(0, 0, 0, 0.05));
592
+ display: inline-flex;
593
+ flex-shrink: 0;
594
+ }
595
+
596
+ .builtin-copy-icon :global(svg) {
597
+ width: var(--table-cell-icon-size, 16px);
598
+ height: var(--table-cell-icon-size, 16px);
599
+ display: block;
600
+ }
601
+
602
+ .builtin-link-copied {
603
+ font-size: var(--table-cell-secondary-font-size, 12px);
604
+ color: var(--table-cell-secondary-color, #6b7280);
605
+ flex-shrink: 0;
606
+ }
607
+ </style>
@@ -0,0 +1,9 @@
1
+ import type { TableCellValue, TableColumn } from './properties';
2
+ type $$ComponentProps = {
3
+ column: TableColumn;
4
+ value: TableCellValue;
5
+ rowIndex: number;
6
+ };
7
+ declare const BuiltinCell: import("svelte").Component<$$ComponentProps, {}, "">;
8
+ type BuiltinCell = ReturnType<typeof BuiltinCell>;
9
+ export default BuiltinCell;