@marianmeres/stuic 2.59.0 → 2.61.0
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/tooltip/tooltip.svelte.d.ts +20 -0
- package/dist/actions/tooltip/tooltip.svelte.js +41 -1
- package/dist/components/AppShell/AppShellSimple.svelte +5 -2
- package/dist/components/Backdrop/Backdrop.svelte +13 -7
- package/dist/components/Backdrop/Backdrop.svelte.d.ts +1 -0
- package/dist/components/Input/_internal/InputWrap.svelte +1 -0
- package/dist/components/Modal/Modal.svelte +4 -0
- package/dist/components/Modal/Modal.svelte.d.ts +2 -0
- package/dist/index.css +8 -1
- package/package.json +1 -1
|
@@ -45,6 +45,26 @@ export type TooltipConfig = () => {
|
|
|
45
45
|
onShow?: CallableFunction;
|
|
46
46
|
onHide?: CallableFunction;
|
|
47
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* Globally enable or disable all tooltips.
|
|
50
|
+
* Useful for disabling tooltips on touch devices where they interfere with interactions.
|
|
51
|
+
*
|
|
52
|
+
* @param value - `true` to enable tooltips, `false` to disable
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* // Disable tooltips on touch devices
|
|
57
|
+
* if ('ontouchstart' in window) {
|
|
58
|
+
* setTooltipsEnabled(false);
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function setTooltipsEnabled(value: boolean): void;
|
|
63
|
+
/**
|
|
64
|
+
* Get the current global tooltip enabled state.
|
|
65
|
+
* @returns `true` if tooltips are globally enabled, `false` otherwise
|
|
66
|
+
*/
|
|
67
|
+
export declare function getTooltipsEnabled(): boolean;
|
|
48
68
|
/**
|
|
49
69
|
* A Svelte action that displays a tooltip anchored to an element using CSS Anchor Positioning.
|
|
50
70
|
*
|
|
@@ -48,6 +48,44 @@ const POSITION_MAP = {
|
|
|
48
48
|
left: "left",
|
|
49
49
|
right: "right",
|
|
50
50
|
};
|
|
51
|
+
// Global tooltip configuration - allows disabling all tooltips at runtime
|
|
52
|
+
const globalTooltipConfig = $state({ enabled: true });
|
|
53
|
+
// Touch device auto-detection (runs once on first tooltip init)
|
|
54
|
+
let touchDetectionDone = false;
|
|
55
|
+
function detectTouchDevice() {
|
|
56
|
+
if (touchDetectionDone)
|
|
57
|
+
return;
|
|
58
|
+
touchDetectionDone = true;
|
|
59
|
+
// Detect touch device and disable tooltips by default
|
|
60
|
+
const isTouchDevice = "ontouchstart" in window || navigator.maxTouchPoints > 0;
|
|
61
|
+
if (isTouchDevice) {
|
|
62
|
+
globalTooltipConfig.enabled = false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Globally enable or disable all tooltips.
|
|
67
|
+
* Useful for disabling tooltips on touch devices where they interfere with interactions.
|
|
68
|
+
*
|
|
69
|
+
* @param value - `true` to enable tooltips, `false` to disable
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* // Disable tooltips on touch devices
|
|
74
|
+
* if ('ontouchstart' in window) {
|
|
75
|
+
* setTooltipsEnabled(false);
|
|
76
|
+
* }
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export function setTooltipsEnabled(value) {
|
|
80
|
+
globalTooltipConfig.enabled = value;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get the current global tooltip enabled state.
|
|
84
|
+
* @returns `true` if tooltips are globally enabled, `false` otherwise
|
|
85
|
+
*/
|
|
86
|
+
export function getTooltipsEnabled() {
|
|
87
|
+
return globalTooltipConfig.enabled;
|
|
88
|
+
}
|
|
51
89
|
/**
|
|
52
90
|
* A Svelte action that displays a tooltip anchored to an element using CSS Anchor Positioning.
|
|
53
91
|
*
|
|
@@ -88,6 +126,8 @@ export function tooltip(anchorEl, fn) {
|
|
|
88
126
|
// the node has been mounted in the DOM
|
|
89
127
|
if (!isTooltipSupported())
|
|
90
128
|
return;
|
|
129
|
+
// Auto-detect touch device on first tooltip init
|
|
130
|
+
detectTouchDevice();
|
|
91
131
|
//
|
|
92
132
|
let tooltipEl;
|
|
93
133
|
let hide_timer = null;
|
|
@@ -215,7 +255,7 @@ export function tooltip(anchorEl, fn) {
|
|
|
215
255
|
on_hide = onHide;
|
|
216
256
|
content = _content || anchorEl.getAttribute("aria-label");
|
|
217
257
|
classTooltip = _classTooltip;
|
|
218
|
-
enabled = _enabled ?? true;
|
|
258
|
+
enabled = globalTooltipConfig.enabled && (_enabled ?? true);
|
|
219
259
|
position = _position || "top";
|
|
220
260
|
// this will be effective here only if currently in open state, otherwise noop
|
|
221
261
|
set_content();
|
|
@@ -50,6 +50,9 @@
|
|
|
50
50
|
|
|
51
51
|
let headerHeight = $state(0);
|
|
52
52
|
|
|
53
|
+
// Safari was showing scrollbar so adding 1px extra which solves the problem
|
|
54
|
+
let topOffset = $derived(headerHeight + 1);
|
|
55
|
+
|
|
53
56
|
// pragmatic use case...
|
|
54
57
|
let mainWidth: number = $state(0);
|
|
55
58
|
setContext(APP_SHELL_SIMPLE_MAIN_WIDTH, {
|
|
@@ -77,7 +80,7 @@
|
|
|
77
80
|
bind:this={elRail}
|
|
78
81
|
data-shell="rail"
|
|
79
82
|
style:top="{headerHeight}px"
|
|
80
|
-
style:height="calc(100dvh - {
|
|
83
|
+
style:height="calc(100dvh - {topOffset}px)"
|
|
81
84
|
class={twMerge(
|
|
82
85
|
"sticky shrink-0",
|
|
83
86
|
"flex flex-col items-center",
|
|
@@ -95,7 +98,7 @@
|
|
|
95
98
|
bind:this={elAside}
|
|
96
99
|
data-shell="aside"
|
|
97
100
|
style:top="{headerHeight}px"
|
|
98
|
-
style:height="calc(100dvh - {
|
|
101
|
+
style:height="calc(100dvh - {topOffset}px)"
|
|
99
102
|
class={twMerge(
|
|
100
103
|
"sticky shrink-0",
|
|
101
104
|
"flex flex-col items-center",
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
2
|
import type { Snippet } from "svelte";
|
|
3
3
|
import type { FocusTrapOptions } from "../../actions/focus-trap.js";
|
|
4
|
+
import { BodyScroll, focusTrap as focusTrapAction, twMerge } from "../../index.js";
|
|
5
|
+
import { createClog } from "@marianmeres/clog";
|
|
6
|
+
import { watch } from "runed";
|
|
7
|
+
import { onDestroy } from "svelte";
|
|
8
|
+
import { fade } from "svelte/transition";
|
|
4
9
|
|
|
5
10
|
export interface Props extends Record<string, any> {
|
|
6
11
|
class?: string;
|
|
@@ -11,6 +16,7 @@
|
|
|
11
16
|
el?: HTMLDivElement;
|
|
12
17
|
children?: Snippet;
|
|
13
18
|
onEscape?: () => void;
|
|
19
|
+
onBackdropClick?: () => void;
|
|
14
20
|
visible?: boolean;
|
|
15
21
|
noScrollLock?: boolean;
|
|
16
22
|
}
|
|
@@ -20,13 +26,7 @@
|
|
|
20
26
|
</script>
|
|
21
27
|
|
|
22
28
|
<script lang="ts">
|
|
23
|
-
|
|
24
|
-
import { createClog } from "@marianmeres/clog";
|
|
25
|
-
import { watch } from "runed";
|
|
26
|
-
import { onDestroy } from "svelte";
|
|
27
|
-
import { fade } from "svelte/transition";
|
|
28
|
-
|
|
29
|
-
const clog = createClog("Backdrop").debug;
|
|
29
|
+
const clog = createClog("Backdrop", { color: "auto" });
|
|
30
30
|
|
|
31
31
|
let {
|
|
32
32
|
class: classProp,
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
el = $bindable(),
|
|
38
38
|
children,
|
|
39
39
|
onEscape,
|
|
40
|
+
onBackdropClick,
|
|
40
41
|
visible = $bindable(false),
|
|
41
42
|
noScrollLock,
|
|
42
43
|
...rest
|
|
@@ -152,6 +153,11 @@
|
|
|
152
153
|
in:fade={{ duration: fadeInDuration }}
|
|
153
154
|
out:fade={{ duration: fadeOutDuration }}
|
|
154
155
|
use:focusTrapAction={focusTrapOptions}
|
|
156
|
+
onmousedown={(e) => {
|
|
157
|
+
if (e.target === el && onBackdropClick) {
|
|
158
|
+
onBackdropClick();
|
|
159
|
+
}
|
|
160
|
+
}}
|
|
155
161
|
{...rest}
|
|
156
162
|
>
|
|
157
163
|
{@render children?.()}
|
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
onEscape?: undefined | (() => void);
|
|
30
30
|
/** Disable body scroll lock when modal is open */
|
|
31
31
|
noScrollLock?: boolean;
|
|
32
|
+
/** Fires when the backdrop is clicked "directly" */
|
|
33
|
+
onBackdropClick?: undefined | (() => void);
|
|
32
34
|
}
|
|
33
35
|
</script>
|
|
34
36
|
|
|
@@ -59,6 +61,7 @@
|
|
|
59
61
|
focusTrap = true,
|
|
60
62
|
onEscape,
|
|
61
63
|
noScrollLock = false,
|
|
64
|
+
onBackdropClick,
|
|
62
65
|
}: Props = $props();
|
|
63
66
|
|
|
64
67
|
let backdrop: Backdrop = $state()!;
|
|
@@ -94,6 +97,7 @@
|
|
|
94
97
|
fadeOutDuration={transitionDuration}
|
|
95
98
|
{onEscape}
|
|
96
99
|
{noScrollLock}
|
|
100
|
+
{onBackdropClick}
|
|
97
101
|
>
|
|
98
102
|
<div
|
|
99
103
|
bind:this={el}
|
|
@@ -27,6 +27,8 @@ export interface Props {
|
|
|
27
27
|
onEscape?: undefined | (() => void);
|
|
28
28
|
/** Disable body scroll lock when modal is open */
|
|
29
29
|
noScrollLock?: boolean;
|
|
30
|
+
/** Fires when the backdrop is clicked "directly" */
|
|
31
|
+
onBackdropClick?: undefined | (() => void);
|
|
30
32
|
}
|
|
31
33
|
declare const Modal: import("svelte").Component<Props, {
|
|
32
34
|
close: () => void;
|
package/dist/index.css
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
/*
|
|
2
|
+
Tailwind import removed here because it causes CSS cascade/layer issues in WebKit browsers
|
|
3
|
+
(Safari, iOS Chrome) when consumers also import Tailwind. The double import can result in
|
|
4
|
+
Tailwind's preflight styles (like border-style: solid) not being applied correctly.
|
|
5
|
+
Consumers of STUIC should import Tailwind at their own app level.
|
|
6
|
+
*/
|
|
7
|
+
/* @import "tailwindcss"; */
|
|
8
|
+
|
|
2
9
|
@plugin '@tailwindcss/forms';
|
|
3
10
|
|
|
4
11
|
@custom-variant dark (&:where(.dark, .dark *));
|