Skip to content

Commit b31b262

Browse files
committed
bump 📦
1 parent 7caf2a6 commit b31b262

4 files changed

Lines changed: 87 additions & 130 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sileo",
3-
"version": "0.0.7",
3+
"version": "0.0.8",
44
"description": "An opinionated, physics based toast notification library for react.",
55
"license": "MIT",
66
"repository": {

src/icons.tsx

Lines changed: 25 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1-
import type { SVGProps } from "react";
1+
import type { ReactNode, SVGProps } from "react";
22

3-
export const ArrowRight = () => (
3+
const Icon = ({
4+
title,
5+
children,
6+
...props
7+
}: SVGProps<SVGSVGElement> & { title: string; children: ReactNode }) => (
48
<svg
9+
{...props}
510
xmlns="http://www.w3.org/2000/svg"
611
width="16"
712
height="16"
@@ -12,102 +17,52 @@ export const ArrowRight = () => (
1217
strokeLinecap="round"
1318
strokeLinejoin="round"
1419
>
15-
<title>Arrow Right</title>
20+
<title>{title}</title>
21+
{children}
22+
</svg>
23+
);
24+
25+
export const ArrowRight = () => (
26+
<Icon title="Arrow Right">
1627
<path d="M5 12h14" />
1728
<path d="m12 5 7 7-7 7" />
18-
</svg>
29+
</Icon>
1930
);
2031

2132
export const LifeBuoy = () => (
22-
<svg
23-
xmlns="http://www.w3.org/2000/svg"
24-
width="16"
25-
height="16"
26-
viewBox="0 0 24 24"
27-
fill="none"
28-
stroke="currentColor"
29-
strokeWidth="2"
30-
strokeLinecap="round"
31-
strokeLinejoin="round"
32-
>
33-
<title>Life Buoy</title>
33+
<Icon title="Life Buoy">
3434
<circle cx="12" cy="12" r="10" />
3535
<path d="m4.93 4.93 4.24 4.24" />
3636
<path d="m14.83 9.17 4.24-4.24" />
3737
<path d="m14.83 14.83 4.24 4.24" />
3838
<path d="m9.17 14.83-4.24 4.24" />
3939
<circle cx="12" cy="12" r="4" />
40-
</svg>
40+
</Icon>
4141
);
4242

4343
export const LoaderCircle = (props: SVGProps<SVGSVGElement>) => (
44-
<svg
45-
{...props}
46-
xmlns="http://www.w3.org/2000/svg"
47-
width="16"
48-
height="16"
49-
viewBox="0 0 24 24"
50-
fill="none"
51-
stroke="currentColor"
52-
strokeWidth="2"
53-
strokeLinecap="round"
54-
strokeLinejoin="round"
55-
>
56-
<title>Loader Circle</title>
44+
<Icon title="Loader Circle" {...props}>
5745
<path d="M21 12a9 9 0 1 1-6.219-8.56" />
58-
</svg>
46+
</Icon>
5947
);
6048

6149
export const X = () => (
62-
<svg
63-
xmlns="http://www.w3.org/2000/svg"
64-
width="16"
65-
height="16"
66-
viewBox="0 0 24 24"
67-
fill="none"
68-
stroke="currentColor"
69-
strokeWidth="2"
70-
strokeLinecap="round"
71-
strokeLinejoin="round"
72-
>
73-
<title>X</title>
50+
<Icon title="X">
7451
<path d="M18 6 6 18" />
7552
<path d="m6 6 12 12" />
76-
</svg>
53+
</Icon>
7754
);
7855

7956
export const CircleAlert = () => (
80-
<svg
81-
xmlns="http://www.w3.org/2000/svg"
82-
width="16"
83-
height="16"
84-
viewBox="0 0 24 24"
85-
fill="none"
86-
stroke="currentColor"
87-
strokeWidth="2"
88-
strokeLinecap="round"
89-
strokeLinejoin="round"
90-
>
91-
<title>Circle Alert</title>
57+
<Icon title="Circle Alert">
9258
<circle cx="12" cy="12" r="10" />
9359
<line x1="12" x2="12" y1="8" y2="12" />
9460
<line x1="12" x2="12.01" y1="16" y2="16" />
95-
</svg>
61+
</Icon>
9662
);
9763

9864
export const Check = () => (
99-
<svg
100-
xmlns="http://www.w3.org/2000/svg"
101-
width="16"
102-
height="16"
103-
viewBox="0 0 24 24"
104-
fill="none"
105-
stroke="currentColor"
106-
strokeWidth="2"
107-
strokeLinecap="round"
108-
strokeLinejoin="round"
109-
>
110-
<title>Check</title>
65+
<Icon title="Check">
11166
<path d="M20 6 9 17l-5-5" />
112-
</svg>
67+
</Icon>
11368
);

src/sileo.css

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,10 @@
6060
background: transparent;
6161
padding: 0;
6262
width: var(--sileo-width);
63-
height: var(--sileo-button-height, var(--sileo-height));
63+
height: var(--_h, var(--sileo-height));
6464
opacity: 0;
6565
transform: translateZ(0) scale(0.95);
6666
transform-origin: center;
67-
filter: drop-shadow(0 0 8px rgba(0, 0, 0, 0.05));
6867
contain: layout style;
6968
overflow: visible;
7069
}
@@ -144,6 +143,17 @@
144143
transform-origin: 50% 0%;
145144
}
146145

146+
[data-sileo-pill] {
147+
transform: scaleY(var(--_sy, 1));
148+
width: var(--_pw);
149+
height: var(--_ph);
150+
}
151+
152+
[data-sileo-body] {
153+
transform: scaleY(var(--_by, 0));
154+
opacity: var(--_by, 0);
155+
}
156+
147157
[data-sileo-toast][data-ready="true"] [data-sileo-pill] {
148158
transition:
149159
transform var(--sileo-duration) var(--sileo-spring-easing),
@@ -174,10 +184,12 @@
174184
padding: 0.5rem;
175185
height: var(--sileo-height);
176186
overflow: hidden;
187+
left: var(--_px, 0px);
188+
transform: var(--_ht);
189+
max-width: var(--_pw);
177190
}
178191

179192
[data-sileo-toast][data-ready="true"] [data-sileo-header] {
180-
max-width: var(--sileo-pill-width);
181193
transition:
182194
transform var(--sileo-duration) var(--sileo-spring-easing),
183195
left var(--sileo-duration) var(--sileo-spring-easing),
@@ -207,10 +219,12 @@
207219
white-space: nowrap;
208220
opacity: 1;
209221
filter: blur(0px);
222+
will-change: opacity, filter;
210223
}
211224

212225
[data-sileo-header-inner][data-layer="current"] {
213-
animation: sileo-header-enter 1s var(--sileo-spring-easing) both;
226+
animation: sileo-header-enter var(--sileo-duration) var(--sileo-spring-easing)
227+
both;
214228
}
215229

216230
[data-sileo-header-inner][data-layer="prev"] {
@@ -286,6 +300,11 @@
286300
z-index: 10;
287301
width: 100%;
288302
pointer-events: none;
303+
opacity: var(--_co, 0);
304+
}
305+
306+
[data-sileo-content]:not([data-visible="true"]) {
307+
content-visibility: hidden;
289308
}
290309

291310
[data-sileo-toast][data-ready="true"] [data-sileo-content] {
@@ -457,22 +476,10 @@
457476
}
458477

459478
@media (prefers-reduced-motion: no-preference) {
460-
[data-sileo-toast][data-ready="true"] {
461-
will-change: transform, opacity;
462-
}
463-
464-
[data-sileo-toast][data-ready="true"][data-expanded="true"] {
479+
[data-sileo-toast][data-ready="true"]:hover,
480+
[data-sileo-toast][data-ready="true"][data-exiting="true"] {
465481
will-change: transform, opacity, height;
466482
}
467-
468-
[data-sileo-pill],
469-
[data-sileo-body] {
470-
will-change: transform;
471-
}
472-
473-
[data-sileo-canvas] {
474-
will-change: filter;
475-
}
476483
}
477484

478485
@media (prefers-reduced-motion: reduce) {

src/sileo.tsx

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,16 @@ export const Sileo = memo(function Sileo({
196196
}
197197
};
198198
measure();
199-
const ro = new ResizeObserver(measure);
199+
let rafId = 0;
200+
const ro = new ResizeObserver(() => {
201+
cancelAnimationFrame(rafId);
202+
rafId = requestAnimationFrame(measure);
203+
});
200204
ro.observe(el);
201-
return () => ro.disconnect();
205+
return () => {
206+
cancelAnimationFrame(rafId);
207+
ro.disconnect();
208+
};
202209
}, [headerLayer.current.key]);
203210

204211
useLayoutEffect(() => {
@@ -213,9 +220,16 @@ export const Sileo = memo(function Sileo({
213220
setContentHeight((prev) => (prev === h ? prev : h));
214221
};
215222
measure();
216-
const ro = new ResizeObserver(measure);
223+
let rafId = 0;
224+
const ro = new ResizeObserver(() => {
225+
cancelAnimationFrame(rafId);
226+
rafId = requestAnimationFrame(measure);
227+
});
217228
ro.observe(el);
218-
return () => ro.disconnect();
229+
return () => {
230+
cancelAnimationFrame(rafId);
231+
ro.disconnect();
232+
};
219233
}, [hasDesc]);
220234

221235
useEffect(() => {
@@ -364,33 +378,18 @@ export const Sileo = memo(function Sileo({
364378

365379
/* ------------------------------- Inline styles ---------------------------- */
366380

367-
const viewport = useMemo<CSSProperties>(
368-
() => ({ height: open ? expanded : HEIGHT }),
369-
[open, expanded],
370-
);
371-
const pill = useMemo<CSSProperties>(
381+
const rootStyle = useMemo<CSSProperties & Record<string, string>>(
372382
() => ({
373-
transform: `scaleY(${open ? 1 : HEIGHT / expanded})`,
374-
width: resolvedPillWidth,
375-
height: open ? expanded - 5 : expanded,
383+
"--_h": `${open ? expanded : HEIGHT}px`,
384+
"--_pw": `${resolvedPillWidth}px`,
385+
"--_px": `${pillX}px`,
386+
"--_sy": `${open ? 1 : HEIGHT / expanded}`,
387+
"--_ph": `${open ? expanded - 5 : expanded}px`,
388+
"--_by": `${open ? 1 : 0}`,
389+
"--_ht": `translateY(${open ? (expand === "bottom" ? 3 : -3) : 0}px) scale(${open ? 0.9 : 1})`,
390+
"--_co": `${open ? 1 : 0}`,
376391
}),
377-
[open, expanded, resolvedPillWidth],
378-
);
379-
const body = useMemo<CSSProperties>(
380-
() => ({ transform: `scaleY(${open ? 1 : 0})`, opacity: open ? 1 : 0 }),
381-
[open],
382-
);
383-
const header = useMemo(
384-
() => ({
385-
left: pillX,
386-
transform: `translateY(${open ? (expand === "bottom" ? 3 : -3) : 0}px) scale(${open ? 0.9 : 1})`,
387-
"--sileo-pill-width": `${resolvedPillWidth}px`,
388-
}),
389-
[pillX, open, expand, resolvedPillWidth],
390-
);
391-
const contentStyle = useMemo<CSSProperties>(
392-
() => ({ opacity: open ? 1 : 0 }),
393-
[open],
392+
[open, expanded, resolvedPillWidth, pillX, expand],
394393
);
395394

396395
/* -------------------------------- Handlers -------------------------------- */
@@ -461,8 +460,8 @@ export const Sileo = memo(function Sileo({
461460
}
462461
};
463462

464-
el.addEventListener("pointermove", onMove);
465-
el.addEventListener("pointerup", onUp);
463+
el.addEventListener("pointermove", onMove, { passive: true });
464+
el.addEventListener("pointerup", onUp, { passive: true });
466465
return () => {
467466
el.removeEventListener("pointermove", onMove);
468467
el.removeEventListener("pointerup", onUp);
@@ -472,6 +471,8 @@ export const Sileo = memo(function Sileo({
472471
const handlePointerDown = useCallback(
473472
(e: React.PointerEvent<HTMLButtonElement>) => {
474473
if (exiting || !onDismiss) return;
474+
const target = e.target as HTMLElement;
475+
if (target.closest("[data-sileo-button]")) return;
475476
pointerStartRef.current = e.clientY;
476477
e.currentTarget.setPointerCapture(e.pointerId);
477478
},
@@ -492,7 +493,7 @@ export const Sileo = memo(function Sileo({
492493
data-position={position}
493494
data-state={view.state}
494495
className={className}
495-
style={viewport}
496+
style={rootStyle}
496497
onMouseEnter={handleEnter}
497498
onMouseLeave={handleLeave}
498499
onTransitionEnd={handleTransitionEnd}
@@ -514,7 +515,6 @@ export const Sileo = memo(function Sileo({
514515
rx={resolvedRoundness}
515516
ry={resolvedRoundness}
516517
fill={view.fill}
517-
style={pill}
518518
/>
519519
<rect
520520
data-sileo-body
@@ -524,13 +524,12 @@ export const Sileo = memo(function Sileo({
524524
rx={resolvedRoundness}
525525
ry={resolvedRoundness}
526526
fill={view.fill}
527-
style={body}
528527
/>
529528
</g>
530529
</svg>
531530
</div>
532531

533-
<div ref={headerRef} data-sileo-header data-edge={expand} style={header}>
532+
<div ref={headerRef} data-sileo-header data-edge={expand}>
534533
<div data-sileo-header-stack>
535534
<div
536535
ref={innerRef}
@@ -582,12 +581,7 @@ export const Sileo = memo(function Sileo({
582581
</div>
583582

584583
{hasDesc && (
585-
<div
586-
data-sileo-content
587-
data-edge={expand}
588-
data-visible={open}
589-
style={contentStyle}
590-
>
584+
<div data-sileo-content data-edge={expand} data-visible={open}>
591585
<div
592586
ref={contentRef}
593587
data-sileo-description
@@ -598,6 +592,7 @@ export const Sileo = memo(function Sileo({
598592
// biome-ignore lint/a11y/useValidAnchor: cannot use button inside a button
599593
<a
600594
href="#"
595+
type="button"
601596
data-sileo-button
602597
data-state={view.state}
603598
className={view.styles?.button}

0 commit comments

Comments
 (0)