@softwareone/spi-sv5-library 1.7.3 → 1.7.4

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.
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { type Snippet } from 'svelte';
3
3
  import type { Action } from 'svelte/action';
4
+ import type { Attachment } from 'svelte/attachments';
4
5
 
5
6
  import { Search, type SelectOption } from '../../index.js';
6
7
  import Label from '../Label.svelte';
@@ -20,6 +21,7 @@
20
21
  disableValidationColor?: boolean;
21
22
  value?: string | string[] | null;
22
23
  error?: string | string[];
24
+ positionStrategy?: 'absolute' | 'fixed';
23
25
  customSelection?: Snippet<[option: SelectOption]>;
24
26
  customOption?: Snippet<[option: SelectOption]>;
25
27
  onclear?: () => void;
@@ -41,6 +43,7 @@
41
43
  disableValidationColor = false,
42
44
  value = $bindable(),
43
45
  error,
46
+ positionStrategy = 'absolute',
44
47
  customSelection,
45
48
  customOption,
46
49
  onclear,
@@ -110,13 +113,43 @@
110
113
  });
111
114
  };
112
115
 
113
- const autoDirection: Action = () => {
114
- $effect(() => {
116
+ const autoDirection: Attachment<HTMLElement> = (element: HTMLElement) => {
117
+ const BOTTOM_SPACING_OFFSET = 300;
118
+ const DROPDOWN_GAP = 8;
119
+
120
+ const updatePosition = () => {
115
121
  const rect = dropdown.getBoundingClientRect();
116
122
  const viewportHeight = window.innerHeight;
117
- const footer = 300;
118
123
 
119
- showInTopPosition = rect.bottom + footer > viewportHeight;
124
+ showInTopPosition = rect.bottom + BOTTOM_SPACING_OFFSET > viewportHeight;
125
+
126
+ if (positionStrategy === 'fixed') {
127
+ setDropdownStyles(element, rect);
128
+ }
129
+ };
130
+
131
+ const setDropdownStyles = (element: HTMLElement, rect: DOMRect) => {
132
+ element.style.setProperty('--dropdown-width', `${rect.width}px`);
133
+ element.style.setProperty('--dropdown-left', `${rect.left}px`);
134
+
135
+ const topPosition = showInTopPosition
136
+ ? rect.top - element.offsetHeight - DROPDOWN_GAP
137
+ : rect.bottom + DROPDOWN_GAP;
138
+
139
+ element.style.setProperty('--dropdown-top', `${topPosition}px`);
140
+ };
141
+
142
+ $effect(() => {
143
+ if (showListOptions) {
144
+ updatePosition();
145
+ window.addEventListener('scroll', updatePosition, true);
146
+ window.addEventListener('resize', updatePosition);
147
+ }
148
+
149
+ return () => {
150
+ window.removeEventListener('scroll', updatePosition, true);
151
+ window.removeEventListener('resize', updatePosition);
152
+ };
120
153
  });
121
154
  };
122
155
 
@@ -213,7 +246,14 @@
213
246
  </section>
214
247
 
215
248
  {#if showListOptions}
216
- <section class="dropdown-list" class:upwards={showInTopPosition} use:autoDirection>
249
+ <section
250
+ class={[
251
+ 'dropdown-list',
252
+ positionStrategy === 'absolute' && showInTopPosition && 'upwards',
253
+ positionStrategy === 'fixed' && 'position-fixed'
254
+ ]}
255
+ {@attach autoDirection}
256
+ >
217
257
  {#if searchable && !noOptionsAvailable}
218
258
  <Search
219
259
  placeholder="Search"
@@ -437,6 +477,13 @@
437
477
  margin-bottom: 8px;
438
478
  }
439
479
 
480
+ .dropdown > .dropdown-list.position-fixed {
481
+ position: fixed;
482
+ width: var(--dropdown-width);
483
+ left: var(--dropdown-left);
484
+ top: var(--dropdown-top);
485
+ }
486
+
440
487
  .dropdown > .dropdown-list > .dropdown-list-options-container {
441
488
  display: flex;
442
489
  flex-direction: column;
@@ -15,6 +15,7 @@ interface SelectProps {
15
15
  disableValidationColor?: boolean;
16
16
  value?: string | string[] | null;
17
17
  error?: string | string[];
18
+ positionStrategy?: 'absolute' | 'fixed';
18
19
  customSelection?: Snippet<[option: SelectOption]>;
19
20
  customOption?: Snippet<[option: SelectOption]>;
20
21
  onclear?: () => void;
@@ -58,7 +58,7 @@
58
58
 
59
59
  .home-container > .home-item {
60
60
  display: flex;
61
- max-height: 150px;
61
+ max-height: 190px;
62
62
  max-width: 770px;
63
63
  gap: 16px;
64
64
  padding: 12px;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softwareone/spi-sv5-library",
3
- "version": "1.7.3",
3
+ "version": "1.7.4",
4
4
  "description": "Svelte components",
5
5
  "keywords": [
6
6
  "svelte",