Skip to content

Commit ceb0176

Browse files
authored
Merge branch 'main' into subscribe-earlier
2 parents f08b61b + fe51da1 commit ceb0176

File tree

8 files changed

+38
-5
lines changed

8 files changed

+38
-5
lines changed

src/assets.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export const getAsset = (type: ToastTypes): JSX.Element | null => {
2323

2424
const bars = Array(12).fill(0);
2525

26-
export const Loader = ({ visible, className }: { visible: boolean, className?: string }) => {
26+
export const Loader = ({ visible, className }: { visible: boolean; className?: string }) => {
2727
return (
2828
<div className={['sonner-loading-wrapper', className].filter(Boolean).join(' ')} data-visible={visible}>
2929
<div className="sonner-spinner">

src/hooks.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export const useIsDocumentHidden = () => {
1010
setIsDocumentHidden(document.hidden);
1111
};
1212
document.addEventListener('visibilitychange', callback);
13-
return () => window.removeEventListener('visibilitychange', callback);
13+
return () => document.removeEventListener('visibilitychange', callback);
1414
}, []);
1515

1616
return isDocumentHidden;

src/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,7 @@ const Toaster = React.forwardRef<HTMLElement, ToasterProps>(function Toaster(pro
627627
dir = getDocumentDirection(),
628628
gap = GAP,
629629
icons,
630+
customAriaLabel,
630631
containerAriaLabel = 'Notifications',
631632
} = props;
632633
const [toasts, setToasts] = React.useState<ToastT[]>([]);
@@ -764,7 +765,7 @@ const Toaster = React.forwardRef<HTMLElement, ToasterProps>(function Toaster(pro
764765

765766
React.useEffect(() => {
766767
const handleKeyDown = (event: KeyboardEvent) => {
767-
const isHotkeyPressed = hotkey.every((key) => (event as any)[key] || event.code === key);
768+
const isHotkeyPressed = hotkey.length > 0 && hotkey.every((key) => (event as any)[key] || event.code === key);
768769

769770
if (isHotkeyPressed) {
770771
setExpanded(true);
@@ -799,12 +800,13 @@ const Toaster = React.forwardRef<HTMLElement, ToasterProps>(function Toaster(pro
799800
// Remove item from normal navigation flow, only available via hotkey
800801
<section
801802
ref={ref}
802-
aria-label={`${containerAriaLabel} ${hotkeyLabel}`}
803+
aria-label={customAriaLabel ?? `${containerAriaLabel} ${hotkeyLabel}`}
803804
tabIndex={-1}
804805
aria-live="polite"
805806
aria-relevant="additions text"
806807
aria-atomic="false"
807808
suppressHydrationWarning
809+
data-react-aria-top-layer
808810
>
809811
{possiblePositions.map((position, index) => {
810812
const [y, x] = position.split('-');

src/state.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ class Observer {
242242

243243
custom = (jsx: (id: number | string) => React.ReactElement, data?: ExternalToast) => {
244244
const id = data?.id || toastsCounter++;
245-
this.create({ jsx: jsx(id), id, ...data });
245+
this.create({ jsx: jsx(id), ...data, id });
246246
return id;
247247
};
248248

src/styles.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ html[dir='rtl'],
348348
}
349349

350350
[data-sonner-toast][data-swiped='true'] {
351+
-webkit-user-select: none; /* Safari 3+ */
351352
user-select: none;
352353
}
353354

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ export interface ToasterProps {
145145
dir?: 'rtl' | 'ltr' | 'auto';
146146
swipeDirections?: SwipeDirection[];
147147
icons?: ToastIcons;
148+
customAriaLabel?: string;
148149
containerAriaLabel?: string;
149150
}
150151

test/src/app/page.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,27 @@ export default function Home({ searchParams }: any) {
121121
>
122122
Render Custom Cancel Button
123123
</button>
124+
<button
125+
data-testid="custom-with-empty-id"
126+
className="button"
127+
onClick={() =>
128+
toast.custom(
129+
(t) => (
130+
<div>
131+
<h1>jsx</h1>
132+
<button data-testid="dismiss-button" onClick={() => toast.dismiss(t)}>
133+
Dismiss
134+
</button>
135+
</div>
136+
),
137+
{
138+
id: undefined,
139+
},
140+
)
141+
}
142+
>
143+
Render Custom Toast with empty id
144+
</button>
124145
<button data-testid="infinity-toast" className="button" onClick={() => toast('My Toast', { duration: Infinity })}>
125146
Render Infinity Toast
126147
</button>

test/tests/basic.spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,14 @@ test.describe('Basic functionality', () => {
270270
await expect(button).toHaveCSS('background-color', 'rgb(254, 226, 226)');
271271
});
272272

273+
test('cancel button dismisses the custom toast with empty id', async ({ page }) => {
274+
await page.getByTestId('custom-with-empty-id').click();
275+
276+
await expect(page.locator('[data-sonner-toast]')).toHaveCount(1);
277+
await page.locator('[data-dismiss]').click();
278+
await expect(page.locator('[data-sonner-toast]')).toHaveCount(0);
279+
});
280+
273281
test('action button is rendered with custom styles', async ({ page }) => {
274282
await page.getByTestId('action').click();
275283
const button = await page.locator('[data-button]');

0 commit comments

Comments
 (0)