@lavalogic/scoria 0.37.39 → 0.37.41
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.
|
@@ -56,6 +56,15 @@ const PORTAL_Z_INDEX = 99998;
|
|
|
56
56
|
* inside their fixed-height box.
|
|
57
57
|
*/
|
|
58
58
|
const FLIP_THRESHOLD_PX = 240;
|
|
59
|
+
/**
|
|
60
|
+
* Hard cap on the dropdown's open height, regardless of how much
|
|
61
|
+
* vertical space the trigger leaves between itself and the viewport
|
|
62
|
+
* edge. Matches Svelecte's own `--sv-dropdown-height` default (320px)
|
|
63
|
+
* so a typical dropdown opens at a sensible "six rows plus search
|
|
64
|
+
* input" size and only shrinks below that when the trigger is genuinely
|
|
65
|
+
* close to the viewport edge.
|
|
66
|
+
*/
|
|
67
|
+
const MAX_DROPDOWN_HEIGHT_PX = 320;
|
|
59
68
|
/** Run a function on the next animation frame, coalescing repeat
|
|
60
69
|
* calls so we don't queue dozens of layout reads per scroll burst. */
|
|
61
70
|
function rafThrottle(fn) {
|
|
@@ -116,16 +125,43 @@ export function attachDropdownPortal(options) {
|
|
|
116
125
|
dropdown.style.minWidth = `${tr.width}px`;
|
|
117
126
|
dropdown.style.maxWidth = `${tr.width}px`;
|
|
118
127
|
dropdown.style.zIndex = String(PORTAL_Z_INDEX);
|
|
128
|
+
// Cap the dropdown height at `MAX_DROPDOWN_HEIGHT_PX` regardless
|
|
129
|
+
// of how much space the trigger has below / above it - we never
|
|
130
|
+
// want the dropdown to be as tall as the viewport just because
|
|
131
|
+
// the option list could fit. The `Math.max(..., 64)` floor
|
|
132
|
+
// stops the dropdown from collapsing to a single-row sliver
|
|
133
|
+
// when the trigger is genuinely pinned against the viewport
|
|
134
|
+
// edge; the inner scroll handles the rest.
|
|
135
|
+
const availableHeightPx = openUp
|
|
136
|
+
? Math.min(MAX_DROPDOWN_HEIGHT_PX, Math.max(spaceAbove - 8, 64))
|
|
137
|
+
: Math.min(MAX_DROPDOWN_HEIGHT_PX, Math.max(spaceBelow - 8, 64));
|
|
119
138
|
if (openUp) {
|
|
120
139
|
dropdown.style.top = '';
|
|
121
140
|
dropdown.style.bottom = `${viewportHeight - tr.top}px`;
|
|
122
|
-
dropdown.style.maxHeight = `${Math.max(spaceAbove - 8, 64)}px`;
|
|
123
141
|
}
|
|
124
142
|
else {
|
|
125
143
|
dropdown.style.top = `${tr.bottom}px`;
|
|
126
144
|
dropdown.style.bottom = '';
|
|
127
|
-
dropdown.style.maxHeight = `${Math.max(spaceBelow - 8, 64)}px`;
|
|
128
145
|
}
|
|
146
|
+
dropdown.style.maxHeight = `${availableHeightPx}px`;
|
|
147
|
+
// Svelecte's inner `.sv-dropdown-scroll` element has its own
|
|
148
|
+
// `max-height: var(--sv-dropdown-height, 320px); overflow-y:
|
|
149
|
+
// auto` rule, AND the outer `.sv_dropdown` element has
|
|
150
|
+
// `overflow-y: auto` by default. When the trigger is near the
|
|
151
|
+
// viewport edge our outer `max-height` is forced below 320px,
|
|
152
|
+
// so both ended up with their own scrollbars (the visible "two
|
|
153
|
+
// scrollbars stacked" symptom). Two complementary fixes:
|
|
154
|
+
// 1. Override `--sv-dropdown-height` to match the outer's
|
|
155
|
+
// max-height so the inner scroll container shrinks in
|
|
156
|
+
// lockstep instead of staying at its 320px default.
|
|
157
|
+
// 2. Force the outer to `overflow: hidden` so even if the
|
|
158
|
+
// inner's actual rendered height nudges a pixel or two
|
|
159
|
+
// past the outer's content box (border / padding
|
|
160
|
+
// rounding), the outer doesn't sprout its own scrollbar
|
|
161
|
+
// on top of the inner's. The inner remains the single
|
|
162
|
+
// scroll surface.
|
|
163
|
+
dropdown.style.setProperty('--sv-dropdown-height', `${availableHeightPx}px`);
|
|
164
|
+
dropdown.style.overflow = 'hidden';
|
|
129
165
|
};
|
|
130
166
|
const throttled = rafThrottle(reposition);
|
|
131
167
|
const handleScroll = () => {
|
|
@@ -162,6 +198,8 @@ export function attachDropdownPortal(options) {
|
|
|
162
198
|
dropdown.style.maxWidth = '';
|
|
163
199
|
dropdown.style.maxHeight = '';
|
|
164
200
|
dropdown.style.zIndex = '';
|
|
201
|
+
dropdown.style.overflow = '';
|
|
202
|
+
dropdown.style.removeProperty('--sv-dropdown-height');
|
|
165
203
|
dropdown.removeAttribute('data-scoria-portal-dropdown');
|
|
166
204
|
if (!dropdown.classList.contains('is-open')) {
|
|
167
205
|
dropdown.style.display = 'none';
|