/* eslint-env node */ import type { DocumentContext, DocumentInitialProps } from 'next/document' import { createElement, Fragment } from 'react' import Document from 'next/document' import { extract } from '@twind/core' export default install function install(): typeof Document function install( DocumentComponent: Component, ): Component function install( BaseComponent: Component = Document as Component, ): Component { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return class TwindDocument extends BaseComponent { static getInitialProps( ctx: DocumentContext & { defaultGetInitialProps: ( ctx: DocumentContext, options?: { nonce?: string }, ) => Promise }, ) { const defaultGetInitialProps = ctx.defaultGetInitialProps.bind(ctx) ctx.defaultGetInitialProps = async (ctx, options: { nonce?: string } = {}) => { const props = await defaultGetInitialProps(ctx, options) const { html, css } = extract(props.html) const styles = createElement( Fragment, null, createElement('style', { 'data-twind': '', nonce: options.nonce, dangerouslySetInnerHTML: { __html: css, }, }), props.styles, ) return { ...props, html, styles } } return BaseComponent.getInitialProps(ctx) } } }