@marianmeres/stuic 2.31.0 → 2.32.1
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/dist/actions/popover/popover.svelte.js +4 -4
- package/dist/components/AppShell/AppShell.svelte +2 -3
- package/dist/components/AppShell/AppShellSimple.svelte +121 -0
- package/dist/components/AppShell/AppShellSimple.svelte.d.ts +20 -0
- package/dist/components/AppShell/README.md +5 -0
- package/dist/components/AppShell/index.d.ts +1 -0
- package/dist/components/AppShell/index.js +1 -0
- package/dist/components/Button/Button.svelte +2 -2
- package/dist/components/Button/Button.svelte.d.ts +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.svelte +82 -16
- package/dist/components/DropdownMenu/DropdownMenu.svelte.d.ts +7 -0
- package/dist/components/DropdownMenu/index.css +5 -0
- package/dist/utils/body-scroll-locker.js +13 -1
- package/package.json +1 -1
|
@@ -400,14 +400,14 @@ export function popover(anchorEl, fn) {
|
|
|
400
400
|
closeBtn.innerHTML = `<svg fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width:1.25rem;height:1.25rem"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /></svg>`;
|
|
401
401
|
closeBtn.style.cssText = `
|
|
402
402
|
position: absolute;
|
|
403
|
-
top:
|
|
404
|
-
right:
|
|
403
|
+
top: 4px;
|
|
404
|
+
right: 4px;
|
|
405
405
|
background: black;
|
|
406
406
|
color: white;
|
|
407
407
|
border: none;
|
|
408
|
-
border-
|
|
408
|
+
border-radius: 0.25rem;
|
|
409
409
|
cursor: pointer;
|
|
410
|
-
opacity: 0.
|
|
410
|
+
opacity: 0.6;
|
|
411
411
|
padding: 0.33rem;
|
|
412
412
|
line-height: 1;
|
|
413
413
|
`;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import type { Snippet } from "svelte";
|
|
3
|
+
import { setContext } from "svelte";
|
|
4
|
+
import { twMerge } from "../../utils/tw-merge.js";
|
|
3
5
|
|
|
4
6
|
export interface Props {
|
|
5
7
|
id?: string;
|
|
@@ -57,9 +59,6 @@
|
|
|
57
59
|
</script>
|
|
58
60
|
|
|
59
61
|
<script lang="ts">
|
|
60
|
-
import { setContext } from "svelte";
|
|
61
|
-
import { twMerge } from "../../utils/tw-merge.js";
|
|
62
|
-
|
|
63
62
|
let {
|
|
64
63
|
id = "shell",
|
|
65
64
|
class: classProp,
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import { setContext, type Snippet } from "svelte";
|
|
3
|
+
import { twMerge } from "../../utils/tw-merge.js";
|
|
4
|
+
|
|
5
|
+
export interface Props {
|
|
6
|
+
class?: string;
|
|
7
|
+
//
|
|
8
|
+
headerClass?: string;
|
|
9
|
+
railClass?: string;
|
|
10
|
+
asideClass?: string;
|
|
11
|
+
mainClass?: string;
|
|
12
|
+
//
|
|
13
|
+
rail?: Snippet;
|
|
14
|
+
header?: Snippet;
|
|
15
|
+
aside?: Snippet;
|
|
16
|
+
children?: Snippet;
|
|
17
|
+
//
|
|
18
|
+
elRail?: HTMLElement;
|
|
19
|
+
elHeader?: HTMLElement;
|
|
20
|
+
elAside?: HTMLElement;
|
|
21
|
+
elMain?: HTMLElement;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const MAIN_WIDTH = Symbol("MAIN_WIDTH");
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<script lang="ts">
|
|
28
|
+
let {
|
|
29
|
+
class: classProp,
|
|
30
|
+
//
|
|
31
|
+
headerClass,
|
|
32
|
+
railClass,
|
|
33
|
+
asideClass,
|
|
34
|
+
mainClass,
|
|
35
|
+
//
|
|
36
|
+
rail,
|
|
37
|
+
header,
|
|
38
|
+
aside,
|
|
39
|
+
children,
|
|
40
|
+
//
|
|
41
|
+
elRail = $bindable(),
|
|
42
|
+
elHeader = $bindable(),
|
|
43
|
+
elAside = $bindable(),
|
|
44
|
+
elMain = $bindable(),
|
|
45
|
+
}: Props = $props();
|
|
46
|
+
|
|
47
|
+
let headerHeight = $state(0);
|
|
48
|
+
|
|
49
|
+
// pragmatic use case...
|
|
50
|
+
let mainWidth: number = $state(0);
|
|
51
|
+
setContext(MAIN_WIDTH, {
|
|
52
|
+
get current() {
|
|
53
|
+
return mainWidth;
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
{#if header}
|
|
59
|
+
<header
|
|
60
|
+
bind:this={elHeader}
|
|
61
|
+
bind:clientHeight={headerHeight}
|
|
62
|
+
data-shell="header"
|
|
63
|
+
class={twMerge("sticky top-0 z-10", headerClass)}
|
|
64
|
+
>
|
|
65
|
+
{@render header()}
|
|
66
|
+
</header>
|
|
67
|
+
{/if}
|
|
68
|
+
|
|
69
|
+
<div class={twMerge("flex", classProp)}>
|
|
70
|
+
{#if rail}
|
|
71
|
+
<div
|
|
72
|
+
bind:this={elRail}
|
|
73
|
+
data-shell="rail"
|
|
74
|
+
style:top="{headerHeight}px"
|
|
75
|
+
style:height="calc(100dvh - {headerHeight}px)"
|
|
76
|
+
class={twMerge(
|
|
77
|
+
"sticky shrink-0",
|
|
78
|
+
"flex flex-col items-center",
|
|
79
|
+
"overflow-x-hidden overflow-y-auto",
|
|
80
|
+
"scrollbar-thin",
|
|
81
|
+
railClass
|
|
82
|
+
)}
|
|
83
|
+
>
|
|
84
|
+
{@render rail()}
|
|
85
|
+
</div>
|
|
86
|
+
{/if}
|
|
87
|
+
|
|
88
|
+
{#if aside}
|
|
89
|
+
<aside
|
|
90
|
+
bind:this={elAside}
|
|
91
|
+
data-shell="aside"
|
|
92
|
+
style:top="{headerHeight}px"
|
|
93
|
+
style:height="calc(100dvh - {headerHeight}px)"
|
|
94
|
+
class={twMerge(
|
|
95
|
+
"sticky shrink-0",
|
|
96
|
+
"flex flex-col items-center",
|
|
97
|
+
"overflow-x-hidden overflow-y-auto",
|
|
98
|
+
"scrollbar-thin",
|
|
99
|
+
asideClass
|
|
100
|
+
)}
|
|
101
|
+
>
|
|
102
|
+
{@render aside()}
|
|
103
|
+
</aside>
|
|
104
|
+
{/if}
|
|
105
|
+
|
|
106
|
+
<main
|
|
107
|
+
bind:this={elMain}
|
|
108
|
+
data-shell="main"
|
|
109
|
+
class={twMerge("flex-1", mainClass)}
|
|
110
|
+
bind:offsetWidth={mainWidth}
|
|
111
|
+
>
|
|
112
|
+
{@render children?.()}
|
|
113
|
+
</main>
|
|
114
|
+
</div>
|
|
115
|
+
|
|
116
|
+
<style>
|
|
117
|
+
.scrollbar-thin {
|
|
118
|
+
scrollbar-width: thin;
|
|
119
|
+
scrollbar-gutter: stable;
|
|
120
|
+
}
|
|
121
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Snippet } from "svelte";
|
|
2
|
+
export interface Props {
|
|
3
|
+
class?: string;
|
|
4
|
+
headerClass?: string;
|
|
5
|
+
railClass?: string;
|
|
6
|
+
asideClass?: string;
|
|
7
|
+
mainClass?: string;
|
|
8
|
+
rail?: Snippet;
|
|
9
|
+
header?: Snippet;
|
|
10
|
+
aside?: Snippet;
|
|
11
|
+
children?: Snippet;
|
|
12
|
+
elRail?: HTMLElement;
|
|
13
|
+
elHeader?: HTMLElement;
|
|
14
|
+
elAside?: HTMLElement;
|
|
15
|
+
elMain?: HTMLElement;
|
|
16
|
+
}
|
|
17
|
+
export declare const MAIN_WIDTH: unique symbol;
|
|
18
|
+
declare const AppShellSimple: import("svelte").Component<Props, {}, "elRail" | "elHeader" | "elAside" | "elMain">;
|
|
19
|
+
type AppShellSimple = ReturnType<typeof AppShellSimple>;
|
|
20
|
+
export default AppShellSimple;
|
|
@@ -97,3 +97,8 @@ import { onMount } from 'svelte';
|
|
|
97
97
|
// Returns cleanup function automatically
|
|
98
98
|
onMount(appShellSetHtmlBodyHeight);
|
|
99
99
|
```
|
|
100
|
+
|
|
101
|
+
## AppShellSimple
|
|
102
|
+
|
|
103
|
+
A simplified approach using a sticky header and a sticky left sidebar, allowing the
|
|
104
|
+
page body to follow its natural flow (and the chrome UI is adjusted on scroll correctly).
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
export const BUTTON_STUIC_BASE_CLASSES = `
|
|
38
38
|
bg-button-bg text-button-text
|
|
39
39
|
dark:bg-button-bg-dark dark:text-button-text-dark
|
|
40
|
-
|
|
40
|
+
text-base text-center
|
|
41
41
|
leading-none
|
|
42
42
|
border-1
|
|
43
43
|
border-button-border dark:border-button-border-dark
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
export const BUTTON_STUIC_PRESET_CLASSES: ButtonPresetClasses = {
|
|
62
62
|
size: {
|
|
63
63
|
sm: `text-sm rounded-md px-3 py-2 min-h-none min-w-none`,
|
|
64
|
-
lg: `text-
|
|
64
|
+
lg: `text-lg rounded-xl`,
|
|
65
65
|
},
|
|
66
66
|
variant: {
|
|
67
67
|
primary: `font-medium`,
|
|
@@ -31,7 +31,7 @@ export interface ButtonPresetClasses {
|
|
|
31
31
|
shadow: string;
|
|
32
32
|
inverse: string;
|
|
33
33
|
}
|
|
34
|
-
export declare const BUTTON_STUIC_BASE_CLASSES = "\n\t\tbg-button-bg text-button-text\n\t\tdark:bg-button-bg-dark dark:text-button-text-dark\n\t\
|
|
34
|
+
export declare const BUTTON_STUIC_BASE_CLASSES = "\n\t\tbg-button-bg text-button-text\n\t\tdark:bg-button-bg-dark dark:text-button-text-dark\n\t\ttext-base text-center\n\t\tleading-none\n\t\tborder-1\n\t\tborder-button-border dark:border-button-border-dark\n\t\trounded-lg\n\t\tinline-flex items-center justify-center gap-x-2\n\t\tpx-4 py-3\n\t\tselect-none\n\t\tmin-h-[44px] min-w-[44px]\n\n\t\thover:brightness-105\n\t\tactive:brightness-95\n\t\tdisabled:hover:brightness-100 disabled:opacity-50\n\n\t\tfocus:brightness-105\n\t\tfocus:border-button-border-focus focus:dark:border-button-border-focus-dark\n\n\t\t focus:outline-4 focus:outline-black/10 focus:dark:outline-white/20\n\t\tfocus-visible:outline-4 focus-visible:outline-black/10 focus-visible:dark:outline-white/20\n\t";
|
|
35
35
|
export declare const BUTTON_STUIC_PRESET_CLASSES: ButtonPresetClasses;
|
|
36
36
|
import "./index.css";
|
|
37
37
|
import { type TooltipConfig } from "../../actions/index.js";
|
|
@@ -138,6 +138,10 @@
|
|
|
138
138
|
classExpandable?: string;
|
|
139
139
|
/** Classes for expandable section content */
|
|
140
140
|
classExpandableContent?: string;
|
|
141
|
+
/** Classes for backdrop (fallback mode only) */
|
|
142
|
+
classBackdrop?: string;
|
|
143
|
+
/** Show backdrop in fallback mode (default: true) */
|
|
144
|
+
showBackdrop?: boolean;
|
|
141
145
|
/** Custom trigger snippet - receives isOpen state, toggle function, and ARIA props for full control */
|
|
142
146
|
trigger?: Snippet<
|
|
143
147
|
[
|
|
@@ -165,6 +169,8 @@
|
|
|
165
169
|
triggerEl?: HTMLButtonElement;
|
|
166
170
|
/** Reference to dropdown element */
|
|
167
171
|
dropdownEl?: HTMLDivElement;
|
|
172
|
+
/** Optional, used only when css positioning not supported (iPhone)*/
|
|
173
|
+
noScrollLock?: boolean;
|
|
168
174
|
}
|
|
169
175
|
|
|
170
176
|
const POSITION_MAP: Record<string, string> = {
|
|
@@ -245,6 +251,12 @@
|
|
|
245
251
|
text-neutral-500 dark:text-neutral-400
|
|
246
252
|
select-none
|
|
247
253
|
`;
|
|
254
|
+
|
|
255
|
+
export const DROPDOWN_MENU_BACKDROP_CLASSES = `
|
|
256
|
+
stuic-dropdown-menu-backdrop
|
|
257
|
+
fixed inset-0 bg-black/25
|
|
258
|
+
z-40
|
|
259
|
+
`;
|
|
248
260
|
</script>
|
|
249
261
|
|
|
250
262
|
<script lang="ts">
|
|
@@ -255,10 +267,11 @@
|
|
|
255
267
|
import { iconLucideChevronDown } from "@marianmeres/icons-fns/lucide/iconLucideChevronDown.js";
|
|
256
268
|
import { iconLucideChevronRight } from "@marianmeres/icons-fns/lucide/iconLucideChevronRight.js";
|
|
257
269
|
import { onClickOutside } from "runed";
|
|
258
|
-
import { slide } from "svelte/transition";
|
|
270
|
+
import { slide, fade } from "svelte/transition";
|
|
259
271
|
import { untrack } from "svelte";
|
|
260
272
|
import Thc from "../Thc/Thc.svelte";
|
|
261
273
|
import "./index.css";
|
|
274
|
+
import { BodyScroll } from "../../utils/body-scroll-locker.js";
|
|
262
275
|
|
|
263
276
|
let {
|
|
264
277
|
items,
|
|
@@ -280,6 +293,8 @@
|
|
|
280
293
|
classHeader,
|
|
281
294
|
classExpandable,
|
|
282
295
|
classExpandableContent,
|
|
296
|
+
classBackdrop,
|
|
297
|
+
showBackdrop = true,
|
|
283
298
|
trigger,
|
|
284
299
|
children,
|
|
285
300
|
onOpen,
|
|
@@ -287,6 +302,7 @@
|
|
|
287
302
|
onSelect,
|
|
288
303
|
triggerEl = $bindable(),
|
|
289
304
|
dropdownEl = $bindable(),
|
|
305
|
+
noScrollLock,
|
|
290
306
|
...rest
|
|
291
307
|
}: Props = $props();
|
|
292
308
|
|
|
@@ -396,6 +412,11 @@
|
|
|
396
412
|
wasOpen = isOpen;
|
|
397
413
|
});
|
|
398
414
|
|
|
415
|
+
$effect(() => {
|
|
416
|
+
if (noScrollLock || isSupported) return;
|
|
417
|
+
isOpen ? BodyScroll.lock() : BodyScroll.unlock();
|
|
418
|
+
});
|
|
419
|
+
|
|
399
420
|
// Click outside handler
|
|
400
421
|
onClickOutside(
|
|
401
422
|
() => wrapperEl,
|
|
@@ -455,22 +476,15 @@
|
|
|
455
476
|
max-height: ${maxHeight};
|
|
456
477
|
`;
|
|
457
478
|
} else {
|
|
458
|
-
// Fallback:
|
|
459
|
-
if (position === "left") {
|
|
460
|
-
return `position: absolute; right: 100%; top: 0; margin-right: ${offset}; max-height: ${maxHeight};`;
|
|
461
|
-
} else if (position === "right") {
|
|
462
|
-
return `position: absolute; left: 100%; top: 0; margin-left: ${offset}; max-height: ${maxHeight};`;
|
|
463
|
-
}
|
|
464
|
-
const isTop = position.startsWith("top");
|
|
465
|
-
const isLeft =
|
|
466
|
-
position.includes("left") || position === "bottom" || position === "top";
|
|
479
|
+
// Fallback: centered modal overlay
|
|
467
480
|
return `
|
|
468
|
-
position:
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
481
|
+
position: fixed;
|
|
482
|
+
top: 50%;
|
|
483
|
+
left: 50%;
|
|
484
|
+
transform: translate(-50%, -50%);
|
|
485
|
+
max-width: 90vw;
|
|
473
486
|
max-height: ${maxHeight};
|
|
487
|
+
z-index: 50;
|
|
474
488
|
`;
|
|
475
489
|
}
|
|
476
490
|
});
|
|
@@ -567,6 +581,22 @@
|
|
|
567
581
|
</button>
|
|
568
582
|
{/if}
|
|
569
583
|
|
|
584
|
+
<!-- Backdrop (fallback mode only) -->
|
|
585
|
+
{#if isOpen && !isSupported && showBackdrop}
|
|
586
|
+
<div
|
|
587
|
+
class={twMerge(DROPDOWN_MENU_BACKDROP_CLASSES, classBackdrop)}
|
|
588
|
+
onclick={() => {
|
|
589
|
+
if (closeOnClickOutside) {
|
|
590
|
+
isOpen = false;
|
|
591
|
+
triggerEl?.focus();
|
|
592
|
+
}
|
|
593
|
+
}}
|
|
594
|
+
onkeydown={() => {}}
|
|
595
|
+
role="presentation"
|
|
596
|
+
transition:fade={{ duration: transitionDuration }}
|
|
597
|
+
></div>
|
|
598
|
+
{/if}
|
|
599
|
+
|
|
570
600
|
<!-- Dropdown Menu -->
|
|
571
601
|
{#if isOpen}
|
|
572
602
|
<div
|
|
@@ -574,10 +604,46 @@
|
|
|
574
604
|
id={dropdownId}
|
|
575
605
|
role="menu"
|
|
576
606
|
aria-labelledby={triggerId}
|
|
577
|
-
class={twMerge(
|
|
607
|
+
class={twMerge(
|
|
608
|
+
DROPDOWN_MENU_DROPDOWN_CLASSES,
|
|
609
|
+
!isSupported && "w-4/5 max-w-32",
|
|
610
|
+
classDropdown
|
|
611
|
+
)}
|
|
578
612
|
style={dropdownStyle}
|
|
579
613
|
transition:slide={{ duration: transitionDuration }}
|
|
580
614
|
>
|
|
615
|
+
<!-- Close button (fallback mode only) -->
|
|
616
|
+
{#if !isSupported}
|
|
617
|
+
<div class="sticky top-0 right-0 z-10 flex just pointer-events-none">
|
|
618
|
+
<button
|
|
619
|
+
type="button"
|
|
620
|
+
aria-label="Close"
|
|
621
|
+
class={[
|
|
622
|
+
"bg-black text-white rounded-md cursor-pointer opacity-60",
|
|
623
|
+
"absolute right-0 top-0 p-2",
|
|
624
|
+
"leading-none hover:opacity-100 pointer-events-auto",
|
|
625
|
+
]}
|
|
626
|
+
onclick={() => {
|
|
627
|
+
isOpen = false;
|
|
628
|
+
triggerEl?.focus();
|
|
629
|
+
}}
|
|
630
|
+
>
|
|
631
|
+
<svg
|
|
632
|
+
fill="none"
|
|
633
|
+
viewBox="0 0 24 24"
|
|
634
|
+
stroke-width="2.5"
|
|
635
|
+
stroke="currentColor"
|
|
636
|
+
class="w-5 h-5"
|
|
637
|
+
>
|
|
638
|
+
<path
|
|
639
|
+
stroke-linecap="round"
|
|
640
|
+
stroke-linejoin="round"
|
|
641
|
+
d="M6 18 18 6M6 6l12 12"
|
|
642
|
+
/>
|
|
643
|
+
</svg>
|
|
644
|
+
</button>
|
|
645
|
+
</div>
|
|
646
|
+
{/if}
|
|
581
647
|
{#each items as item}
|
|
582
648
|
{#if item.type === "action"}
|
|
583
649
|
{@const isActive = _navItems.active?.id === item.id}
|
|
@@ -110,6 +110,10 @@ export interface Props extends Omit<HTMLButtonAttributes, "children"> {
|
|
|
110
110
|
classExpandable?: string;
|
|
111
111
|
/** Classes for expandable section content */
|
|
112
112
|
classExpandableContent?: string;
|
|
113
|
+
/** Classes for backdrop (fallback mode only) */
|
|
114
|
+
classBackdrop?: string;
|
|
115
|
+
/** Show backdrop in fallback mode (default: true) */
|
|
116
|
+
showBackdrop?: boolean;
|
|
113
117
|
/** Custom trigger snippet - receives isOpen state, toggle function, and ARIA props for full control */
|
|
114
118
|
trigger?: Snippet<[
|
|
115
119
|
{
|
|
@@ -135,6 +139,8 @@ export interface Props extends Omit<HTMLButtonAttributes, "children"> {
|
|
|
135
139
|
triggerEl?: HTMLButtonElement;
|
|
136
140
|
/** Reference to dropdown element */
|
|
137
141
|
dropdownEl?: HTMLDivElement;
|
|
142
|
+
/** Optional, used only when css positioning not supported (iPhone)*/
|
|
143
|
+
noScrollLock?: boolean;
|
|
138
144
|
}
|
|
139
145
|
export declare const DROPDOWN_MENU_BASE_CLASSES = "stuic-dropdown-menu relative inline-block";
|
|
140
146
|
export declare const DROPDOWN_MENU_TRIGGER_CLASSES = "\n\t\tinline-flex items-center justify-center gap-2\n\t\tpx-3 py-2\n\t\trounded-md border\n\t\tbg-white dark:bg-neutral-800\n\t\ttext-neutral-900 dark:text-neutral-100\n\t\tborder-neutral-200 dark:border-neutral-700\n\t\thover:brightness-95 dark:hover:brightness-110\n\t\tfocus-visible:outline-2 focus-visible:outline-offset-2\n\t\tcursor-pointer\n\t";
|
|
@@ -142,6 +148,7 @@ export declare const DROPDOWN_MENU_DROPDOWN_CLASSES = "\n\t\tstuic-dropdown-menu
|
|
|
142
148
|
export declare const DROPDOWN_MENU_ITEM_CLASSES = "\n\t\tw-full\n\t\tflex items-center gap-2\n\t\tpx-2 py-1.5\n\t\tmin-h-[44px]\n\t\ttext-left text-sm\n\t\trounded-sm\n\t\tcursor-pointer\n\t\ttouch-action-manipulation\n\t\thover:bg-neutral-100 dark:hover:bg-neutral-700\n\t\tfocus:outline-none\n\t\tfocus-visible:bg-neutral-200 dark:focus-visible:bg-neutral-600\n\t";
|
|
143
149
|
export declare const DROPDOWN_MENU_DIVIDER_CLASSES = "\n\t\th-px my-1\n\t\tbg-neutral-200 dark:bg-neutral-700\n\t";
|
|
144
150
|
export declare const DROPDOWN_MENU_HEADER_CLASSES = "\n\t\tpx-2 py-1.5\n\t\ttext-xs font-semibold uppercase tracking-wide\n\t\ttext-neutral-500 dark:text-neutral-400\n\t\tselect-none\n\t";
|
|
151
|
+
export declare const DROPDOWN_MENU_BACKDROP_CLASSES = "\n\t\tstuic-dropdown-menu-backdrop\n\t\tfixed inset-0 bg-black/25\n\t\tz-40\n\t";
|
|
145
152
|
import "./index.css";
|
|
146
153
|
declare const DropdownMenu: import("svelte").Component<Props, {}, "isOpen" | "triggerEl" | "dropdownEl">;
|
|
147
154
|
type DropdownMenu = ReturnType<typeof DropdownMenu>;
|
|
@@ -40,6 +40,9 @@ export class BodyScroll {
|
|
|
40
40
|
document.body.style.top = `-${scrollY}px`;
|
|
41
41
|
document.body.style.width = "100%";
|
|
42
42
|
document.body.style.overflow = "hidden";
|
|
43
|
+
//
|
|
44
|
+
document.body.style.left = "0";
|
|
45
|
+
document.body.style.right = "0";
|
|
43
46
|
}
|
|
44
47
|
else {
|
|
45
48
|
// Another component already locked the scroll, just increment the counter
|
|
@@ -79,10 +82,19 @@ export class BodyScroll {
|
|
|
79
82
|
top: style.position || null,
|
|
80
83
|
width: style.width || null,
|
|
81
84
|
overflow: style.overflow || null,
|
|
85
|
+
left: style.left || null,
|
|
86
|
+
right: style.left || null,
|
|
82
87
|
});
|
|
83
88
|
}
|
|
84
89
|
static _restore_body_styles(originalJsonString) {
|
|
85
|
-
let original = {
|
|
90
|
+
let original = {
|
|
91
|
+
position: null,
|
|
92
|
+
top: null,
|
|
93
|
+
width: null,
|
|
94
|
+
overflow: null,
|
|
95
|
+
left: null,
|
|
96
|
+
right: null,
|
|
97
|
+
};
|
|
86
98
|
try {
|
|
87
99
|
original = JSON.parse(originalJsonString);
|
|
88
100
|
}
|