0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-23 21:53:55 -05:00
astro/packages/integrations/solid/src/server.ts
Matthew Phillips 3d525efc95
Prevent removal of nested slots within islands (#7093)
* Prevent removal of nested slots within islands

* Fix build errors
2023-05-17 10:18:04 -04:00

57 lines
1.7 KiB
TypeScript

import { createComponent, renderToString, ssr } from 'solid-js/web';
import { getContext, incrementId } from './context.js';
import type { RendererContext } from './types';
const slotName = (str: string) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase());
function check(this: RendererContext, Component: any, props: Record<string, any>, children: any) {
if (typeof Component !== 'function') return false;
const { html } = renderToStaticMarkup.call(this, Component, props, children);
return typeof html === 'string';
}
function renderToStaticMarkup(
this: RendererContext,
Component: any,
props: Record<string, any>,
{ default: children, ...slotted }: any,
metadata?: undefined | Record<string, any>
) {
const renderId = metadata?.hydrate ? incrementId(getContext(this.result)) : '';
const needsHydrate = metadata?.astroStaticSlot ? !!metadata.hydrate : true;
const tagName = needsHydrate ? 'astro-slot' : 'astro-static-slot';
const html = renderToString(
() => {
const slots: Record<string, any> = {};
for (const [key, value] of Object.entries(slotted)) {
const name = slotName(key);
slots[name] = ssr(`<${tagName} name="${name}">${value}</${tagName}>`);
}
// Note: create newProps to avoid mutating `props` before they are serialized
const newProps = {
...props,
...slots,
// In Solid SSR mode, `ssr` creates the expected structure for `children`.
children: children != null ? ssr(`<${tagName}>${children}</${tagName}>`) : children,
};
return createComponent(Component, newProps);
},
{
renderId,
}
);
return {
attrs: {
'data-solid-render-id': renderId,
},
html,
};
}
export default {
check,
renderToStaticMarkup,
supportsAstroStaticSlot: true,
};