import TRenderEngine from '@native-html/transient-render-engine';
import React, { PropsWithChildren, ReactElement } from 'react';
import { Platform } from 'react-native';
import PropTypes from 'prop-types';
import useTRenderEngine from './hooks/useTRenderEngine';
import { TRenderEngineConfig } from './shared-types';
import defaultSystemFonts from './defaultSystemFonts';
const defaultTRenderEngine = {} as any;
const TRenderEngineContext =
React.createContext(defaultTRenderEngine);
export const tRenderEngineProviderPropTypes: Record<
keyof TRenderEngineConfig,
any
> = {
customHTMLElementModels: PropTypes.object.isRequired,
enableCSSInlineProcessing: PropTypes.bool,
enableUserAgentStyles: PropTypes.bool,
idsStyles: PropTypes.object,
ignoredDomTags: PropTypes.array,
ignoreDomNode: PropTypes.func,
domVisitors: PropTypes.object,
ignoredStyles: PropTypes.array.isRequired,
allowedStyles: PropTypes.array,
htmlParserOptions: PropTypes.object,
tagsStyles: PropTypes.object,
classesStyles: PropTypes.object,
emSize: PropTypes.number.isRequired,
baseStyle: PropTypes.object,
systemFonts: PropTypes.arrayOf(PropTypes.string),
fallbackFonts: PropTypes.shape({
serif: PropTypes.string,
'sans-serif': PropTypes.string,
monospace: PropTypes.string
}),
setMarkersForTNode: PropTypes.func,
dangerouslyDisableHoisting: PropTypes.bool,
dangerouslyDisableWhitespaceCollapsing: PropTypes.bool,
selectDomRoot: PropTypes.func
};
/**
* Default fallback font for special keys such as 'sans-serif', 'monospace',
* 'serif', based on current platform.
*/
export const defaultFallbackFonts = {
'sans-serif': Platform.select({ ios: 'system', default: 'sans-serif' }),
monospace: Platform.select({ ios: 'Menlo', default: 'monospace' }),
serif: Platform.select({ ios: 'Times New Roman', default: 'serif' })
};
export const defaultTRenderEngineProviderProps: TRenderEngineConfig = {
htmlParserOptions: {
decodeEntities: true
},
emSize: 14,
ignoredDomTags: [],
ignoredStyles: [],
baseStyle: { fontSize: 14 },
tagsStyles: {},
classesStyles: {},
enableUserAgentStyles: true,
enableCSSInlineProcessing: true,
customHTMLElementModels: {},
fallbackFonts: defaultFallbackFonts,
systemFonts: defaultSystemFonts
};
/**
* Use the ambient transient render engine.
*
* @returns The ambient transient render engine.
*
* @public
*/
export function useAmbientTRenderEngine() {
const engine = React.useContext(TRenderEngineContext);
if (
typeof __DEV__ === 'boolean' &&
__DEV__ &&
engine === defaultTRenderEngine
) {
console.error('TRenderEngineProvider is missing in the render tree.');
}
return engine;
}
/**
* A react component to share a {@link TRenderEngine} instance across different
* rendered contents via {@link RenderHTMLSource}. This can significantly enhance
* performance in applications with potentially dozens or hundreds of distinct
* rendered snippets such as chat apps.
*
* @param props - Pass engine config here.
*/
export default function TRenderEngineProvider({
children,
...config
}: PropsWithChildren): ReactElement {
const engine = useTRenderEngine(config);
return (
{children}
);
}
/**
* @ignore
*/
TRenderEngineProvider.defaultProps = defaultTRenderEngineProviderProps;
/**
* @ignore
*/
TRenderEngineProvider.propTypes = tRenderEngineProviderPropTypes;