Skip to content

Commit b4626a2

Browse files
authoredFeb 28, 2023
Fix toast ESM build and SSR support (adobe#4124)
1 parent d7cb26e commit b4626a2

File tree

8 files changed

+73
-9
lines changed

8 files changed

+73
-9
lines changed
 

‎examples/rsp-next-ts/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"dependencies": {
1515
"@adobe/react-spectrum": "^3.22.0",
1616
"@react-spectrum/color": "^3.0.0-beta.16",
17+
"@react-spectrum/toast": "^3.0.0-alpha.0",
1718
"@spectrum-icons/illustrations": "^3.5.0",
1819
"@spectrum-icons/workflow": "^4.0.3",
1920
"next": "^13.1.1",

‎examples/rsp-next-ts/pages/_app.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { ColorScheme } from "@react-types/provider";
1313
import { useState } from "react";
1414
import Moon from "@spectrum-icons/workflow/Moon";
1515
import Light from "@spectrum-icons/workflow/Light";
16+
import { ToastContainer } from "@react-spectrum/toast";
1617

1718
function MyApp({ Component, pageProps }: AppProps) {
1819
const [theme, setTheme] = useState<ColorScheme>("light");
@@ -46,6 +47,7 @@ function MyApp({ Component, pageProps }: AppProps) {
4647
<Component {...pageProps} />
4748
</View>
4849
</Grid>
50+
<ToastContainer />
4951
</Provider>
5052
</SSRProvider>
5153
);

‎examples/rsp-next-ts/pages/index.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ import {
8080
ColorWheel,
8181
} from "@react-spectrum/color";
8282
import ReorderableListView from "../components/ReorderableListView";
83+
import {ToastQueue} from '@react-spectrum/toast';
8384

8485
export default function Home() {
8586
let [isDialogOpen, setIsDialogOpen] = useState(false);
@@ -138,7 +139,7 @@ export default function Home() {
138139
<ReorderableListView />
139140
<MenuTrigger>
140141
<ActionButton>Menu</ActionButton>
141-
<Menu onAction={(key) => alert(key)}>
142+
<Menu onAction={(key) => ToastQueue.positive(key)}>
142143
<Item key="cut">Cut</Item>
143144
<Item key="copy">Copy</Item>
144145
<Item key="paste">Paste</Item>

‎packages/@react-aria/landmark/src/useLandmark.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import {AriaLabelingProps, DOMAttributes, FocusableElement} from '@react-types/shared';
1414
import {MutableRefObject, useCallback, useEffect, useState} from 'react';
1515
import {useLayoutEffect} from '@react-aria/utils';
16-
import {useSyncExternalStore} from 'use-sync-external-store/shim';
16+
import {useSyncExternalStore} from 'use-sync-external-store/shim/index.js';
1717

1818
export type AriaLandmarkRole = 'main' | 'region' | 'search' | 'navigation' | 'form' | 'banner' | 'contentinfo' | 'complementary';
1919

@@ -85,7 +85,11 @@ function subscribe(fn: () => void) {
8585
return () => document.removeEventListener('react-aria-landmark-manager-change', fn);
8686
}
8787

88-
function getLandmarkManager(): LandmarkManagerApi {
88+
function getLandmarkManager(): LandmarkManagerApi | null {
89+
if (typeof document === 'undefined') {
90+
return null;
91+
}
92+
8993
// Reuse an existing instance if it has the same or greater version.
9094
let instance = document[landmarkSymbol];
9195
if (instance && instance.version >= LANDMARK_API_VERSION) {
@@ -100,8 +104,8 @@ function getLandmarkManager(): LandmarkManagerApi {
100104
}
101105

102106
// Subscribes a React component to the current landmark manager instance.
103-
function useLandmarkManager(): LandmarkManagerApi {
104-
return useSyncExternalStore(subscribe, getLandmarkManager);
107+
function useLandmarkManager(): LandmarkManagerApi | null {
108+
return useSyncExternalStore(subscribe, getLandmarkManager, getLandmarkManager);
105109
}
106110

107111
class LandmarkManager implements LandmarkManagerApi {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2023 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
import {testSSR} from '@react-spectrum/test-utils';
14+
15+
describe('useLandmark SSR', function () {
16+
it('should render without errors', async function () {
17+
await testSSR(__filename, `
18+
import {useLandmark} from '../';
19+
20+
function Main(props) {
21+
let ref = React.useRef();
22+
let {landmarkProps} = useLandmark({...props, role: 'main'}, ref);
23+
return <main ref={ref} {...landmarkProps}>{props.children}</main>;
24+
}
25+
26+
<Main />
27+
`);
28+
});
29+
});

‎packages/@react-spectrum/toast/src/ToastContainer.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import React, {ReactElement, ReactNode, useEffect, useRef} from 'react';
1515
import {SpectrumToastValue, Toast} from './Toast';
1616
import {Toaster} from './Toaster';
1717
import {ToastOptions, ToastQueue, useToastQueue} from '@react-stately/toast';
18-
import {useSyncExternalStore} from 'use-sync-external-store/shim';
18+
import {useSyncExternalStore} from 'use-sync-external-store/shim/index.js';
1919

2020
export interface SpectrumToastContainerProps extends AriaToastRegionProps {}
2121

@@ -60,7 +60,7 @@ function getActiveToastContainer() {
6060
}
6161

6262
function useActiveToastContainer() {
63-
return useSyncExternalStore(subscribe, getActiveToastContainer);
63+
return useSyncExternalStore(subscribe, getActiveToastContainer, getActiveToastContainer);
6464
}
6565

6666
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2023 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
import {testSSR} from '@react-spectrum/test-utils';
14+
15+
describe('ToastContainer SSR', function () {
16+
it('should render without errors', async function () {
17+
await testSSR(__filename, `
18+
import {Provider} from '@react-spectrum/provider';
19+
import {theme} from '@react-spectrum/theme-default';
20+
import {ToastContainer} from '../';
21+
22+
<Provider theme={theme}>
23+
<ToastContainer />
24+
</Provider>
25+
`);
26+
});
27+
});

‎packages/@react-stately/toast/src/useToastState.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import {useCallback, useMemo} from 'react';
1414
// Shim to support React 17 and below.
15-
import {useSyncExternalStore} from 'use-sync-external-store/shim';
15+
import {useSyncExternalStore} from 'use-sync-external-store/shim/index.js';
1616

1717
export interface ToastStateProps {
1818
/** The maximum number of toasts to display at a time. */
@@ -79,7 +79,7 @@ export function useToastState<T>(props: ToastStateProps = {}): ToastState<T> {
7979
export function useToastQueue<T>(queue: ToastQueue<T>): ToastState<T> {
8080
let subscribe = useCallback(fn => queue.subscribe(fn), [queue]);
8181
let getSnapshot = useCallback(() => queue.visibleToasts, [queue]);
82-
let visibleToasts = useSyncExternalStore(subscribe, getSnapshot);
82+
let visibleToasts = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
8383

8484
return {
8585
visibleToasts,

0 commit comments

Comments
 (0)
Failed to load comments.