@likable-hair/svelte 4.2.0 → 4.2.2

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 (38) hide show
  1. package/dist/components/composed/common/MenuOrDrawer.svelte +1 -1
  2. package/dist/components/composed/common/MenuOrDrawerOptions.svelte +1 -1
  3. package/dist/components/composed/dashboard/DashboardShaper.svelte +20 -13
  4. package/dist/components/composed/dashboard/DashboardShaper.svelte.d.ts +123 -100
  5. package/dist/components/composed/forms/AsyncAutocomplete.svelte.d.ts +1 -0
  6. package/dist/components/composed/forms/DatePickerTextField.svelte +10 -2
  7. package/dist/components/composed/forms/DatePickerTextField.svelte.d.ts +1 -0
  8. package/dist/components/composed/forms/Dropdown.svelte +15 -6
  9. package/dist/components/composed/forms/PeriodPicker.svelte +115 -0
  10. package/dist/components/composed/forms/PeriodPicker.svelte.d.ts +21 -0
  11. package/dist/components/composed/forms/PeriodSelector.svelte +633 -0
  12. package/dist/components/composed/forms/PeriodSelector.svelte.d.ts +75 -0
  13. package/dist/components/composed/list/DynamicTable.svelte +130 -82
  14. package/dist/components/composed/list/DynamicTable.svelte.d.ts +2 -0
  15. package/dist/components/composed/list/EnhancedPaginatedTable.svelte +1 -2
  16. package/dist/components/composed/list/EnhancedPaginatedTable.svelte.d.ts +2 -1
  17. package/dist/components/composed/list/PaginatedTable.svelte +20 -16
  18. package/dist/components/composed/list/PaginatedTable.svelte.d.ts +2 -1
  19. package/dist/components/composed/search/DynamicFilters.svelte +10 -10
  20. package/dist/components/composed/search/DynamicFilters.svelte.d.ts +6 -0
  21. package/dist/components/composed/search/FilterEditor.svelte +10 -9
  22. package/dist/components/simple/buttons/Button.css +1 -0
  23. package/dist/components/simple/buttons/Button.svelte +4 -1
  24. package/dist/components/simple/common/Menu.svelte +124 -104
  25. package/dist/components/simple/common/Menu.svelte.d.ts +2 -0
  26. package/dist/components/simple/dates/Calendar.css +2 -2
  27. package/dist/components/simple/dates/Calendar.svelte +76 -27
  28. package/dist/components/simple/dates/Calendar.svelte.d.ts +1 -0
  29. package/dist/components/simple/dates/DatePicker.svelte +30 -12
  30. package/dist/components/simple/dates/DatePicker.svelte.d.ts +8 -1
  31. package/dist/components/simple/forms/Autocomplete.svelte +2 -2
  32. package/dist/components/simple/forms/Autocomplete.svelte.d.ts +1 -0
  33. package/dist/components/simple/lists/SelectableVerticalList.svelte +5 -4
  34. package/dist/components/simple/lists/SimpleTable.svelte +86 -54
  35. package/dist/components/simple/lists/SimpleTable.svelte.d.ts +1 -1
  36. package/dist/index.d.ts +2 -0
  37. package/dist/index.js +2 -0
  38. package/package.json +1 -1
@@ -139,19 +139,20 @@ function onclick(event) {
139
139
  minWidth={'100px'}
140
140
  height={'100%'}
141
141
  --button-padding="10px 12px"
142
- --button-border='var(--dropdown-button-border, none)'
143
- --button-background-color='var(--dropdown-button-background-color, rgb(var(--global-color-background-300), .6))'
144
- --button-hover-background-color='var(--dropdown-button-hover-color, rgb(var(--global-color-background-300), .6))'
145
- --button-focus-background-color='var(--dropdown-button-focus-color, rgb(var(--global-color-background-300), .6))'
146
- --button-active-background-color='var(--dropdown-button-active-color, rgb(var(--global-color-background-300), .6))'
142
+ --button-border='var(--dropdown-button-border)'
143
+ --button-background-color='var(--dropdown-button-background-color)'
144
+ --button-hover-background-color='var(--dropdown-button-hover-color)'
145
+ --button-focus-background-color='var(--dropdown-button-focus-color)'
146
+ --button-active-background-color='var(--dropdown-button-active-color)'
147
+ --button-border-radius='var(--dropdown-button-border-radius)'
148
+ --button-default-height='var(--dropdown-button-height)'
149
+ --button-active-box-shadow='var(--dropdown-button-active-box-shadow)'
150
+ --button-focus-box-shadow='var(--dropdown-button-focus-box-shadow)'
151
+ --button-box-sizing='var(--dropdown-button-box-sizing)'
147
152
  --button-hover-color='rgb(var(--global-color-contrast-800))'
148
- --button-border-radius='var(--dropdown-button-border-radius, 4px)'
149
- --button-default-height='var(--dropdown-button-height, 20px)'
150
153
  --autocomplete-default-selected-item-background-color='rgb(var(--global-color-background-500), .5)'
151
154
  --autocomplete-default-selected-item-color='rgb(var(--global-color-contrast-800))'
152
155
  --autocomplete-default-hover-item-background-color='rgb(var(--global-color-background-300), .5)'
153
- --button-active-box-shadow='var(--dropdown-button-active-box-shadow)'
154
- --button-focus-box-shadow='var(--dropdown-button-focus-box-shadow)'
155
156
  ></Dropdown>
156
157
  </div>
157
158
  </div>
@@ -22,4 +22,5 @@
22
22
  --button-default-icon-focus-color: rgb(var(--global-color-primary-500));
23
23
  --button-default-box-shadow: none;
24
24
  --button-default-text-font-weight: 600;
25
+ --button-default-box-sizing: content-box;
25
26
  }
@@ -86,7 +86,10 @@ import CircularLoader from "../loaders/CircularLoader.svelte";
86
86
 
87
87
  .button {
88
88
  overflow: hidden;
89
- box-sizing: content-box;
89
+ box-sizing: var(
90
+ --button-box-sizing,
91
+ var(--button-default-box-sizing)
92
+ );
90
93
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
91
94
  width: var(
92
95
  --button-width,
@@ -7,24 +7,32 @@ let { _activatorGap = 5, _height = 'auto', _overflow = 'auto', _width = 'auto',
7
7
  }, open = $bindable(), outAnimation = fly, outAnimationConfig = {
8
8
  duration: 100,
9
9
  y: 10,
10
- }, refreshPosition = $bindable(false), stayInViewport = $bindable(false), _borderRadius = undefined, _boxShadow = undefined, _left = undefined, _maxHeight = undefined, _minWidth = undefined, _top = undefined, activator = $bindable(), menuElement = $bindable(), openingId = $bindable(), onkeydown, children, } = $props();
10
+ }, refreshPosition = $bindable(false), stayInViewport = $bindable(false), _borderRadius = undefined, _boxShadow = undefined, _left = undefined, _maxHeight = undefined, _minWidth = undefined, _top = undefined, _offsetTop = 0, _offsetLeft = 0, activator = $bindable(), menuElement = $bindable(), openingId = $bindable(), onkeydown, children, } = $props();
11
11
  let zIndex = $state(50), currentUid = createId(), closeController;
12
+ let calculatedTop = $state(undefined);
13
+ let calculatedLeft = $state(undefined);
14
+ let finalTop = $derived(_top !== undefined ? _top : (calculatedTop !== undefined ? calculatedTop + _offsetTop : undefined));
15
+ let finalLeft = $derived(_left !== undefined ? _left : (calculatedLeft !== undefined ? calculatedLeft + _offsetLeft : undefined));
12
16
  function calculateMenuPosition(params) {
17
+ if (_top !== undefined && _left !== undefined)
18
+ return;
19
+ let tempTop = 0;
20
+ let tempLeft = 0;
13
21
  if (params.menuElement) {
14
22
  if (params.activator) {
15
23
  if (anchor == "bottom") {
16
24
  let { left: activatorLeft, top: activatorTop } = params.activator.getBoundingClientRect();
17
25
  let activatorHeight = params.activator.offsetHeight;
18
- _top = activatorTop + activatorHeight + _activatorGap;
19
- _left = activatorLeft;
26
+ tempTop = activatorTop + activatorHeight + _activatorGap;
27
+ tempLeft = activatorLeft;
20
28
  let { top: fixedParentTop, left: fixedParentLeft, fixedParent, validStickyParent } = getParentInstanceFromViewport(activator?.parentElement);
21
29
  if (!!fixedParent) {
22
- _top = _top - fixedParentTop;
23
- _left = _left - fixedParentLeft;
30
+ tempTop = tempTop - fixedParentTop;
31
+ tempLeft = tempLeft - fixedParentLeft;
24
32
  }
25
33
  else if (!validStickyParent && !fixedParent) {
26
- _top = _top + window.scrollY;
27
- _left = _left + window.scrollX;
34
+ tempTop = tempTop + window.scrollY;
35
+ tempLeft = tempLeft + window.scrollX;
28
36
  }
29
37
  }
30
38
  else if (anchor == "bottom-center") {
@@ -32,22 +40,22 @@ function calculateMenuPosition(params) {
32
40
  let activatorHeight = params.activator.offsetHeight;
33
41
  let activatorWidth = params.activator.offsetWidth;
34
42
  let menuWidth = params.menuElement.offsetWidth;
35
- _top = activatorTop + activatorHeight + _activatorGap;
36
- _left = activatorLeft;
43
+ tempTop = activatorTop + activatorHeight + _activatorGap;
44
+ tempLeft = activatorLeft;
37
45
  let { top: fixedParentTop, left: fixedParentLeft, fixedParent, validStickyParent } = getParentInstanceFromViewport(activator?.parentElement);
38
46
  if (!!fixedParent) {
39
- _top = _top - fixedParentTop;
40
- _left = _left - fixedParentLeft;
47
+ tempTop = tempTop - fixedParentTop;
48
+ tempLeft = tempLeft - fixedParentLeft;
41
49
  }
42
50
  else if (!validStickyParent && !fixedParent) {
43
- _top = _top + window.scrollY;
44
- _left = _left + window.scrollX;
51
+ tempTop = tempTop + window.scrollY;
52
+ tempLeft = tempLeft + window.scrollX;
45
53
  }
46
54
  if (menuWidth > activatorWidth) {
47
- _left = _left - (menuWidth - activatorWidth) / 2;
55
+ tempLeft = tempLeft - (menuWidth - activatorWidth) / 2;
48
56
  }
49
57
  else {
50
- _left = _left + (activatorWidth - menuWidth) / 2;
58
+ tempLeft = tempLeft + (activatorWidth - menuWidth) / 2;
51
59
  }
52
60
  }
53
61
  else if (anchor == 'right-center') {
@@ -56,8 +64,8 @@ function calculateMenuPosition(params) {
56
64
  let activatorWidth = params.activator.offsetWidth;
57
65
  let menuHeight = params.menuElement.offsetHeight;
58
66
  let { top: fixedParentTop, left: fixedParentLeft } = getParentInstanceFromViewport(activator?.parentElement);
59
- _top = activatorTop + window.scrollY + (activatorHeight / 2) - (menuHeight / 2) - fixedParentTop;
60
- _left = activatorLeft + window.scrollX + activatorWidth + _activatorGap - fixedParentLeft;
67
+ tempTop = activatorTop + window.scrollY + (activatorHeight / 2) - (menuHeight / 2) - fixedParentTop;
68
+ tempLeft = activatorLeft + window.scrollX + activatorWidth + _activatorGap - fixedParentLeft;
61
69
  }
62
70
  else if (anchor == 'left-center') {
63
71
  let { left: activatorLeft, top: activatorTop } = params.activator.getBoundingClientRect();
@@ -65,60 +73,60 @@ function calculateMenuPosition(params) {
65
73
  let menuHeight = params.menuElement.offsetHeight;
66
74
  let menuWidth = params.menuElement.offsetWidth;
67
75
  let { top: fixedParentTop, left: fixedParentLeft, fixedParent, validStickyParent } = getParentInstanceFromViewport(activator?.parentElement);
68
- _top = activatorTop + (activatorHeight / 2) - (menuHeight / 2);
69
- _left = activatorLeft - menuWidth - _activatorGap;
76
+ tempTop = activatorTop + (activatorHeight / 2) - (menuHeight / 2);
77
+ tempLeft = activatorLeft - menuWidth - _activatorGap;
70
78
  if (!!fixedParent) {
71
- _top = _top - fixedParentTop;
72
- _left = _left - fixedParentLeft;
79
+ tempTop = tempTop - fixedParentTop;
80
+ tempLeft = tempLeft - fixedParentLeft;
73
81
  }
74
82
  else if (!validStickyParent && !fixedParent) {
75
- _top = _top + window.scrollY;
76
- _left = _left + window.scrollX;
83
+ tempTop = tempTop + window.scrollY;
84
+ tempLeft = tempLeft + window.scrollX;
77
85
  }
78
86
  }
79
- else if (anchor == 'up') {
87
+ else if (anchor == 'left') {
80
88
  let { left: activatorLeft, top: activatorTop } = params.activator.getBoundingClientRect();
81
- let menuHeight = params.menuElement.offsetHeight;
82
- _top = activatorTop - menuHeight - _activatorGap;
83
- _left = activatorLeft;
89
+ let menuWidth = params.menuElement.offsetWidth;
90
+ tempTop = activatorTop;
91
+ tempLeft = activatorLeft - menuWidth - _activatorGap;
84
92
  let { top: fixedParentTop, left: fixedParentLeft, fixedParent, validStickyParent } = getParentInstanceFromViewport(activator?.parentElement);
85
93
  if (!!fixedParent) {
86
- _top = _top - fixedParentTop;
87
- _left = _left - fixedParentLeft;
94
+ tempTop = tempTop - fixedParentTop;
95
+ tempLeft = tempLeft - fixedParentLeft;
88
96
  }
89
97
  else if (!validStickyParent && !fixedParent) {
90
- _top = _top + window.scrollY;
91
- _left = _left + window.scrollX;
98
+ tempTop = tempTop + window.scrollY;
99
+ tempLeft = tempLeft + window.scrollX;
92
100
  }
93
101
  }
94
- else if (anchor == 'left') {
102
+ else if (anchor == 'right') {
95
103
  let { left: activatorLeft, top: activatorTop } = params.activator.getBoundingClientRect();
96
- let menuWidth = params.menuElement.offsetWidth;
97
- _top = activatorTop;
98
- _left = activatorLeft - menuWidth - _activatorGap;
104
+ let activatorWidth = params.activator.offsetWidth;
105
+ tempTop = activatorTop;
106
+ tempLeft = activatorLeft + activatorWidth + _activatorGap;
99
107
  let { top: fixedParentTop, left: fixedParentLeft, fixedParent, validStickyParent } = getParentInstanceFromViewport(activator?.parentElement);
100
108
  if (!!fixedParent) {
101
- _top = _top - fixedParentTop;
102
- _left = _left - fixedParentLeft;
109
+ tempTop = tempTop - fixedParentTop;
110
+ tempLeft = tempLeft - fixedParentLeft;
103
111
  }
104
112
  else if (!validStickyParent && !fixedParent) {
105
- _top = _top + window.scrollY;
106
- _left = _left + window.scrollX;
113
+ tempTop = tempTop + window.scrollY;
114
+ tempLeft = tempLeft + window.scrollX;
107
115
  }
108
116
  }
109
- else if (anchor == 'right') {
117
+ else if (anchor == 'up') {
110
118
  let { left: activatorLeft, top: activatorTop } = params.activator.getBoundingClientRect();
111
- let activatorWidth = params.activator.offsetWidth;
112
- _top = activatorTop;
113
- _left = activatorLeft + activatorWidth + _activatorGap;
119
+ let menuHeight = params.menuElement.offsetHeight;
120
+ tempTop = activatorTop - menuHeight - _activatorGap;
121
+ tempLeft = activatorLeft;
114
122
  let { top: fixedParentTop, left: fixedParentLeft, fixedParent, validStickyParent } = getParentInstanceFromViewport(activator?.parentElement);
115
123
  if (!!fixedParent) {
116
- _top = _top - fixedParentTop;
117
- _left = _left - fixedParentLeft;
124
+ tempTop = tempTop - fixedParentTop;
125
+ tempLeft = tempLeft - fixedParentLeft;
118
126
  }
119
127
  else if (!validStickyParent && !fixedParent) {
120
- _top = _top + window.scrollY;
121
- _left = _left + window.scrollX;
128
+ tempTop = tempTop + window.scrollY;
129
+ tempLeft = tempLeft + window.scrollX;
122
130
  }
123
131
  }
124
132
  else if (anchor == 'up-center') {
@@ -126,93 +134,91 @@ function calculateMenuPosition(params) {
126
134
  let activatorWidth = params.activator.offsetWidth;
127
135
  let menuHeight = params.menuElement.offsetHeight;
128
136
  let menuWidth = params.menuElement.offsetWidth;
129
- _top = activatorTop - menuHeight - _activatorGap;
130
- _left = activatorLeft;
137
+ tempTop = activatorTop - menuHeight - _activatorGap;
138
+ tempLeft = activatorLeft;
131
139
  let { top: fixedParentTop, left: fixedParentLeft, fixedParent, validStickyParent } = getParentInstanceFromViewport(activator?.parentElement);
132
140
  if (!!fixedParent) {
133
- _top = _top - fixedParentTop;
134
- _left = _left - fixedParentLeft;
141
+ tempTop = tempTop - fixedParentTop;
142
+ tempLeft = tempLeft - fixedParentLeft;
135
143
  }
136
144
  else if (!validStickyParent && !fixedParent) {
137
- _top = _top + window.scrollY;
138
- _left = _left + window.scrollX;
145
+ tempTop = tempTop + window.scrollY;
146
+ tempLeft = tempLeft + window.scrollX;
139
147
  }
140
148
  if (menuWidth > activatorWidth) {
141
- _left = _left - (menuWidth - activatorWidth) / 2;
149
+ tempLeft = tempLeft - (menuWidth - activatorWidth) / 2;
142
150
  }
143
151
  else {
144
- _left = _left + (activatorWidth - menuWidth) / 2;
152
+ tempLeft = tempLeft + (activatorWidth - menuWidth) / 2;
145
153
  }
146
154
  }
147
155
  }
148
156
  if (flipOnOverflow && !!params.activator) {
149
157
  let { top: activatorTopDistance } = params.activator.getBoundingClientRect();
150
158
  if (window.innerHeight < activatorTopDistance + (menuElement?.offsetHeight || 0) + ((menuElement?.offsetHeight || 0) * 0.1)) {
151
- _top = getTopDistance(params.activator) - _activatorGap - (menuElement?.offsetHeight || 0);
159
+ tempTop = getTopDistance(params.activator) - _activatorGap - (menuElement?.offsetHeight || 0);
152
160
  }
153
161
  if (anchor == 'right-center' &&
154
162
  window.innerWidth + window.scrollX <
155
- (_left || 0) + (menuElement?.offsetWidth || 0)) {
163
+ tempLeft + (menuElement?.offsetWidth || 0)) {
156
164
  let { left: activatorLeft } = params.activator.getBoundingClientRect();
157
- _left = activatorLeft + window.scrollX - _activatorGap - (menuElement?.offsetWidth || 0);
165
+ tempLeft = activatorLeft + window.scrollX - _activatorGap - (menuElement?.offsetWidth || 0);
158
166
  }
159
167
  if (anchor == 'left-center' &&
160
- (_left || 0) < 0) {
168
+ tempLeft < 0) {
161
169
  let { left: activatorLeft } = params.activator.getBoundingClientRect();
162
170
  let activatorWidth = params.activator.offsetWidth;
163
- _left = activatorLeft + window.scrollX + activatorWidth + _activatorGap;
171
+ tempLeft = activatorLeft + window.scrollX + activatorWidth + _activatorGap;
164
172
  }
165
173
  if (anchor == 'left' &&
166
- (_left || 0) < 0) {
174
+ tempLeft < 0) {
167
175
  let { left: activatorLeft } = params.activator.getBoundingClientRect();
168
176
  let activatorWidth = params.activator.offsetWidth;
169
- _left = activatorLeft + window.scrollX + activatorWidth + _activatorGap;
177
+ tempLeft = activatorLeft + window.scrollX + activatorWidth + _activatorGap;
170
178
  }
171
179
  if (anchor == 'right' &&
172
180
  window.innerWidth + window.scrollX <
173
- (_left || 0) + (menuElement?.offsetWidth || 0)) {
181
+ tempLeft + (menuElement?.offsetWidth || 0)) {
174
182
  let { left: activatorLeft } = params.activator.getBoundingClientRect();
175
183
  let menuWidth = params.menuElement.offsetWidth;
176
- _left = activatorLeft + window.scrollX - menuWidth - _activatorGap;
184
+ tempLeft = activatorLeft + window.scrollX - menuWidth - _activatorGap;
177
185
  }
178
186
  if (anchor == 'up' &&
179
- (_top || 0) < window.scrollY) {
187
+ tempTop < window.scrollY) {
180
188
  let { top: activatorTop } = params.activator.getBoundingClientRect();
181
189
  let activatorHeight = params.activator.offsetHeight;
182
- _top = activatorTop + window.scrollY + activatorHeight + _activatorGap;
190
+ tempTop = activatorTop + window.scrollY + activatorHeight + _activatorGap;
183
191
  }
184
192
  if (anchor == 'up-center' &&
185
- (_top || 0) < window.scrollY) {
193
+ tempTop < window.scrollY) {
186
194
  let { top: activatorTop } = params.activator.getBoundingClientRect();
187
195
  let activatorHeight = params.activator.offsetHeight;
188
- _top = activatorTop + window.scrollY + activatorHeight + _activatorGap;
196
+ tempTop = activatorTop + window.scrollY + activatorHeight + _activatorGap;
189
197
  }
190
198
  }
191
199
  if (stayInViewport) {
192
200
  if (window.innerWidth + window.scrollX <
193
- (_left || 0) + (menuElement?.offsetWidth || 0)) {
194
- _left = Math.max(window.innerWidth + window.scrollX - (menuElement?.offsetWidth || 0), 0);
201
+ tempLeft + (menuElement?.offsetWidth || 0)) {
202
+ tempLeft = Math.max(window.innerWidth + window.scrollX - (menuElement?.offsetWidth || 0), 0);
195
203
  }
196
- if ((_left || 0) < window.scrollX) {
197
- _left = window.scrollX;
204
+ if (tempLeft < window.scrollX) {
205
+ tempLeft = window.scrollX;
198
206
  }
199
207
  }
200
208
  if (!!positionedAncestor) {
201
209
  let { left: positionedAncestorLeft, top: positionedAncestorTop } = positionedAncestor.getBoundingClientRect();
202
- if (!_left)
203
- _left = 0;
204
- if (!_top)
205
- _top = 0;
206
- _left = _left - (positionedAncestorLeft + window.scrollX - positionedAncestor.scrollLeft);
207
- _top = _top - (positionedAncestorTop + window.scrollY - positionedAncestor.scrollTop);
210
+ tempLeft = tempLeft - (positionedAncestorLeft + window.scrollX - positionedAncestor.scrollLeft);
211
+ tempTop = tempTop - (positionedAncestorTop + window.scrollY - positionedAncestor.scrollTop);
208
212
  if (!!activator) {
209
213
  let { validStickyParent, fixedParent } = getParentInstanceFromViewport(activator?.parentElement);
210
214
  if (!!validStickyParent || !!fixedParent) {
211
- _left = _left + window.scrollX;
212
- _top = _top + window.scrollY;
215
+ tempLeft = tempLeft + window.scrollX;
216
+ tempTop = tempTop + window.scrollY;
213
217
  }
214
218
  }
215
219
  }
220
+ calculatedTop = tempTop;
221
+ calculatedLeft = tempLeft;
216
222
  }
217
223
  }
218
224
  function getTopDistance(elem) {
@@ -306,30 +312,43 @@ $effect(() => {
306
312
  refreshPosition = false;
307
313
  }
308
314
  });
309
- $effect(() => {
310
- if (closeOnClickOutside && !!menuElement) {
311
- window.addEventListener("mousedown", () => {
312
- open = false;
313
- });
314
- window.addEventListener("touchstart", () => {
315
- open = false;
316
- });
317
- if (activator) {
318
- activator.addEventListener("mousedown", (event) => {
319
- event.stopPropagation();
320
- });
321
- activator.addEventListener("touchstart", (event) => {
322
- event.stopPropagation();
323
- });
315
+ function handleOutsideClick(node, params) {
316
+ const handleWindowClick = () => {
317
+ open = false;
318
+ };
319
+ const handleStopPropagation = (event) => {
320
+ event.stopPropagation();
321
+ };
322
+ function updateListeners(currentParams) {
323
+ window.removeEventListener("mousedown", handleWindowClick);
324
+ window.removeEventListener("touchstart", handleWindowClick);
325
+ node.removeEventListener("mousedown", handleStopPropagation);
326
+ node.removeEventListener("touchstart", handleStopPropagation);
327
+ if (currentParams.activator) {
328
+ currentParams.activator.removeEventListener("mousedown", handleStopPropagation);
329
+ currentParams.activator.removeEventListener("touchstart", handleStopPropagation);
330
+ }
331
+ if (currentParams.enabled) {
332
+ window.addEventListener("mousedown", handleWindowClick);
333
+ window.addEventListener("touchstart", handleWindowClick);
334
+ node.addEventListener("mousedown", handleStopPropagation);
335
+ node.addEventListener("touchstart", handleStopPropagation);
336
+ if (currentParams.activator) {
337
+ currentParams.activator.addEventListener("mousedown", handleStopPropagation);
338
+ currentParams.activator.addEventListener("touchstart", handleStopPropagation);
339
+ }
324
340
  }
325
- menuElement.addEventListener("mousedown", (event) => {
326
- event.stopPropagation();
327
- });
328
- menuElement.addEventListener("touchstart", (event) => {
329
- event.stopPropagation();
330
- });
331
341
  }
332
- });
342
+ updateListeners(params);
343
+ return {
344
+ update(newParams) {
345
+ updateListeners(newParams);
346
+ },
347
+ destroy() {
348
+ updateListeners({ enabled: false, activator: params.activator });
349
+ }
350
+ };
351
+ }
333
352
  function getPositionedAncestor(elem, positions = ['fixed', 'absolute', 'sticky', 'relative']) {
334
353
  if (!elem)
335
354
  return null;
@@ -414,14 +433,15 @@ $effect(() => {
414
433
  <div
415
434
  role="presentation"
416
435
  bind:this={menuElement}
436
+ use:handleOutsideClick={{ enabled: closeOnClickOutside, activator }}
417
437
  data-menu
418
438
  data-uid={currentUid}
419
439
  style:z-index={zIndex}
420
440
  style:position="absolute"
421
- style:top={_top + "px"}
441
+ style:top={finalTop + "px"}
422
442
  style:box-shadow={_boxShadow}
423
443
  style:border-radius={_borderRadius}
424
- style:left={_left + "px"}
444
+ style:left={finalLeft + "px"}
425
445
  style:height={_height}
426
446
  style:max-height={_maxHeight}
427
447
  style:width={_width}
@@ -3,6 +3,8 @@ import type { Snippet } from 'svelte';
3
3
  interface Props {
4
4
  _top?: number;
5
5
  _left?: number;
6
+ _offsetTop?: number;
7
+ _offsetLeft?: number;
6
8
  _width?: string;
7
9
  _height?: string;
8
10
  _maxHeight?: string;
@@ -5,14 +5,14 @@
5
5
  --calendar-default-day-height: 100%;
6
6
  --calendar-default-day-border-radius: 0px;
7
7
  --calendar-default-day-hover-background-color: rgb(var(--global-color-primary-600), .3);
8
+ --calendar-default-day-hover-border-radius: 4px;
8
9
  --calendar-default-selected-day-background-color: rgb(var(--global-color-primary-600));
9
10
  --calendar-default-selected-day-color: rgb(var(--global-color-grey-50));
10
11
  --calendar-default-selected-day-border-radius: 4px;
11
12
  --calendar-default-today-background-color: rgb(var(--global-color-error-200), .7);
12
13
  --calendar-default-today-color: rgb(var(--global-color-contrast-800));
13
14
  --calendar-default-today-border-radius: 9999px;
14
- --calendar-default-today-height: 30px;
15
- --calendar-default-today-width: 30px;
15
+ --calendar-default-today-height: min(90%,30px);
16
16
  --calendar-default-between-range-background-color: rgb(var(--global-color-primary-400), .4);
17
17
  --calendar-default-between-range-color: rgb(var(--global-color-contrast-800));
18
18
  --calendar-default-grid-gap: 0px;
@@ -2,7 +2,7 @@
2
2
  import './Calendar.css';
3
3
  import { fly } from "svelte/transition";
4
4
  import { dateToDateStat, getDateRowsStats, getDaysNames } from "./utils";
5
- let { selectedDate = $bindable(undefined), selectedDateTo = $bindable(undefined), visibleMonth = $bindable(new Date().getMonth()), visibleYear = $bindable(new Date().getFullYear()), locale = "it", showExtraMonthDays = true, showHeader = true, animationDuration = 200, disabled = false, type = 'singleDate', class: clazz = {}, ondayClick, weekHeaderSnippet, daySnippet, } = $props();
5
+ let { selectedDate = $bindable(undefined), selectedDateTo = $bindable(undefined), visibleMonth = $bindable(new Date().getMonth()), visibleYear = $bindable(new Date().getFullYear()), locale = "it", showExtraMonthDays = true, showHeader = true, animationDuration = 200, disabled = false, type = 'singleDate', fillOpenRange = false, class: clazz = {}, ondayClick, weekHeaderSnippet, daySnippet, } = $props();
6
6
  const today = new Date();
7
7
  let hoveredDateStat = $state();
8
8
  function handleDayClick(dateStat, extraMonth) {
@@ -46,25 +46,43 @@ function hoverDateStat(dateStat) {
46
46
  hoveredDateStat = dateStat;
47
47
  }
48
48
  function isBetweenRange(dateStat) {
49
- if (type == 'dateRange') {
50
- let rangeDate = !!selectedDateTo
51
- ? dateToDateStat(selectedDateTo)
52
- : hoveredDateStat;
53
- if (!!rangeDate && !!selectedDate) {
54
- const date = new Date(dateStat.year, dateStat.month, dateStat.dayOfMonth);
55
- const selected = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate());
56
- const hovered = new Date(rangeDate.year, rangeDate.month, rangeDate.dayOfMonth);
57
- const minDate = selected < hovered ? selected : hovered;
58
- const maxDate = selected < hovered ? hovered : selected;
59
- return date > minDate && date < maxDate;
60
- }
61
- else {
62
- return false;
49
+ if (type !== 'dateRange')
50
+ return false;
51
+ const current = new Date(dateStat.year, dateStat.month, dateStat.dayOfMonth);
52
+ const start = selectedDate
53
+ ? new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate())
54
+ : undefined;
55
+ const end = selectedDateTo
56
+ ? new Date(selectedDateTo.getFullYear(), selectedDateTo.getMonth(), selectedDateTo.getDate())
57
+ : undefined;
58
+ let limitA;
59
+ let limitB;
60
+ if (start && end) {
61
+ limitA = start;
62
+ limitB = end;
63
+ }
64
+ else if (start && hoveredDateStat) {
65
+ limitA = start;
66
+ limitB = new Date(hoveredDateStat.year, hoveredDateStat.month, hoveredDateStat.dayOfMonth);
67
+ }
68
+ else if (end && hoveredDateStat) {
69
+ limitA = new Date(hoveredDateStat.year, hoveredDateStat.month, hoveredDateStat.dayOfMonth);
70
+ limitB = end;
71
+ }
72
+ if (limitA && limitB) {
73
+ if (limitA.getTime() !== limitB.getTime()) {
74
+ const min = limitA < limitB ? limitA : limitB;
75
+ const max = limitA < limitB ? limitB : limitA;
76
+ return current > min && current < max;
63
77
  }
64
78
  }
65
- else {
66
- return false;
79
+ if (fillOpenRange) {
80
+ if (start && !end)
81
+ return current > start;
82
+ if (!start && end)
83
+ return current < end;
67
84
  }
85
+ return false;
68
86
  }
69
87
  </script>
70
88
 
@@ -96,22 +114,30 @@ function isBetweenRange(dateStat) {
96
114
  selectedDateTo.getMonth() == day.month &&
97
115
  selectedDateTo.getFullYear() == day.year}
98
116
  {@const extraMonth = day.month != visibleMonth}
117
+ {@const isBetween = isBetweenRange(day)}
99
118
  {@const isToday =
100
119
  day.dayOfMonth == today.getDate() &&
101
120
  day.month == today.getMonth() &&
102
121
  day.year == today.getFullYear()}
122
+ {@const hovered =
123
+ !(type == 'dateRange') &&
124
+ !!hoveredDateStat &&
125
+ hoveredDateStat.dayOfMonth == day.dayOfMonth &&
126
+ hoveredDateStat.month == day.month &&
127
+ hoveredDateStat.year == day.year}
103
128
  <div
104
129
  onmouseenter={() => hoverDateStat(day)}
105
130
  onmouseleave={() => hoverDateStat()}
106
131
  role='presentation'
107
132
  class="day-slot {clazz.day || ''}"
108
133
  class:extra-month={extraMonth}
109
- class:today={isToday}
134
+ class:today={isToday && !(firstDaySelected || lastDaySelected) && !isBetween}
110
135
  class:selected={firstDaySelected || lastDaySelected}
111
- class:between-range={isBetweenRange(day)}
136
+ class:between-range={isBetween}
112
137
  class:not-selected={!(firstDaySelected || lastDaySelected)}
113
138
  class:range-start={type == 'dateRange' && firstDaySelected}
114
139
  class:range-end={type == 'dateRange' && lastDaySelected}
140
+ class:hovered={hovered}
115
141
  onclick={() => handleDayClick(day, extraMonth)}
116
142
  onkeydown={() => handleDayClick(day, extraMonth)}
117
143
  >
@@ -142,7 +168,7 @@ function isBetweenRange(dateStat) {
142
168
 
143
169
  .grid-layout {
144
170
  display: grid;
145
- grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
171
+ grid-template-columns: repeat(7, 1fr);
146
172
  height: 100%;
147
173
  gap: var(
148
174
  --calendar-grid-gap,
@@ -151,6 +177,8 @@ function isBetweenRange(dateStat) {
151
177
  }
152
178
 
153
179
  .day-slot {
180
+ position: relative;
181
+ z-index: 1;
154
182
  display: flex;
155
183
  justify-content: center;
156
184
  align-items: center;
@@ -184,27 +212,39 @@ function isBetweenRange(dateStat) {
184
212
  }
185
213
 
186
214
  .today {
187
- background-color: var(
188
- --calendar-today-background-color,
189
- var(--calendar-default-today-background-color)
190
- );
191
215
  color: var(
192
216
  --calendar-today-color,
193
217
  var(--calendar-default-today-color)
194
218
  );
219
+ }
220
+
221
+ .today::before {
222
+ content: '';
223
+ position: absolute;
224
+ z-index: -1;
225
+ top: 50%;
226
+ left: 50%;
227
+ transform: translate(-50%, -50%);
228
+
195
229
  height: var(
196
230
  --calendar-today-height,
197
231
  var(--calendar-default-today-height)
198
232
  );
233
+ width: auto;
234
+ aspect-ratio: 1 / 1;
199
235
  border-radius: var(
200
236
  --calendar-today-border-radius,
201
237
  var(--calendar-default-today-border-radius)
202
238
  );
203
- width: var(
204
- --calendar-today-width,
205
- var(--calendar-default-today-width)
239
+ background-color: var(
240
+ --calendar-today-background-color,
241
+ var(--calendar-default-today-background-color)
206
242
  );
207
243
  }
244
+
245
+ .today:hover::before {
246
+ background-color: transparent;
247
+ }
208
248
 
209
249
  .between-range {
210
250
  background-color: var(
@@ -227,6 +267,7 @@ function isBetweenRange(dateStat) {
227
267
  --calendar-day-width,
228
268
  var(--calendar-default-day-width)
229
269
  );
270
+ aspect-ratio: auto;
230
271
  }
231
272
 
232
273
  .selected {
@@ -263,6 +304,14 @@ function isBetweenRange(dateStat) {
263
304
  --calendar-day-hover-background-color,
264
305
  var(--calendar-default-day-hover-background-color)
265
306
  );
307
+ border-radius: var(
308
+ --calendar-day-hover-border-radius,
309
+ var(--calendar-default-day-hover-border-radius)
310
+ );
311
+ }
312
+
313
+ .day-slot.not-selected:hover:not(.hovered) {
314
+ border-radius: 0px;
266
315
  }
267
316
 
268
317
  .week-header-slot {