@likable-hair/svelte 3.3.11 → 3.3.13

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.
@@ -48,5 +48,6 @@ $:
48
48
  .selectable-list-wrapper {
49
49
  background-color: rgb(var(--global-color-background-100));
50
50
  overflow: auto;
51
+ height: 100%
51
52
  }
52
53
  </style>
@@ -15,4 +15,5 @@
15
15
  --dynamic-table-default-hover-color: rgb(var(--global-color-contrast-800), .7);
16
16
  --dynamic-table-default-header-border-radius: 5px;
17
17
  --dynamic-table-default-header-height: 30px;
18
+ --dynamic-table-default-row-min-height: auto;
18
19
  }
@@ -15,7 +15,7 @@
15
15
  import { DateTime } from "luxon";
16
16
  import { createEventDispatcher, onMount } from "svelte";
17
17
  import { quintOut } from "svelte/easing";
18
- import { crossfade } from "svelte/transition";
18
+ import { crossfade, fade } from "svelte/transition";
19
19
  import Filters from "../search/Filters.svelte";
20
20
  import ConfirmOrCancelButtons from "../forms/ConfirmOrCancelButtons.svelte";
21
21
  import { flip } from "svelte/animate";
@@ -31,10 +31,15 @@ import DynamicFilters from "../search/DynamicFilters.svelte";
31
31
  import QuickActions, {} from "../common/QuickActions.svelte";
32
32
  import "./DynamicTable.css";
33
33
  import Switch from "../../simple/forms/Switch.svelte";
34
+ import CircularLoader from "../../simple/loaders/CircularLoader.svelte";
34
35
  onMount(() => {
35
36
  updateHeaderHeight();
36
37
  window.addEventListener("resize", updateHeaderHeight);
37
- return () => window.removeEventListener("resize", updateHeaderHeight);
38
+ tableContainer.addEventListener("scroll", setReachedBottom);
39
+ return () => {
40
+ window.removeEventListener("resize", updateHeaderHeight);
41
+ tableContainer.removeEventListener("scroll", setReachedBottom);
42
+ };
38
43
  });
39
44
  let mainHeader;
40
45
  function updateHeaderHeight() {
@@ -43,6 +48,9 @@ function updateHeaderHeight() {
43
48
  document.documentElement.style.setProperty("--main-header-height", headerHeight + "px");
44
49
  }
45
50
  }
51
+ function setReachedBottom() {
52
+ reachedBottom = tableContainer.scrollHeight - tableContainer.scrollTop === tableContainer.clientHeight;
53
+ }
46
54
  const [send, receive] = crossfade({
47
55
  duration: 500,
48
56
  fallback(node, params) {
@@ -61,8 +69,10 @@ const [send, receive] = crossfade({
61
69
  let clazz = {};
62
70
  export { clazz as class };
63
71
  const dispatch = createEventDispatcher();
64
- export let headers = [], headersToShowInTable = headers, subHeaders = [], customizeHeaders = false, rows = [], sortedBy = void 0, sortDirection = "asc", cellEdit = false, noItemsText = "No items to show", showSelect = false, showSelectContainer = true, selectMode = "single", selectedItems = [], showExpand = false, loading = false, disabled = false, filters = [], searchBarColumns = void 0, searchBarVisible = false, searchBarPlaceholder = "Type to search for identification code, description and MRN...", filtersVisible = false, quickFiltersVisible = false, lang = "en", editFilterMode = "one-edit", showActiveFilters = true, quickFilters = [], actionsForSelectedItems = [], totalRows = rows.length, searchText = void 0, renderedRowsNumber = 100, sectionRowsNumber = 20, sectionTreshold = 2, backwardTresholdPixel = 100, forwardTresholdPixel = 100;
65
- let openCellEditor = false, cellEditorActivator, cellEditorContainer, menuElementCellEditor, menuElementQuickFilters, cellEditorInfoActive, saveEditDisabled = false, searchBarInput = void 0, openQuickFilter = false, quickFilterActivator, quickFilterActive, globalBuilder = new FilterBuilder(), slotSelectActionsContainer, isSelectedAll = false, calendarOpened = false, calendarOpened2 = false, selectedIndexes = [], cellEditorIndexRow, cellEditorIndexHeader, cellEditorSubItem, currentSectionNumber = 0, tableBody, tableContainer, userScrolling = true, totalSections = (totalRows - renderedRowsNumber) / sectionRowsNumber;
72
+ export let headers = [], headersToShowInTable = headers, subHeaders = [], customizeHeaders = false, rows = [], sortedBy = void 0, sortDirection = "asc", cellEdit = false, noItemsText = "No items to show", showSelect = false, showSelectContainer = true, selectMode = "single", selectedItems = [], showExpand = false, loading = false, disabled = false, filters = [], searchBarColumns = void 0, searchBarVisible = false, searchBarPlaceholder = "Type to search for identification code, description and MRN...", filtersVisible = false, quickFiltersVisible = false, lang = "en", editFilterMode = "one-edit", showActiveFilters = true, quickFilters = [], actionsForSelectedItems = [], totalRows = rows.length, searchText = void 0, renderedRowsNumber = 100, sectionRowsNumber = 20, sectionThreshold = 2, backwardThresholdPixel = 100, forwardThresholdPixel = 100, uniqueKey = "id", numberOfResultsVisible = false, endLineVisible = false;
73
+ let openCellEditor = false, cellEditorActivator, cellEditorContainer, menuElementCellEditor, menuElementQuickFilters, cellEditorInfoActive, saveEditDisabled = false, searchBarInput = void 0, openQuickFilter = false, quickFilterActivator, quickFilterActive, globalBuilder = new FilterBuilder(), slotSelectActionsContainer, isSelectedAll = false, calendarOpened = false, calendarOpened2 = false, selectedIndexes = [], cellEditorIndexRow, cellEditorIndexHeader, cellEditorSubItem, currentSectionNumber = 0, tableBody, tableContainer, userScrolling = true, reachedBottom = false;
74
+ $:
75
+ totalSections = (totalRows - renderedRowsNumber) / sectionRowsNumber;
66
76
  $:
67
77
  hasMoreToRender = totalSections > currentSectionNumber;
68
78
  $:
@@ -172,14 +182,14 @@ function handleCancelClick() {
172
182
  openQuickFilter = false;
173
183
  }
174
184
  function handleSelect(item, shiftKeyPressed) {
175
- let index = selectedItems.findIndex((i) => i.id == item.id);
185
+ let index = selectedItems.findIndex((i) => i[uniqueKey] == item[uniqueKey]);
176
186
  if (index == -1) {
177
187
  if (selectMode == "single") {
178
188
  selectedItems = [item];
179
- selectedIndexes = [rows.findIndex((r) => r.item.id == item.id)];
189
+ selectedIndexes = [rows.findIndex((r) => r.item[uniqueKey] == item[uniqueKey])];
180
190
  } else if (selectMode == "multiple") {
181
191
  if (shiftKeyPressed && selectedIndexes.length > 0 && !isSelectedAll) {
182
- let lastSelectedIndex = selectedIndexes[selectedIndexes.length - 1], selectedIndex = rows.findIndex((r) => r.item.id == item.id);
192
+ let lastSelectedIndex = selectedIndexes[selectedIndexes.length - 1], selectedIndex = rows.findIndex((r) => r.item[uniqueKey] == item[uniqueKey]);
183
193
  if (selectedIndex != -1) {
184
194
  if (selectedIndex < lastSelectedIndex) {
185
195
  let x = lastSelectedIndex;
@@ -187,19 +197,19 @@ function handleSelect(item, shiftKeyPressed) {
187
197
  selectedIndex = x;
188
198
  }
189
199
  for (let i = lastSelectedIndex + 1; i <= selectedIndex; i++) {
190
- if (!selectedItems.find((selectedItem) => selectedItem.id == rows[i].item.id)) {
200
+ if (!selectedItems.find((selectedItem) => selectedItem[uniqueKey] == rows[i].item[uniqueKey])) {
191
201
  selectedItems = [...selectedItems, rows[i].item];
192
202
  }
193
203
  }
194
204
  }
195
205
  } else {
196
206
  selectedItems = [...selectedItems, item];
197
- selectedIndexes.push(rows.findIndex((r) => r.item.id == item.id));
207
+ selectedIndexes.push(rows.findIndex((r) => r.item[uniqueKey] == item[uniqueKey]));
198
208
  }
199
209
  }
200
210
  } else {
201
- selectedItems = selectedItems.filter((i) => i.id != item.id);
202
- selectedIndexes = selectedIndexes.filter((r) => r != rows.findIndex((r2) => r2.item.id == item.id));
211
+ selectedItems = selectedItems.filter((i) => i[uniqueKey] != item[uniqueKey]);
212
+ selectedIndexes = selectedIndexes.filter((r) => r != rows.findIndex((r2) => r2.item[uniqueKey] == item[uniqueKey]));
203
213
  isSelectedAll = false;
204
214
  }
205
215
  }
@@ -216,11 +226,11 @@ function handleSelectAll() {
216
226
  }
217
227
  }
218
228
  function expandRow(row) {
219
- let index = expandedRows.findIndex((r) => r.item.id == row.item.id);
229
+ let index = expandedRows.findIndex((r) => r.item[uniqueKey] == row.item[uniqueKey]);
220
230
  if (index == -1) {
221
231
  expandedRows = [...expandedRows, row];
222
232
  } else {
223
- expandedRows = expandedRows.filter((r) => r.item.id != row.item.id);
233
+ expandedRows = expandedRows.filter((r) => r.item[uniqueKey] != row.item[uniqueKey]);
224
234
  }
225
235
  }
226
236
  function formatDate(dateTime, dateFormat) {
@@ -278,10 +288,12 @@ $:
278
288
  if (searchText != void 0)
279
289
  handleSearchChange(searchText);
280
290
  function handleFiltersChange() {
281
- userScrolling = false;
282
- currentSectionNumber = 0;
283
- tableContainer.scrollTop = 0;
284
- setTimeout(() => userScrolling = true, 20);
291
+ if (!!tableContainer) {
292
+ userScrolling = false;
293
+ currentSectionNumber = 0;
294
+ tableContainer.scrollTop = 0;
295
+ setTimeout(() => userScrolling = true, 20);
296
+ }
285
297
  dispatch("filtersChange", {
286
298
  builder: globalBuilder
287
299
  });
@@ -477,14 +489,14 @@ function quickFilterBuilder(builder, quickFilter, clearPreaviousValue = true) {
477
489
  builder.where(
478
490
  quickFilter.column,
479
491
  ">=",
480
- DateTime.fromJSDate(from).toString()
492
+ DateTime.fromJSDate(from).setLocale("it-IT").startOf("day").toString()
481
493
  );
482
494
  }
483
495
  if (!!to) {
484
496
  builder.where(
485
497
  quickFilter.column,
486
498
  "<=",
487
- DateTime.fromJSDate(to).toString()
499
+ DateTime.fromJSDate(to).setLocale("it-IT").endOf("day").toString()
488
500
  );
489
501
  }
490
502
  }
@@ -567,27 +579,68 @@ function handleRemoveFilter(filter) {
567
579
  handleSearchChange(searchText);
568
580
  }
569
581
  function handleLoadForward() {
570
- userScrolling = false;
571
- let topElementsHeight = 0;
572
- for (let i = 0; i < sectionRowsNumber; i++) {
573
- topElementsHeight += tableBody?.children.item(i)?.getBoundingClientRect().height || 0;
574
- }
575
- currentSectionNumber = currentSectionNumber + 1;
576
- tableContainer.scrollTop -= topElementsHeight;
577
- setTimeout(() => userScrolling = true, 20);
578
- if (totalCachedSections - sectionTreshold <= currentSectionNumber && !loading && totalRows > rows.length) {
582
+ if (renderedRows.length >= renderedRowsNumber) {
583
+ userScrolling = false;
584
+ const anchorIndex = renderedRowsNumber - 1;
585
+ const anchorUniqueKey = renderedRows[anchorIndex].item[uniqueKey];
586
+ const anchorElement = findAnchorElement(anchorUniqueKey);
587
+ const anchorOffsetBefore = anchorElement?.getBoundingClientRect().top || 0;
588
+ let removedRowCount = 0;
589
+ for (let i = 0; removedRowCount < sectionRowsNumber; i++) {
590
+ let row = tableBody.children.item(i);
591
+ removedRowCount++;
592
+ const rowKey = row?.getAttribute("data-key");
593
+ const isExpanded = expandedRows.some((r) => r.item[uniqueKey] == rowKey);
594
+ if (isExpanded) {
595
+ i++;
596
+ }
597
+ }
598
+ currentSectionNumber = currentSectionNumber + 1;
599
+ setTimeout(() => {
600
+ const anchorElementAfter = findAnchorElement(anchorUniqueKey);
601
+ const anchorOffsetAfter = anchorElementAfter?.getBoundingClientRect().top || 0;
602
+ const offsetDiff = anchorOffsetAfter - anchorOffsetBefore;
603
+ tableContainer.scrollTop += offsetDiff;
604
+ userScrolling = true;
605
+ }, 10);
606
+ }
607
+ if (totalCachedSections - sectionThreshold <= currentSectionNumber && !loading && totalRows > rows.length) {
579
608
  dispatch("fetchData", {});
580
609
  }
581
610
  }
582
611
  function handleLoadBackward() {
583
612
  userScrolling = false;
584
- let topElementsHeight = 0;
585
- for (let i = renderedRows.length - 1; i > renderedRows.length - sectionRowsNumber + 1; i--) {
586
- topElementsHeight += tableBody?.children.item(i)?.getBoundingClientRect().height || 0;
613
+ const anchorIndex = 0;
614
+ const anchorUniqueKey = renderedRows[anchorIndex].item[uniqueKey];
615
+ const anchorElement = findAnchorElement(anchorUniqueKey);
616
+ const anchorOffsetBefore = anchorElement?.getBoundingClientRect().top || 0;
617
+ let removedRowCount = 0;
618
+ for (let i = renderedRows.length - 1; removedRowCount < sectionRowsNumber; i--) {
619
+ let row = tableBody.children.item(i);
620
+ removedRowCount++;
621
+ const rowKey = row?.getAttribute("data-key");
622
+ const isExpanded = expandedRows.some((r) => r.item[uniqueKey] == rowKey);
623
+ if (isExpanded) {
624
+ i--;
625
+ }
587
626
  }
588
627
  currentSectionNumber = currentSectionNumber - 1;
589
- tableContainer.scrollTop += topElementsHeight;
590
- setTimeout(() => userScrolling = true, 20);
628
+ setTimeout(() => {
629
+ const anchorElementAfter = findAnchorElement(anchorUniqueKey);
630
+ const anchorOffsetAfter = anchorElementAfter?.getBoundingClientRect().top || 0;
631
+ const offsetDiff = anchorOffsetAfter - anchorOffsetBefore;
632
+ tableContainer.scrollTop += offsetDiff;
633
+ userScrolling = true;
634
+ }, 10);
635
+ }
636
+ function findAnchorElement(key) {
637
+ for (let i = 0; i < tableBody.children.length; i++) {
638
+ const child = tableBody.children.item(i);
639
+ if (child?.getAttribute("data-key") == key) {
640
+ return child;
641
+ }
642
+ }
643
+ return void 0;
591
644
  }
592
645
  </script>
593
646
 
@@ -705,12 +758,26 @@ function handleLoadBackward() {
705
758
  {/if}
706
759
  </div>
707
760
  {/if}
761
+
762
+ {#if numberOfResultsVisible}
763
+ <div class='results-number'>
764
+ { lang == 'en' ? 'Results: ' : 'Risultati: '}
765
+ {#if !loading}
766
+ {totalRows || rows.length}
767
+ {:else}
768
+ <CircularLoader
769
+ {loading}
770
+ --circular-loader-height='10px'
771
+ ></CircularLoader>
772
+ {/if}
773
+ </div>
774
+ {/if}
708
775
  <div class="outer-container">
709
776
  <div class="inner-container" bind:this={tableContainer}>
710
777
  <!-- <div class="table-container" bind:this={tableContainer}> -->
711
778
  <InfiniteScroll
712
779
  on:loadMore={handleLoadBackward}
713
- treshold={backwardTresholdPixel}
780
+ threshold={backwardThresholdPixel}
714
781
  hasMore={currentSectionNumber > 0 && userScrolling}
715
782
  direction='backward'
716
783
  />
@@ -843,14 +910,15 @@ function handleLoadBackward() {
843
910
  {#each renderedRows as row, indexRow}
844
911
  <tr
845
912
  class="item-row"
913
+ data-key={row.item[uniqueKey]}
846
914
  style:background-color={
847
915
  !!row.item.disableEdit ?
848
916
  !!row.item.rowDisableBackgroundColor ?
849
917
  row.item.rowDisableBackgroundColor :
850
918
  'var(--dynamic-table-row-disabled-background-color, var(--dynamic-table-row-default-disabled-background-color))' :
851
- expandedRows.findIndex((r) => r.item.id == row.item.id ) != -1 ?
919
+ expandedRows.findIndex((r) => r.item[uniqueKey] == row.item[uniqueKey] ) != -1 ?
852
920
  'var(--dynamic-table-expanded-row-background-color, var(--dynamic-table-expanded-row-default-background-color))' :
853
- !!selectedItems.find(i => i.id == row.item.id) ?
921
+ !!selectedItems.find(i => i[uniqueKey] == row.item[uniqueKey]) ?
854
922
  'var(--dynamic-table-selected-row-background-color, var(--dynamic-table-selected-row-default-background-color))' :
855
923
  ""
856
924
  }
@@ -860,9 +928,9 @@ function handleLoadBackward() {
860
928
  {#if !!showSelect && !showExpand}
861
929
  <td style:padding-left="0px" style:text-align="center">
862
930
  <Checkbox
863
- id={row.item.id}
931
+ id={row.item[uniqueKey]}
864
932
  value={selectedItems.findIndex(
865
- (i) => i.id == row.item.id
933
+ (i) => i[uniqueKey] == row.item[uniqueKey]
866
934
  ) != -1}
867
935
  disabled={disabled || loading}
868
936
  on:change={(e) => handleSelect(row.item, e.detail.shiftKeyPressed)}
@@ -873,7 +941,7 @@ function handleLoadBackward() {
873
941
  <td style:padding-left="0px" style:text-align="center">
874
942
  <Icon
875
943
  name={expandedRows.findIndex(
876
- (r) => r.item.id == row.item.id
944
+ (r) => r.item[uniqueKey] == row.item[uniqueKey]
877
945
  ) == -1
878
946
  ? "mdi-chevron-down"
879
947
  : "mdi-chevron-up"}
@@ -940,7 +1008,7 @@ function handleLoadBackward() {
940
1008
  {/if}
941
1009
  </tr>
942
1010
  {#if showExpand}
943
- {#if expandedRows.findIndex((r) => r.item.id == row.item.id) != -1}
1011
+ {#if expandedRows.findIndex((r) => r.item[uniqueKey] == row.item[uniqueKey]) != -1}
944
1012
  <tr>
945
1013
  <td
946
1014
  colspan={headersToShowInTable.length + 1}
@@ -1000,7 +1068,7 @@ function handleLoadBackward() {
1000
1068
  {#each subHeaders as subHeader, indexSubHeader}
1001
1069
  <td
1002
1070
  class:cell-edit-activator={cellEditorIndexHeader == indexSubHeader && cellEditorIndexRow == indexSubItem && cellEditorSubItem}
1003
- class:hover-cell={cellEdit}
1071
+ class:hover-cell={cellEdit && !loading && !!subHeader.cellEditorInfo}
1004
1072
  on:click={(e) => {
1005
1073
  handleCellClick(
1006
1074
  e,
@@ -1042,7 +1110,7 @@ function handleLoadBackward() {
1042
1110
  {subHeader.type.params.nullText}
1043
1111
  {/if}
1044
1112
  {:else}
1045
- {subItem[subHeader.value]}
1113
+ <div style="display: flex; justify-content: center;">-</div>
1046
1114
  {/if}
1047
1115
  {:else}
1048
1116
  {subItem[subHeader.value]}
@@ -1077,10 +1145,17 @@ function handleLoadBackward() {
1077
1145
  </table>
1078
1146
  <InfiniteScroll
1079
1147
  on:loadMore={handleLoadForward}
1080
- treshold={forwardTresholdPixel}
1148
+ threshold={forwardThresholdPixel}
1081
1149
  hasMore={hasMoreToRender && userScrolling}
1082
1150
  />
1083
1151
  </div>
1152
+ {#if totalSections - 1 < currentSectionNumber && reachedBottom && endLineVisible}
1153
+ <div class="line-container" transition:fade>
1154
+ <span class="line"></span>
1155
+ <span class="text">{lang == 'en' ? 'End' : 'Fine'}</span>
1156
+ <span class="line"></span>
1157
+ </div>
1158
+ {/if}
1084
1159
  </div>
1085
1160
  {/if}
1086
1161
 
@@ -1234,55 +1309,57 @@ function handleLoadBackward() {
1234
1309
  >
1235
1310
  {/if}
1236
1311
  </div>
1237
- <Autocomplete
1238
- multiple
1239
- items={quickFilterActive.type.items}
1240
- bind:values={quickFilterActive.type.values}
1241
- --autocomplete-border="1px solid rgb(var(--global-color-background-500))"
1242
- --autocomplete-focus-box-shadow="0 0 0 2px rgb(var(--global-color-primary-500))"
1243
- >
1244
- <svelte:fragment slot="selection" let:selection let:unselect>
1245
- <slot name="selection" {selection} {unselect}>
1246
- <div tabindex="-1">
1247
- <Chip
1248
- close={true}
1249
- on:close={() => unselect(selection)}
1250
- --chip-default-border-radius="var(--autocomplete-border-radius, var(--autocomplete-default-border-radius))"
1251
- buttonTabIndex={-1}
1252
- truncateText
1253
- >
1254
- <slot name="chip-label" {selection}>
1255
- {#if !!quickFilterActive.type.countriesAlpha2 && quickFilterActive.type.countriesAlpha2.find((c) => c.value == selection.value)}
1256
- <div>
1257
- <FlagIcon
1258
- alpha2={quickFilterActive.type.countriesAlpha2
1259
- .find((c) => c.value == selection.value)
1260
- ?.label?.toString()
1261
- .toLowerCase() ?? ""}
1262
- --flag-icon-size="16px"
1263
- />
1264
- </div>
1265
- {/if}
1266
- {selection.label}
1267
- </slot>
1268
- </Chip>
1269
- </div>
1270
- </slot>
1271
- </svelte:fragment>
1272
- <svelte:fragment slot="item-label" let:item>
1273
- <slot name="item-label" {item}>
1274
- {#if !!quickFilterActive.type.countriesAlpha2 && quickFilterActive.type.countriesAlpha2.find((c) => c.value == item.value)}
1275
- <FlagIcon
1276
- alpha2={quickFilterActive.type.countriesAlpha2
1277
- .find((c) => c.value == item.value)
1278
- ?.label?.toString()
1279
- .toLowerCase() ?? ""}
1280
- />
1281
- {/if}
1282
- {item.label}
1283
- </slot>
1284
- </svelte:fragment>
1285
- </Autocomplete>
1312
+ <div on:click|stopPropagation role="presentation" tabindex="-1">
1313
+ <Autocomplete
1314
+ multiple
1315
+ items={quickFilterActive.type.items}
1316
+ bind:values={quickFilterActive.type.values}
1317
+ --autocomplete-border="1px solid rgb(var(--global-color-background-500))"
1318
+ --autocomplete-focus-box-shadow="0 0 0 2px rgb(var(--global-color-primary-500))"
1319
+ >
1320
+ <svelte:fragment slot="selection" let:selection let:unselect>
1321
+ <slot name="selection" {selection} {unselect}>
1322
+ <div tabindex="-1">
1323
+ <Chip
1324
+ close={true}
1325
+ on:close={() => unselect(selection)}
1326
+ --chip-default-border-radius="var(--autocomplete-border-radius, var(--autocomplete-default-border-radius))"
1327
+ buttonTabIndex={-1}
1328
+ truncateText
1329
+ >
1330
+ <slot name="chip-label" {selection}>
1331
+ {#if !!quickFilterActive.type.countriesAlpha2 && quickFilterActive.type.countriesAlpha2.find((c) => c.value == selection.value)}
1332
+ <div>
1333
+ <FlagIcon
1334
+ alpha2={quickFilterActive.type.countriesAlpha2
1335
+ .find((c) => c.value == selection.value)
1336
+ ?.label?.toString()
1337
+ .toLowerCase() ?? ""}
1338
+ --flag-icon-size="16px"
1339
+ />
1340
+ </div>
1341
+ {/if}
1342
+ {selection.label}
1343
+ </slot>
1344
+ </Chip>
1345
+ </div>
1346
+ </slot>
1347
+ </svelte:fragment>
1348
+ <svelte:fragment slot="item-label" let:item>
1349
+ <slot name="item-label" {item}>
1350
+ {#if !!quickFilterActive.type.countriesAlpha2 && quickFilterActive.type.countriesAlpha2.find((c) => c.value == item.value)}
1351
+ <FlagIcon
1352
+ alpha2={quickFilterActive.type.countriesAlpha2
1353
+ .find((c) => c.value == item.value)
1354
+ ?.label?.toString()
1355
+ .toLowerCase() ?? ""}
1356
+ />
1357
+ {/if}
1358
+ {item.label}
1359
+ </slot>
1360
+ </svelte:fragment>
1361
+ </Autocomplete>
1362
+ </div>
1286
1363
  {:else if quickFilterActive.type.key === "boolean"}
1287
1364
  {#if quickFilterActive.type.params}
1288
1365
  <div class="vertical-quick-filters">
@@ -1314,22 +1391,24 @@ function handleLoadBackward() {
1314
1391
  >
1315
1392
  {/if}
1316
1393
  </div>
1317
- <CountriesAutocomplete
1318
- bind:selected={quickFilterActive.type.selected}
1319
- {...((!!quickFilterActive.type.countriesOptions && quickFilterActive.type.countriesOptions.length > 0) && {
1320
- items: quickFilterActive.type.countriesOptions,
1321
- })}
1322
- autocompleteProps={{
1323
- placeholder: !!quickFilterActive.type.selected
1324
- ? quickFilterActive.type.selected.length > 0
1325
- ? ""
1326
- : quickFilterActive.description
1327
- : quickFilterActive.description,
1328
- multiple: true,
1329
- }}
1330
- --autocomplete-border="1px solid rgb(var(--global-color-background-500))"
1331
- --autocomplete-focus-box-shadow="0 0 0 2px rgb(var(--global-color-primary-500))"
1332
- />
1394
+ <div on:click|stopPropagation role="presentation" tabindex="-1">
1395
+ <CountriesAutocomplete
1396
+ bind:selected={quickFilterActive.type.selected}
1397
+ {...((!!quickFilterActive.type.countriesOptions && quickFilterActive.type.countriesOptions.length > 0) && {
1398
+ items: quickFilterActive.type.countriesOptions,
1399
+ })}
1400
+ autocompleteProps={{
1401
+ placeholder: !!quickFilterActive.type.selected
1402
+ ? quickFilterActive.type.selected.length > 0
1403
+ ? ""
1404
+ : quickFilterActive.description
1405
+ : quickFilterActive.description,
1406
+ multiple: true,
1407
+ }}
1408
+ --autocomplete-border="1px solid rgb(var(--global-color-background-500))"
1409
+ --autocomplete-focus-box-shadow="0 0 0 2px rgb(var(--global-color-primary-500))"
1410
+ />
1411
+ </div>
1333
1412
  {:else if quickFilterActive.type.key === "date"}
1334
1413
  <div on:click|stopPropagation role="presentation" tabindex="-1">
1335
1414
  <div>
@@ -1513,10 +1592,18 @@ function handleLoadBackward() {
1513
1592
  z-index: 2;
1514
1593
  }
1515
1594
 
1595
+ @media not all and (min-resolution:.001dpcm) {
1596
+ .table-header {
1597
+ position: sticky;
1598
+ top: -2px;
1599
+ z-index: 2;
1600
+ }
1601
+ }
1602
+
1516
1603
  .table-subheader {
1517
- top: var(--main-header-height);
1518
- z-index: 1;
1519
- }
1604
+ top: var(--main-header-height);
1605
+ z-index: 1;
1606
+ }
1520
1607
  .table-header th {
1521
1608
  padding: var(
1522
1609
  --dynamic-table-header-padding,
@@ -1599,7 +1686,7 @@ function handleLoadBackward() {
1599
1686
  }
1600
1687
 
1601
1688
  table {
1602
- border-collapse: collapse;
1689
+ border-collapse: separate;
1603
1690
  width: 100%;
1604
1691
  }
1605
1692
 
@@ -1620,6 +1707,13 @@ function handleLoadBackward() {
1620
1707
  border-radius: 5px;
1621
1708
  }
1622
1709
 
1710
+ .item-row > td {
1711
+ height: var(
1712
+ --dynamic-table-row-min-height,
1713
+ var(--dynamic-table-default-row-min-height)
1714
+ );
1715
+ }
1716
+
1623
1717
  .item-row:hover {
1624
1718
  background-color: var(
1625
1719
  --dynamic-table-row-background-color-hover,
@@ -1766,4 +1860,30 @@ function handleLoadBackward() {
1766
1860
  gap: 12px;
1767
1861
  padding: 8px;
1768
1862
  }
1769
- </style>
1863
+
1864
+ .line-container {
1865
+ position: sticky;
1866
+ bottom: 0;
1867
+ left: 0;
1868
+ width: 100%;
1869
+ background: white;
1870
+ display: flex;
1871
+ justify-content: center;
1872
+ align-items: center;
1873
+ z-index: 3;
1874
+ }
1875
+
1876
+ .line {
1877
+ flex-grow: 1;
1878
+ height: 1px;
1879
+ background: rgb(var(--global-color-contrast-800));
1880
+ margin: 0 10px;
1881
+ }
1882
+
1883
+ .results-number {
1884
+ margin: 0px 0px 4px 4px;
1885
+ display: flex;
1886
+ align-items: center;
1887
+ gap: 4px;
1888
+ }
1889
+ </style>
@@ -153,9 +153,16 @@ declare const __propDef: {
153
153
  searchText?: string | undefined;
154
154
  renderedRowsNumber?: number | undefined;
155
155
  sectionRowsNumber?: number | undefined;
156
- sectionTreshold?: number | undefined;
157
- backwardTresholdPixel?: number | undefined;
158
- forwardTresholdPixel?: number | undefined;
156
+ sectionThreshold?: number | undefined;
157
+ backwardThresholdPixel?: number | undefined;
158
+ forwardThresholdPixel?: number | undefined;
159
+ uniqueKey?: keyof {
160
+ [key: string]: any;
161
+ disableEdit?: boolean | undefined;
162
+ rowDisableBackgroundColor?: string | undefined;
163
+ } | undefined;
164
+ numberOfResultsVisible?: boolean | undefined;
165
+ endLineVisible?: boolean | undefined;
159
166
  };
160
167
  events: {
161
168
  click: MouseEvent;
@@ -17,6 +17,7 @@ import { fly } from "svelte/transition";
17
17
  import Dialog from "../../simple/dialogs/Dialog.svelte";
18
18
  import Validator from "../../../utils/filters/validator";
19
19
  import ToolTip from "../common/ToolTip.svelte";
20
+ import { DateTime } from "luxon";
20
21
  export let filters = [], lang = "en", addFilterLabel = lang == "en" ? "Filters" : "Filtri", cancelFilterLabel = lang == "en" ? "Cancel" : "Annulla", applyFilterLabel = lang == "en" ? "Apply filter" : "Applica filtro", showActiveFilters = true, filterTitleLabel = lang == "en" ? "Filter by" : "Filtra per", dateLocale = lang == "en" ? "en" : "it", betweenSeparator = lang == "en" ? "and" : "e", trueString = lang == "en" ? "true" : "vero", falseString = lang == "en" ? "false" : "falso", editFilterMode = "one-edit", labelsMapper = lang == "en" ? {
21
22
  "equal": {
22
23
  extended: "equal to",
@@ -276,8 +277,13 @@ function updateMultiFilterValues(filterName, newValue, newValid, mode) {
276
277
  if (tmpFilter.type == "select") {
277
278
  tmpFilter.values = newValue;
278
279
  } else if ("mode" in tmpFilter && tmpFilter.mode == "between") {
279
- tmpFilter.to = newValue.to;
280
- tmpFilter.from = newValue.from;
280
+ if (tmpFilter.type == "date") {
281
+ tmpFilter.from = DateTime.fromJSDate(newValue.to).setLocale("it-IT").startOf("day").toJSDate();
282
+ tmpFilter.to = DateTime.fromJSDate(newValue.to).setLocale("it-IT").endOf("day").toJSDate();
283
+ } else {
284
+ tmpFilter.from = newValue.from;
285
+ tmpFilter.to = newValue.to;
286
+ }
281
287
  } else {
282
288
  tmpFilter.value = newValue;
283
289
  }
@@ -1,11 +1,11 @@
1
1
  <script>import { onDestroy, createEventDispatcher } from "svelte";
2
- export let treshold = 0, horizontal = false, elementScroll = null, hasMore = true, direction = "forward";
2
+ export let threshold = 0, horizontal = false, elementScroll = null, hasMore = true, direction = "forward";
3
3
  const dispatch = createEventDispatcher();
4
4
  let isLoadMore = false, component;
5
5
  function onScroll(e) {
6
6
  const element = e.target;
7
7
  const offset = horizontal ? direction == "forward" ? element.scrollWidth - element.clientWidth - element.scrollLeft : element.scrollLeft : direction == "forward" ? element.scrollHeight - element.clientHeight - element.scrollTop : element.scrollTop;
8
- if (offset <= treshold) {
8
+ if (offset <= threshold) {
9
9
  if (!isLoadMore && hasMore) {
10
10
  dispatch("loadMore");
11
11
  }
@@ -1,7 +1,7 @@
1
1
  import { SvelteComponent } from "svelte";
2
2
  declare const __propDef: {
3
3
  props: {
4
- treshold?: number | undefined;
4
+ threshold?: number | undefined;
5
5
  horizontal?: boolean | undefined;
6
6
  elementScroll?: HTMLElement | null | undefined;
7
7
  hasMore?: boolean | undefined;
@@ -93,20 +93,20 @@ export default class Converter {
93
93
  return params.builder;
94
94
  }
95
95
  applyNumberFilter(params) {
96
- if (params.filter.mode == 'equal' && !!params.filter.value) {
96
+ if (params.filter.mode == 'equal' && params.filter.value !== undefined) {
97
97
  params.builder.where(params.filter.column, '=', params.filter.value);
98
98
  }
99
- else if (params.filter.mode == 'greater' && !!params.filter.value) {
99
+ else if (params.filter.mode == 'greater' && params.filter.value !== undefined) {
100
100
  params.builder.where(params.filter.column, '>', params.filter.value);
101
101
  }
102
- else if (params.filter.mode == 'lower' && !!params.filter.value) {
102
+ else if (params.filter.mode == 'lower' && params.filter.value !== undefined) {
103
103
  params.builder.where(params.filter.column, '<', params.filter.value);
104
104
  }
105
105
  else if (params.filter.mode == 'between') {
106
- if (!!params.filter.from) {
106
+ if (params.filter.from !== undefined) {
107
107
  params.builder.where(params.filter.column, '>=', params.filter.from);
108
108
  }
109
- if (!!params.filter.to) {
109
+ if (params.filter.to !== undefined) {
110
110
  params.builder.where(params.filter.column, '<=', params.filter.to);
111
111
  }
112
112
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@likable-hair/svelte",
3
3
  "description": "A Svelte component for likablehair and others",
4
- "version": "3.3.11",
4
+ "version": "3.3.13",
5
5
  "scripts": {
6
6
  "host": "vite --host",
7
7
  "dev": "vite dev",