@marianmeres/stuic 2.1.33 → 2.2.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.
@@ -668,7 +668,7 @@
668
668
  <!-- {#if options.items.length} -->
669
669
  <div
670
670
  class={[
671
- "options overflow-y-auto overflow-x-hidden space-y-1",
671
+ "options overflow-y-auto overflow-x-hidden space-y-1 scrollbar-thin",
672
672
  "h-[220px] max-h-[220px]",
673
673
  ]}
674
674
  bind:this={optionsBox}
@@ -0,0 +1,144 @@
1
+ <script lang="ts" module>
2
+ import { createClog } from "@marianmeres/clog";
3
+ import { type Snippet } from "svelte";
4
+ import { waitForNextRepaint } from "../../utils/paint.js";
5
+ import { twMerge } from "../../utils/tw-merge.js";
6
+ import { sleep } from "../../utils/sleep.js";
7
+
8
+ const clog = createClog("SlidingContainer");
9
+
10
+ type PanelId = "A" | "B";
11
+
12
+ // internal state values DRY consts
13
+ const DIRECTION_RTL = "rtl";
14
+ const DIRECTION_LTR = "ltr";
15
+ const SLIDING_IN = "in";
16
+ const SLIDING_OUT = "out";
17
+ const ACTIVE = "active";
18
+ const INACTIVE_LEFT = "inactive-left";
19
+ const INACTIVE_RIGHT = "inactive-right";
20
+ const DESTROYED = "destroyed";
21
+ </script>
22
+
23
+ <script lang="ts">
24
+ let {
25
+ class: classProp = "",
26
+ destroyInactive = true,
27
+ duration = 300,
28
+ initial = "A",
29
+ panelA,
30
+ panelB = null,
31
+ }: {
32
+ class?: string;
33
+ destroyInactive?: boolean;
34
+ duration?: number;
35
+ initial?: PanelId;
36
+ panelA: Snippet<[{ show: typeof show; active: PanelId; inTransition: boolean }]>;
37
+ panelB?: null | Snippet<
38
+ [{ show: typeof show; active: PanelId; inTransition: boolean }]
39
+ >;
40
+ } = $props();
41
+
42
+ //
43
+ let active: PanelId = $state(initial);
44
+ let inTransition = $state(false);
45
+
46
+ // panel states
47
+ let A = $state(initial === "A" ? ACTIVE : INACTIVE_LEFT);
48
+ let B = $state(initial === "B" ? ACTIVE : INACTIVE_RIGHT);
49
+
50
+ /** */
51
+ export async function show(targetPanel: PanelId): Promise<boolean> {
52
+ if (inTransition) {
53
+ clog.warn("Transition in progress, ignoring...");
54
+ return false;
55
+ }
56
+
57
+ if (active === targetPanel) {
58
+ clog.debug(`Panel ${targetPanel} already active`);
59
+ return false;
60
+ }
61
+
62
+ inTransition = true;
63
+ const direction = targetPanel === "B" ? DIRECTION_RTL : DIRECTION_LTR;
64
+
65
+ // set up states for transition
66
+ if (direction === DIRECTION_RTL) {
67
+ B = INACTIVE_RIGHT;
68
+
69
+ // ensure panel exists before transitioning
70
+ await waitForNextRepaint();
71
+
72
+ A = SLIDING_OUT;
73
+ B = SLIDING_IN;
74
+ } else {
75
+ A = INACTIVE_LEFT;
76
+
77
+ // ensure panel exists before transitioning
78
+ await waitForNextRepaint();
79
+
80
+ B = SLIDING_OUT;
81
+ A = SLIDING_IN;
82
+ }
83
+
84
+ // wait for transition to end
85
+ await sleep(duration);
86
+
87
+ // clean up after transition
88
+ if (direction === DIRECTION_RTL) {
89
+ A = destroyInactive ? DESTROYED : INACTIVE_LEFT;
90
+ B = ACTIVE;
91
+ active = "B";
92
+ } else {
93
+ B = destroyInactive ? DESTROYED : INACTIVE_RIGHT;
94
+ A = ACTIVE;
95
+ active = "A";
96
+ }
97
+
98
+ inTransition = false;
99
+
100
+ return true;
101
+ }
102
+
103
+ /** To be able to consume from outside */
104
+ export function current() {
105
+ return {
106
+ get active(): PanelId {
107
+ return active;
108
+ },
109
+ get isTransitioning(): boolean {
110
+ return inTransition;
111
+ },
112
+ };
113
+ }
114
+
115
+ const PANEL_CLASS = "absolute inset-0 transition-transform ease-in-out";
116
+ </script>
117
+
118
+ <div class={twMerge("relative w-full h-full overflow-hidden", classProp)}>
119
+ <!-- Panel A -->
120
+ {#if A !== DESTROYED}
121
+ <div
122
+ class={PANEL_CLASS}
123
+ style="transition-duration:{duration}ms;"
124
+ class:translate-x-0={[ACTIVE, SLIDING_IN].includes(A)}
125
+ class:-translate-x-full={[INACTIVE_LEFT, SLIDING_OUT].includes(A)}
126
+ class:translate-x-full={A === INACTIVE_RIGHT}
127
+ >
128
+ {@render panelA({ show, active, inTransition })}
129
+ </div>
130
+ {/if}
131
+
132
+ <!-- Panel B -->
133
+ {#if B !== DESTROYED}
134
+ <div
135
+ class={PANEL_CLASS}
136
+ style="transition-duration:{duration}ms;"
137
+ class:translate-x-0={[ACTIVE, SLIDING_IN].includes(B)}
138
+ class:-translate-x-full={B === INACTIVE_LEFT}
139
+ class:translate-x-full={[INACTIVE_RIGHT, SLIDING_OUT].includes(B)}
140
+ >
141
+ {@render panelB?.({ show, active, inTransition })}
142
+ </div>
143
+ {/if}
144
+ </div>
@@ -0,0 +1,26 @@
1
+ import { type Snippet } from "svelte";
2
+ type PanelId = "A" | "B";
3
+ declare const SlidingPanels: import("svelte").Component<{
4
+ class?: string;
5
+ destroyInactive?: boolean;
6
+ duration?: number;
7
+ initial?: PanelId;
8
+ panelA: Snippet<[{
9
+ show: (targetPanel: PanelId) => Promise<boolean>;
10
+ active: PanelId;
11
+ inTransition: boolean;
12
+ }]>;
13
+ panelB?: null | Snippet<[{
14
+ show: (targetPanel: PanelId) => Promise<boolean>;
15
+ active: PanelId;
16
+ inTransition: boolean;
17
+ }]>;
18
+ }, {
19
+ show: (targetPanel: PanelId) => Promise<boolean>;
20
+ current: () => {
21
+ readonly active: PanelId;
22
+ readonly isTransitioning: boolean;
23
+ };
24
+ }, "">;
25
+ type SlidingPanels = ReturnType<typeof SlidingPanels>;
26
+ export default SlidingPanels;
@@ -0,0 +1 @@
1
+ export { default as SlidingPanels } from "./SlidingPanels.svelte";
@@ -0,0 +1 @@
1
+ export { default as SlidingPanels } from "./SlidingPanels.svelte";
package/dist/index.css CHANGED
@@ -32,3 +32,7 @@ so, since we need to override, sticking with that */
32
32
  /* opacity: 0.5 !important; moved to Button itself, so it can be overridden */
33
33
  }
34
34
  }
35
+
36
+ .scrollbar-thin {
37
+ scrollbar-width: thin;
38
+ }
package/dist/index.d.ts CHANGED
@@ -15,6 +15,7 @@ export * from "./components/Modal/index.js";
15
15
  export * from "./components/ModalDialog/index.js";
16
16
  export * from "./components/Notifications/index.js";
17
17
  export * from "./components/Progress/index.js";
18
+ export * from "./components/SlidingPanels/index.js";
18
19
  export * from "./components/Spinner/index.js";
19
20
  export * from "./components/Switch/index.js";
20
21
  export * from "./components/TwCheck/index.js";
package/dist/index.js CHANGED
@@ -16,6 +16,7 @@ export * from "./components/Modal/index.js";
16
16
  export * from "./components/ModalDialog/index.js";
17
17
  export * from "./components/Notifications/index.js";
18
18
  export * from "./components/Progress/index.js";
19
+ export * from "./components/SlidingPanels/index.js";
19
20
  export * from "./components/Spinner/index.js";
20
21
  export * from "./components/Switch/index.js";
21
22
  export * from "./components/TwCheck/index.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marianmeres/stuic",
3
- "version": "2.1.33",
3
+ "version": "2.2.1",
4
4
  "files": [
5
5
  "dist",
6
6
  "!dist/**/*.test.*",