@happyvertical/smrt-ui 0.51.39 → 0.52.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.
Files changed (212) hide show
  1. package/AGENTS.md +14 -2
  2. package/README.md +257 -5
  3. package/dist/actions/__tests__/swipe-dismiss.test.js +69 -0
  4. package/dist/actions/swipe-dismiss.d.ts +42 -0
  5. package/dist/actions/swipe-dismiss.d.ts.map +1 -0
  6. package/dist/actions/swipe-dismiss.js +69 -0
  7. package/dist/components/calendar/Calendar.svelte +5 -0
  8. package/dist/components/calendar/Calendar.svelte.d.ts.map +1 -1
  9. package/dist/components/calendar/CalendarView.svelte +1250 -0
  10. package/dist/components/calendar/CalendarView.svelte.d.ts +66 -0
  11. package/dist/components/calendar/CalendarView.svelte.d.ts.map +1 -0
  12. package/dist/components/calendar/DayView.svelte +5 -0
  13. package/dist/components/calendar/DayView.svelte.d.ts.map +1 -1
  14. package/dist/components/calendar/__tests__/CalendarView.test.js +226 -0
  15. package/dist/components/calendar/__tests__/calendar-model.test.js +138 -0
  16. package/dist/components/calendar/calendar-model.d.ts +178 -0
  17. package/dist/components/calendar/calendar-model.d.ts.map +1 -0
  18. package/dist/components/calendar/calendar-model.js +362 -0
  19. package/dist/components/calendar/index.d.ts +12 -1
  20. package/dist/components/calendar/index.d.ts.map +1 -1
  21. package/dist/components/calendar/index.js +11 -1
  22. package/dist/components/data/CollectionList.svelte +23 -5
  23. package/dist/components/data/CollectionList.svelte.d.ts +8 -2
  24. package/dist/components/data/CollectionList.svelte.d.ts.map +1 -1
  25. package/dist/components/data/DataTable.svelte +118 -40
  26. package/dist/components/data/DataTable.svelte.d.ts.map +1 -1
  27. package/dist/components/data/DataTableController.d.ts +4 -0
  28. package/dist/components/data/DataTableController.d.ts.map +1 -1
  29. package/dist/components/data/DataTableController.js +11 -4
  30. package/dist/components/data/ListSortSelect.svelte +121 -0
  31. package/dist/components/data/ListSortSelect.svelte.d.ts +22 -0
  32. package/dist/components/data/ListSortSelect.svelte.d.ts.map +1 -0
  33. package/dist/components/data/SortableHeader.svelte +169 -0
  34. package/dist/components/data/SortableHeader.svelte.d.ts +30 -0
  35. package/dist/components/data/SortableHeader.svelte.d.ts.map +1 -0
  36. package/dist/components/data/__tests__/CollectionList.test.js +37 -0
  37. package/dist/components/data/__tests__/DataTable.test.js +76 -0
  38. package/dist/components/data/__tests__/DataTableController.test.js +35 -0
  39. package/dist/components/data/__tests__/SortableHeader.test.js +101 -0
  40. package/dist/components/data/__tests__/link-step-surface.test.js +172 -0
  41. package/dist/components/data/__tests__/list-sort-state.svelte.test.js +71 -0
  42. package/dist/components/data/__tests__/list-sort.test.js +91 -0
  43. package/dist/components/data/__tests__/surface-navigation.test.js +121 -0
  44. package/dist/components/data/data-surface.d.ts +1 -0
  45. package/dist/components/data/data-surface.d.ts.map +1 -1
  46. package/dist/components/data/data-surface.js +1 -0
  47. package/dist/components/data/index.d.ts +6 -0
  48. package/dist/components/data/index.d.ts.map +1 -1
  49. package/dist/components/data/index.js +6 -0
  50. package/dist/components/data/link-surface.d.ts +79 -0
  51. package/dist/components/data/link-surface.d.ts.map +1 -0
  52. package/dist/components/data/link-surface.js +155 -0
  53. package/dist/components/data/list-sort-state.svelte.d.ts +39 -0
  54. package/dist/components/data/list-sort-state.svelte.d.ts.map +1 -0
  55. package/dist/components/data/list-sort-state.svelte.js +47 -0
  56. package/dist/components/data/list-sort.d.ts +94 -0
  57. package/dist/components/data/list-sort.d.ts.map +1 -0
  58. package/dist/components/data/list-sort.js +182 -0
  59. package/dist/components/data/step-surface.d.ts +73 -0
  60. package/dist/components/data/step-surface.d.ts.map +1 -0
  61. package/dist/components/data/step-surface.js +177 -0
  62. package/dist/components/data/surface-navigation.d.ts +49 -0
  63. package/dist/components/data/surface-navigation.d.ts.map +1 -0
  64. package/dist/components/data/surface-navigation.js +100 -0
  65. package/dist/components/data/types.d.ts +19 -0
  66. package/dist/components/data/types.d.ts.map +1 -1
  67. package/dist/components/feedback/PhoneSheet.svelte +224 -0
  68. package/dist/components/feedback/PhoneSheet.svelte.d.ts +35 -0
  69. package/dist/components/feedback/PhoneSheet.svelte.d.ts.map +1 -0
  70. package/dist/components/feedback/WorkingStrip.svelte +426 -0
  71. package/dist/components/feedback/WorkingStrip.svelte.d.ts +37 -0
  72. package/dist/components/feedback/WorkingStrip.svelte.d.ts.map +1 -0
  73. package/dist/components/feedback/__tests__/PhoneSheet.test.js +101 -0
  74. package/dist/components/feedback/__tests__/WorkingStrip.test.js +172 -0
  75. package/dist/components/feedback/index.d.ts +4 -0
  76. package/dist/components/feedback/index.d.ts.map +1 -1
  77. package/dist/components/feedback/index.js +5 -0
  78. package/dist/components/feedback/working-status.d.ts +34 -0
  79. package/dist/components/feedback/working-status.d.ts.map +1 -0
  80. package/dist/components/feedback/working-status.js +5 -0
  81. package/dist/components/forms/Checkbox.svelte +26 -2
  82. package/dist/components/forms/Combobox.svelte +68 -12
  83. package/dist/components/forms/Combobox.svelte.d.ts +6 -0
  84. package/dist/components/forms/Combobox.svelte.d.ts.map +1 -1
  85. package/dist/components/forms/DictationButton.svelte +128 -0
  86. package/dist/components/forms/DictationButton.svelte.d.ts +19 -0
  87. package/dist/components/forms/DictationButton.svelte.d.ts.map +1 -0
  88. package/dist/components/forms/DictationStatus.svelte +164 -0
  89. package/dist/components/forms/DictationStatus.svelte.d.ts +11 -0
  90. package/dist/components/forms/DictationStatus.svelte.d.ts.map +1 -0
  91. package/dist/components/forms/Fieldset.svelte +5 -1
  92. package/dist/components/forms/Fieldset.svelte.d.ts +2 -0
  93. package/dist/components/forms/Fieldset.svelte.d.ts.map +1 -1
  94. package/dist/components/forms/FormActionBar.svelte +84 -0
  95. package/dist/components/forms/FormActionBar.svelte.d.ts +23 -0
  96. package/dist/components/forms/FormActionBar.svelte.d.ts.map +1 -0
  97. package/dist/components/forms/Input.svelte +9 -0
  98. package/dist/components/forms/Radio.svelte +15 -4
  99. package/dist/components/forms/SearchInput.svelte +207 -0
  100. package/dist/components/forms/SearchInput.svelte.d.ts +22 -0
  101. package/dist/components/forms/SearchInput.svelte.d.ts.map +1 -0
  102. package/dist/components/forms/Select.svelte +9 -0
  103. package/dist/components/forms/StagedControlReview.svelte +21 -12
  104. package/dist/components/forms/StagedControlReview.svelte.d.ts.map +1 -1
  105. package/dist/components/forms/Switch.svelte +11 -5
  106. package/dist/components/forms/TagsInput.svelte +8 -1
  107. package/dist/components/forms/Textarea.svelte +8 -0
  108. package/dist/components/forms/__tests__/Combobox.test.js +87 -0
  109. package/dist/components/forms/__tests__/ControlHitArea.test.js +73 -0
  110. package/dist/components/forms/__tests__/DictationButton.test.js +176 -0
  111. package/dist/components/forms/__tests__/Fieldset.test.js +37 -0
  112. package/dist/components/forms/__tests__/FormActionBar.test.js +22 -0
  113. package/dist/components/forms/__tests__/SearchInput.test.js +92 -0
  114. package/dist/components/forms/__tests__/StagedControlReview.test.js +37 -3
  115. package/dist/components/forms/__tests__/combobox-labels.fixture.svelte +19 -0
  116. package/dist/components/forms/__tests__/combobox-labels.fixture.svelte.d.ts +11 -0
  117. package/dist/components/forms/__tests__/combobox-labels.fixture.svelte.d.ts.map +1 -0
  118. package/dist/components/forms/__tests__/composite-registration.fixture.svelte +29 -0
  119. package/dist/components/forms/__tests__/composite-registration.fixture.svelte.d.ts +8 -0
  120. package/dist/components/forms/__tests__/composite-registration.fixture.svelte.d.ts.map +1 -0
  121. package/dist/components/forms/__tests__/control-interaction.test.js +19 -1
  122. package/dist/components/forms/__tests__/control-proposals.test.js +63 -0
  123. package/dist/components/forms/__tests__/dictation-recording.test.js +582 -0
  124. package/dist/components/forms/__tests__/dictation.test.js +486 -0
  125. package/dist/components/forms/__tests__/long-press.test.js +175 -0
  126. package/dist/components/forms/__tests__/place-picker.fixture.svelte +33 -0
  127. package/dist/components/forms/__tests__/place-picker.fixture.svelte.d.ts +12 -0
  128. package/dist/components/forms/__tests__/place-picker.fixture.svelte.d.ts.map +1 -0
  129. package/dist/components/forms/audio-capture.d.ts +69 -0
  130. package/dist/components/forms/audio-capture.d.ts.map +1 -0
  131. package/dist/components/forms/audio-capture.js +193 -0
  132. package/dist/components/forms/control-interaction.d.ts +6 -0
  133. package/dist/components/forms/control-interaction.d.ts.map +1 -1
  134. package/dist/components/forms/control-interaction.js +12 -1
  135. package/dist/components/forms/control-proposals.d.ts +55 -0
  136. package/dist/components/forms/control-proposals.d.ts.map +1 -0
  137. package/dist/components/forms/control-proposals.js +188 -0
  138. package/dist/components/forms/dictation-transcribe.d.ts +36 -0
  139. package/dist/components/forms/dictation-transcribe.d.ts.map +1 -0
  140. package/dist/components/forms/dictation-transcribe.js +65 -0
  141. package/dist/components/forms/dictation.svelte.d.ts +200 -0
  142. package/dist/components/forms/dictation.svelte.d.ts.map +1 -0
  143. package/dist/components/forms/dictation.svelte.js +686 -0
  144. package/dist/components/forms/index.d.ts +14 -1
  145. package/dist/components/forms/index.d.ts.map +1 -1
  146. package/dist/components/forms/index.js +14 -1
  147. package/dist/components/forms/insert-text.d.ts +12 -0
  148. package/dist/components/forms/insert-text.d.ts.map +1 -0
  149. package/dist/components/forms/insert-text.js +38 -0
  150. package/dist/components/forms/long-press.d.ts +88 -0
  151. package/dist/components/forms/long-press.d.ts.map +1 -0
  152. package/dist/components/forms/long-press.js +213 -0
  153. package/dist/components/forms/ready-beep.d.ts +24 -0
  154. package/dist/components/forms/ready-beep.d.ts.map +1 -0
  155. package/dist/components/forms/ready-beep.js +82 -0
  156. package/dist/components/layout/PageHeader.svelte +151 -17
  157. package/dist/components/layout/PageHeader.svelte.d.ts +47 -7
  158. package/dist/components/layout/PageHeader.svelte.d.ts.map +1 -1
  159. package/dist/components/layout/__tests__/PageHeader.test.js +87 -1
  160. package/dist/components/layout/index.d.ts +1 -0
  161. package/dist/components/layout/index.d.ts.map +1 -1
  162. package/dist/components/layout/index.js +1 -0
  163. package/dist/components/layout/page-header-context.d.ts +25 -0
  164. package/dist/components/layout/page-header-context.d.ts.map +1 -0
  165. package/dist/components/layout/page-header-context.js +16 -0
  166. package/dist/components/nav/Tabs.svelte +241 -0
  167. package/dist/components/nav/Tabs.svelte.d.ts +15 -0
  168. package/dist/components/nav/Tabs.svelte.d.ts.map +1 -1
  169. package/dist/components/nav/__tests__/LinkTabs.test.js +117 -0
  170. package/dist/components/nav/index.d.ts +1 -0
  171. package/dist/components/nav/index.d.ts.map +1 -1
  172. package/dist/components/nav/index.js +1 -0
  173. package/dist/components/nav/tabs-overflow.d.ts +12 -0
  174. package/dist/components/nav/tabs-overflow.d.ts.map +1 -0
  175. package/dist/components/nav/tabs-overflow.js +17 -0
  176. package/dist/components/nav/types.d.ts +8 -0
  177. package/dist/components/nav/types.d.ts.map +1 -1
  178. package/dist/components/ui/Button.svelte +7 -0
  179. package/dist/components/ui/Card.svelte +14 -5
  180. package/dist/components/ui/Dropdown.svelte +55 -1
  181. package/dist/components/ui/Dropdown.svelte.d.ts +8 -0
  182. package/dist/components/ui/Dropdown.svelte.d.ts.map +1 -1
  183. package/dist/components/ui/IconToggle.svelte +139 -0
  184. package/dist/components/ui/IconToggle.svelte.d.ts +32 -0
  185. package/dist/components/ui/IconToggle.svelte.d.ts.map +1 -0
  186. package/dist/components/ui/IconToggleGroup.svelte +56 -0
  187. package/dist/components/ui/IconToggleGroup.svelte.d.ts +21 -0
  188. package/dist/components/ui/IconToggleGroup.svelte.d.ts.map +1 -0
  189. package/dist/components/ui/Pagination.svelte +1 -1
  190. package/dist/components/ui/Popover.svelte +17 -1
  191. package/dist/components/ui/Popover.svelte.d.ts +8 -0
  192. package/dist/components/ui/Popover.svelte.d.ts.map +1 -1
  193. package/dist/components/ui/__tests__/IconToggle.test.js +59 -0
  194. package/dist/components/ui/__tests__/IconToggleGroup.test.js +30 -0
  195. package/dist/components/ui/__tests__/Popover.test.js +44 -0
  196. package/dist/components/ui/__tests__/dropdown-popover-icon.test.js +125 -0
  197. package/dist/components/ui/__tests__/phone-touch-targets.test.js +39 -0
  198. package/dist/components/ui/index.d.ts +2 -0
  199. package/dist/components/ui/index.d.ts.map +1 -1
  200. package/dist/components/ui/index.js +2 -0
  201. package/dist/i18n/strings.ui.d.ts +41 -0
  202. package/dist/i18n/strings.ui.d.ts.map +1 -1
  203. package/dist/i18n/strings.ui.js +46 -0
  204. package/dist/svelte/__tests__/playground.test.js +1 -0
  205. package/dist/svelte/playground/CalendarPreview.svelte +140 -0
  206. package/dist/svelte/playground/CalendarPreview.svelte.d.ts +4 -0
  207. package/dist/svelte/playground/CalendarPreview.svelte.d.ts.map +1 -0
  208. package/dist/svelte/playground.d.ts.map +1 -1
  209. package/dist/svelte/playground.js +10 -0
  210. package/dist/types-generic.d.ts +2 -0
  211. package/dist/types-generic.d.ts.map +1 -1
  212. package/package.json +3 -3
@@ -77,6 +77,7 @@ let {
77
77
  sortable = false,
78
78
  sort = $bindable({ columnId: null, direction: null }),
79
79
  onSortChange,
80
+ sortClearable = true,
80
81
  manualSorting = false,
81
82
  filterFn,
82
83
  page = $bindable(1),
@@ -105,6 +106,7 @@ let {
105
106
  striped = false,
106
107
  hoverable = true,
107
108
  stickyHeader = false,
109
+ phoneLayout = 'scroll',
108
110
  caption,
109
111
  dense = false,
110
112
  cell,
@@ -648,6 +650,10 @@ function handleSort(column: DataTableColumn<T>, event: MouseEvent) {
648
650
  type: 'toggleSorting',
649
651
  columnId: column.id,
650
652
  multi: event.shiftKey,
653
+ ...(column.sortFirstDirection
654
+ ? { firstDirection: column.sortFirstDirection }
655
+ : {}),
656
+ ...(sortClearable ? {} : { clearable: false }),
651
657
  });
652
658
  }
653
659
 
@@ -661,10 +667,22 @@ function sortActionLabel(column: DataTableColumn<T>): string {
661
667
  const columnSort = tableState.sorting.find(
662
668
  (sort) => sort.columnId === column.id,
663
669
  );
664
- if (!columnSort) {
670
+ const first = column.sortFirstDirection === 'desc' ? 'desc' : 'asc';
671
+ const next = !columnSort
672
+ ? first
673
+ : !sortClearable
674
+ ? columnSort.direction === 'asc'
675
+ ? 'desc'
676
+ : 'asc'
677
+ : columnSort.direction === first
678
+ ? first === 'asc'
679
+ ? 'desc'
680
+ : 'asc'
681
+ : null;
682
+ if (next === 'asc') {
665
683
  return t(M['ui.data_table.sort_ascending'], { column: column.label });
666
684
  }
667
- if (columnSort.direction === 'asc') {
685
+ if (next === 'desc') {
668
686
  return t(M['ui.data_table.sort_descending'], { column: column.label });
669
687
  }
670
688
  return t(M['ui.data_table.clear_sort'], { column: column.label });
@@ -1173,6 +1191,12 @@ const errorMessage = $derived.by(() => {
1173
1191
  return message.trim() || t(M['ui.data_table.load_error']);
1174
1192
  });
1175
1193
  const hasRenderedRows = $derived(displayRows.length > 0);
1194
+ // Phone cards restyle table, rows and cells as blocks and grids, which drops
1195
+ // their table roles in WebKit. Explicit roles keep the table, its column
1196
+ // headers (visually hidden, still in the accessibility tree) and every cell
1197
+ // announced as such.
1198
+ const cardsRole = (role: string) =>
1199
+ phoneLayout === 'cards' ? role : undefined;
1176
1200
  const isInitialLoading = $derived(
1177
1201
  (loading || refreshing) && !hasRenderedRows && !errorMessage,
1178
1202
  );
@@ -1392,6 +1416,7 @@ $effect(() => {
1392
1416
  class:data-table-container--overflowing={hasHorizontalOverflow}
1393
1417
  class:data-table-container--virtualized={virtualizationWindow.enabled}
1394
1418
  class:data-table-container--highlighted={surfaceHighlighted}
1419
+ class:data-table-container--phone-cards={phoneLayout === 'cards'}
1395
1420
  style:height={virtualContainerHeight === undefined ? undefined : `${virtualContainerHeight}px`}
1396
1421
  tabindex={virtualizationWindow.enabled || hasHorizontalOverflow ? 0 : dataSurface ? -1 : undefined}
1397
1422
  role={virtualizationWindow.enabled || hasHorizontalOverflow ? 'region' : undefined}
@@ -1411,7 +1436,7 @@ $effect(() => {
1411
1436
  if (!event.defaultPrevented) handleOverflowKeydown(event);
1412
1437
  }}
1413
1438
  >
1414
- <table
1439
+ <table role={cardsRole('table')}
1415
1440
  class="data-table {sizeClasses[size]}"
1416
1441
  class:data-table--striped={striped}
1417
1442
  class:data-table--virtualized={virtualizationWindow.enabled}
@@ -1428,16 +1453,16 @@ $effect(() => {
1428
1453
  <caption bind:this={tableCaption} class="data-table__caption">{caption}</caption>
1429
1454
  {/if}
1430
1455
 
1431
- <thead bind:this={tableHead} class="data-table__head">
1456
+ <thead role={cardsRole('rowgroup')} bind:this={tableHead} class="data-table__head">
1432
1457
  {#each dataTableLayout.headerRows as headerRow, headerIndex (headerIndex)}
1433
- <tr class="data-table__row data-table__row--header">
1458
+ <tr role={cardsRole('row')} class="data-table__row data-table__row--header">
1434
1459
  {#if headerIndex === 0 && expandedContent}
1435
- <th class="data-table__cell data-table__cell--expand" scope="col" rowspan={headerRowCount}>
1460
+ <th role={cardsRole('columnheader')} class="data-table__cell data-table__cell--expand" scope="col" rowspan={headerRowCount}>
1436
1461
  <span class="sr-only"><Trans key={M['ui.data_table.expand']} /></span>
1437
1462
  </th>
1438
1463
  {/if}
1439
1464
  {#if headerIndex === 0 && selectable}
1440
- <th class="data-table__cell data-table__cell--checkbox" scope="col" rowspan={headerRowCount}>
1465
+ <th role={cardsRole('columnheader')} class="data-table__cell data-table__cell--checkbox" scope="col" rowspan={headerRowCount}>
1441
1466
  <input
1442
1467
  type="checkbox"
1443
1468
  checked={allSelected}
@@ -1451,7 +1476,7 @@ $effect(() => {
1451
1476
 
1452
1477
  {#each headerRow as headerCell, cellIndex (`${headerIndex}:${cellIndex}`)}
1453
1478
  {#if headerCell.kind === 'group'}
1454
- <th
1479
+ <th role={cardsRole('columnheader')}
1455
1480
  class="data-table__cell data-table__cell--header data-table__cell--header-group"
1456
1481
  class:data-table__cell--pinned-start={headerCell.pin === 'start'}
1457
1482
  class:data-table__cell--pinned-end={headerCell.pin === 'end'}
@@ -1466,7 +1491,7 @@ $effect(() => {
1466
1491
  {:else}
1467
1492
  {@const resolvedColumn = headerCell.column}
1468
1493
  {@const column = resolvedColumn.column}
1469
- <th
1494
+ <th role={cardsRole('columnheader')}
1470
1495
  class="data-table__cell data-table__cell--header"
1471
1496
  class:data-table__cell--sortable={usesAutomaticSortButton(column)}
1472
1497
  class:data-table__cell--sorted={currentSort.columnId === column.id}
@@ -1557,10 +1582,10 @@ $effect(() => {
1557
1582
  {/each}
1558
1583
  </thead>
1559
1584
 
1560
- <tbody bind:this={tableBody} class="data-table__body">
1585
+ <tbody role={cardsRole('rowgroup')} bind:this={tableBody} class="data-table__body">
1561
1586
  {#if errorMessage && !hasRenderedRows}
1562
- <tr class="data-table__row data-table__row--error">
1563
- <td
1587
+ <tr role={cardsRole('row')} class="data-table__row data-table__row--error">
1588
+ <td role={cardsRole('cell')}
1564
1589
  class="data-table__cell data-table__cell--error"
1565
1590
  colspan={columnCount}
1566
1591
  >
@@ -1575,8 +1600,8 @@ $effect(() => {
1575
1600
  </td>
1576
1601
  </tr>
1577
1602
  {:else if isInitialLoading}
1578
- <tr class="data-table__row data-table__row--loading">
1579
- <td
1603
+ <tr role={cardsRole('row')} class="data-table__row data-table__row--loading">
1604
+ <td role={cardsRole('cell')}
1580
1605
  class="data-table__cell data-table__cell--loading"
1581
1606
  colspan={columnCount}
1582
1607
  >
@@ -1587,8 +1612,8 @@ $effect(() => {
1587
1612
  </td>
1588
1613
  </tr>
1589
1614
  {:else if displayRows.length === 0}
1590
- <tr class="data-table__row data-table__row--empty">
1591
- <td
1615
+ <tr role={cardsRole('row')} class="data-table__row data-table__row--empty">
1616
+ <td role={cardsRole('cell')}
1592
1617
  class="data-table__cell data-table__cell--empty"
1593
1618
  colspan={columnCount}
1594
1619
  >
@@ -1603,8 +1628,8 @@ $effect(() => {
1603
1628
  </tr>
1604
1629
  {:else}
1605
1630
  {#if virtualizationWindow.topSpacerHeight > 0}
1606
- <tr class="data-table__virtual-spacer" aria-hidden="true">
1607
- <td colspan={columnCount} style:height={`${virtualizationWindow.topSpacerHeight}px`}></td>
1631
+ <tr role={cardsRole('row')} class="data-table__virtual-spacer" aria-hidden="true">
1632
+ <td role={cardsRole('cell')} colspan={columnCount} style:height={`${virtualizationWindow.topSpacerHeight}px`}></td>
1608
1633
  </tr>
1609
1634
  {/if}
1610
1635
  {#each renderedRows as entry, index (entry.rowId)}
@@ -1614,7 +1639,7 @@ $effect(() => {
1614
1639
  {@const isSelected = tableState.selection.scope === 'allMatching' || selectedIds.has(key)}
1615
1640
  {@const isExpanded = expandedIds.has(key)}
1616
1641
  {@const rowCanExpand = canExpand?.(row, displayIndex) ?? true}
1617
- <tr
1642
+ <tr role={cardsRole('row')}
1618
1643
  class="data-table__row {rowClass?.(row, displayIndex) ?? ''}"
1619
1644
  class:data-table__row--selected={isSelected}
1620
1645
  class:data-table__row--striped={
@@ -1631,12 +1656,12 @@ $effect(() => {
1631
1656
  onkeydown={(event) => handleRowKeydown(event, row, displayIndex)}
1632
1657
  >
1633
1658
  {#if expandedContent}
1634
- <td class="data-table__cell data-table__cell--expand">
1659
+ <td role={cardsRole('cell')} class="data-table__cell data-table__cell--expand">
1635
1660
  {#if rowCanExpand}<button type="button" class="data-table__expand-button" aria-label={isExpanded ? t(M['ui.data_table.collapse_row'], { row: getRowLabel(row, displayIndex) }) : t(M['ui.data_table.expand_row'], { row: getRowLabel(row, displayIndex) })} aria-expanded={isExpanded} aria-controls={expansionContentId(key)} onclick={(event) => handleExpanded(key, event)}>{isExpanded ? '−' : '+'}</button>{/if}
1636
1661
  </td>
1637
1662
  {/if}
1638
1663
  {#if selectable}
1639
- <td class="data-table__cell data-table__cell--checkbox">
1664
+ <td role={cardsRole('cell')} class="data-table__cell data-table__cell--checkbox">
1640
1665
  <input
1641
1666
  type="checkbox"
1642
1667
  checked={isSelected}
@@ -1651,8 +1676,9 @@ $effect(() => {
1651
1676
  {#each visibleColumns as resolvedColumn (resolvedColumn.column.id)}
1652
1677
  {@const column = resolvedColumn.column}
1653
1678
  {@const value = getCellValue(row, column)}
1654
- <td
1679
+ <td role={cardsRole('cell')}
1655
1680
  class="data-table__cell {column.className ?? ''}"
1681
+ data-label={phoneLayout === 'cards' ? column.label : undefined}
1656
1682
  class:data-table__cell--pinned-start={resolvedColumn.pin === 'start'}
1657
1683
  class:data-table__cell--pinned-end={resolvedColumn.pin === 'end'}
1658
1684
  data-column-id={column.id}
@@ -1677,26 +1703,26 @@ $effect(() => {
1677
1703
  {/each}
1678
1704
  </tr>
1679
1705
  {#if expandedContent && isExpanded}
1680
- <tr id={expansionContentId(key)} class="data-table__row data-table__row--expanded">
1681
- <td class="data-table__cell data-table__cell--expanded" colspan={columnCount}>{@render expandedContent({ row, index: displayIndex })}</td>
1706
+ <tr role={cardsRole('row')} id={expansionContentId(key)} class="data-table__row data-table__row--expanded">
1707
+ <td role={cardsRole('cell')} class="data-table__cell data-table__cell--expanded" colspan={columnCount}>{@render expandedContent({ row, index: displayIndex })}</td>
1682
1708
  </tr>
1683
1709
  {/if}
1684
1710
  {/each}
1685
1711
  {#if virtualizationWindow.bottomSpacerHeight > 0}
1686
- <tr class="data-table__virtual-spacer" aria-hidden="true">
1687
- <td colspan={columnCount} style:height={`${virtualizationWindow.bottomSpacerHeight}px`}></td>
1712
+ <tr role={cardsRole('row')} class="data-table__virtual-spacer" aria-hidden="true">
1713
+ <td role={cardsRole('cell')} colspan={columnCount} style:height={`${virtualizationWindow.bottomSpacerHeight}px`}></td>
1688
1714
  </tr>
1689
1715
  {/if}
1690
1716
  {/if}
1691
1717
  </tbody>
1692
1718
  {#if dataBodyStructuralRows.length > 0}
1693
- <tbody
1719
+ <tbody role={cardsRole('rowgroup')}
1694
1720
  bind:this={tableStructuralBody}
1695
1721
  class="data-table__body data-table__body--structural"
1696
1722
  >
1697
1723
  {#each dataBodyStructuralRows as structuralRow, structuralIndex (structuralRow.id)}
1698
1724
  {@const labelColumnId = structuralLabelColumnId(structuralRow)}
1699
- <tr
1725
+ <tr role={cardsRole('row')}
1700
1726
  class="data-table__row data-table__row--structural"
1701
1727
  data-row-kind={structuralRow.kind}
1702
1728
  aria-label={structuralRowLabel(structuralRow)}
@@ -1704,13 +1730,13 @@ $effect(() => {
1704
1730
  ? virtualRowOffset + displayRows.length + headerRowCount + structuralIndex + 1
1705
1731
  : undefined}
1706
1732
  >
1707
- {#if expandedContent}<td class="data-table__cell data-table__cell--expand"></td>{/if}
1708
- {#if selectable}<td class="data-table__cell data-table__cell--checkbox"></td>{/if}
1733
+ {#if expandedContent}<td role={cardsRole('cell')} class="data-table__cell data-table__cell--expand"></td>{/if}
1734
+ {#if selectable}<td role={cardsRole('cell')} class="data-table__cell data-table__cell--checkbox"></td>{/if}
1709
1735
  {#each visibleColumns as resolvedColumn (resolvedColumn.column.id)}
1710
1736
  {@const column = resolvedColumn.column}
1711
1737
  {@const value = structuralCellValue(structuralRow, column)}
1712
1738
  {#if column.id === labelColumnId}
1713
- <th
1739
+ <th role={cardsRole('rowheader')}
1714
1740
  class="data-table__cell data-table__cell--structural-label {column.className ?? ''}"
1715
1741
  class:data-table__cell--pinned-start={resolvedColumn.pin === 'start'}
1716
1742
  class:data-table__cell--pinned-end={resolvedColumn.pin === 'end'}
@@ -1731,8 +1757,9 @@ $effect(() => {
1731
1757
  {/if}
1732
1758
  </th>
1733
1759
  {:else}
1734
- <td
1760
+ <td role={cardsRole('cell')}
1735
1761
  class="data-table__cell {column.className ?? ''}"
1762
+ data-label={phoneLayout === 'cards' ? column.label : undefined}
1736
1763
  class:data-table__cell--pinned-start={resolvedColumn.pin === 'start'}
1737
1764
  class:data-table__cell--pinned-end={resolvedColumn.pin === 'end'}
1738
1765
  data-column-id={column.id}
@@ -1756,10 +1783,10 @@ $effect(() => {
1756
1783
  </tbody>
1757
1784
  {/if}
1758
1785
  {#if footer || footerStructuralRows.length > 0}
1759
- <tfoot bind:this={tableFooter}>
1786
+ <tfoot role={cardsRole('rowgroup')} bind:this={tableFooter}>
1760
1787
  {#each footerStructuralRows as structuralRow, structuralIndex (structuralRow.id)}
1761
1788
  {@const labelColumnId = structuralLabelColumnId(structuralRow)}
1762
- <tr
1789
+ <tr role={cardsRole('row')}
1763
1790
  class="data-table__row data-table__row--structural data-table__row--footer"
1764
1791
  data-row-kind={structuralRow.kind}
1765
1792
  aria-label={structuralRowLabel(structuralRow)}
@@ -1767,13 +1794,13 @@ $effect(() => {
1767
1794
  ? virtualRowCount + headerRowCount + dataBodyStructuralRows.length + structuralIndex + 1
1768
1795
  : undefined}
1769
1796
  >
1770
- {#if expandedContent}<td class="data-table__cell data-table__cell--expand"></td>{/if}
1771
- {#if selectable}<td class="data-table__cell data-table__cell--checkbox"></td>{/if}
1797
+ {#if expandedContent}<td role={cardsRole('cell')} class="data-table__cell data-table__cell--expand"></td>{/if}
1798
+ {#if selectable}<td role={cardsRole('cell')} class="data-table__cell data-table__cell--checkbox"></td>{/if}
1772
1799
  {#each visibleColumns as resolvedColumn (resolvedColumn.column.id)}
1773
1800
  {@const column = resolvedColumn.column}
1774
1801
  {@const value = structuralCellValue(structuralRow, column)}
1775
1802
  {#if column.id === labelColumnId}
1776
- <th
1803
+ <th role={cardsRole('rowheader')}
1777
1804
  class="data-table__cell data-table__cell--structural-label {column.className ?? ''}"
1778
1805
  class:data-table__cell--pinned-start={resolvedColumn.pin === 'start'}
1779
1806
  class:data-table__cell--pinned-end={resolvedColumn.pin === 'end'}
@@ -1794,8 +1821,9 @@ $effect(() => {
1794
1821
  {/if}
1795
1822
  </th>
1796
1823
  {:else}
1797
- <td
1824
+ <td role={cardsRole('cell')}
1798
1825
  class="data-table__cell {column.className ?? ''}"
1826
+ data-label={phoneLayout === 'cards' ? column.label : undefined}
1799
1827
  class:data-table__cell--pinned-start={resolvedColumn.pin === 'start'}
1800
1828
  class:data-table__cell--pinned-end={resolvedColumn.pin === 'end'}
1801
1829
  data-column-id={column.id}
@@ -1817,10 +1845,10 @@ $effect(() => {
1817
1845
  </tr>
1818
1846
  {/each}
1819
1847
  {#if footer}
1820
- <tr aria-rowindex={virtualizationWindow.enabled
1848
+ <tr role={cardsRole('row')} aria-rowindex={virtualizationWindow.enabled
1821
1849
  ? virtualRowCount + headerRowCount + structuralRowCount
1822
1850
  : undefined}>
1823
- <td class="data-table__cell data-table__footer" colspan={columnCount}>
1851
+ <td role={cardsRole('cell')} class="data-table__cell data-table__footer" colspan={columnCount}>
1824
1852
  {@render footer({ rows: displayRows.map(({ row }) => row) })}
1825
1853
  </td>
1826
1854
  </tr>
@@ -2209,6 +2237,56 @@ $effect(() => {
2209
2237
  opacity: 0.7;
2210
2238
  }
2211
2239
 
2240
+ /* Phones with phoneLayout="cards": one block of stacked cells per row. Each cell shows its
2241
+ column's name (data-label) above its value; the header row stays in the accessibility tree,
2242
+ visually hidden, and the explicit roles keep the table structure announced. */
2243
+ @media (max-width: 48rem) {
2244
+ /* A virtualized body keeps its own scroller. */
2245
+ .data-table-container--phone-cards:not(.data-table-container--virtualized) {
2246
+ overflow: visible;
2247
+ }
2248
+ .data-table-container--phone-cards .data-table,
2249
+ .data-table-container--phone-cards .data-table__body {
2250
+ display: block;
2251
+ width: 100%;
2252
+ }
2253
+ .data-table-container--phone-cards .data-table__head {
2254
+ position: absolute;
2255
+ width: 1px;
2256
+ height: 1px;
2257
+ overflow: hidden;
2258
+ clip: rect(0 0 0 0);
2259
+ clip-path: inset(50%);
2260
+ white-space: nowrap;
2261
+ }
2262
+ .data-table-container--phone-cards .data-table__overflow-cue {
2263
+ display: none;
2264
+ }
2265
+ .data-table-container--phone-cards .data-table__cell[data-label]:not([data-label=''])::before {
2266
+ content: attr(data-label);
2267
+ /* The header already names the cell for assistive technology. */
2268
+ content: attr(data-label) / '';
2269
+ display: block;
2270
+ font-size: var(--smrt-typography-label-small-size, 0.75rem);
2271
+ font-weight: 600;
2272
+ color: var(--smrt-color-on-surface-variant, #4b5563);
2273
+ }
2274
+ .data-table-container--phone-cards .data-table__row {
2275
+ display: grid;
2276
+ gap: var(--smrt-spacing-1, 0.35rem);
2277
+ padding: var(--smrt-spacing-3, 0.85rem) var(--smrt-spacing-4, 1rem);
2278
+ border-bottom: 1px solid var(--smrt-color-outline-variant, #e5e7eb);
2279
+ }
2280
+ .data-table-container--phone-cards .data-table__cell {
2281
+ display: block;
2282
+ padding: 0;
2283
+ border: 0;
2284
+ }
2285
+ .data-table-container--phone-cards .data-table__cell:empty {
2286
+ display: none;
2287
+ }
2288
+ }
2289
+
2212
2290
  @media (prefers-reduced-motion: reduce) {
2213
2291
  .data-table__spinner {
2214
2292
  animation: none;
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/data/DataTable.svelte.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,OAAO,EAAa,KAAK,OAAO,EAAiB,MAAM,QAAQ,CAAC;AAmChE,OAAO,KAAK,EACV,eAAe,EAEf,cAAc,EAGf,MAAM,YAAY,CAAC;AAIpB,UAAU,aAAa,CAAC,CAAC,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;IAClD,+DAA+D;IAC/D,IAAI,CAAC,EAAE,OAAO,CACZ;QAAC;YAAE,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;YAAC,GAAG,EAAE,CAAC,CAAC;YAAC,KAAK,EAAE,OAAO,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE;KAAC,CACxE,CAAC;CACH;AAYC,iBAAS,QAAQ,CAAC,CAAC;WAglDQ,aAAa,CAAC,CAAC,CAAC;;;;;EAAgH;AAC7J,cAAM,iBAAiB,CAAC,CAAC;IACrB,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAChD,MAAM,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAClD,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAChD,QAAQ;IACR,OAAO;CACV;AAED,UAAU,qBAAqB;IAC3B,KAAK,CAAC,EAAE,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAA;KAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5X,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC3H,YAAY,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;CACjE;AACD,QAAA,MAAM,SAAS,EAAE,qBAAmC,CAAC;AACnC,KAAK,SAAS,CAAC,CAAC,IAAI,YAAY,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACxD,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"DataTable.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/data/DataTable.svelte.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,OAAO,EAAa,KAAK,OAAO,EAAiB,MAAM,QAAQ,CAAC;AAmChE,OAAO,KAAK,EACV,eAAe,EAEf,cAAc,EAGf,MAAM,YAAY,CAAC;AAIpB,UAAU,aAAa,CAAC,CAAC,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;IAClD,+DAA+D;IAC/D,IAAI,CAAC,EAAE,OAAO,CACZ;QAAC;YAAE,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;YAAC,GAAG,EAAE,CAAC,CAAC;YAAC,KAAK,EAAE,OAAO,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE;KAAC,CACxE,CAAC;CACH;AAYC,iBAAS,QAAQ,CAAC,CAAC;WAwmDQ,aAAa,CAAC,CAAC,CAAC;;;;;EAAgH;AAC7J,cAAM,iBAAiB,CAAC,CAAC;IACrB,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAChD,MAAM,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAClD,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAChD,QAAQ;IACR,OAAO;CACV;AAED,UAAU,qBAAqB;IAC3B,KAAK,CAAC,EAAE,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAA;KAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5X,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC3H,YAAY,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;CACjE;AACD,QAAA,MAAM,SAAS,EAAE,qBAAmC,CAAC;AACnC,KAAK,SAAS,CAAC,CAAC,IAAI,YAAY,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACxD,eAAe,SAAS,CAAC"}
@@ -114,6 +114,10 @@ export type DataTableCommand = {
114
114
  type: 'toggleSorting';
115
115
  columnId: string;
116
116
  multi?: boolean;
117
+ /** Direction when the column is not sorted yet (default `asc`). */
118
+ firstDirection?: DataTableSortRule['direction'];
119
+ /** `false` toggles asc ⇄ desc instead of clearing on the third activation. */
120
+ clearable?: boolean;
117
121
  } | {
118
122
  type: 'setPage';
119
123
  page: number;
@@ -1 +1 @@
1
- {"version":3,"file":"DataTableController.d.ts","sourceRoot":"","sources":["../../../src/components/data/DataTableController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DataTableController.d.ts","sourceRoot":"","sources":["../../../src/components/data/DataTableController.ts"],"names":[],"mappings":"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"}
@@ -403,11 +403,18 @@ export function transitionDataTableState(state, command) {
403
403
  const columnId = assertColumnId(command.columnId, 'sort column id');
404
404
  const index = current.sorting.findIndex((rule) => rule.columnId === columnId);
405
405
  const previous = index >= 0 ? current.sorting[index] : undefined;
406
+ const firstDirection = command.firstDirection === 'desc' ? 'desc' : 'asc';
407
+ const lastDirection = firstDirection === 'asc' ? 'desc' : 'asc';
406
408
  const toggled = !previous
407
- ? { columnId, direction: 'asc' }
408
- : previous.direction === 'asc'
409
- ? { columnId, direction: 'desc' }
410
- : null;
409
+ ? { columnId, direction: firstDirection }
410
+ : command.clearable === false
411
+ ? {
412
+ columnId,
413
+ direction: previous.direction === 'asc' ? 'desc' : 'asc',
414
+ }
415
+ : previous.direction === firstDirection
416
+ ? { columnId, direction: lastDirection }
417
+ : null;
411
418
  const sorting = command.multi
412
419
  ? previous
413
420
  ? toggled
@@ -0,0 +1,121 @@
1
+ <!--
2
+ ListSortSelect — a "Sort by" picker for lists without column headers
3
+ (card lists, and tables that turn into cards on phones).
4
+
5
+ One option per column and direction, in plain words: dates read
6
+ "newest first / oldest first", numbers "highest first / lowest first",
7
+ text "A–Z / Z–A". Calls `onChange` with the chosen sort; server-sorted lists
8
+ navigate to `listSortHref(...)` there.
9
+ -->
10
+ <script lang="ts">
11
+ import type {
12
+ ListSort,
13
+ ListSortDirection,
14
+ ListSortSelectColumn,
15
+ } from './list-sort.js';
16
+ import type { ListSortState } from './list-sort-state.svelte.js';
17
+
18
+ interface Props {
19
+ /** Sortable columns; each gives two options, one per direction. */
20
+ columns: readonly ListSortSelectColumn[];
21
+ /** The list's sort state; supplies `sort` and `onChange`. */
22
+ list?: ListSortState;
23
+ /** Current sort of the list, when `list` is not given. */
24
+ sort?: ListSort;
25
+ /** Called with the chosen sort, when `list` is not given. */
26
+ onChange?: (sort: ListSort) => void;
27
+ /** Visible label for the picker (default "Sort by"). */
28
+ label?: string;
29
+ /** Id of the select element, tying the label to it. */
30
+ id?: string;
31
+ /** Extra class names. */
32
+ class?: string;
33
+ }
34
+
35
+ let {
36
+ columns,
37
+ list,
38
+ sort: sortProp,
39
+ onChange: onChangeProp,
40
+ label = 'Sort by',
41
+ id = `list-sort-${Math.random().toString(36).slice(2, 9)}`,
42
+ class: className = '',
43
+ }: Props = $props();
44
+
45
+ function directionWords(
46
+ kind: ListSortSelectColumn['kind'],
47
+ direction: ListSortDirection,
48
+ ): string {
49
+ if (kind === 'date')
50
+ return direction === 'desc' ? 'newest first' : 'oldest first';
51
+ if (kind === 'number')
52
+ return direction === 'desc' ? 'highest first' : 'lowest first';
53
+ return direction === 'asc' ? 'A–Z' : 'Z–A';
54
+ }
55
+
56
+ const sort = $derived<ListSort>(
57
+ list?.sort ??
58
+ sortProp ?? { columnId: columns[0]?.id ?? '', direction: 'desc' },
59
+ );
60
+ const onChange = (next: ListSort) => {
61
+ if (list) void list.set(next);
62
+ else onChangeProp?.(next);
63
+ };
64
+
65
+ const options = $derived(
66
+ columns.flatMap((column) => {
67
+ const order: ListSortDirection[] =
68
+ column.kind === 'date' || column.kind === 'number'
69
+ ? ['desc', 'asc']
70
+ : ['asc', 'desc'];
71
+ return order.map((direction) => ({
72
+ value: `${column.id}:${direction}`,
73
+ label: `${column.label}, ${directionWords(column.kind, direction)}`,
74
+ }));
75
+ }),
76
+ );
77
+
78
+ function handleChange(event: Event) {
79
+ const value = (event.currentTarget as HTMLSelectElement).value;
80
+ const separator = value.lastIndexOf(':');
81
+ const direction = value.slice(separator + 1);
82
+ if (direction !== 'asc' && direction !== 'desc') return;
83
+ onChange({ columnId: value.slice(0, separator), direction });
84
+ }
85
+ </script>
86
+
87
+ <div class={`list-sort-select ${className}`}>
88
+ <label class="list-sort-select__label" for={id}>{label}</label>
89
+ <select
90
+ {id}
91
+ class="list-sort-select__control"
92
+ value={`${sort.columnId}:${sort.direction}`}
93
+ onchange={handleChange}
94
+ >
95
+ {#each options as option (option.value)}
96
+ <option value={option.value}>{option.label}</option>
97
+ {/each}
98
+ </select>
99
+ </div>
100
+
101
+ <style>
102
+ .list-sort-select {
103
+ display: inline-flex;
104
+ align-items: center;
105
+ gap: 0.5rem;
106
+ }
107
+ .list-sort-select__label {
108
+ font-size: 0.875rem;
109
+ color: var(--color-text-secondary, inherit);
110
+ white-space: nowrap;
111
+ }
112
+ .list-sort-select__control {
113
+ min-height: 2.75rem;
114
+ padding: 0.25rem 0.5rem;
115
+ border: 1px solid var(--color-border, currentColor);
116
+ border-radius: var(--radius-md, 0.375rem);
117
+ background: var(--color-surface, transparent);
118
+ color: inherit;
119
+ font: inherit;
120
+ }
121
+ </style>
@@ -0,0 +1,22 @@
1
+ import type { ListSort, ListSortSelectColumn } from './list-sort.js';
2
+ import type { ListSortState } from './list-sort-state.svelte.js';
3
+ interface Props {
4
+ /** Sortable columns; each gives two options, one per direction. */
5
+ columns: readonly ListSortSelectColumn[];
6
+ /** The list's sort state; supplies `sort` and `onChange`. */
7
+ list?: ListSortState;
8
+ /** Current sort of the list, when `list` is not given. */
9
+ sort?: ListSort;
10
+ /** Called with the chosen sort, when `list` is not given. */
11
+ onChange?: (sort: ListSort) => void;
12
+ /** Visible label for the picker (default "Sort by"). */
13
+ label?: string;
14
+ /** Id of the select element, tying the label to it. */
15
+ id?: string;
16
+ /** Extra class names. */
17
+ class?: string;
18
+ }
19
+ declare const ListSortSelect: import("svelte").Component<Props, {}, "">;
20
+ type ListSortSelect = ReturnType<typeof ListSortSelect>;
21
+ export default ListSortSelect;
22
+ //# sourceMappingURL=ListSortSelect.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListSortSelect.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/data/ListSortSelect.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,QAAQ,EAER,oBAAoB,EACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAGjE,UAAU,KAAK;IACb,mEAAmE;IACnE,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACzC,6DAA6D;IAC7D,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAwED,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}