@likable-hair/svelte 4.0.17 → 4.0.19

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.
@@ -3,12 +3,12 @@
3
3
 
4
4
  <script lang="ts" generics="Data">import '../../../css/main.css';
5
5
  import Chip from "../../simple/navigation/Chip.svelte";
6
- let { values = $bindable([]), items, multiple = true, disabled = false, onchange, } = $props();
6
+ let { values = $bindable(), items, multiple = true, disabled = false, onchange, } = $props();
7
7
  function select(item) {
8
- const alreadyPresent = values.findIndex((i) => i.value === item.value) != -1;
8
+ const alreadyPresent = values?.findIndex((i) => i.value === item.value) !== -1;
9
9
  if (!alreadyPresent) {
10
10
  if (multiple)
11
- values = [...values, item];
11
+ values = [...(values || []), item];
12
12
  else
13
13
  values = [item];
14
14
  if (onchange) {
@@ -23,19 +23,19 @@ function select(item) {
23
23
  }
24
24
  }
25
25
  function unselect(item) {
26
- values = values.filter((i) => i.value != item.value);
26
+ values = values?.filter((i) => i.value != item.value);
27
27
  if (onchange) {
28
28
  onchange({
29
29
  detail: {
30
30
  unselect: item,
31
31
  select: undefined,
32
- selection: values,
32
+ selection: values || [],
33
33
  }
34
34
  });
35
35
  }
36
36
  }
37
37
  function toggle(item) {
38
- const alreadyPresent = values.findIndex((i) => i.value === item.value) != -1;
38
+ const alreadyPresent = values?.findIndex((i) => i.value === item.value) !== -1;
39
39
  if (alreadyPresent)
40
40
  unselect(item);
41
41
  else
@@ -55,7 +55,7 @@ function toggle(item) {
55
55
  {#each (items || []) as item}
56
56
  <div class="chip">
57
57
  <Chip
58
- outlined={values.findIndex(i => i.value === item.value) === -1}
58
+ outlined={!values || values?.findIndex(i => i.value === item.value) === -1}
59
59
  onclick={() => toggle(item)}
60
60
  buttonTabIndex={0}
61
61
  truncateText
@@ -5,16 +5,16 @@ import {} from "svelte";
5
5
  import Filters from "../search/Filters.svelte";
6
6
  import SearchBar from "../search/SearchBar.svelte";
7
7
  import Converter from "../../../utils/filters/filters";
8
- let { headers = [], items = [], sortedBy = $bindable(undefined), sortDirection = $bindable('asc'), page = $bindable(1), maxPage = undefined, rowsPerPageOptions = [
8
+ let { headers = [], items = [], sortedBy = $bindable(undefined), sortDirection = $bindable("asc"), page = $bindable(1), maxPage = undefined, rowsPerPageOptions = [
9
9
  { label: "20", value: 20 },
10
10
  { label: "50", value: 50 },
11
11
  { label: "100", value: 100 },
12
- ], hideRowsPerPage = false, totalElements = undefined, rowsPerPage = $bindable(20), filters = $bindable([]), searchBarColumns = undefined, searchBarVisible = true, searchBarPlaceholder = "Type something to search...", lang = "en", editFilterMode = "one-edit", showActiveFilters = true, resizableColumns = false, resizedColumnSizeWithPadding = {}, pointerOnRowHover = undefined, doubleClickActive = false, doubleClickDelay = 250, calculateRowStyles = undefined, calculateRowClasses = undefined, class: clazz = {}, onfiltersChange, onpaginationChange, onremoveFilter, onremoveAllFilters, customFilterChipSnippet, customFilterSnippet, filterAppendSnippet, onrowClick, onrowDoubleClick, appendSnippet, customSnippet, headerLabelSnippet, headerSnippet, rowActionsSnippet, onsort, footerSnippet, rangeDescriptorSnippet, searchBarSnippet, noDataSnippet, oncolumnResize, } = $props();
12
+ ], hideRowsPerPage = false, totalElements = undefined, rowsPerPage = $bindable(20), filters = $bindable([]), searchBarColumns = undefined, searchBarVisible = true, lang = "en", editFilterMode = "one-edit", showActiveFilters = true, resizableColumns = false, resizedColumnSizeWithPadding = {}, pointerOnRowHover = undefined, doubleClickActive = false, doubleClickDelay = 250, calculateRowStyles = undefined, calculateRowClasses = undefined, class: clazz = {}, onfiltersChange, onpaginationChange, onremoveFilter, onremoveAllFilters, customFilterChipSnippet, customFilterSnippet, filterAppendSnippet, onrowClick, onrowDoubleClick, appendSnippet, customSnippet, headerLabelSnippet, headerSnippet, rowActionsSnippet, onsort, footerSnippet, rangeDescriptorSnippet, searchBarSnippet, noDataSnippet, oncolumnResize, } = $props();
13
13
  let searchBarInput = $state(), searchText = $state(), sortModify;
14
14
  let rowsPerPageSelection = $state([]);
15
15
  $effect(() => {
16
16
  rowsPerPageSelection = [
17
- { label: rowsPerPage.toString(), value: rowsPerPage }
17
+ { label: rowsPerPage.toString(), value: rowsPerPage },
18
18
  ];
19
19
  });
20
20
  $effect(() => {
@@ -30,8 +30,10 @@ function handlePaginationChange() {
30
30
  if (onpaginationChange) {
31
31
  onpaginationChange({
32
32
  detail: {
33
- rowsPerPage, page, builder
34
- }
33
+ rowsPerPage,
34
+ page,
35
+ builder,
36
+ },
35
37
  });
36
38
  }
37
39
  }
@@ -40,8 +42,8 @@ function handleSearchChange(searchText) {
40
42
  if (onfiltersChange) {
41
43
  onfiltersChange({
42
44
  detail: {
43
- builder
44
- }
45
+ builder,
46
+ },
45
47
  });
46
48
  }
47
49
  }
@@ -53,8 +55,8 @@ function handleFiltersChange() {
53
55
  if (onfiltersChange) {
54
56
  onfiltersChange({
55
57
  detail: {
56
- builder
57
- }
58
+ builder,
59
+ },
58
60
  });
59
61
  }
60
62
  }
@@ -81,19 +83,24 @@ function buildFilters(params) {
81
83
  let converter = new Converter();
82
84
  let builder;
83
85
  builder = converter.createBuilder({
84
- filters: filters || []
86
+ filters: filters || [],
85
87
  });
86
- if (!!params?.searchText && !!searchBarColumns && searchBarColumns.length > 0) {
87
- builder.where(b => {
88
- b.where(searchBarColumns[0], 'ilike', '%' + params?.searchText + '%');
88
+ if (!!params?.searchText &&
89
+ !!searchBarColumns &&
90
+ searchBarColumns.length > 0) {
91
+ builder.where((b) => {
92
+ b.where(searchBarColumns[0], "ilike", "%" + params?.searchText + "%");
89
93
  for (let i = 1; i < searchBarColumns.length; i += 1) {
90
- b.orWhere(searchBarColumns[i], 'ilike', '%' + params?.searchText + '%');
94
+ b.orWhere(searchBarColumns[i], "ilike", "%" + params?.searchText + "%");
91
95
  }
92
96
  });
93
97
  }
94
98
  if (!!sortedBy) {
95
99
  if (sortModify) {
96
- builder = sortModify({ builder, sortDirection: sortDirection || 'asc' });
100
+ builder = sortModify({
101
+ builder,
102
+ sortDirection: sortDirection || "asc",
103
+ });
97
104
  }
98
105
  else {
99
106
  builder.orderBy(sortedBy, sortDirection || "asc");
@@ -104,35 +111,36 @@ function buildFilters(params) {
104
111
  </script>
105
112
 
106
113
  <div class="paginated-table">
107
- {#if searchBarVisible}
108
- {#if searchBarSnippet}
109
- {@render searchBarSnippet({ handleSearchChange })}
110
- {:else}
111
- <div class="search-bar-container">
112
- <SearchBar
113
- placeholder={searchBarPlaceholder}
114
- bind:input={searchBarInput}
115
- bind:value={searchText}
116
- >
117
- </SearchBar>
118
- </div>
119
- {/if}
120
- {/if}
121
114
  <div class="filter-container">
115
+ {#if searchBarVisible}
116
+ {#if searchBarSnippet}
117
+ {@render searchBarSnippet({ handleSearchChange })}
118
+ {:else}
119
+ <div class="search-bar-container">
120
+ <SearchBar
121
+ bind:input={searchBarInput}
122
+ bind:value={searchText}
123
+ --search-bar-default-height="36px"
124
+ --search-bar-default-border-radius="4px"
125
+ --search-bar-default-ring-color="rgb(var(--global-color-background-300),.6)"
126
+ --search-bar-default-background-color="rgb(var(--global-color-background-300),.4)"
127
+ ></SearchBar>
128
+ </div>
129
+ {/if}
130
+ {/if}
122
131
  <Filters
123
132
  bind:filters
124
133
  onapplyFilter={handleFiltersChange}
125
134
  onremoveFilter={handleRemoveFilter}
126
135
  onremoveAllFilters={handleRemoveAllFilters}
127
- --filters-default-wrapper-width="100%"
136
+ --filters-default-wrapper-width={!!searchBarVisible ? undefined : "100%"}
128
137
  {lang}
129
138
  {editFilterMode}
130
139
  {showActiveFilters}
131
140
  appendSnippet={filterAppendSnippet}
132
141
  customChipSnippet={customFilterChipSnippet}
133
142
  customSnippet={customFilterSnippet}
134
- >
135
- </Filters>
143
+ ></Filters>
136
144
  </div>
137
145
  <SimpleTable
138
146
  {headers}
@@ -158,12 +166,11 @@ function buildFilters(params) {
158
166
  {headerLabelSnippet}
159
167
  {noDataSnippet}
160
168
  {oncolumnResize}
161
- >
162
- </SimpleTable>
169
+ ></SimpleTable>
163
170
 
164
171
  <div class="footer">
165
172
  {#if footerSnippet}
166
- {@render footerSnippet({
173
+ {@render footerSnippet({
167
174
  hideRowsPerPage,
168
175
  rowsPerPageOptions,
169
176
  rowsPerPageSelection,
@@ -171,7 +178,7 @@ function buildFilters(params) {
171
178
  page,
172
179
  maxPage,
173
180
  rowsPerPage,
174
- handlePaginationChange
181
+ handlePaginationChange,
175
182
  })}
176
183
  {:else}
177
184
  {#if !hideRowsPerPage}
@@ -189,17 +196,20 @@ function buildFilters(params) {
189
196
  {/if}
190
197
  {#if totalElements !== undefined}
191
198
  {#if rangeDescriptorSnippet}
192
- {@render rangeDescriptorSnippet({ page, maxPage, rowsPerPage, totalElements })}
199
+ {@render rangeDescriptorSnippet({
200
+ page,
201
+ maxPage,
202
+ rowsPerPage,
203
+ totalElements,
204
+ })}
193
205
  {:else}
194
206
  <div class="range-descriptor">
195
- viewing {((page || 1) - 1) * rowsPerPage} - {(page || 1) * rowsPerPage} of {totalElements}
207
+ viewing {((page || 1) - 1) * rowsPerPage} - {(page || 1) *
208
+ rowsPerPage} of {totalElements}
196
209
  </div>
197
210
  {/if}
198
211
  {/if}
199
- <Paginator
200
- bind:page
201
- {maxPage}
202
- onchange={handlePaginationChange}
212
+ <Paginator bind:page {maxPage} onchange={handlePaginationChange}
203
213
  ></Paginator>
204
214
  {/if}
205
215
  </div>
@@ -214,7 +224,7 @@ function buildFilters(params) {
214
224
  }
215
225
 
216
226
  .range-descriptor {
217
- font-size: .7rem;
227
+ font-size: 0.7rem;
218
228
  }
219
229
 
220
230
  .footer {
@@ -225,11 +235,10 @@ function buildFilters(params) {
225
235
  }
226
236
 
227
237
  .filter-container {
228
- margin-top: var(--paginated-table-filter-container-margin-top, 10px);
229
238
  display: flex;
230
239
  align-items: center;
231
240
  flex-direction: row;
232
- gap: 10px;
241
+ gap: 12px;
233
242
  width: 100%;
234
243
  }
235
244
 
@@ -238,6 +247,7 @@ function buildFilters(params) {
238
247
  --paginated-table-search-bar-container-padding,
239
248
  var(--paginated-table-search-bar-container-default-padding, 0)
240
249
  );
250
+ flex-grow: 1;
241
251
  }
242
252
 
243
253
  @media only screen and (max-width: 768px) {
@@ -245,5 +255,4 @@ function buildFilters(params) {
245
255
  display: none;
246
256
  }
247
257
  }
248
-
249
- </style>
258
+ </style>
@@ -26,6 +26,7 @@ function closeDropDown() {
26
26
  dropdownOpened = false;
27
27
  }
28
28
  $effect(() => {
29
+ console.log('effect 1');
29
30
  if (!!filter) {
30
31
  tick().then(() => {
31
32
  initTmpFilter();
@@ -34,6 +35,7 @@ $effect(() => {
34
35
  }
35
36
  });
36
37
  $effect(() => {
38
+ console.log('effect 2');
37
39
  if (!!tmpFilter) {
38
40
  let modes;
39
41
  if (tmpFilter.type == 'string') {
@@ -62,6 +64,7 @@ $effect(() => {
62
64
  }
63
65
  });
64
66
  $effect(() => {
67
+ console.log('effect 3');
65
68
  if (!tmpFilter?.advanced) {
66
69
  advancedModeSelectedOptions = [];
67
70
  }
@@ -86,6 +89,7 @@ function handleAdvancedModeSelection() {
86
89
  }
87
90
  let applyFilterDisabled = $derived(!Validator.isValid(tmpFilter) && !forceApplyValid);
88
91
  $effect.pre(() => {
92
+ console.log('effect 4');
89
93
  if (!!tmpFilter && tmpFilter.type == 'bool') {
90
94
  if (tmpFilter.value === undefined) {
91
95
  tmpFilter.value = false;
@@ -93,6 +97,7 @@ $effect.pre(() => {
93
97
  }
94
98
  });
95
99
  $effect.pre(() => {
100
+ console.log('effect 5');
96
101
  if (!!tmpFilter && tmpFilter.type == 'select') {
97
102
  if (tmpFilter.values === undefined) {
98
103
  tmpFilter.values = [];
@@ -3,5 +3,5 @@
3
3
  --filters-button-cancel-default-color: rgb(var(--global-color-primary-400));
4
4
  --filters-default-one-edit-menu-max-height: 100%;
5
5
  --filters-default-wrapper-width: auto;
6
- --filters-default-button-height: 28px;
6
+ --filters-default-button-height: 20px;
7
7
  }
@@ -19,7 +19,7 @@ import Dialog from '../../simple/dialogs/Dialog.svelte';
19
19
  import Validator from '../../../utils/filters/validator';
20
20
  import ToolTip from '../common/ToolTip.svelte';
21
21
  import { DateTime } from 'luxon';
22
- let { filters = $bindable([]), 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'
22
+ let { filters = $bindable([]), lang = 'en', addFilterLabel = lang === 'en' ? "Filters" : "Filtri", cancelFilterLabel = lang === 'en' ? "Cancel" : "Annulla", applyFilterLabel = lang === 'en' ? "Apply filters" : "Applica filtri", 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'
23
23
  ? {
24
24
  equal: { extended: 'equal to', short: 'equal' },
25
25
  like: { short: 'includes' },
@@ -39,7 +39,7 @@ let { filters = $bindable([]), lang = 'en', addFilterLabel = lang === 'en' ? "Fi
39
39
  lower: { short: 'minore', extended: 'minore di' },
40
40
  between: { short: 'compreso', extended: 'è compreso tra' },
41
41
  different: { short: 'diverso', extended: 'diverso da' }
42
- }, drawerSpace = '20rem', onaddFilterClick, onapplyFilter, onremoveAllFilters, onremoveFilter, customSnippet: customInternalSnippet, customChipSnippet, appendSnippet, contentSnippet, onclick: onclickInternal, onkeydown, } = $props();
42
+ }, drawerSpace = '60vh', onaddFilterClick, onapplyFilter, onremoveAllFilters, onremoveFilter, customSnippet: customInternalSnippet, customChipSnippet, appendSnippet, contentSnippet, onclick: onclickInternal, onkeydown, } = $props();
43
43
  let open = $state(false), mobileOpen = $state(false), activator = $state();
44
44
  function handleAddFilterClick() {
45
45
  if (onaddFilterClick) {
@@ -321,7 +321,7 @@ function onclick(event, stopPropagation = false) {
321
321
 
322
322
  <MediaQuery>
323
323
  {#snippet defaultSnippet({ mAndDown})}
324
- <div class="filters-wrapper" class:mobile={mAndDown} style:--filter-dot-size={activeFilters.length > 0 ? '22px' : '0px'} style:--filter-dot-content={activeFilters.length > 0 ? `"${activeFilters.length}"` : '""'}>
324
+ <div class="filters-wrapper" class:mobile={mAndDown} style:--filter-dot-size={activeFilters.length > 0 ? '16px' : '0px'} style:--filter-dot-content={activeFilters.length > 0 ? `"${activeFilters.length}"` : '""'}>
325
325
  <div class="filters-container" class:mobile={mAndDown} class:hidden={mAndDown && (!showActiveFilters || activeFilters.length == 0)}>
326
326
  {#if showActiveFilters}
327
327
  {#each activeFilters as filter}
@@ -332,6 +332,7 @@ function onclick(event, stopPropagation = false) {
332
332
  <Chip
333
333
  label
334
334
  close
335
+ --chip-border-radius="4px"
335
336
  onclose={() => handleRemoveFilter(filter)}
336
337
  onclick={() => handleActiveFilterClick(filter)}
337
338
  >
@@ -385,7 +386,7 @@ function onclick(event, stopPropagation = false) {
385
386
  <span class="more-items" bind:this={moreItemsActivator}>+{filter.values.length - 1}</span>
386
387
  <ToolTip activator={moreItemsActivator}>
387
388
  <div class="more-tooltip-content">
388
- <ul>
389
+ <ul style:margin="0px">
389
390
  {#each filter.values as value}
390
391
  <li><div class="truncate-text">{value.label}</div></li>
391
392
  {/each}
@@ -408,6 +409,7 @@ function onclick(event, stopPropagation = false) {
408
409
  >
409
410
  <Button
410
411
  --button-color="var(--chip-color, var(--chip-default-color))"
412
+ --button-border-radius="4px"
411
413
  --button-height="var(--filters-button-height, var(--filters-default-button-height))"
412
414
  onclick={handleAddFilterClick}
413
415
  >
@@ -415,7 +417,11 @@ function onclick(event, stopPropagation = false) {
415
417
  <Icon name="mdi-filter"></Icon>
416
418
  {addFilterLabel}
417
419
  <div class="remove-filters" class:hidden={activeFilters.length <= 0}>
418
- <Icon name="mdi-close-circle" onclick={handleRemoveAllFilters}></Icon>
420
+ <Icon
421
+ name="mdi-close-circle"
422
+ onclick={handleRemoveAllFilters}
423
+ --icon-hover-color="var(--chip-color, var(--chip-default-color))"
424
+ ></Icon>
419
425
  </div>
420
426
  </div>
421
427
  </Button>
@@ -430,6 +436,8 @@ function onclick(event, stopPropagation = false) {
430
436
  >
431
437
  <Button
432
438
  --button-color="var(--chip-color, var(--chip-default-color))"
439
+ --button-hover-color="var(--chip-color, var(--chip-default-color))"
440
+ --button-border-radius="4px"
433
441
  --button-height="var(--filters-button-height, var(--filters-default-button-height))"
434
442
  onclick={handleAddFilterClick}
435
443
  >
@@ -437,7 +445,11 @@ function onclick(event, stopPropagation = false) {
437
445
  <Icon name="mdi-filter"></Icon>
438
446
  {addFilterLabel}
439
447
  <div class="remove-filters" class:hidden={activeFilters.length <= 0}>
440
- <Icon name="mdi-close-circle" onclick={handleRemoveAllFilters}></Icon>
448
+ <Icon
449
+ name="mdi-close-circle"
450
+ onclick={handleRemoveAllFilters}
451
+ --icon-hover-color="var(--chip-color, var(--chip-default-color))"
452
+ ></Icon>
441
453
  </div>
442
454
  </div>
443
455
  </Button>
@@ -536,9 +548,9 @@ function onclick(event, stopPropagation = false) {
536
548
  >
537
549
  <div class="form-container" style:background-color={mAndDown ? 'transparent' : 'rgb(var(--global-color-background-100))'} style:width={mAndDown ? '100%' : '50vw'} style:box-sizing="border-box">
538
550
  <div class="header">
539
- <h1>{addFilterLabel}</h1>
551
+ <div>{addFilterLabel}</div>
540
552
  </div>
541
- <div class="body">
553
+ <div class="drawer-body">
542
554
  {#if contentSnippet}
543
555
  {@render contentSnippet({ mAndDown, updateMultiFilterValues, filters, handleRemoveAllFilters })}
544
556
  {:else}
@@ -706,12 +718,19 @@ function onclick(event, stopPropagation = false) {
706
718
  {:else if editFilterMode === 'multi-edit'}
707
719
  <Dialog
708
720
  bind:open={open}
721
+ _overlayOpacity="50%"
722
+ _overlayBackdropFilter="blur(4px)"
709
723
  >
710
- <div class="form-container" style:background-color={mAndDown ? 'transparent' : 'rgb(var(--global-color-background-100))'} style:width={mAndDown ? '100%' : '50vw'} style:box-sizing="border-box">
724
+ <div
725
+ class="form-container"
726
+ style:background-color={mAndDown ? 'transparent' : 'rgb(var(--global-color-background-100))'}
727
+ style:width={mAndDown ? '100%' : '800px'}
728
+ style:box-sizing="border-box"
729
+ >
711
730
  <div class="header">
712
- <h1>{addFilterLabel}</h1>
731
+ <div>{addFilterLabel}</div>
713
732
  </div>
714
- <div class="body">
733
+ <div class="dialog-body">
715
734
  {#if contentSnippet}
716
735
  {@render contentSnippet({ mAndDown, updateMultiFilterValues, filters, handleRemoveAllFilters })}
717
736
  {:else}
@@ -744,30 +763,37 @@ function onclick(event, stopPropagation = false) {
744
763
  </div>
745
764
  {/if}
746
765
  </div>
747
- <div class="footer">
766
+ <div class="dialog-footer">
748
767
  <div class="actions" style:padding-bottom={mAndDown ? '20px' : undefined}>
749
768
  <Button
750
- --button-background-color="var(--filters-button-cancel-background-color, var(--filters-button-cancel-default-background-color))"
751
- --button-color="var(--filters-button-cancel-color, var(--filters-button-cancel-default-color))"
752
- --button-hover-background-color="rgb(var(--global-color-primary-500))"
753
- --button-hover-box-shadow="0 0 0.5rem rgba(0, 0, 0, 0.3)"
769
+ --button-color="rgb(var(--global-color-contrast-900))"
770
+ --button-background-color="transparent"
771
+ --button-focus-background-color="rgb(var(--global-color-background-200, .5))"
772
+ --button-active-background-color="rgb(var(--global-color-background-200, .5))"
773
+ --button-hover-background-color="rgb(var(--global-color-background-200, .5))"
774
+ --button-hover-box-shadow="none"
754
775
  --button-box-shadow="none"
776
+ --button-padding="12px 16px"
755
777
  onclick={handleCancelFilterClick}
756
778
  >
757
779
  {cancelFilterLabel}
758
780
  </Button>
759
781
  <Button
760
- --button-color="rgb(var(--global-color-primary-400))"
782
+ --button-color="rgb(var(--global-color-contrast-900))"
761
783
  --button-background-color="transparent"
762
- --button-hover-background-color="rgb(var(--global-color-primary-500))"
763
- --button-hover-box-shadow="0 0 0.5rem rgba(0, 0, 0, 0.3)"
784
+ --button-focus-background-color="rgb(var(--global-color-background-200, .5))"
785
+ --button-active-background-color="rgb(var(--global-color-background-200, .5))"
786
+ --button-hover-background-color="rgb(var(--global-color-background-200, .5))"
787
+ --button-hover-box-shadow="none"
764
788
  --button-box-shadow="none"
789
+ --button-padding="12px 16px"
765
790
  onclick={handleMultiEditRemoveClick}
766
791
  >
767
792
  {lang == 'en' ? "Remove filters" : "Rimuovi filtri"}
768
793
  </Button>
769
794
  <Button
770
- --button-min-width="100px"
795
+ --button-min-width="fit-content"
796
+ --button-padding="12px 16px"
771
797
  onclick={handleApplyMultiFilterClick}
772
798
  >
773
799
  {applyFilterLabel}
@@ -798,7 +824,6 @@ function onclick(event, stopPropagation = false) {
798
824
  }
799
825
 
800
826
  .filter-button-content .remove-filters {
801
- margin: 0px 8px 0px 8px;
802
827
  color: rgb(var(--global-color-primary-100));
803
828
  }
804
829
 
@@ -813,15 +838,16 @@ function onclick(event, stopPropagation = false) {
813
838
  .filter-button::before {
814
839
  content: var(--filter-dot-content, '0');
815
840
  text-align: center;
816
- font-size: .6rem;
841
+ font-size: .5rem;
817
842
  background-color: rgb(var(--global-color-background-500));
818
843
  color: rgb(var(--global-color-contrast-700));
819
844
  position: absolute;
820
845
  box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px;
821
- top: -40%;
822
- left: calc(100% - 10px);
846
+ top: -16%;
847
+ right: -8%;
823
848
  border-radius: 100px;
824
849
  width: var(--filter-dot-size, 0px);
850
+ line-height: 16px;
825
851
  height: var(--filter-dot-size, 0px);
826
852
  }
827
853
 
@@ -840,7 +866,7 @@ function onclick(event, stopPropagation = false) {
840
866
  .filters-container {
841
867
  display: flex;
842
868
  flex-wrap: wrap;
843
- gap: 5px;
869
+ gap: 8px;
844
870
  align-items: center;
845
871
  }
846
872
 
@@ -852,7 +878,7 @@ function onclick(event, stopPropagation = false) {
852
878
  .filters-wrapper {
853
879
  display: flex;
854
880
  align-items: start;
855
- gap: 20px;
881
+ gap: 8px;
856
882
  max-width: 100%;
857
883
  width: var(
858
884
  --filters-wrapper-width,
@@ -873,13 +899,13 @@ function onclick(event, stopPropagation = false) {
873
899
 
874
900
  .more-items {
875
901
  position: relative;
876
- padding: 2px 8px 2px 8px;
877
- border-radius: 20px;
878
- margin-left: 5px;
902
+ padding: 0px 6px;
903
+ border-radius: 8px;
904
+ margin-left: 2px;
879
905
  background-color: rgb(var(--global-color-grey-50));
880
906
  color: rgb(var(--global-color-primary-500));
881
907
  font-weight: 800;
882
- font-size: .7rem;
908
+ font-size: 10px;
883
909
  }
884
910
 
885
911
  .more-tooltip-content {
@@ -887,7 +913,7 @@ function onclick(event, stopPropagation = false) {
887
913
  text-overflow: ellipsis;
888
914
  width: fit-content;
889
915
  border-radius: 6px;
890
- padding: 10px 20px 10px 20px;
916
+ padding: 16px;
891
917
  text-align: left;
892
918
  background-color: rgb(var(--global-color-background-200));
893
919
  color: rgb(var(--global-color-background-950));
@@ -913,7 +939,7 @@ function onclick(event, stopPropagation = false) {
913
939
 
914
940
  .form-container {
915
941
  border-radius: 10px;
916
- padding: 20px;
942
+ box-shadow: 0 0 1px 1px rgb(var(--global-color-background-200));
917
943
  height: 100%;
918
944
  max-height: 90vh;
919
945
  overflow-y: auto;
@@ -963,7 +989,31 @@ function onclick(event, stopPropagation = false) {
963
989
  .header {
964
990
  font-weight: 600;
965
991
  font-size: 1.5rem;
966
- padding: 0 0 8px 8px;
992
+ padding: 16px;
993
+ height: 32px;
994
+ display: flex;
995
+ align-items: center;
996
+ border-bottom: 1px solid rgb(var(--global-color-background-200));
997
+ }
998
+
999
+ .drawer-body {
1000
+ padding: 16px;
1001
+ }
1002
+
1003
+ .dialog-body {
1004
+ padding: 16px;
1005
+ height: calc(90vh - 96px);
1006
+ max-height: calc(90vh - 164px);
1007
+ overflow-y: auto;
1008
+ }
1009
+
1010
+ .dialog-footer {
1011
+ height: 32px;
1012
+ padding: 16px;
1013
+ display: flex;
1014
+ align-items: center;
1015
+ justify-content: flex-end;
1016
+ border-top: 1px solid rgb(var(--global-color-background-200));
967
1017
  }
968
1018
 
969
1019
  </style>
@@ -8,17 +8,11 @@ import { fly } from "svelte/transition";
8
8
  import Autocomplete from "../../simple/forms/Autocomplete.svelte";
9
9
  import Checkbox from "../../simple/forms/Checkbox.svelte";
10
10
  import ToggleList from "../forms/ToggleList.svelte";
11
- let { filter = $bindable(undefined), lang = 'en', backIcon = "mdi-arrow-left", betweenFromLabel = lang === 'en' ? "From" : "Da", betweenToLabel = lang === 'en' ? "To" : "A", labelsMapper, forceApplyValid = false, tmpFilter = $bindable(undefined), onbackClick, onkeypress, onclick: onclickInternal, onclose, customSnippet, filterActionsSnippet, titleSnippet, } = $props();
12
- // function handleApplyFilterClick() {
13
- // if(!!filter && !!tmpFilter) {
14
- // filter = {...tmpFilter}
15
- // filter.active = true
16
- // dispatch('apply')
17
- // }
18
- // }
11
+ import lodash from 'lodash';
12
+ let { filter = $bindable(), lang = 'en', backIcon = "mdi-arrow-left", betweenFromLabel = lang === 'en' ? "From" : "Da", betweenToLabel = lang === 'en' ? "To" : "A", labelsMapper, forceApplyValid = false, tmpFilter = $bindable(), onbackClick, onkeypress, onclick: onclickInternal, onclose, customSnippet, filterActionsSnippet, titleSnippet, } = $props();
19
13
  let step = $state();
20
14
  function initTmpFilter() {
21
- tmpFilter = filter === undefined ? undefined : { ...filter };
15
+ tmpFilter = filter === undefined ? undefined : lodash.cloneDeep(filter);
22
16
  if (!!tmpFilter && tmpFilter.advanced) {
23
17
  if (['string', 'number', 'date', 'select'].includes(tmpFilter.type) && Object.keys(tmpFilter).includes('mode')) {
24
18
  //@ts-ignore
@@ -39,14 +33,53 @@ function initTmpFilter() {
39
33
  step = "editor";
40
34
  }
41
35
  }
36
+ let advancedModeOptions = $state(), advancedModeSelectedOption = $state();
37
+ let calendarOpened = $state(false), calendarOpened2 = $state(false);
38
+ // TODO I don't like that there is a single dropdown to handle all filter advance mode.
39
+ // In some case would be necessary to handle more than one selection and this code
40
+ // could become non sense
41
+ function handleAdvancedModeSelection() {
42
+ if (!!advancedModeSelectedOption && !!tmpFilter) {
43
+ if (tmpFilter.type == 'date')
44
+ tmpFilter.mode = advancedModeSelectedOption;
45
+ else if (tmpFilter.type == 'string')
46
+ tmpFilter.mode = advancedModeSelectedOption;
47
+ else if (tmpFilter.type == 'number')
48
+ tmpFilter.mode = advancedModeSelectedOption;
49
+ else if (tmpFilter.type == 'select')
50
+ tmpFilter.mode = advancedModeSelectedOption;
51
+ step = 'editor';
52
+ canRenderOptions = false;
53
+ }
54
+ }
55
+ let canRenderOptions = $state(true);
56
+ let applyFilterDisabled = $derived(!Validator.isValid(tmpFilter) && !forceApplyValid);
57
+ let lastSyncedFilter = $state(filter);
42
58
  $effect(() => {
43
- if (!!filter) {
59
+ if (!tmpFilter || !step || (!!filter && !lodash.isEqual($state.snapshot(filter), $state.snapshot(lastSyncedFilter)))) {
44
60
  initTmpFilter();
61
+ lastSyncedFilter = filter;
45
62
  }
46
- });
47
- let advancedModeOptions = $state(), advancedModeSelectedOption = $state();
48
- $effect(() => {
49
63
  if (!!tmpFilter) {
64
+ if (tmpFilter.type == 'bool') {
65
+ if (tmpFilter.value === undefined) {
66
+ tmpFilter.value = false;
67
+ }
68
+ }
69
+ else if (tmpFilter.type == 'select') {
70
+ if (tmpFilter.values === undefined) {
71
+ tmpFilter.values = [];
72
+ }
73
+ }
74
+ else if (tmpFilter.type == 'date' && tmpFilter.mode == 'between') {
75
+ if (!tmpFilter.from)
76
+ tmpFilter.from = new Date();
77
+ if (!tmpFilter.to)
78
+ tmpFilter.to = new Date();
79
+ }
80
+ if (!tmpFilter.advanced) {
81
+ advancedModeSelectedOption = undefined;
82
+ }
50
83
  let modes;
51
84
  if (tmpFilter.type == 'string') {
52
85
  modes = STRING_MODES;
@@ -70,45 +103,6 @@ $effect(() => {
70
103
  }
71
104
  }
72
105
  });
73
- $effect(() => {
74
- if (!tmpFilter?.advanced) {
75
- advancedModeSelectedOption = undefined;
76
- }
77
- });
78
- let calendarOpened = $state(false), calendarOpened2 = $state(false);
79
- // TODO I don't like that there is a singlo dropdow to handle all filter advance mode.
80
- // In some case would be necessary to handle more than one selection and this code
81
- // could become non sense
82
- function handleAdvancedModeSelection() {
83
- if (!!advancedModeSelectedOption && !!tmpFilter) {
84
- if (tmpFilter.type == 'date')
85
- tmpFilter.mode = advancedModeSelectedOption;
86
- else if (tmpFilter.type == 'string')
87
- tmpFilter.mode = advancedModeSelectedOption;
88
- else if (tmpFilter.type == 'number')
89
- tmpFilter.mode = advancedModeSelectedOption;
90
- else if (tmpFilter.type == 'select')
91
- tmpFilter.mode = advancedModeSelectedOption;
92
- step = 'editor';
93
- canRenderOptions = false;
94
- }
95
- }
96
- let canRenderOptions = $state(true);
97
- let applyFilterDisabled = $derived(!Validator.isValid(tmpFilter) && !forceApplyValid);
98
- $effect(() => {
99
- if (!!tmpFilter && tmpFilter.type == 'bool') {
100
- if (tmpFilter.value === undefined) {
101
- tmpFilter.value = false;
102
- }
103
- }
104
- });
105
- $effect(() => {
106
- if (!!tmpFilter && tmpFilter.type == 'select') {
107
- if (tmpFilter.values === undefined) {
108
- tmpFilter.values = [];
109
- }
110
- }
111
- });
112
106
  function handleModeBackClick() {
113
107
  if (onbackClick) {
114
108
  onbackClick();
@@ -128,14 +122,6 @@ function handleEditorBackCLick() {
128
122
  }, 100);
129
123
  }
130
124
  }
131
- $effect(() => {
132
- if (!!tmpFilter && tmpFilter.type == 'date' && tmpFilter.mode == 'between') {
133
- if (!tmpFilter.from)
134
- tmpFilter.from = new Date();
135
- if (!tmpFilter.to)
136
- tmpFilter.to = new Date();
137
- }
138
- });
139
125
  function onclick(event) {
140
126
  event.stopPropagation();
141
127
  if (onclickInternal) {
@@ -1,5 +1,6 @@
1
1
  :root {
2
2
  --search-bar-default-ring-color: rgb(var(--global-color-contrast-100));
3
+ --search-bar-default-ring-width: 1px;
3
4
  --search-bar-default-background-color: rgb(var(--global-color-background-100));
4
5
  --search-bar-default-border-radius: 0.5rem;
5
6
  --search-bar-default-height: 3rem;
@@ -1,11 +1,9 @@
1
- <script lang="ts">import '../../../css/main.css';
2
- import './SearchBar.css';
1
+ <script lang="ts">import "../../../css/main.css";
2
+ import "./SearchBar.css";
3
3
  let { input = $bindable(undefined), value = $bindable(undefined), placeholder = undefined, class: clazz = {}, onblur, onchange, onfocus, oninput, onkeydown, iconSnippet, inputSnippet, } = $props();
4
4
  </script>
5
5
 
6
- <div
7
- class="search-bar-container {clazz.container}"
8
- >
6
+ <div class="search-bar-container {clazz.container}">
9
7
  {#if iconSnippet}
10
8
  {@render iconSnippet()}
11
9
  {:else}
@@ -34,11 +32,11 @@ let { input = $bindable(undefined), value = $bindable(undefined), placeholder =
34
32
  autocapitalize="off"
35
33
  enterkeyhint="search"
36
34
  spellcheck="false"
37
- placeholder={placeholder}
35
+ {placeholder}
38
36
  maxlength="512"
39
37
  tabindex="0"
40
38
  bind:this={input}
41
- bind:value={value}
39
+ bind:value
42
40
  {oninput}
43
41
  {onchange}
44
42
  {onkeydown}
@@ -47,15 +45,12 @@ let { input = $bindable(undefined), value = $bindable(undefined), placeholder =
47
45
  class="input {clazz.input}"
48
46
  />
49
47
  {/if}
50
-
51
48
  </div>
52
49
 
53
50
  <style>
54
51
  .search-bar-container {
55
- box-shadow: inset 0 0 0 1px var(
56
- --search-bar-ring-color,
57
- var(--search-bar-default-ring-color)
58
- );
52
+ box-shadow: inset 0 0 0 var(--search-bar-ring-width, var(--search-bar-default-ring-width))
53
+ var(--search-bar-ring-color, var(--search-bar-default-ring-color));
59
54
  background-color: var(
60
55
  --search-bar-background-color,
61
56
  var(--search-bar-default-background-color)
@@ -64,33 +59,18 @@ let { input = $bindable(undefined), value = $bindable(undefined), placeholder =
64
59
  --search-bar-border-radius,
65
60
  var(--search-bar-default-border-radius)
66
61
  );
67
- height: var(
68
- --search-bar-height,
69
- var(--search-bar-default-height)
70
- );
62
+ height: var(--search-bar-height, var(--search-bar-default-height));
71
63
  display: flex;
72
64
  align-items: center;
73
65
  gap: 0.5rem;
74
- padding: var(
75
- --search-bar-padding,
76
- var(--search-bar-default-padding)
77
- );
66
+ padding: var(--search-bar-padding, var(--search-bar-default-padding));
78
67
  box-sizing: border-box;
79
- max-width: var(
80
- --search-bar-max-width,
81
- var(--search-bar-default-max-width)
82
- );
83
- width: var(
84
- --search-bar-width,
85
- var(--search-bar-default-width)
86
- );
68
+ max-width: var(--search-bar-max-width, var(--search-bar-default-max-width));
69
+ width: var(--search-bar-width, var(--search-bar-default-width));
87
70
  }
88
71
 
89
72
  .input {
90
- font-size: var(
91
- --search-bar-font-size,
92
- var(--search-bar-default-font-size)
93
- );
73
+ font-size: var(--search-bar-font-size, var(--search-bar-default-font-size));
94
74
  line-height: var(
95
75
  --search-bar-line-height,
96
76
  var(--search-bar-default-line-height)
@@ -110,4 +90,4 @@ let { input = $bindable(undefined), value = $bindable(undefined), placeholder =
110
90
  width: 1.25rem;
111
91
  stroke: currentColor;
112
92
  }
113
- </style>
93
+ </style>
@@ -1,7 +1,7 @@
1
- import type { ChangeEventHandler, FocusEventHandler, FormEventHandler, KeyboardEventHandler } from 'svelte/elements';
2
- import '../../../css/main.css';
3
- import './SearchBar.css';
4
- import type { Snippet } from 'svelte';
1
+ import type { ChangeEventHandler, FocusEventHandler, FormEventHandler, KeyboardEventHandler } from "svelte/elements";
2
+ import "../../../css/main.css";
3
+ import "./SearchBar.css";
4
+ import type { Snippet } from "svelte";
5
5
  interface Props {
6
6
  input?: HTMLElement;
7
7
  value?: string;
@@ -49,13 +49,23 @@ function toggleSidebar() {
49
49
  />
50
50
  </div>
51
51
  {:else if !sidebarExpanded}
52
- <div style:margin-right="2rem">
53
- <Icon
54
- name="mdi-menu-close"
55
- --icon-default-size="1.5rem"
56
- onclick={toggleSidebar}
57
- />
58
- </div>
52
+ {#if !sidebarExpanded}
53
+ <div style:margin-right="2rem">
54
+ <Icon
55
+ name="mdi-dock-left"
56
+ --icon-default-size="1.5rem"
57
+ onclick={toggleSidebar}
58
+ />
59
+ </div>
60
+ {:else}
61
+ <div style:margin-right="2rem">
62
+ <Icon
63
+ name="mdi-dock-left"
64
+ --icon-default-size="1.5rem"
65
+ onclick={toggleSidebar}
66
+ />
67
+ </div>
68
+ {/if}
59
69
  {/if}
60
70
  {#if innerMenuSnippet}
61
71
  {@render innerMenuSnippet({ hamburgerVisible: mAndDown })}
@@ -87,17 +97,6 @@ function toggleSidebar() {
87
97
  <div class="logo">Logo</div>
88
98
  {/if}
89
99
  </div>
90
- <div class="pin-container">
91
- {#if sidebarExpanded}
92
- <div class="sidebar-close-button">
93
- <Icon
94
- name="mdi-menu-open"
95
- --icon-default-size="1.5rem"
96
- onclick={toggleSidebar}
97
- />
98
- </div>
99
- {/if}
100
- </div>
101
100
  </div>
102
101
  {#if menuSnippet}
103
102
  {@render menuSnippet({ hamburgerVisible: mAndDown, sidebarExpanded })}
@@ -188,15 +187,6 @@ function toggleSidebar() {
188
187
  margin-bottom: 1rem;
189
188
  }
190
189
 
191
- .pin-container {
192
- display: flex;
193
- justify-content: flex-end;
194
- align-items: center;
195
- width: 30%;
196
- margin-bottom: 1rem;
197
- margin-right: 1rem;
198
- }
199
-
200
190
  .sidebar-close-button {
201
191
  cursor: pointer;
202
192
  display: flex;
@@ -20,6 +20,6 @@
20
20
  --button-default-text-active-background-color: rgb(var(--global-color-primary-500), 0.4);
21
21
  --button-default-icon-active-color: rgb(var(--global-color-primary-500));
22
22
  --button-default-icon-focus-color: rgb(var(--global-color-primary-500));
23
- --button-default-box-shadow: 0 0 0.5rem rgba(0, 0, 0, 0.3);
23
+ --button-default-box-shadow: none;
24
24
  --button-default-text-font-weight: 600;
25
25
  }
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": "4.0.17",
4
+ "version": "4.0.19",
5
5
  "scripts": {
6
6
  "host": "vite --host",
7
7
  "dev": "vite dev",