react-dom/server#renderToString TypeScript Examples
The following examples show how to use
react-dom/server#renderToString.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: IconButton.tsx From lucide with ISC License | 6 votes |
function IconButton({ name, component: IconComponent }: IconButtonProps) {
const onIconClick = () => {
const svg = renderToString(<IconComponent/>);
parent.postMessage({ pluginMessage: {
type: 'drawIcon',
icon: { name, svg }
}}, '*')
}
return (
<button
key={name}
aria-label={name}
onClick={onIconClick}
className='icon-button'
>
<IconComponent />
</button>
)
}
Example #2
Source File: article.tsx From fluent-reader with BSD 3-Clause "New" or "Revised" License | 6 votes |
articleView = () => {
const a = encodeURIComponent(
this.state.loadFull
? this.state.fullContent
: this.props.item.content
)
const h = encodeURIComponent(
renderToString(
<>
<p className="title">{this.props.item.title}</p>
<p className="date">
{this.props.item.date.toLocaleString(
this.props.locale,
{ hour12: !this.props.locale.startsWith("zh") }
)}
</p>
<article></article>
</>
)
)
return `article/article.html?a=${a}&h=${h}&f=${encodeURIComponent(
this.state.fontFamily
)}&s=${this.state.fontSize}&d=${this.props.source.textDir}&u=${
this.props.item.link
}&m=${this.state.loadFull ? 1 : 0}`
}
Example #3
Source File: render.tsx From cra-serverless with MIT License | 6 votes |
render = (Tree: React.ElementType, path: string) => {
const context = { helmet: {} as HelmetData }
const sheets = new ServerStyleSheet()
const markup = renderToString(
sheets.collectStyles(
<HelmetProvider context={context}>
<StaticRouter location={path}>
<Tree />
</StaticRouter>
</HelmetProvider>,
),
)
return html
.replace('<div id="root"></div>', `<div id="root">${markup}</div>`)
.replace('<title>React App</title>', context.helmet.title.toString())
.replace('</head>', `${context.helmet.meta.toString()}</head>`)
.replace('</head>', `${context.helmet.link.toString()}</head>`)
.replace('</head>', `${sheets.getStyleTags()}</head>`)
.replace('<body>', `<body ${context.helmet.bodyAttributes.toString()}>`)
}
Example #4
Source File: expectToBeDefault404Page.tsx From next-page-tester with MIT License | 6 votes |
export function expectToBeDefault404Page(actual: Element): void {
const expectedHtml = renderToString(
<div id={NEXT_ROOT_ELEMENT_ID}>
<ErrorPage statusCode={404} />
</div>
);
const expectedDocument = parseHTML(expectedHtml);
const expected = expectedDocument.getElementById(NEXT_ROOT_ELEMENT_ID);
if (!expected) {
throw new InternalError(`Missing ${NEXT_ROOT_ELEMENT_ID} div`);
}
expectDOMElementsToMatch(actual, expected);
}
Example #5
Source File: top-tracks.ts From natemoo-re with MIT License | 6 votes |
export default async function (req: NowRequest, res: NowResponse) {
let { i, open } = req.query;
i = Array.isArray(i) ? i[0] : i;
const item = await topTrack({ index: Number.parseInt(i) });
if (!item) {
return res.status(404).end();
}
if (typeof open !== "undefined") {
if (item && item.external_urls) {
res.writeHead(302, {
Location: item.external_urls.spotify,
});
return res.end();
}
return res.status(200).end();
}
res.setHeader("Content-Type", "image/svg+xml");
res.setHeader("Cache-Control", "s-maxage=1, stale-while-revalidate");
const { name: track } = item;
const { images = [] } = item.album || {};
const cover = images[images.length - 1]?.url;
let coverImg = null;
if (cover) {
const buff = await (await fetch(cover)).arrayBuffer();
coverImg = `data:image/jpeg;base64,${Buffer.from(buff).toString("base64")}`;
}
const artist = (item.artists || []).map(({ name }) => name).join(", ");
const text = renderToString(
Track({ index: Number.parseInt(i), cover: coverImg, artist, track })
);
return res.status(200).send(text);
}
Example #6
Source File: now-playing.ts From natemoo-re with MIT License | 6 votes |
export default async function (req: NowRequest, res: NowResponse) {
const {
item = ({} as any),
is_playing: isPlaying = false,
progress_ms: progress = 0,
} = await nowPlaying();
const params = decode(req.url.split("?")[1]) as any;
if (params && typeof params.open !== "undefined") {
if (item && item.external_urls) {
res.writeHead(302, {
Location: item.external_urls.spotify,
});
return res.end();
}
return res.status(200).end();
}
res.setHeader("Content-Type", "image/svg+xml");
res.setHeader("Cache-Control", "s-maxage=1, stale-while-revalidate");
const { duration_ms: duration, name: track } = item;
const { images = [] } = item.album || {};
const cover = images[images.length - 1]?.url;
let coverImg = null;
if (cover) {
const buff = await (await fetch(cover)).arrayBuffer();
coverImg = `data:image/jpeg;base64,${Buffer.from(buff).toString("base64")}`;
}
const artist = (item.artists || []).map(({ name }) => name).join(", ");
const text = renderToString(
Player({ cover: coverImg, artist, track, isPlaying, progress, duration })
);
return res.status(200).send(text);
}
Example #7
Source File: [num].ts From natemoo-re with MIT License | 6 votes |
export default async function (req: NowRequest, res: NowResponse) {
const { query: { num }, headers } = req;
const index = Number.parseInt(num as string) - 1;
const dest = headers["sec-fetch-dest"] || headers["Sec-Fetch-Dest"];
const accept = headers['accept'];
const image = dest ? dest === 'image' : !/text\/html/.test(accept);
const color = await getBlockColor(index);
if (image) {
const svg = renderToString(Block({ color }));
const etag = createHash("md5").update(svg).digest("hex");
res.setHeader("Content-Type", "image/svg+xml");
res.setHeader("Cache-Control", "no-cache, max-age=0");
res.setHeader("Etag", etag);
return res.status(200).send(svg);
}
const newColor: string = getNextColor(color);
await setBlockColor(index, newColor);
return res.status(204).end();
}
Example #8
Source File: worker.ts From lucide with ISC License | 6 votes |
getSvg = async ({ cachedIcons, iconName, size = 24 }: { cachedIcons: LucideIcons, iconName: string, size: number }) => {
if (!cachedIcons) {
return;
}
console.log( iconName, size)
const iconNode = cachedIcons.iconNodes[iconName];
if (iconNode) {
const IconComponent = createReactComponent(iconName, iconNode)
const svg = renderToString(createElement(IconComponent, { size }));
parent.postMessage({ pluginMessage: {
type: 'drawIcon',
icon: {
name: iconName,
svg,
size
}
}}, '*')
parent.postMessage({ pluginMessage: {
type: 'close',
}}, '*')
}
}
Example #9
Source File: MapClusterMarker.tsx From Teyvat.moe with GNU General Public License v3.0 | 6 votes |
createClusterIcon = (cluster: leaflet.MarkerCluster): L.DivIcon => {
const childMarkers = cluster.getAllChildMarkers() as LExtendedMarker[];
const childCount = childMarkers.length;
// Filter by the 'completed' property of each marker.
const childMarkersCompleted = _.filter(childMarkers, 'completed');
const childCompletedCount = childMarkersCompleted.length;
const iconUrl = childMarkers?.[0]?.clusterIconUrl ?? '';
// Since createClusterIcon is called by Leaflet, we can't use makeStyles.
// We have to use hard-coded classnames, then define the styles in index.css.
const iconHTML = renderToString(
<>
<img
className="map-marker-cluster-marker"
src="/images/icons/marker/marker_blue_bg.svg"
alt=""
/>
<b className="map-marker-cluster-label">
{childCompletedCount}/{childCount}
</b>
<img className="map-marker-cluster-img" src={iconUrl} alt="" />
</>
);
const iconSize = 36 + childCount / 3;
return leaflet.divIcon({
html: iconHTML,
className: 'map-marker-cluster',
iconSize: [iconSize, iconSize], // size of the icon
shadowSize: [iconSize, iconSize], // size of the shadow
iconAnchor: [iconSize / 2, iconSize * 0.95],
});
}
Example #10
Source File: entry.server.tsx From geist-ui with MIT License | 6 votes |
export default function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext,
) {
let markup = renderToString(<RemixServer context={remixContext} url={request.url} />)
markup = markup.replace('__STYLES__', CssBaseline.flushToHTML())
responseHeaders.set('Content-Type', 'text/html')
return new Response('<!DOCTYPE html>' + markup, {
status: responseStatusCode,
headers: responseHeaders,
})
}
Example #11
Source File: ssr.test.tsx From frontend-frameworks with MIT License | 6 votes |
describe('ssr', () => {
it('should render accessibility transformation with accessibility', function (done) {
const ElementImageHtml = renderToString(<AdvancedImage cldImg={cloudinaryImage} plugins={[accessibility()]} />);
setTimeout(() => {
expect(ElementImageHtml).toContain('https://res.cloudinary.com/demo/image/upload/co_black,e_colorize:70/sample');
done();
}, 0);// one tick
});
it('should render the placeholder image in SSR', function (done) {
const ElementImageHtml = renderToString(<AdvancedImage cldImg={cloudinaryImage} plugins={[placeholder()]} />);
setTimeout(() => {
expect(ElementImageHtml).toContain('https://res.cloudinary.com/demo/image/upload/e_vectorize/q_auto/f_svg/sample');
done();
}, 0);// one tick
});
it('should render original image when responsive', function (done) {
const ElementImageHtml = renderToString(<AdvancedImage cldImg={cloudinaryImage} plugins={[responsive()]} />);
setTimeout(() => {
expect(ElementImageHtml).toContain('https://res.cloudinary.com/demo/image/upload/sample');
done();
}, 0);// one tick
});
it('should render original image when lazy loaded', function (done) {
const ElementImageHtml = renderToString(<AdvancedImage cldImg={cloudinaryImage} plugins={[lazyload()]} />);
setTimeout(() => {
expect(ElementImageHtml).toContain('https://res.cloudinary.com/demo/image/upload/sample');
done();
}, 0);// one tick
});
});
Example #12
Source File: entry.server.tsx From tweet2image with MIT License | 6 votes |
export default function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext
) {
const markup = renderToString(
<RemixServer context={remixContext} url={request.url} />
)
responseHeaders.set("Content-Type", "text/html")
return new Response("<!DOCTYPE html>" + markup, {
status: responseStatusCode,
headers: responseHeaders,
})
}
Example #13
Source File: RegionLabelLayer.tsx From Teyvat.moe with GNU General Public License v3.0 | 6 votes |
_RegionLabelLayer: FunctionComponent<RegionLabelLayerProps> = ({ displayed, zoomLevel }) => {
const classes = useStyles();
const map = useMap();
const layerReference = useRef<GeoJSONLeaflet | null>(null);
useEffect(() => {
if (layerReference.current != null) {
if (displayed) {
layerReference.current.addTo(map);
} else {
layerReference.current.removeFrom(map);
}
}
}, [map, displayed]);
const pointToLayer = (featureData: Feature<Point, any>, latLng: LatLng) => {
const html = renderToString(<RegionLabel featureData={featureData} zoomLevel={zoomLevel} />);
return LeafletMarker([latLng.lng, latLng.lat], {
interactive: false, // Allow clicks to pass through.
icon: LeafletDivIcon({
html,
className: classes.regionLabelMarker,
}),
zIndexOffset: -900,
});
};
return (
<GeoJSON
ref={layerReference}
key={zoomLevel}
pointToLayer={pointToLayer}
data={RegionLabelData as GeoJsonObject}
/>
);
}
Example #14
Source File: entry.server.tsx From remix-hexagonal-architecture with MIT License | 6 votes |
export default function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext
) {
let markup = renderToString(
<RemixServer context={remixContext} url={request.url} />
);
responseHeaders.set("Content-Type", "text/html");
return new Response("<!DOCTYPE html>" + markup, {
status: responseStatusCode,
headers: responseHeaders,
});
}
Example #15
Source File: index.tsx From react-loosely-lazy with Apache License 2.0 | 6 votes |
renderApp = (v: string) => {
const appContainer = document.querySelector('#app');
const mode = isRender() ? MODE.RENDER : MODE.HYDRATE;
if (v === 'SSR' && appContainer && !isFailSsr()) {
const components = buildServerComponents(mode);
const ssr = renderToString(<App initialStep={v} components={components} />);
appContainer.innerHTML = isRender() ? `<div>${ssr}</div>` : ssr;
}
if (v === 'PAINT LOADING') {
const components = buildClientComponents(mode);
const renderer = isRender() ? render : hydrate;
renderer(<App initialStep={v} components={components} />, appContainer);
}
}
Example #16
Source File: index-ssr.tsx From clearflask with Apache License 2.0 | 6 votes |
renderIndexSsr = (props: {
i18n: typeof i18n;
url: string;
staticRouterContext: StaticRouterContext;
storesState: StoresState;
awaitPromises: Array<Promise<any>>;
renderResult: RenderResult;
requestedUrl: string;
}) => renderToString(props.renderResult.muiSheets.collect(
<ChunkExtractorManager extractor={props.renderResult.extractor}>
<WindowIsoSsrProvider
fetch={fetch}
apiBasePath={connectConfig.apiBasePath}
url={props.requestedUrl}
setTitle={newTitle => props.renderResult.title = newTitle}
setFaviconUrl={newFaviconUrl => props.renderResult.faviconUrl = newFaviconUrl}
setMaxAge={maxAge => props.renderResult.maxAge = maxAge}
storesState={props.storesState}
awaitPromises={props.awaitPromises}
staticRouterContext={props.staticRouterContext}
parentDomain={connectConfig.parentDomain}
>
<Main
i18n={props.i18n}
ssrLocation={props.url}
ssrStaticRouterContext={props.staticRouterContext}
/>
</WindowIsoSsrProvider>
</ChunkExtractorManager>
))
Example #17
Source File: iconNodeToSvg.ts From lucide with ISC License | 5 votes |
iconNodeToSvg = (iconName: string, iconNode : IconNode) => {
const IconComponent = createReactComponent(iconName, iconNode)
return renderToString(createElement(IconComponent));
}
Example #18
Source File: entry-server.tsx From vite-tsconfig-paths with MIT License | 5 votes |
export function renderPage() {
return renderToString(<Root />)
}
Example #19
Source File: pageBuilder.tsx From react-app-architecture with Apache License 2.0 | 5 votes |
export default function pageBuilder(
req: PublicRequest,
pageinfo: PageInfo = {
title: 'AfterAcademy | React Project',
description: 'This is the sample project to learn and implement React app.',
},
currentState: Partial<RootState> = {},
): string {
// create mui server style
const sheets = new ServerStyleSheets();
const authData = req.universalCookies.get(KEY_AUTH_DATA);
if (authData?.tokens?.accessToken) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { tokens, ...data } = authData;
currentState.authState = {
data: data, // security
isLoggingIn: false,
isLoggingOut: false,
isLoggedIn: true,
isForcedLogout: false,
isRedirectHome: false,
message: null,
};
}
const store = isDev
? configureStore(currentState)
: createStore(rootReducer, currentState, applyMiddleware(thunk));
// Render the component to a string
const html = renderToString(
sheets.collect(
<Provider store={store}>
<CookiesProvider cookies={req.universalCookies}>
<StaticRouter location={req.url} context={{}}>
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>
</StaticRouter>
</CookiesProvider>
</Provider>,
),
);
// Grab the CSS from our sheets.
const css = sheets.toString();
const baseUrl = `${getProtocol(req)}://${req.get('host')}`;
const siteUrl = baseUrl + req.originalUrl;
const { coverImg, title, description } = pageinfo;
let htmlPage = render({
html: html,
css: css,
preloadedState: store.getState(),
siteUrl: siteUrl,
title: title,
coverImg: coverImg ? coverImg : `${baseUrl}/assets/og-cover-image.jpg`,
description: description,
});
try {
htmlPage = minifyHtml(htmlPage, {
minifyCSS: true,
minifyJS: true,
});
} catch (e) {
console.log(e);
}
return htmlPage;
}
Example #20
Source File: server.tsx From elephize with MIT License | 5 votes |
server.get('/', (req, res) => {
const body = renderToString(<App />);
res.send(html.replace('{{placeholder}}', body));
});
Example #21
Source File: gatsby-ssr.ts From plasmic with MIT License | 5 votes |
replaceRenderer = async (
{ bodyComponent, replaceBodyHTMLString }: any,
opts: GatsbyPluginOptions
) => {
await fetchServerFiles(opts);
replaceBodyHTMLString(renderToString(bodyComponent));
}
Example #22
Source File: render.tsx From elephize with MIT License | 5 votes |
body = renderToString(<App />)
Example #23
Source File: render.tsx From vanilla-extract with MIT License | 5 votes |
render = (route: string, headTags: HeadTags) =>
renderToString(
<StaticRouter location={route}>
<HeadProvider headTags={headTags}>
<App />
</HeadProvider>
</StaticRouter>,
)
Example #24
Source File: jsx-runtime.test.tsx From swc-node with MIT License | 5 votes |
test('should read jsx runtime options from tsconfig', () => {
expect(renderToString(<Component />)).toMatchInlineSnapshot(`"<div>Hello</div>"`)
})
Example #25
Source File: createServerRender.tsx From use-platform with MIT License | 5 votes |
function serverRender(element: ReactElement) {
const html = renderToString(element)
return { html }
}
Example #26
Source File: integration.test.tsx From react-loosely-lazy with Apache License 2.0 | 4 votes |
describe('hydrates', () => {
const hydrate = true;
describe('a lazyForPaint component', () => {
describe('when ssr is true', () => {
const ssr = true;
it('by rendering and persisting the server content, before replacing', async () => {
const { App: ServerApp } = createApp({
hydrate,
server: true,
ssr,
});
document.body.innerHTML = `
<div id="root">${renderToString(<ServerApp />)}</div>
`;
// expect ssr to render content
expect(document.body).toContainHTML('<p class="p">Content</p>');
expect(document.body.querySelector('input')).toBeInTheDocument();
const {
App: ClientApp,
Child,
resolveImport,
} = createApp({
hydrate,
server: false,
ssr,
});
const { container } = render(<ClientApp />, {
container: document.getElementById('root') as HTMLElement,
hydrate,
});
// expect client to use placeholder and persist ssr content
expect(Child).not.toHaveBeenCalled();
expect(container).toContainHTML('<p class="p">Content</p>');
expect(container.querySelector('input')).toBeInTheDocument();
await act(resolveImport);
// expect component to be live after being resolved
expect(Child).toHaveBeenCalled();
expect(container).toContainHTML('<p class="p">Content</p>');
expect(container.querySelector('input')).not.toBeInTheDocument();
});
});
describe('when ssr is false', () => {
const ssr = false;
it('by rendering and persisting the server fallback, before replacing', async () => {
const { App: ServerApp } = createApp({
hydrate,
server: true,
ssr,
});
document.body.innerHTML = `
<div id="root">${renderToString(<ServerApp />)}</div>
`;
// expect ssr to render fallback
expect(document.body).toContainHTML('<i>Fallback</i>');
expect(document.body.querySelector('input')).toBeInTheDocument();
const {
App: ClientApp,
Child,
resolveImport,
} = createApp({
hydrate,
server: false,
ssr,
});
const { container } = render(<ClientApp />, {
container: document.getElementById('root') as HTMLElement,
hydrate,
});
// expect client to use placeholder and persist ssr fallback
expect(Child).not.toHaveBeenCalled();
expect(container).toContainHTML('<i>Fallback</i>');
expect(container.querySelector('input')).toBeInTheDocument();
await act(resolveImport);
// expect component to be live after being resolved
expect(Child).toHaveBeenCalled();
expect(container).toContainHTML('<p class="p">Content</p>');
expect(container.querySelector('input')).not.toBeInTheDocument();
});
});
});
describe('a lazyAfterPaint component', () => {
const lazyMethod = lazyAfterPaint;
describe('when ssr is true', () => {
const ssr = true;
it('by rendering and persisting the server content, before replacing', async () => {
const { App: ServerApp } = createApp({
hydrate,
lazyMethod,
server: true,
ssr,
});
document.body.innerHTML = `
<div id="root">${renderToString(<ServerApp />)}</div>
`;
// expect ssr to render content
expect(document.body).toContainHTML('<p class="p">Content</p>');
expect(document.body.querySelector('input')).toBeInTheDocument();
const {
App: ClientApp,
Child,
resolveImport,
} = createApp({
hydrate,
lazyMethod,
server: false,
ssr,
});
const { container, rerender } = render(<ClientApp />, {
container: document.getElementById('root') as HTMLElement,
hydrate,
});
// simulate component being ready on next tick
await act(resolveImport);
// expect client to use placeholder and persist ssr content regardless
expect(Child).not.toHaveBeenCalled();
expect(container).toContainHTML('<p class="p">Content</p>');
expect(container.querySelector('input')).toBeInTheDocument();
rerender(<ClientApp phase={PHASE.AFTER_PAINT} />);
await nextTick();
// expect component to be live after phase changed
expect(Child).toHaveBeenCalled();
expect(container).toContainHTML('<p class="p">Content</p>');
expect(container.querySelector('input')).not.toBeInTheDocument();
});
});
describe('when ssr is false', () => {
const ssr = false;
it('by rendering and persisting the server content, before replacing', async () => {
const { App: ServerApp } = createApp({
hydrate,
lazyMethod,
server: true,
ssr,
});
document.body.innerHTML = `
<div id="root">${renderToString(<ServerApp />)}</div>
`;
// expect ssr to render fallback
expect(document.body).toContainHTML('<i>Fallback</i>');
expect(document.body.querySelector('input')).toBeInTheDocument();
const {
App: ClientApp,
Child,
resolveImport,
} = createApp({
hydrate,
lazyMethod,
server: false,
ssr,
});
const { container, rerender } = render(<ClientApp />, {
container: document.getElementById('root') as HTMLElement,
hydrate,
});
// simulate component being ready on next tick
await act(resolveImport);
// expect client to use placeholder and persist ssr content
expect(Child).not.toHaveBeenCalled();
expect(container).toContainHTML('<i>Fallback</i>');
expect(container.querySelector('input')).toBeInTheDocument();
rerender(<ClientApp phase={PHASE.AFTER_PAINT} />);
await nextTick();
// expect component to be live after phase changed
expect(Child).toHaveBeenCalled();
expect(container).toContainHTML('<p class="p">Content</p>');
expect(container.querySelector('input')).not.toBeInTheDocument();
});
});
});
});
Example #27
Source File: integration.test.tsx From react-loosely-lazy with Apache License 2.0 | 4 votes |
describe('renders', () => {
const hydrate = false;
describe('a lazyForPaint component', () => {
describe('when ssr is true', () => {
const ssr = true;
it('by rendering and persisting the server content, before replacing', async () => {
const { App: ServerApp } = createApp({
hydrate,
server: true,
ssr,
});
document.body.innerHTML = `
<div id="root">${renderToString(<ServerApp />)}</div>
`;
// expect ssr to render content
expect(document.body).toContainHTML('<p class="p">Content</p>');
expect(document.body.querySelector('input')).toBeInTheDocument();
const {
App: ClientApp,
Child,
resolveImport,
} = createApp({
hydrate,
server: false,
ssr,
});
const { container } = render(<ClientApp />, {
container: document.getElementById('root') as HTMLElement,
hydrate,
});
// expect client to use placeholder and persist ssr content
expect(Child).not.toHaveBeenCalled();
expect(container).toContainHTML('<p class="p">Content</p>');
expect(container.querySelector('input')).toBeInTheDocument();
await act(resolveImport);
// expect component to be live after being resolved
expect(Child).toHaveBeenCalled();
expect(container).toContainHTML('<p class="p">Content</p>');
expect(container.querySelector('input')).not.toBeInTheDocument();
});
});
describe('when ssr is false', () => {
const ssr = false;
it('by rendering and persisting the server fallback, before replacing', async () => {
const { App: ServerApp } = createApp({
hydrate,
server: true,
ssr,
});
document.body.innerHTML = `
<div id="root">${renderToString(<ServerApp />)}</div>
`;
// expect ssr to render fallback
expect(document.body).toContainHTML('<i>Fallback</i>');
expect(document.body.querySelector('input')).toBeInTheDocument();
const {
App: ClientApp,
Child,
resolveImport,
} = createApp({
hydrate,
server: false,
ssr,
});
const { container } = render(<ClientApp />, {
container: document.getElementById('root') as HTMLElement,
hydrate,
});
// expect client to use placeholder and persist ssr fallback
expect(Child).not.toHaveBeenCalled();
expect(container).toContainHTML('<i>Fallback</i>');
expect(container.querySelector('input')).toBeInTheDocument();
await act(resolveImport);
// expect component to be live after being resolved
expect(Child).toHaveBeenCalled();
expect(container).toContainHTML('<p class="p">Content</p>');
expect(container.querySelector('input')).not.toBeInTheDocument();
});
});
});
});
Example #28
Source File: render.tsx From next-page-tester with MIT License | 4 votes |
export default async function serverRenderDocument({ options, appProps, pageProps, pageObject, wrapWithRouter, }: { options: ExtendedOptions; appProps: PageProps | undefined; pageProps: PageProps | undefined; pageObject: PageObject; wrapWithRouter: (children: JSX.Element) => JSX.Element; }): Promise<JSX.Element> { return executeAsIfOnServer(async () => { const { useDocument } = options; const { documentFile: { default: DocumentComponent }, appFile: { default: AppComponent }, pageFile: { default: PageComponent }, wrappersFile, } = pageObject.files.server; const wrappers = { appWrapper: wrappersFile?.App, pageWrapper: wrappersFile?.Page, }; const render = (App: NextApp, Page: NextPage) => { return renderEnhancedApp({ App, Page, appProps, pageProps, wrappers, }); }; // Return an empty dummy document if useDocument is not enabled if (!useDocument) { return ( <html> <head></head> <body> <div id={NEXT_ROOT_ELEMENT_ID}> {wrapWithRouter(render(AppComponent, PageComponent))} </div> </body> </html> ); } const renderPage: RenderPage = (options = {}) => { const { App: EnhancedApp, Component: EnhancedComponent, } = enhanceComponents(options, AppComponent, PageComponent); let head: JSX.Element[] = []; const html = renderToString( // @NOTE: implemented from: // https://github.com/vercel/next.js/blob/v10.0.3/packages/next/next-server/server/render.tsx#L561 // Now in: https://github.com/vercel/next.js/blob/v11.1.0/packages/next/server/render.tsx#L639 <HeadManagerContext.Provider value={{ updateHead: (state) => { head = state; }, mountedInstances: new Set(), }} > {wrapWithRouter(render(EnhancedApp, EnhancedComponent))} </HeadManagerContext.Provider> ); return { html, head }; }; const initialProps = await fetchDocumentData({ Document: DocumentComponent, renderPage, pageObject, }); const documentProps: DocumentProps = { ...initialProps, buildManifest: { ampDevFiles: [], ampFirstPages: [], devFiles: [], lowPriorityFiles: [], polyfillFiles: [], pages: { [APP_PATH]: [], [pageObject.pagePath]: [], }, }, __NEXT_DATA__: { page: pageObject.pagePath, query: pageObject.query, buildId: 'next-page-tester', props: { pageProps }, }, scriptLoader: {}, docComponentsRendered: {}, dangerousAsPath: '', ampPath: '', inAmpMode: false, dynamicImports: [], isDevelopment: false, hybridAmp: false, canonicalBase: '', headTags: [], devOnlyCacheBusterQueryString: '', // @ts-expect-error We don't expect to use this method useMaybeDeferContent: () => {}, }; // @ts-expect-error this method doesn't exist since Next.js v11.1.2 and useDocument option is currently disabled return DocumentComponent.renderDocument(DocumentComponent, documentProps); }); }
Example #29
Source File: SelectedIcon.tsx From iconsax-react with MIT License | 4 votes |
SelectedIcon = () => {
const { state } = useIconContext()
const hideIcon = selectedStore((state) => state.hideIcon)
const selected = selectedStore((state) => state.selected)
const [isOpen, setIsOpen] = useState<boolean>(!!selected || false)
const ref = useRef(null)
const iconRef = useRef<SVGSVGElement>(null)
const Icon = selected?.Icon
useEffect(() => {
if (isOpen) {
gsap.to(ref.current, {
y: '0',
ease: 'expo.inOUt',
duration: duration / 1000,
})
}
}, [isOpen])
useEffect(() => {
setIsOpen(!!selected)
}, [selected])
useOnClickOutside(ref, (e) => {
const path = e.composedPath() as HTMLElement[]
let isAnIcon = false
for (let p = 0; p < path.length; p++) {
if (path[p].classList && path[p].classList.contains('icon')) {
return (isAnIcon = true)
}
}
if (!isAnIcon) handleClose()
})
const handleClose = () => {
if (!hideIcon) return
gsap.to(ref.current, {
y: '500',
ease: 'expo.inOUt',
duration: duration / 1000,
})
setTimeout(() => {
hideIcon()
}, duration)
}
const iconSaveName = `${selected?.name}-${state.variant}-${state.size}px`
const iconString =
Icon &&
renderToString(
<Icon size={state.size} color={state.color} variant={state.variant} />
)
const handleCopySvg = () => {
if (!iconString) return
copy(iconString)
}
const handleDownloadSvg = () => {
if (!iconString) return
const blob = new Blob([iconString])
saveAs(blob, `${iconSaveName}.svg`)
}
const handleDownloadPng = async () => {
if (!iconString) return
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
const v = canvg.fromString(ctx, iconString)
v.render()
const img = canvas.toDataURL('image/png')
console.log(img)
saveAs(img, `${iconSaveName}.png`)
}
return (
<>
{isOpen && (
<div
ref={ref}
className="fixed bg-bg p-3 h-72 md:w-96 mx-4 left-0 md:left-auto right-0 bottom-0 rounded-t-3xl border-2 translate-y-[500px] border-border"
>
<div className="flex justify-between items-center">
<span className="font-bold text-md">{selected?.name}</span>
<span className="cursor-pointer" onClick={handleClose}>
<CloseCircle color="white" />
</span>
</div>
<div className="flex gap-1 mt-3">
<div className="flex-1 border-dashed border-2 p-4 border-border rounded-lg">
{Icon && (
<Icon size={64} color={state.color} variant={state.variant} />
)}
</div>
<div className="flex-[7] flex flex-col gap-1 text-xs">
<Button handleClick={handleCopySvg} name="copy#svg" />
<div className="flex-1 grid grid-cols-2 gap-1">
<Button handleClick={handleDownloadSvg} name="download#svg" />
<Button handleClick={handleDownloadPng} name="download#png" />
</div>
</div>
</div>
<Code name={selected?.name!} />
</div>
)}
</>
)
}