@shellui/core 0.2.0-beta.4 → 0.2.0-beta.5
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/package.json +2 -2
- package/src/components/ui/sonner.tsx +28 -29
- package/src/index.css +6 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shellui/core",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.5",
|
|
4
4
|
"description": "ShellUI Core - Core React application runtime",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"workbox-routing": "^7.4.0",
|
|
59
59
|
"workbox-strategies": "^7.4.0",
|
|
60
60
|
"workbox-window": "^7.4.0",
|
|
61
|
-
"@shellui/sdk": "0.2.0-beta.
|
|
61
|
+
"@shellui/sdk": "0.2.0-beta.5"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -14,38 +14,37 @@ const TOAST_BUTTON_SELECTOR = '[data-close-button], [data-cancel], [data-action]
|
|
|
14
14
|
*/
|
|
15
15
|
function useToastButtonPointerFix() {
|
|
16
16
|
useEffect(() => {
|
|
17
|
-
const onPointerDown
|
|
17
|
+
const onPointerDown = (e: Event) => {
|
|
18
18
|
const ev = e as PointerEvent;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
// Only trigger programmatic click for touch/pen (iPad etc.); mouse gets native click.
|
|
20
|
+
if (ev.pointerType !== 'touch' && ev.pointerType !== 'pen') return;
|
|
21
|
+
// When a modal is open (e.g. Radix), body has pointer-events: none so the toaster
|
|
22
|
+
// may never receive the event on iPad. Use document capture + elementFromPoint so we
|
|
23
|
+
// still detect touches over the toaster and trigger the button.
|
|
24
|
+
const toaster = document.querySelector('[data-sonner-toaster]');
|
|
25
|
+
if (!toaster) return;
|
|
26
|
+
const elementUnderPoint = document.elementFromPoint(ev.clientX, ev.clientY);
|
|
27
|
+
if (!elementUnderPoint?.isConnected) return;
|
|
28
|
+
const button = (elementUnderPoint as HTMLElement).closest?.(TOAST_BUTTON_SELECTOR);
|
|
29
|
+
if (!button || !toaster.contains(button) || button.getAttribute('data-disabled') === 'true')
|
|
30
|
+
return;
|
|
31
|
+
ev.preventDefault();
|
|
32
|
+
ev.stopImmediatePropagation();
|
|
33
|
+
const clickEvent = new MouseEvent('click', {
|
|
34
|
+
bubbles: true,
|
|
35
|
+
cancelable: true,
|
|
36
|
+
view: ev.view ?? window,
|
|
37
|
+
detail: 1,
|
|
38
|
+
clientX: ev.clientX,
|
|
39
|
+
clientY: ev.clientY,
|
|
40
|
+
screenX: ev.screenX,
|
|
41
|
+
screenY: ev.screenY,
|
|
42
|
+
});
|
|
43
|
+
button.dispatchEvent(clickEvent);
|
|
26
44
|
};
|
|
27
45
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return () => toaster.removeEventListener('pointerdown', onPointerDown, true);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
let toaster = document.querySelector('[data-sonner-toaster]');
|
|
34
|
-
if (!toaster) {
|
|
35
|
-
let cancelled = false;
|
|
36
|
-
let cleanup: (() => void) | undefined;
|
|
37
|
-
const id = requestAnimationFrame(() => {
|
|
38
|
-
if (cancelled) return;
|
|
39
|
-
toaster = document.querySelector('[data-sonner-toaster]');
|
|
40
|
-
if (toaster) cleanup = attach(toaster);
|
|
41
|
-
});
|
|
42
|
-
return () => {
|
|
43
|
-
cancelled = true;
|
|
44
|
-
cancelAnimationFrame(id);
|
|
45
|
-
cleanup?.();
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
return attach(toaster);
|
|
46
|
+
document.addEventListener('pointerdown', onPointerDown, true);
|
|
47
|
+
return () => document.removeEventListener('pointerdown', onPointerDown, true);
|
|
49
48
|
}, []);
|
|
50
49
|
}
|
|
51
50
|
|
package/src/index.css
CHANGED
|
@@ -235,6 +235,12 @@
|
|
|
235
235
|
outline-color: hsl(var(--ring) / 0.5);
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
+
/* Toaster must receive pointer events when a modal has body pointer-events: none (e.g. Radix).
|
|
239
|
+
* Without this, pointerdown never fires on iPad when a modal is open. */
|
|
240
|
+
[data-sonner-toaster] {
|
|
241
|
+
pointer-events: auto !important;
|
|
242
|
+
}
|
|
243
|
+
|
|
238
244
|
/* Ensure Sonner toasts use theme variables - override Sonner defaults */
|
|
239
245
|
[data-sonner-toast] {
|
|
240
246
|
background-color: hsl(var(--background)) !important;
|