@spaethtech/svelte-ui 0.7.1-dev.44.97afb0d → 0.7.1-dev.46.8e420d1
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.
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
align = "start",
|
|
36
36
|
boundary = "viewport",
|
|
37
37
|
offset = 4,
|
|
38
|
+
margin = 8,
|
|
38
39
|
matchWidth = false,
|
|
39
40
|
surface = false,
|
|
40
41
|
variant,
|
|
@@ -51,6 +52,9 @@
|
|
|
51
52
|
/** Default the viewport; pass a container element or CSS selector to bound flipping to it. */
|
|
52
53
|
boundary?: Boundary;
|
|
53
54
|
offset?: number;
|
|
55
|
+
/** Minimum gap kept from the boundary edges, in px (default 8). Set `0` to let the box sit flush
|
|
56
|
+
* against an edge — e.g. a sidebar popout that must align to the sidebar's (viewport) edge. */
|
|
57
|
+
margin?: number;
|
|
54
58
|
matchWidth?: boolean;
|
|
55
59
|
/** Render a themed floating PANEL around the children (background, border, padding, shadow) instead
|
|
56
60
|
* of the default bare positioner. `variant`/`size`/`borderless` configure that panel. Consumers
|
|
@@ -132,6 +136,7 @@
|
|
|
132
136
|
align,
|
|
133
137
|
boundary,
|
|
134
138
|
offset,
|
|
139
|
+
margin,
|
|
135
140
|
matchWidth,
|
|
136
141
|
onplaced: (p) => (placed = p),
|
|
137
142
|
}}
|
|
@@ -12,6 +12,9 @@ type $$ComponentProps = {
|
|
|
12
12
|
/** Default the viewport; pass a container element or CSS selector to bound flipping to it. */
|
|
13
13
|
boundary?: Boundary;
|
|
14
14
|
offset?: number;
|
|
15
|
+
/** Minimum gap kept from the boundary edges, in px (default 8). Set `0` to let the box sit flush
|
|
16
|
+
* against an edge — e.g. a sidebar popout that must align to the sidebar's (viewport) edge. */
|
|
17
|
+
margin?: number;
|
|
15
18
|
matchWidth?: boolean;
|
|
16
19
|
/** Render a themed floating PANEL around the children (background, border, padding, shadow) instead
|
|
17
20
|
* of the default bare positioner. `variant`/`size`/`borderless` configure that panel. Consumers
|
|
@@ -216,8 +216,13 @@
|
|
|
216
216
|
return active;
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
//
|
|
220
|
-
|
|
219
|
+
// Resolve the mode synchronously on the CLIENT at init (from the real viewport width) so the first
|
|
220
|
+
// client render is already correct — no post-hydration flash from `expanded` → the actual mode. On
|
|
221
|
+
// the server `window` is undefined, so SSR emits `expanded`; the client corrects during hydration
|
|
222
|
+
// (not via a delayed effect). The effect below keeps it in sync on subsequent viewport changes.
|
|
223
|
+
let currentMode = $state<SideBarMenuMode>(
|
|
224
|
+
typeof window !== "undefined" ? resolveMode(effectiveModes, window.innerWidth) : "expanded",
|
|
225
|
+
);
|
|
221
226
|
|
|
222
227
|
$effect(() => {
|
|
223
228
|
const map = effectiveModes;
|
|
@@ -276,6 +281,15 @@
|
|
|
276
281
|
// Labels show in every mode except a collapsed (not hover-expanded) icon rail.
|
|
277
282
|
const labelsVisible = $derived(currentMode !== "icon" || effectivelyExpanded);
|
|
278
283
|
|
|
284
|
+
// Aside width in px, driven by mode (inline style — robust, no Tailwind arbitrary-var class).
|
|
285
|
+
const asideWidthCss = $derived(
|
|
286
|
+
currentMode === "stepped"
|
|
287
|
+
? "100%"
|
|
288
|
+
: currentMode === "icon" && !effectivelyExpanded
|
|
289
|
+
? `${collapsedWidth}px`
|
|
290
|
+
: `${expandedWidth}px`,
|
|
291
|
+
);
|
|
292
|
+
|
|
279
293
|
// ── DEV depth warning ───────────────────────────────────────────
|
|
280
294
|
if (DEV) {
|
|
281
295
|
const walk = (list: SideBarMenuItem[], depth: number, path: string[]) => {
|
|
@@ -699,7 +713,8 @@
|
|
|
699
713
|
role="menu"
|
|
700
714
|
tabindex="-1"
|
|
701
715
|
id={popoutId}
|
|
702
|
-
|
|
716
|
+
style="width: {expandedWidth}px;"
|
|
717
|
+
class="overflow-hidden shadow-lg [background-color:var(--ui-color-background)] [color:var(--ui-color-text)] [border-color:color-mix(in_srgb,var(--ui-color-text)_15%,transparent)] {borderClass}"
|
|
703
718
|
onmouseenter={cancelClose}
|
|
704
719
|
onmouseleave={scheduleClose}
|
|
705
720
|
>
|
|
@@ -749,27 +764,28 @@
|
|
|
749
764
|
width, so the expanded float below is positioned against the SIDEBAR's own box (container-relative,
|
|
750
765
|
never the viewport). In every other mode it's `display: contents` (no box) so layout is unchanged. -->
|
|
751
766
|
<div
|
|
752
|
-
class={hoverExpandActive ? "relative shrink-0
|
|
753
|
-
style="
|
|
767
|
+
class={hoverExpandActive ? "relative shrink-0" : "contents"}
|
|
768
|
+
style="{hoverExpandActive ? `width: ${collapsedWidth}px;` : ''}"
|
|
754
769
|
>
|
|
755
770
|
<aside
|
|
756
771
|
bind:this={asideRef}
|
|
772
|
+
style="width: {asideWidthCss};"
|
|
757
773
|
onmouseenter={hoverExpandActive ? openHoverExpand : undefined}
|
|
758
774
|
onmouseleave={hoverExpandActive ? scheduleHoverCollapse : undefined}
|
|
759
775
|
class="
|
|
760
|
-
flex flex-col z-[60] overflow-hidden
|
|
776
|
+
flex flex-col z-[60] overflow-hidden shrink-0
|
|
761
777
|
[background-color:var(--ui-color-background)]
|
|
762
778
|
[color:var(--ui-color-text)]
|
|
763
779
|
{dockBorder}
|
|
764
780
|
{currentMode === 'stepped'
|
|
765
|
-
? `absolute inset-y-0 ${dockEdge}
|
|
781
|
+
? `absolute inset-y-0 ${dockEdge} z-[75] transition-transform duration-200 ${open ? 'translate-x-0' : dockOff}`
|
|
766
782
|
: currentMode === 'drawer'
|
|
767
|
-
? `absolute inset-y-0 ${dockEdge}
|
|
783
|
+
? `absolute inset-y-0 ${dockEdge} z-[75] transition-transform duration-200 ${open ? 'translate-x-0' : dockOff}`
|
|
768
784
|
: currentMode === 'icon'
|
|
769
785
|
? hoverExpandActive
|
|
770
|
-
? `absolute inset-y-0 ${dockEdge} z-[65] transition-[width] duration-200 ${effectivelyExpanded ? '
|
|
771
|
-
: 'relative
|
|
772
|
-
: 'relative
|
|
786
|
+
? `absolute inset-y-0 ${dockEdge} z-[65] transition-[width] duration-200 ${effectivelyExpanded ? 'shadow-lg' : ''}`
|
|
787
|
+
: 'relative'
|
|
788
|
+
: 'relative'}
|
|
773
789
|
{additionalClass}
|
|
774
790
|
"
|
|
775
791
|
>
|
|
@@ -802,6 +818,7 @@
|
|
|
802
818
|
side={popoutSide}
|
|
803
819
|
align={geom.align}
|
|
804
820
|
offset={0}
|
|
821
|
+
margin={0}
|
|
805
822
|
onclose={() => {
|
|
806
823
|
if (openId === id) openId = null;
|
|
807
824
|
}}
|
|
@@ -838,6 +855,7 @@
|
|
|
838
855
|
side={popoutSide}
|
|
839
856
|
align={geom.align}
|
|
840
857
|
offset={0}
|
|
858
|
+
margin={0}
|
|
841
859
|
onclose={() => {
|
|
842
860
|
if (openId === id) openId = null;
|
|
843
861
|
}}
|
package/dist/index.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ export type { Columns, Gap } from "./components/field-group.js";
|
|
|
41
41
|
export { default as Disclosure } from "./components/Disclosure.svelte";
|
|
42
42
|
export { default as Accordion } from "./components/Accordion.svelte";
|
|
43
43
|
export { default as SideBarMenu } from "./components/SideBarMenu/SideBarMenu.svelte";
|
|
44
|
-
export type { SideBarMenuItem, SideBarMenuBadge, SideBarMenuBadgeVariant, SideBarMenuApi, } from "./components/SideBarMenu/SideBarMenu.svelte";
|
|
44
|
+
export type { SideBarMenuItem, SideBarMenuBadge, SideBarMenuBadgeVariant, SideBarMenuApi, SideBarMenuMode, } from "./components/SideBarMenu/SideBarMenu.svelte";
|
|
45
45
|
export { default as TabStrip } from "./components/TabStrip/TabStrip.svelte";
|
|
46
46
|
export type { TabDefinition } from "./components/TabStrip/TabStrip.svelte";
|
|
47
47
|
export { default as DataTable } from "./components/DataTable.svelte";
|