Hi,
Would you be open to a PR to add .d.ts type file(s) to your project for typescript support?
Hi, yes that would be a very nice addition to the plugin. I was thinking about rewriting the whole codebase in typescript, since I'm pretty sure there are a lot of leftovers from previous versions that haven't been cleaned up properly. Switching to TS would help me see them.
In the meantime, providing typings would be a great start.
I have a preliminary version that I'm using in my project, but I didn't dig enough into the documentation and/or code to fill in all the types, so there are quite a few anys in place.
I'll submit a PR later when I have some time with improvements. If you would like any help with a typescript re-write I'd be happy to help
declare module "react-native-render-html" {
import * as React from "react";
import * as ReactNative from "react-native";
type Renderer = (
htmlAttribs: any,
children: React.Children,
convertedCSSStyles: any,
passProps: any,
) => JSX.Element;
export default class HTML extends React.PureComponent<{
renderers?: { [key: string]: Renderer };
ignoredTags?: string[];
ignoredStyles?: string[];
allowedStyles?: string[];
decodeEntities?: boolean;
debug?: boolean;
listsPrefixesRenderers?: { ul?: Renderer; ol?: Renderer };
ignoreNodesFunction?: (...args: any[]) => any;
alterData?: (...args: any[]) => any;
alterChildren?: (...args: any[]) => any;
alterNode?: (...args: any[]) => any;
html?: string;
uri?: string;
tagsStyles?: { [key: string]: ReactNative.ViewStyle | Array<ReactNative.ViewStyle> };
classesStyles?: { [key: string]: ReactNative.ViewStyle | Array<ReactNative.ViewStyle> };
containerStyle?: ReactNative.ViewStyle | Array<ReactNative.ViewStyle>;
customWrapper?: (...args: any[]) => any;
onLinkPress?: (...args: any[]) => any;
onParsed?: (...args: any[]) => any;
imagesMaxWidth?: number;
staticContentMaxWidth?: number;
imagesInitialDimensions?: {
width?: number;
height?: number;
};
emSize?: number;
ptSize?: number;
baseFontStyle?: ReactNative.ViewStyle | Array<ReactNative.ViewStyle>;
textSelectable?: boolean;
}> {}
}
@Exilz I am writing a more accurate version of typescript definitions for my own usage, with comments from your documentation.
I'll offer a PR when it's complete enough, but bellow is a draft:
declare module 'react-native-render-html' {
import { ComponentType, ReactNode } from "react"
import { StyleProp, Text, View, GestureResponderEvent, RecursiveArray, Falsy } from "react-native"
namespace HTML {
type HTMLNode = any
type NonRegisteredStylesProp<T> = T | Falsy | RecursiveArray<T | Falsy>
type HtmlAttributesDictionary = {
[attribute: string]: string
}
type PassProps<T> = any
type RendererFunction = <T>(htmlAttribs: HtmlAttributesDictionary, children: HTMLNode[], convertedCSSStyles: NonRegisteredStylesProp<any>, passProps: PassProps<T>) => ReactNode
type RendererDeclaration = RendererFunction | { renderer: RendererFunction, wrapper: 'Text' | 'View' }
type RendererDictionary = {
[tag: string]: RendererDeclaration
}
type StylesDictionary = {
[tag: string]: NonRegisteredStylesProp<any>
}
type ImageDimensions = {
width: number,
height: number
}
interface ContainerProps {
/**
* HTML string to parse and render
*/
html: string
/**
* Resize your images to this maximum width.
*/
imagesMaxWidth?: number
/**
* Your custom renderers.
*/
renderers?: RendererDictionary
/**
* Your custom renderers from ul and ol bullets, see [lists prefixes](https://github.com/archriss/react-native-render-html#lists-prefixes)
*/
listsPrefixesRenderers?: RendererDictionary
/**
* Remote website to parse and render
*/
uri?: string
/**
* Decode HTML entities of your content.
* Optional, defaults to true
*/
decodeEntities?: boolean
/**
* Set a maximum width to non-responsive content (<iframe> for instance)
*/
staticContentMaxWidth?: number
/**
* Default width and height to display while image's dimensions are being retrieved.
*/
imagesInitialDimensions?: ImageDimensions
/**
* Fired with the event, the href and an object with all attributes of the tag as its arguments when tapping a link
*/
onLinkPress?: (event: GestureResponderEvent, href: string, htmlAttribs: HtmlAttributesDictionary) => void
/**
* Fired when your HTML content has been parsed. Also useful to tweak your rendering.
*/
onParsed?: any
/**
* Provide your styles for specific HTML tags.
*
* **Important note** Do NOT use the StyleSheet API to create the styles you're going to feed to tagsStyle and classesStyles.
* Although it might look like it's working at first, the caching logic of react-native makes it impossible for this module
* to deep check each of your style to properly apply the precedence and priorities of your nested tags' styles.
*/
tagsStyles?: StylesDictionary
/**
* Provide your styles for specific HTML classes.
*
* **Important note** Do NOT use the StyleSheet API to create the styles you're going to feed to tagsStyle and classesStyles.
* Although it might look like it's working at first, the caching logic of react-native makes it impossible for this module
* to deep check each of your style to properly apply the precedence and priorities of your nested tags' styles.
*/
classesStyles?: StylesDictionary
/**
* Custom style for the default container of the renderered HTML.
*/
containerStyle?: StyleProp<View>
/**
* Replace the default wrapper with a function that takes your content as the first parameter.
*/
customWrapper?: Function
/**
* Replace the default loader while fetching a remote website's content.
*/
remoteLoadingView?: Function
/**
* Replace the default error if a remote website's content could not be fetched.
*/
remoteErrorView?: Function
/**
* The default value in pixels for 1em
*/
emSize?: number
/**
* The default value in pixels for 1pt
*/
ptSize?: number
/**
* The default style applied to `<Text>` components
*/
baseFontStyle?: NonRegisteredStylesProp<TextStyle>
/**
* Allow all texts to be selected. Default to `false`.
*/
textSelectable?: boolean
/**
* Target some specific texts and change their content, see [altering content](https://github.com/archriss/react-native-render-html#altering-content)
*/
alterData?: (...args: any[]) => any;
/**
* Target some specific nested children and change them, see [altering content](https://github.com/archriss/react-native-render-html#altering-content)
*/
alterChildren?: (...args: any[]) => any;
/**
* Target a specific node and change it, see [altering content](https://github.com/archriss/react-native-render-html#altering-content)
*/
alterNode?: (...args: any[]) => any;
/**
* HTML tags you don't want rendered, see [ignoring HTML content](https://github.com/archriss/react-native-render-html#ignoring-html-content)
*/
ingoredTags?: string[]
/**
* Allow render only certain CSS style properties and ignore every other. If you have some property both in `allowedStyles` and `ignoredStyles`, it will be ignored anyway.
*/
allowedStyles?: string[]
/**
* CSS styles from the style attribute you don't want rendered, see [ignoring HTML content](https://github.com/archriss/react-native-render-html#ignoring-html-content)
*/
ignoredStyles?: string[]
/**
* Return true in this custom function to ignore nodes very precisely, see [ignoring HTML content](https://github.com/archriss/react-native-render-html#ignoring-html-content)
*/
ignoreNodesFunction?: (node: HTMLNode) => boolean
/**
* Prints the parsing result from htmlparser2 and render-html after the initial render
*/
debug?: boolean
}
}
const HTML: ComponentType<HTML.ContainerProps>
export = HTML
}
declare module 'react-native-render-html/src/HTMLUtils' {
type HTMLNode = any
/**
* Returns an array with the tagname of every parent of a node or an empty array if nothing is found.
* @param node A parsed HTML node from alterChildren for example
*/
export const getParentsTagsRecursively: (node: HTMLNode) => string[]
/**
* Returns the closest parent of a node with a specific tag.
* @param node A parsed HTML node from alterChildren for example
* @param tag The tag to match
*/
export const getClosestNodeParentByTag: (node: HTMLNode, tag: string) => HTMLNode
/**
* The set of default ignored tags
*/
export const IGNORED_TAGS: string[]
}
@jsamr Any progress on the PR? It would be a great addition to this library 馃憤
@jsamr this is a must have
I'd also love this please! 馃挴
@jsamr I used yours, included one missing property from the new version and fixed a typo.
declare module 'react-native-render-html' {
import { ComponentType, ReactNode } from 'react';
import {
StyleProp,
Text,
View,
GestureResponderEvent,
RecursiveArray,
Falsy,
} from 'react-native';
namespace HTML {
type HTMLNode = any;
type NonRegisteredStylesProp<T> = T | Falsy | RecursiveArray<T | Falsy>;
type HtmlAttributesDictionary = {
[attribute: string]: string;
};
type PassProps<T> = any;
type RendererFunction = <T>(
htmlAttribs: HtmlAttributesDictionary,
children: HTMLNode[],
convertedCSSStyles: NonRegisteredStylesProp<any>,
passProps: PassProps<T>,
) => ReactNode;
type RendererDeclaration =
| RendererFunction
| { renderer: RendererFunction; wrapper: 'Text' | 'View' };
type RendererDictionary = {
[tag: string]: RendererDeclaration;
};
type StylesDictionary = {
[tag: string]: NonRegisteredStylesProp<any>;
};
type ImageDimensions = {
width: number;
height: number;
};
interface ContainerProps {
/**
* HTML string to parse and render
*/
html: string;
/**
* Your custom renderers.
*/
renderers?: RendererDictionary;
/**
* Set of props accessible into your custom renderers in passProps (4th argument)
*/
renderersProps?: PassProps<T>;
/**
* (experimental) Remote website to parse and render
*/
uri?: string;
/**
* Decode HTML entities of your content.
* Optional, defaults to true
*/
decodeEntities?: boolean;
/**
* Resize your images to this maximum width.
*/
imagesMaxWidth?: number;
/**
* Set a maximum width to non-responsive content (<iframe> for instance)
*/
staticContentMaxWidth?: number;
/**
* Default width and height to display while image's dimensions are being retrieved.
*/
imagesInitialDimensions?: ImageDimensions;
/**
* Fired with the event, the href and an object with all attributes of the tag as its arguments when tapping a link
*/
onLinkPress?: (
event: GestureResponderEvent,
href: string,
htmlAttribs: HtmlAttributesDictionary,
) => void;
/**
* Fired when your HTML content has been parsed. Also useful to tweak your rendering.
*/
onParsed?: any;
/**
* Provide your styles for specific HTML tags.
*
* **Important note** Do NOT use the StyleSheet API to create the styles you're going to feed to tagsStyle and classesStyles.
* Although it might look like it's working at first, the caching logic of react-native makes it impossible for this module
* to deep check each of your style to properly apply the precedence and priorities of your nested tags' styles.
*/
tagsStyles?: StylesDictionary;
/**
* Provide your styles for specific HTML classes.
*
* **Important note** Do NOT use the StyleSheet API to create the styles you're going to feed to tagsStyle and classesStyles.
* Although it might look like it's working at first, the caching logic of react-native makes it impossible for this module
* to deep check each of your style to properly apply the precedence and priorities of your nested tags' styles.
*/
classesStyles?: StylesDictionary;
/**
* Your custom renderers from ul and ol bullets, see [lists prefixes](https://github.com/archriss/react-native-render-html#lists-prefixes)
*/
listsPrefixesRenderers?: RendererDictionary;
/**
* Custom style for the default container of the renderered HTML.
*/
containerStyle?: StyleProp<View>;
/**
* Replace the default wrapper with a function that takes your content as the first parameter.
*/
customWrapper?: Function;
/**
* Replace the default loader while fetching a remote website's content.
*/
remoteLoadingView?: Function;
/**
* Replace the default error if a remote website's content could not be fetched.
*/
remoteErrorView?: Function;
/**
* The default value in pixels for 1em
*/
emSize?: number;
/**
* The default value in pixels for 1pt
*/
ptSize?: number;
/**
* The default style applied to `<Text>` components
*/
baseFontStyle?: NonRegisteredStylesProp<TextStyle>;
/**
* Allow all texts to be selected. Default to `false`.
*/
textSelectable?: boolean;
/**
* Target some specific texts and change their content, see [altering content](https://github.com/archriss/react-native-render-html#altering-content)
*/
alterData?: (...args: any[]) => any;
/**
* Target some specific nested children and change them, see [altering content](https://github.com/archriss/react-native-render-html#altering-content)
*/
alterChildren?: (...args: any[]) => any;
/**
* Target a specific node and change it, see [altering content](https://github.com/archriss/react-native-render-html#altering-content)
*/
alterNode?: (...args: any[]) => any;
/**
* HTML tags you don't want rendered, see [ignoring HTML content](https://github.com/archriss/react-native-render-html#ignoring-html-content)
*/
ignoredTags?: string[];
/**
* Allow render only certain CSS style properties and ignore every other. If you have some property both in `allowedStyles` and `ignoredStyles`, it will be ignored anyway.
*/
allowedStyles?: string[];
/**
* CSS styles from the style attribute you don't want rendered, see [ignoring HTML content](https://github.com/archriss/react-native-render-html#ignoring-html-content)
*/
ignoredStyles?: string[];
/**
* Return true in this custom function to ignore nodes very precisely, see [ignoring HTML content](https://github.com/archriss/react-native-render-html#ignoring-html-content)
*/
ignoreNodesFunction?: (node: HTMLNode) => boolean;
/**
* Prints the parsing result from htmlparser2 and render-html after the initial render
*/
debug?: boolean;
}
}
const HTML: ComponentType<HTML.ContainerProps>;
export = HTML;
}
declare module 'react-native-render-html/src/HTMLUtils' {
type HTMLNode = any;
/**
* Returns an array with the tagname of every parent of a node or an empty array if nothing is found.
* @param node A parsed HTML node from alterChildren for example
*/
export const getParentsTagsRecursively: (node: HTMLNode) => string[];
/**
* Returns the closest parent of a node with a specific tag.
* @param node A parsed HTML node from alterChildren for example
* @param tag The tag to match
*/
export const getClosestNodeParentByTag: (
node: HTMLNode,
tag: string,
) => HTMLNode;
/**
* The set of default ignored tags
*/
export const IGNORED_TAGS: string[];
}
OK I'll do a PR!
Done, #341
If you want to see those types landing fast, it would be appreciated if you could test locally and give some feedback in PR #341.
To test, just change your version of react-native-render-html to:
{
"dependencies": {
"react-native-render-html": "github:jsamr/react-native-render-html#ts"
}
}
and run npm i
Still there no typings when downloading from NPM.
Hi guys, any progress with this? Thanks
@dkoprowski @felisio Please test the branch as I instructed. @Exilz is waiting for a few user feedback before merging. Report your feedback in #341!
Any updates on adding type definitions to the npm package?
This is available as of 4.2.1
Most helpful comment
@Exilz I am writing a more accurate version of typescript definitions for my own usage, with comments from your documentation.
I'll offer a PR when it's complete enough, but bellow is a draft: