From 98ead4be4b06b065662baad964d52f2ac4eef793 Mon Sep 17 00:00:00 2001 From: Henri Normak Date: Sun, 4 Nov 2018 21:20:06 +0200 Subject: [PATCH] Add types for mjml-react --- types/mjml-react/index.d.ts | 413 ++++++++++++++++++++++++++ types/mjml-react/mjml-react-tests.tsx | 40 +++ types/mjml-react/tsconfig.json | 24 ++ types/mjml-react/tslint.json | 1 + 4 files changed, 478 insertions(+) create mode 100644 types/mjml-react/index.d.ts create mode 100644 types/mjml-react/mjml-react-tests.tsx create mode 100644 types/mjml-react/tsconfig.json create mode 100644 types/mjml-react/tslint.json diff --git a/types/mjml-react/index.d.ts b/types/mjml-react/index.d.ts new file mode 100644 index 0000000000..6367d1d1ec --- /dev/null +++ b/types/mjml-react/index.d.ts @@ -0,0 +1,413 @@ +// Type definitions for mjml-react 1.0 +// Project: https://github.com/wix-incubator/mjml-react +// Definitions by: Henri Normak +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.3 + +import * as React from 'react'; + +export namespace extensions { + class MjmlComment extends React.Component<{ children: string }> { } + class MjmlConditionalComment extends React.Component<{ children: string; condition: string }> { } + class MjmlTrackingPixel extends React.Component<{ src: string }> { } + class MjmlYahooStyle extends React.Component<{ children: string }> { } +} + +export namespace utils { + function namedEntityToHexCode(html: string): string; + function fixConditionalComment(html: string, havingContent: string, newCondition: string): string; + function useHttps(url?: string): string | undefined; + function toMobileFontSize(sizeWithUnit: string): number; + function addQueryParams(url: string, params: { [key: string]: any }): string; + + type TextAlignment = 'left' | 'right' | 'center' | 'justify' | 'inherit'; + function getTextAlign(value: string, fallback?: TextAlignment): TextAlignment; +} + +export function renderToMjml(email: React.ReactElement): string; + +export interface Mjml2HtmlOptions { + fonts?: { [key: string]: string }; + keepComments?: boolean; + beautify?: boolean; + minify?: boolean; + validationLevel?: 'strict' | 'soft' | 'skip'; + filePath?: string; +} + +export function render(email: React.ReactElement, options?: Mjml2HtmlOptions): { html: string; errors: Error[] }; + +// Components + +export interface RequiredChildrenProps { + children: React.ReactNode; +} + +export interface PaddingProps { + padding?: string | number; + paddingTop?: string | number; + paddingRight?: string | number; + paddingBottom?: string | number; + paddingLeft?: string | number; +} + +export interface BorderProps { + border?: string; + borderBottom?: string; + borderLeft?: string; + borderTop?: string; + borderRight?: string; + borderRadius?: string | number; +} + +export interface ClassNameProps { + cssClass?: string; +} + +export interface HrefProps { + href?: string; + target?: string; + rel?: string; +} + +// mjml +export interface MjmlProps { + lang?: string; + owa?: string; +} + +export class Mjml extends React.Component { } + +// mj-head +export class MjmlHead extends React.Component { } + +// mj-attributes +export class MjmlAttributes extends React.Component { } +export class MjmlAll extends React.Component<{ [key: string]: any; children?: React.ReactNode }> { } +export class MjmlClass extends React.Component<{ [key: string]: any; children?: React.ReactNode; name: string }> { } + +// mj-breakpoint +export interface MjmlBreakpointProps { + width?: string | number; +} + +export class MjmlBreakpoint extends React.Component { } + +// mj-body +export interface MjmlBodyProps { + width ?: number; + backgroundColor?: React.CSSProperties['backgroundColor']; +} + +export class MjmlBody extends React.Component { } + +// mj-font +export interface MjmlFontProps { + href?: string; + name?: string; +} + +export class MjmlFont extends React.Component { } + +// mj-preview +export class MjmlPreview extends React.Component<{ children: string }> { } + +// mj-style +export class MjmlStyle extends React.Component<{ children: string, inline?: boolean }> { } + +// mj-title +export class MjmlTitle extends React.Component<{ children: string }> { } + +// mj-accordion +export class MjmlAccordion extends React.Component { } + +export interface MjmlAccordionElementProps { + fontFamily?: string; + iconAlign?: string; + iconWrappedUrl?: string; + iconWrappedAlt?: string; + iconUnwrappedAlt?: string; + iconUnwrappedUrl?: string; + iconPosition?: 'left' | 'right'; + iconHeight?: string; + iconWidth?: string; + backgroundColor?: React.CSSProperties['backgroundColor']; +} + +export class MjmlAccordionElement extends React.Component { } + +export interface MjmlAccordionTextProps { + color?: React.CSSProperties['color']; + fontFamily?: string; + fontSize?: string | number; + backgroundColor?: React.CSSProperties['backgroundColor']; +} + +export class MjmlAccordionText extends React.Component { } + +export interface MjmlAccordionTitleProps { + color?: React.CSSProperties['color']; + backgroundColor?: React.CSSProperties['backgroundColor']; + fontFamily?: string; + fontSize?: string | number; +} + +export class MjmlAccordionTitle extends React.Component { } + +// mj-button +export interface MjmlButtonProps { + backgroundColor?: React.CSSProperties['backgroundColor']; + containerBackgroundColor?: React.CSSProperties['backgroundColor']; + fontStyle?: string; + fontSize?: string | number; + fontWeight?: number; + fontFamily?: string; + color?: React.CSSProperties['color']; + textAlign?: React.CSSProperties['textAlign']; + textDecoration?: string; + textTransform?: string; + align?: string; + verticalAlign?: React.CSSProperties['verticalAlign']; + lineHeight?: string | number; + innerPadding?: string; + width?: string | number; + height?: string | number; +} + +export class MjmlButton extends React.Component { } + +// mj-carousel +export interface MjmlCarouselProps { + backgroundColor?: React.CSSProperties['backgroundColor']; + align?: string; + borderRadius?: string | number; + thumbnails?: 'hidden' | 'visible'; + tbBorder?: React.CSSProperties['border']; + tbBorderRadius?: React.CSSProperties['borderRadius']; + tbHoverBorderColor?: string; + tbSelectedBorderColor?: string; + tbWidth?: string; + leftIcon?: string; + rightIcon?: string; + iconWidth?: string; +} + +export class MjmlCarousel extends React.Component {} + +export interface MjmlCarouselImageProps { + src?: string; + thumbnailsSrc?: string; + alt?: string; + title?: string; +} + +export class MjmlCarouselImage extends React.Component { } + +// mj-carousel +export interface MjmlColumnProps { + width?: string | number; + verticalAlign?: React.CSSProperties['verticalAlign']; + backgroundColor?: React.CSSProperties['backgroundColor']; +} + +export class MjmlColumn extends React.Component { } + +// mj-divider +export interface MjmlDividerProps { + borderColor?: React.CSSProperties['borderColor']; + borderStyle?: React.CSSProperties['borderStyle']; + borderWidth?: string | number; + width?: string | number; + containerBackgroundColor?: React.CSSProperties['backgroundColor']; +} + +export class MjmlDivider extends React.Component { } + +// mj-group +export interface MjmlGroupProps { + width?: string | number; + verticalAlign?: React.CSSProperties['verticalAlign']; + backgroundColor?: React.CSSProperties['backgroundColor']; +} + +export class MjmlGroup extends React.Component { } + +// mj-hero +export interface MjmlHeroProps { + width?: string | number; + height?: string | number; + mode?: 'fluid-height' | 'fixed-height'; + backgroundWidth?: string; + backgroundHeight?: string; + backgroundUrl?: string; + backgroundPosition?: React.CSSProperties['backgroundPosition']; + verticalAlign?: React.CSSProperties['verticalAlign']; + backgroundColor?: React.CSSProperties['backgroundColor']; +} + +export class MjmlHero extends React.Component { } + +// mj-image +export interface MjmlImageProps { + containerBackgroundColor?: React.CSSProperties['backgroundColor']; + border?: React.CSSProperties['border']; + borderRadius?: string | number; + width?: string | number; + height?: string | number; + src?: string; + srcset?: string; + alt?: string; + align?: string; + title?: string; + fluidOnMobile?: string; +} + +export class MjmlImage extends React.Component { } + +// mj-navbar +export interface MjmlNavbarProps { + baseUrl?: string; + hamburger?: 'hamburger'; + align?: string; + icoOpen?: string; + icoClose?: string; + icoPadding?: string; + icoPaddingTop?: string; + icoPaddingRight?: string; + icoPaddingBottom?: string; + icoPaddingLeft?: string; + icoAlign?: string; + icoColor?: React.CSSProperties['color']; + icoFontSize?: string; + icoTextTransform?: string; + icoTextDecoration?: string; + icoLineHeight?: string; +} + +export class MjmlNavbar extends React.Component { } + +export interface MjmlNavbarLinkProps { + color?: React.CSSProperties['color']; + fontFamily?: string; + fontSize?: string | number; + fontStyle?: string; + fontWeight?: number; + lineHeight?: string | number; + textDecoration?: string; + textTransform?: string; +} + +export class MjmlNavbarLink extends React.Component { } + +// mj-raw +export class MjmlRaw extends React.Component { } + +// mj-section +export interface MjmlSectionProps { + fullWidth?: boolean; + backgroundColor?: React.CSSProperties['backgroundColor']; + backgroundUrl?: string; + backgroundRepeat?: React.CSSProperties['backgroundRepeat']; + backgroundSize?: React.CSSProperties['backgroundSize']; + verticalAlign?: React.CSSProperties['verticalAlign']; + textAlign?: React.CSSProperties['textAlign']; + direction?: 'ltr' | 'rtl'; +} + +export class MjmlSection extends React.Component { } + +// mj-social +export interface MjmlSocialProps { + borderRadius?: string | number; + fontFamily?: string; + fontSize?: string | number; + iconSize?: string; + iconHeight?: string; + lineHeight?: string | number; + mode?: 'vertical' | 'horizontal'; + textDecoration?: string; + align?: string; + color?: React.CSSProperties['color']; + innerPadding?: string; + containerBackgroundColor?: React.CSSProperties['backgroundColor']; +} + +export class MjmlSocial extends React.Component { } + +export interface MjmlSocialElementProps { + borderRadius?: string | number; + backgroundColor?: React.CSSProperties['backgroundColor']; + fontFamily?: string; + fontSize?: string | number; + iconSize?: string; + iconHeight?: string; + lineHeight?: string | number; + mode?: 'vertical' | 'horizontal'; + textDecoration?: string; + align?: string; + color?: React.CSSProperties['color']; + name?: 'facebook' | 'facebook-noshare' | 'twitter' | 'twitter-noshare' | 'google' | 'google-noshare' | 'pinterest' | 'pinterest-noshare' | + 'linkedin' | 'linkedin-noshare' | 'tumblr' | 'tumblr-noshare' | 'xing' | 'xing-noshare' | + 'github' | 'instagram' | 'web' | 'snapchat' | 'youtube' | 'vimeo' | 'medium' | 'soundcloud' | 'dribbble'; + src?: string; + alt?: string; +} + +export class MjmlSocialElement extends React.Component { } + +// mj-spacer +export interface MjmlSpacerProps { + height?: string | number; + width?: string | number; + containerBackgroundColor?: React.CSSProperties['backgroundColor']; + verticalAlign?: React.CSSProperties['verticalAlign']; +} + +export class MjmlSpacer extends React.Component { } + +// mj-table +export interface MjmlTableProps { + color?: React.CSSProperties['color']; + cellpadding?: string; + cellspacing?: string; + fontFamily?: string; + fontSize?: string | number; + fontStyle?: string; + lineHeight?: string | number; + containerBackgroundColor?: React.CSSProperties['backgroundColor']; + width?: string | number; + tableLayout?: 'auto' | 'fixed' | 'initial' | 'inherit'; +} + +export class MjmlTable extends React.Component { } + +// mj-text +export interface MjmlTextProps { + color?: React.CSSProperties['color']; + fontFamily?: string; + fontSize?: string | number; + fontStyle?: string; + fontWeight?: number; + lineHeight?: string; + letterSpacing?: string; + height?: string | number; + textDecoration?: string; + textTransform?: string; + align?: string; + containerBackgroundColor?: React.CSSProperties['backgroundColor']; +} + +export class MjmlText extends React.Component { } + +// mj-wrapper +export interface MjmlWrapperProps { + fullWidth?: boolean; + backgroundColor?: React.CSSProperties['backgroundColor']; + backgroundUrl?: string; + backgroundRepeat?: React.CSSProperties['backgroundRepeat']; + backgroundSize?: React.CSSProperties['backgroundSize']; + verticalAlign?: React.CSSProperties['verticalAlign']; + textAlign?: React.CSSProperties['textAlign']; +} + +export class MjmlWrapper extends React.Component { } diff --git a/types/mjml-react/mjml-react-tests.tsx b/types/mjml-react/mjml-react-tests.tsx new file mode 100644 index 0000000000..7ff38e21f8 --- /dev/null +++ b/types/mjml-react/mjml-react-tests.tsx @@ -0,0 +1,40 @@ +import * as React from 'react'; +import { + render, + Mjml, + MjmlHead, + MjmlTitle, + MjmlPreview, + MjmlBody, + MjmlSection, + MjmlColumn, + MjmlButton, + MjmlImage +} from 'mjml-react'; + +function renderOutTestEmail() { + // $ExpectType { html: string; errors: Error[]; } + const result = render(( + + + Last Minute Offer + Last Minute Offer... + + + + + + + + + + + + I like it! + + + + + + ), { validationLevel: 'soft' }); +} diff --git a/types/mjml-react/tsconfig.json b/types/mjml-react/tsconfig.json new file mode 100644 index 0000000000..11cabc646f --- /dev/null +++ b/types/mjml-react/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "jsx": "react", + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true, + "strictFunctionTypes": true + }, + "files": [ + "index.d.ts", + "mjml-react-tests.tsx" + ] +} diff --git a/types/mjml-react/tslint.json b/types/mjml-react/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/mjml-react/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }