import r2wc from '@rxfork/r2wc-react-to-web-component' import type { ComponentType } from 'react' import type { Container } from 'react-dom' import type { CommonProps } from 'lib/seam/components/common-props.js' import { SeamProvider, type SeamProviderPropsWithClientSessionToken, type SeamProviderPropsWithPublishableKey, } from 'lib/seam/SeamProvider.js' declare global { // eslint-disable-next-line no-var var disableSeamTelemetry: boolean | undefined // eslint-disable-next-line no-var var disableSeamCssInjection: boolean | undefined // eslint-disable-next-line no-var var disableSeamFontInjection: boolean | undefined // eslint-disable-next-line no-var var unminifiySeamCss: boolean | undefined } export interface ElementDefinition { name: string Component: Parameters[0] props?: R2wcProps> } export type ElementProps = R2wcProps> type R2wcProps = Record< keyof T, 'string' | 'number' | 'boolean' | 'array' | 'object' > type ProviderProps = Omit< SeamProviderPropsWithPublishableKey & SeamProviderPropsWithClientSessionToken, 'children' > const commonProps: R2wcProps = { errorFilter: 'object', warningFilter: 'object', disableLockUnlock: 'boolean', disableCreateAccessCode: 'boolean', disableEditAccessCode: 'boolean', disableDeleteAccessCode: 'boolean', disableResourceIds: 'boolean', disableConnectedAccountInformation: 'boolean', onBack: 'object', className: 'string', } const providerProps: R2wcProps = { publishableKey: 'string', userIdentifierKey: 'string', clientSessionToken: 'string', endpoint: 'string', isUndocumentedApiEnabled: 'boolean', queryClient: 'object', telemetryClient: 'object', disableTelemetry: 'boolean', disableCssInjection: 'boolean', disableFontInjection: 'boolean', unminifiyCss: 'boolean', onSessionUpdate: 'object', } export const defineCustomElement = ({ name, Component, props = {}, }: ElementDefinition): void => { const element = r2wc(withProvider(Component), { props: { ...props, ...providerProps, ...commonProps, }, }) globalThis.customElements?.define(name, element) } function withProvider

( Component: ComponentType

): (props: ProviderProps & { container: Container } & P) => JSX.Element | null { const name = Component.displayName ?? Component.name ?? 'Component' function WithProvider({ publishableKey, endpoint, userIdentifierKey, clientSessionToken, disableTelemetry, disableCssInjection, disableFontInjection, unminifiyCss, onSessionUpdate, container: _container, ...props }: ProviderProps & { container: Container } & P): JSX.Element | null { return ( ) } WithProvider.displayName = `WithProvider(${name})` return WithProvider }