@winkintel/bootstrap-svelte 1.0.1 → 1.0.3
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.
- package/README.md +2 -2
- package/dist/Carousel/carousel-item.svelte +8 -2
- package/dist/Carousel/carousel.svelte.js +26 -7
- package/dist/Dropdown/dropdown.svelte.js +4 -1
- package/dist/Modal/modal.svelte +24 -6
- package/dist/Offcanvas/offcanvas.svelte +18 -6
- package/dist/Tooltip/tooltip.svelte +1 -1
- package/dist/common/scrollbar.d.ts +22 -0
- package/dist/common/scrollbar.js +44 -0
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -54,7 +54,7 @@ yarn add @winkintel/bootstrap-svelte bootstrap
|
|
|
54
54
|
This package requires Svelte 5:
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
pnpm add svelte@^5.
|
|
57
|
+
pnpm add svelte@^5.29.0
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
## Bootstrap CSS
|
|
@@ -174,7 +174,7 @@ Interactive components are implemented as Svelte components rather than requirin
|
|
|
174
174
|
|
|
175
175
|
## Status and feedback
|
|
176
176
|
|
|
177
|
-
This package is published as `1.0.
|
|
177
|
+
This package is published as `1.0.3`, but feedback from Svelte developers is still very welcome. Useful feedback includes:
|
|
178
178
|
|
|
179
179
|
- Component API ergonomics
|
|
180
180
|
- Svelte 5 idioms and runes compatibility
|
|
@@ -62,6 +62,12 @@ let classes = $derived(uniqueClsx('carousel-item', {
|
|
|
62
62
|
let styles = $derived(`transition: transform ${itemState.root.transitionDuration / 1000}s ease-in-out !important;` + (style ? style : ''));
|
|
63
63
|
</script>
|
|
64
64
|
|
|
65
|
+
<!--
|
|
66
|
+
The slide and crossfade branches use in: (never transition:) — their exit visuals are
|
|
67
|
+
driven by the carousel-item-start/-end CSS classes during the transition window, and
|
|
68
|
+
Svelte freezes class bindings inside an outroing block, so an outro would hold the
|
|
69
|
+
outgoing item in the DOM with a stale 'active' class after the commit.
|
|
70
|
+
-->
|
|
65
71
|
{#if itemState.doSlideItem}
|
|
66
72
|
<div
|
|
67
73
|
bind:this={elementRef}
|
|
@@ -70,7 +76,7 @@ let styles = $derived(`transition: transform ${itemState.root.transitionDuration
|
|
|
70
76
|
onintrostart={onSlide}
|
|
71
77
|
onintroend={onSlid}
|
|
72
78
|
style={styles}
|
|
73
|
-
|
|
79
|
+
in:fly={{
|
|
74
80
|
duration: itemState.root.transitionDuration,
|
|
75
81
|
x: flyX,
|
|
76
82
|
y: undefined,
|
|
@@ -109,7 +115,7 @@ let styles = $derived(`transition: transform ${itemState.root.transitionDuration
|
|
|
109
115
|
{id}
|
|
110
116
|
onintrostart={onSlide}
|
|
111
117
|
onintroend={onSlid}
|
|
112
|
-
|
|
118
|
+
in:fly={{
|
|
113
119
|
duration: itemState.root.transitionDuration,
|
|
114
120
|
x: '0%',
|
|
115
121
|
y: undefined,
|
|
@@ -19,6 +19,8 @@ export class CarouselRootState {
|
|
|
19
19
|
#indicators = [];
|
|
20
20
|
#interval = $state(0);
|
|
21
21
|
#timeoutId = $state(null);
|
|
22
|
+
#pendingTimeoutIds = [];
|
|
23
|
+
#isDisposed = false;
|
|
22
24
|
#isAnimating = $state(false);
|
|
23
25
|
#isHovered = $state(false);
|
|
24
26
|
#isPaused = $state(true);
|
|
@@ -66,8 +68,9 @@ export class CarouselRootState {
|
|
|
66
68
|
};
|
|
67
69
|
document.addEventListener('visibilitychange', this.#visibilityListener);
|
|
68
70
|
}
|
|
69
|
-
// Start autoplay immediately if ride='carousel', otherwise wait for user interaction
|
|
70
|
-
|
|
71
|
+
// Start autoplay immediately in the browser if ride='carousel', otherwise wait for user interaction.
|
|
72
|
+
// During static prerendering there is no browser timer API, so autoplay starts during hydration instead.
|
|
73
|
+
if (typeof window !== 'undefined' && this.#ride === 'carousel' && !this.#timeoutId) {
|
|
71
74
|
this.cycle();
|
|
72
75
|
}
|
|
73
76
|
}
|
|
@@ -86,6 +89,16 @@ export class CarouselRootState {
|
|
|
86
89
|
shouldCycle() {
|
|
87
90
|
return this.#ride === 'carousel' || (this.#ride === true && this.#hasUserInteraction);
|
|
88
91
|
}
|
|
92
|
+
// Schedules a setTimeout whose id is tracked so dispose() can cancel it if the
|
|
93
|
+
// instance is torn down before the callback fires. The id de-registers itself
|
|
94
|
+
// once the callback runs, keeping #pendingTimeoutIds from growing unbounded.
|
|
95
|
+
#schedule(callback, delay) {
|
|
96
|
+
const timeoutId = window.setTimeout(() => {
|
|
97
|
+
this.#pendingTimeoutIds = this.#pendingTimeoutIds.filter((id) => id !== timeoutId);
|
|
98
|
+
callback();
|
|
99
|
+
}, delay);
|
|
100
|
+
this.#pendingTimeoutIds.push(timeoutId);
|
|
101
|
+
}
|
|
89
102
|
get animation() {
|
|
90
103
|
return this.#animation;
|
|
91
104
|
}
|
|
@@ -225,7 +238,7 @@ export class CarouselRootState {
|
|
|
225
238
|
toItem.direction = 'end';
|
|
226
239
|
toItem.order = 'prev';
|
|
227
240
|
}
|
|
228
|
-
|
|
241
|
+
this.#schedule(() => {
|
|
229
242
|
fromItem.order = undefined;
|
|
230
243
|
fromItem.direction = undefined;
|
|
231
244
|
toItem.order = undefined;
|
|
@@ -247,7 +260,7 @@ export class CarouselRootState {
|
|
|
247
260
|
if (isPrev) {
|
|
248
261
|
toItem.order = 'prev';
|
|
249
262
|
}
|
|
250
|
-
|
|
263
|
+
this.#schedule(() => {
|
|
251
264
|
toItem.order = undefined;
|
|
252
265
|
this.#isAnimating = false;
|
|
253
266
|
}, this.#transitionDuration / 2);
|
|
@@ -277,7 +290,9 @@ export class CarouselRootState {
|
|
|
277
290
|
*/
|
|
278
291
|
cycle() {
|
|
279
292
|
if (typeof window === 'undefined') {
|
|
280
|
-
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
if (this.#isDisposed) {
|
|
281
296
|
return;
|
|
282
297
|
}
|
|
283
298
|
// Don't start cycling if we're hovered and pause='hover'
|
|
@@ -306,7 +321,6 @@ export class CarouselRootState {
|
|
|
306
321
|
}
|
|
307
322
|
pause() {
|
|
308
323
|
if (typeof window === 'undefined') {
|
|
309
|
-
console.warn('[Carousel] Pause called in non-browser environment, ignoring.');
|
|
310
324
|
return;
|
|
311
325
|
}
|
|
312
326
|
if (this.#timeoutId) {
|
|
@@ -368,16 +382,21 @@ export class CarouselRootState {
|
|
|
368
382
|
this.#isPointerDown = false;
|
|
369
383
|
// Resume cycling after touch with a delay to prevent immediate transition
|
|
370
384
|
if (this.shouldCycle()) {
|
|
371
|
-
|
|
385
|
+
this.#schedule(() => {
|
|
372
386
|
this.cycle();
|
|
373
387
|
}, 1000);
|
|
374
388
|
}
|
|
375
389
|
}
|
|
376
390
|
dispose() {
|
|
391
|
+
this.#isDisposed = true;
|
|
377
392
|
if (this.#timeoutId) {
|
|
378
393
|
window.clearTimeout(this.#timeoutId);
|
|
379
394
|
this.#timeoutId = null;
|
|
380
395
|
}
|
|
396
|
+
for (const id of this.#pendingTimeoutIds) {
|
|
397
|
+
window.clearTimeout(id);
|
|
398
|
+
}
|
|
399
|
+
this.#pendingTimeoutIds = [];
|
|
381
400
|
// Remove visibility change listener
|
|
382
401
|
if (typeof document !== 'undefined' && this.#visibilityListener) {
|
|
383
402
|
document.removeEventListener('visibilitychange', this.#visibilityListener);
|
|
@@ -210,10 +210,13 @@ export class DropdownMenuState {
|
|
|
210
210
|
if (!this.isShown) {
|
|
211
211
|
return;
|
|
212
212
|
}
|
|
213
|
+
if (!this.root.props.id) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
213
216
|
const target = event.target;
|
|
214
217
|
// Check if the click occurred within this specific dropdown instance.
|
|
215
218
|
// This prevents closing if a click happens inside the dropdown menu or on its toggle.
|
|
216
|
-
const nearestDropdown = target.closest(`#${this.root.props.id}`);
|
|
219
|
+
const nearestDropdown = target.closest(`#${CSS.escape(this.root.props.id)}`);
|
|
217
220
|
if (nearestDropdown && nearestDropdown.id === this.root.props.id) {
|
|
218
221
|
// The click is within the current dropdown, so do nothing.
|
|
219
222
|
return;
|
package/dist/Modal/modal.svelte
CHANGED
|
@@ -47,9 +47,9 @@ Add dialogs to your site for lightboxes, user notifications, or completely custo
|
|
|
47
47
|
- `useBackdrop` (boolean | 'static'): Optional. Controls whether the modal has a backdrop and if it's static (non-dismissible).
|
|
48
48
|
- `useFade` (boolean): Optional. Controls whether the modal uses a fade transition.
|
|
49
49
|
-->
|
|
50
|
-
<script lang="ts">import {
|
|
50
|
+
<script lang="ts">import { acquireBodyScrollLock, noop, releaseBodyScrollLock, uniqueClsx } from '../common/index.js';
|
|
51
51
|
import { Portal } from '../index.js';
|
|
52
|
-
import { onMount, tick } from 'svelte';
|
|
52
|
+
import { onDestroy, onMount, tick } from 'svelte';
|
|
53
53
|
import { fade, fly } from 'svelte/transition';
|
|
54
54
|
import { initModalRootState, ModalRootState } from './modal.svelte.js';
|
|
55
55
|
// Generate a unique ID for the modal element, in case one is not provided...
|
|
@@ -57,6 +57,7 @@ const uid = $props.id();
|
|
|
57
57
|
let { children, class: classValues, elementRef = $bindable(null), id = `modal-${uid}`, isShown = false, isKeyboardDismissible = true, isFocusable = true, onHide = noop, onHidePrevented = noop, onHidden = noop, onShow = noop, onShown = noop, useBackdrop = true, useFade = true, ...restOfProps } = $props();
|
|
58
58
|
// Initialize the root state of the modal component...
|
|
59
59
|
let bodyElement = $state(null);
|
|
60
|
+
let holdsScrollLock = false;
|
|
60
61
|
let previouslyFocusedElement = null;
|
|
61
62
|
const unset = Symbol('unset');
|
|
62
63
|
let previousIsShown = unset;
|
|
@@ -115,15 +116,21 @@ $effect(() => {
|
|
|
115
116
|
});
|
|
116
117
|
const handleOnShow = (event) => {
|
|
117
118
|
if (bodyElement) {
|
|
118
|
-
|
|
119
|
+
if (!holdsScrollLock) {
|
|
120
|
+
acquireBodyScrollLock(bodyElement);
|
|
121
|
+
holdsScrollLock = true;
|
|
122
|
+
}
|
|
119
123
|
bodyElement.classList.add('modal-open');
|
|
120
124
|
}
|
|
121
125
|
onShow(event);
|
|
122
126
|
};
|
|
123
127
|
const handleOnHidden = (event) => {
|
|
124
|
-
if (bodyElement) {
|
|
125
|
-
|
|
126
|
-
|
|
128
|
+
if (bodyElement && holdsScrollLock) {
|
|
129
|
+
const remainingLocks = releaseBodyScrollLock(bodyElement);
|
|
130
|
+
holdsScrollLock = false;
|
|
131
|
+
if (remainingLocks === 0) {
|
|
132
|
+
bodyElement.classList.remove('modal-open');
|
|
133
|
+
}
|
|
127
134
|
}
|
|
128
135
|
onHidden(event);
|
|
129
136
|
};
|
|
@@ -166,6 +173,17 @@ onMount(() => {
|
|
|
166
173
|
bodyElement = document.querySelector('body');
|
|
167
174
|
}
|
|
168
175
|
});
|
|
176
|
+
// Release a held scroll lock if the modal is destroyed while shown, so a
|
|
177
|
+
// removed-while-open modal doesn't permanently disable body scrolling...
|
|
178
|
+
onDestroy(() => {
|
|
179
|
+
if (holdsScrollLock && bodyElement) {
|
|
180
|
+
const remainingLocks = releaseBodyScrollLock(bodyElement);
|
|
181
|
+
holdsScrollLock = false;
|
|
182
|
+
if (remainingLocks === 0) {
|
|
183
|
+
bodyElement.classList.remove('modal-open');
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
});
|
|
169
187
|
// Dismiss the modal when the backdrop is clicked...
|
|
170
188
|
const handleBackdropMouseDown = (event) => {
|
|
171
189
|
const target = event.target;
|
|
@@ -58,14 +58,15 @@ Build hidden sidebars into your project for navigation, shopping carts, and more
|
|
|
58
58
|
-->
|
|
59
59
|
<script lang="ts">import { noop, uniqueClsx } from '../common/index.js';
|
|
60
60
|
import { initOffcanvasRootState, OffcanvasRootState } from '../common/navbar-offcanvas.svelte.js';
|
|
61
|
-
import {
|
|
62
|
-
import { onMount, tick } from 'svelte';
|
|
61
|
+
import { acquireBodyScrollLock, releaseBodyScrollLock } from '../common/scrollbar.js';
|
|
62
|
+
import { onDestroy, onMount, tick } from 'svelte';
|
|
63
63
|
import { fade, fly } from 'svelte/transition';
|
|
64
64
|
// Generate a unique ID for the offcanvas element, in case one is not provided...
|
|
65
65
|
const uid = $props.id();
|
|
66
66
|
let { children, class: classValues, dir = 'ltr', elementRef = $bindable(null), id = `offcanvas-${uid}`, isBodyScrollable = false, isKeyboardDismissible = true, isShown = false, placement = 'start', showOnBreakpoint, useBackdrop = true, onHide = noop, onHidePrevented = noop, onHidden = noop, onShow = noop, onShown = noop, ...restOfProps } = $props();
|
|
67
67
|
// Initialize the root state of the offcanvas component...
|
|
68
68
|
let bodyElement = $state(null);
|
|
69
|
+
let holdsScrollLock = false;
|
|
69
70
|
const unset = Symbol('unset');
|
|
70
71
|
let previousIsShown = unset;
|
|
71
72
|
let previousShowOnBreakpoint = unset;
|
|
@@ -151,18 +152,29 @@ onMount(() => {
|
|
|
151
152
|
});
|
|
152
153
|
// Listen to the transition events to properly manage the body scrollbar...
|
|
153
154
|
const handleOnShow = (event) => {
|
|
154
|
-
if (bodyElement && !isBodyScrollable && !rootState.isMediaQueryMatched) {
|
|
155
|
-
|
|
155
|
+
if (bodyElement && !isBodyScrollable && !rootState.isMediaQueryMatched && !holdsScrollLock) {
|
|
156
|
+
acquireBodyScrollLock(bodyElement);
|
|
157
|
+
holdsScrollLock = true;
|
|
156
158
|
}
|
|
157
159
|
onShow(event);
|
|
158
160
|
};
|
|
159
161
|
// Listen to the transition events to properly manage the body scrollbar...
|
|
160
162
|
const handleOnHidden = (event) => {
|
|
161
|
-
if (
|
|
162
|
-
|
|
163
|
+
if (holdsScrollLock && bodyElement) {
|
|
164
|
+
releaseBodyScrollLock(bodyElement);
|
|
165
|
+
holdsScrollLock = false;
|
|
163
166
|
}
|
|
164
167
|
onHidden(event);
|
|
165
168
|
};
|
|
169
|
+
// Release a held scroll lock if the offcanvas is destroyed while shown,
|
|
170
|
+
// so a removed-while-open offcanvas doesn't permanently disable body
|
|
171
|
+
// scrolling...
|
|
172
|
+
onDestroy(() => {
|
|
173
|
+
if (holdsScrollLock && bodyElement) {
|
|
174
|
+
releaseBodyScrollLock(bodyElement);
|
|
175
|
+
holdsScrollLock = false;
|
|
176
|
+
}
|
|
177
|
+
});
|
|
166
178
|
// Dismiss the offcanvas when the backdrop is clicked...
|
|
167
179
|
const handleBackdropMouseDown = (event) => {
|
|
168
180
|
const target = event.target;
|
|
@@ -138,7 +138,7 @@ onMount(() => {
|
|
|
138
138
|
}
|
|
139
139
|
// accommodate the id containing a hash or not...
|
|
140
140
|
const elementId = referenceElementId.startsWith('#') ? referenceElementId.substring(1) : referenceElementId;
|
|
141
|
-
referenceElement = document.
|
|
141
|
+
referenceElement = document.getElementById(elementId);
|
|
142
142
|
addEventListeners();
|
|
143
143
|
return () => {
|
|
144
144
|
destroyPopper();
|
|
@@ -8,6 +8,9 @@ export declare const getScrollbarWidth: () => number;
|
|
|
8
8
|
* Disables body scrolling by setting overflow to hidden and
|
|
9
9
|
* adjusting padding to prevent layout shift from scrollbar removal
|
|
10
10
|
*
|
|
11
|
+
* @remarks Prefer {@link acquireBodyScrollLock} in library code — calling
|
|
12
|
+
* this directly is not safe when multiple overlays may lock scrolling at
|
|
13
|
+
* once, since a second call overwrites the saved "original" values.
|
|
11
14
|
* @param {HTMLElement} bodyElement - The body element to disable scrolling on
|
|
12
15
|
*/
|
|
13
16
|
export declare const disableBodyScrolling: (bodyElement: HTMLElement) => void;
|
|
@@ -15,6 +18,25 @@ export declare const disableBodyScrolling: (bodyElement: HTMLElement) => void;
|
|
|
15
18
|
* Restores body scrolling by resetting overflow and padding-right to their
|
|
16
19
|
* original values before scrolling was disabled
|
|
17
20
|
*
|
|
21
|
+
* @remarks Prefer {@link releaseBodyScrollLock} in library code — pairing
|
|
22
|
+
* this directly with {@link disableBodyScrolling} corrupts scroll state
|
|
23
|
+
* when more than one overlay locks scrolling at the same time.
|
|
18
24
|
* @param {HTMLElement} bodyElement - The body element to restore scrolling on
|
|
19
25
|
*/
|
|
20
26
|
export declare const resetBodyScrolling: (bodyElement: HTMLElement) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Acquires a body scroll lock. The first acquisition disables scrolling;
|
|
29
|
+
* nested acquisitions only increment the count.
|
|
30
|
+
*
|
|
31
|
+
* @param {HTMLElement} bodyElement - The body element to lock scrolling on
|
|
32
|
+
* @returns {number} the lock count after acquiring
|
|
33
|
+
*/
|
|
34
|
+
export declare const acquireBodyScrollLock: (bodyElement: HTMLElement) => number;
|
|
35
|
+
/**
|
|
36
|
+
* Releases a body scroll lock. Scrolling is restored only when the last
|
|
37
|
+
* holder releases. Releasing with no lock held is a no-op.
|
|
38
|
+
*
|
|
39
|
+
* @param {HTMLElement} bodyElement - The body element to unlock scrolling on
|
|
40
|
+
* @returns {number} the lock count after releasing
|
|
41
|
+
*/
|
|
42
|
+
export declare const releaseBodyScrollLock: (bodyElement: HTMLElement) => number;
|
package/dist/common/scrollbar.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { hasAttribute, isRTL, setAttribute } from './dom.js';
|
|
2
2
|
const SCROLLBAR_INITIAL_OVERFLOW = 'data-scrollbar-initial-overflow-value';
|
|
3
3
|
const SCROLLBAR_INITIAL_PADDING = 'data-scrollbar-initial-padding-value';
|
|
4
|
+
const SCROLLBAR_LOCK_COUNT = 'data-scrollbar-lock-count';
|
|
4
5
|
/**
|
|
5
6
|
* Calculates the width of the browser's scrollbar
|
|
6
7
|
*
|
|
@@ -14,6 +15,9 @@ export const getScrollbarWidth = () => {
|
|
|
14
15
|
* Disables body scrolling by setting overflow to hidden and
|
|
15
16
|
* adjusting padding to prevent layout shift from scrollbar removal
|
|
16
17
|
*
|
|
18
|
+
* @remarks Prefer {@link acquireBodyScrollLock} in library code — calling
|
|
19
|
+
* this directly is not safe when multiple overlays may lock scrolling at
|
|
20
|
+
* once, since a second call overwrites the saved "original" values.
|
|
17
21
|
* @param {HTMLElement} bodyElement - The body element to disable scrolling on
|
|
18
22
|
*/
|
|
19
23
|
export const disableBodyScrolling = (bodyElement) => {
|
|
@@ -33,6 +37,9 @@ export const disableBodyScrolling = (bodyElement) => {
|
|
|
33
37
|
* Restores body scrolling by resetting overflow and padding-right to their
|
|
34
38
|
* original values before scrolling was disabled
|
|
35
39
|
*
|
|
40
|
+
* @remarks Prefer {@link releaseBodyScrollLock} in library code — pairing
|
|
41
|
+
* this directly with {@link disableBodyScrolling} corrupts scroll state
|
|
42
|
+
* when more than one overlay locks scrolling at the same time.
|
|
36
43
|
* @param {HTMLElement} bodyElement - The body element to restore scrolling on
|
|
37
44
|
*/
|
|
38
45
|
export const resetBodyScrolling = (bodyElement) => {
|
|
@@ -51,3 +58,40 @@ export const resetBodyScrolling = (bodyElement) => {
|
|
|
51
58
|
bodyElement.removeAttribute(SCROLLBAR_INITIAL_OVERFLOW);
|
|
52
59
|
bodyElement.removeAttribute(SCROLLBAR_INITIAL_PADDING);
|
|
53
60
|
};
|
|
61
|
+
/**
|
|
62
|
+
* Acquires a body scroll lock. The first acquisition disables scrolling;
|
|
63
|
+
* nested acquisitions only increment the count.
|
|
64
|
+
*
|
|
65
|
+
* @param {HTMLElement} bodyElement - The body element to lock scrolling on
|
|
66
|
+
* @returns {number} the lock count after acquiring
|
|
67
|
+
*/
|
|
68
|
+
export const acquireBodyScrollLock = (bodyElement) => {
|
|
69
|
+
const count = parseInt(bodyElement.getAttribute(SCROLLBAR_LOCK_COUNT) ?? '0', 10) + 1;
|
|
70
|
+
bodyElement.setAttribute(SCROLLBAR_LOCK_COUNT, `${count}`);
|
|
71
|
+
if (count === 1) {
|
|
72
|
+
disableBodyScrolling(bodyElement);
|
|
73
|
+
}
|
|
74
|
+
return count;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Releases a body scroll lock. Scrolling is restored only when the last
|
|
78
|
+
* holder releases. Releasing with no lock held is a no-op.
|
|
79
|
+
*
|
|
80
|
+
* @param {HTMLElement} bodyElement - The body element to unlock scrolling on
|
|
81
|
+
* @returns {number} the lock count after releasing
|
|
82
|
+
*/
|
|
83
|
+
export const releaseBodyScrollLock = (bodyElement) => {
|
|
84
|
+
const current = parseInt(bodyElement.getAttribute(SCROLLBAR_LOCK_COUNT) ?? '0', 10);
|
|
85
|
+
if (current <= 0) {
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
const count = current - 1;
|
|
89
|
+
if (count === 0) {
|
|
90
|
+
bodyElement.removeAttribute(SCROLLBAR_LOCK_COUNT);
|
|
91
|
+
resetBodyScrolling(bodyElement);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
bodyElement.setAttribute(SCROLLBAR_LOCK_COUNT, `${count}`);
|
|
95
|
+
}
|
|
96
|
+
return count;
|
|
97
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "Wink, Inc.",
|
|
3
3
|
"name": "@winkintel/bootstrap-svelte",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.3",
|
|
5
5
|
"description": "Bootstrap components for Svelte 5 with TypeScript support.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"repository": {
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"bnd": "pnpm build && pnpm dev",
|
|
19
19
|
"bnp": "pnpm build && pnpm preview",
|
|
20
20
|
"build": "vite build && pnpm prepack",
|
|
21
|
+
"build:site": "vite build",
|
|
21
22
|
"check-types": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
22
23
|
"check-types:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
23
24
|
"clean": "rimraf --glob --max-retries=10 --retry-delay=250 '{.svelte-kit,.turbo,.vercel,build,dist,node_modules,playwright-mcp,test-results}'",
|
|
@@ -25,8 +26,8 @@
|
|
|
25
26
|
"format": "prettier --write --ignore-path=.prettierignore $(git diff --name-only --diff-filter d --relative . && git ls-files --others --exclude-standard | sed \"s|^$(git rev-parse --show-prefix)||\")",
|
|
26
27
|
"format-all": "prettier --write --ignore-path=.prettierignore ./src",
|
|
27
28
|
"lint": "prettier --check ./src && eslint ./src",
|
|
28
|
-
"ncu:check": "ncu --target minor && ncu --target minor --cooldown 0d --filter \"@sveltejs/adapter-
|
|
29
|
-
"ncu:upgrade": "ncu --target minor -u && ncu --target minor --cooldown 0d -u --filter \"@sveltejs/adapter-
|
|
29
|
+
"ncu:check": "ncu --target minor && ncu --target minor --cooldown 0d --filter \"@sveltejs/adapter-static,@sveltejs/kit,@sveltejs/vite-plugin-svelte,svelte,svelte-check,svelte-preprocess\"",
|
|
30
|
+
"ncu:upgrade": "ncu --target minor -u && ncu --target minor --cooldown 0d -u --filter \"@sveltejs/adapter-static,@sveltejs/kit,@sveltejs/vite-plugin-svelte,svelte,svelte-check,svelte-preprocess\" && pnpm install",
|
|
30
31
|
"prepare": "svelte-kit sync || echo ''",
|
|
31
32
|
"prepack": "svelte-kit sync && svelte-package && publint",
|
|
32
33
|
"preview": "vite preview --port 4176",
|
|
@@ -53,7 +54,7 @@
|
|
|
53
54
|
}
|
|
54
55
|
},
|
|
55
56
|
"peerDependencies": {
|
|
56
|
-
"svelte": "^5.
|
|
57
|
+
"svelte": "^5.29.0"
|
|
57
58
|
},
|
|
58
59
|
"dependencies": {
|
|
59
60
|
"@popperjs/core": "~2.11.8",
|
|
@@ -63,7 +64,7 @@
|
|
|
63
64
|
"devDependencies": {
|
|
64
65
|
"@eslint/compat": "~2.1.0",
|
|
65
66
|
"@eslint/js": "~10.0.1",
|
|
66
|
-
"@sveltejs/adapter-
|
|
67
|
+
"@sveltejs/adapter-static": "^3.0.10",
|
|
67
68
|
"@sveltejs/kit": "~2.61.1",
|
|
68
69
|
"@sveltejs/package": "~2.5.7",
|
|
69
70
|
"@sveltejs/vite-plugin-svelte": "~7.1.2",
|