phosphorjs / phosphor

The PhosphorJS Library
BSD 3-Clause "New" or "Revised" License
1.03k stars 166 forks source link

TSX Support for Phosphor vdom API #279

Open ellisonbg opened 7 years ago

ellisonbg commented 7 years ago

We have been able to get TSX syntax working with phosphor's virtualdom package. The needed steps are the following:

First, add the following lines to you tsconfig.json:

    "jsx": "react",
    "jsxFactory": "h"

Second, import the phosphor virtual DOM library:

import {
  h, VirtualDOM, VirtualElement, ElementAttrs
} from '@phosphor/virtualdom';

Third, add this to one of your ts files to provide the types needed:

declare global {

  namespace JSX {
    interface IntrinsicElements {
      a: ElementAttrs;
      abbr: ElementAttrs;
      address: ElementAttrs;
      area: ElementAttrs;
      article: ElementAttrs;
      aside: ElementAttrs;
      audio: ElementAttrs;
      b: ElementAttrs;
      bdi: ElementAttrs;
      bdo: ElementAttrs;
      blockquote: ElementAttrs;
      br: ElementAttrs;
      button: ElementAttrs;
      canvas: ElementAttrs;
      caption: ElementAttrs;
      cite: ElementAttrs;
      code: ElementAttrs;
      col: ElementAttrs;
      colgroup: ElementAttrs;
      data: ElementAttrs;
      datalist: ElementAttrs;
      dd: ElementAttrs;
      del: ElementAttrs;
      dfn: ElementAttrs;
      div: ElementAttrs;
      dl: ElementAttrs;
      dt: ElementAttrs;
      em: ElementAttrs;
      embed: ElementAttrs;
      fieldset: ElementAttrs;
      figcaption: ElementAttrs;
      figure: ElementAttrs;
      footer: ElementAttrs;
      form: ElementAttrs;
      h1: ElementAttrs;
      h2: ElementAttrs;
      h3: ElementAttrs;
      h4: ElementAttrs;
      h5: ElementAttrs;
      h6: ElementAttrs;
      header: ElementAttrs;
      hr: ElementAttrs;
      i: ElementAttrs;
      iframe: ElementAttrs;
      img: ElementAttrs;
      input: ElementAttrs;
      ins: ElementAttrs;
      kbd: ElementAttrs;
      label: ElementAttrs;
      legend: ElementAttrs;
      li: ElementAttrs;
      main: ElementAttrs;
      map: ElementAttrs;
      mark: ElementAttrs;
      meter: ElementAttrs;
      nav: ElementAttrs;
      noscript: ElementAttrs;
      object: ElementAttrs;
      ol: ElementAttrs;
      optgroup: ElementAttrs;
      option: ElementAttrs;
      output: ElementAttrs;
      p: ElementAttrs;
      param: ElementAttrs;
      pre: ElementAttrs;
      progress: ElementAttrs;
      q: ElementAttrs;
      rp: ElementAttrs;
      rt: ElementAttrs;
      ruby: ElementAttrs;
      s: ElementAttrs;
      samp: ElementAttrs;
      section: ElementAttrs;
      select: ElementAttrs;
      small: ElementAttrs;
      source: ElementAttrs;
      span: ElementAttrs;
      strong: ElementAttrs;
      sub: ElementAttrs;
      summary: ElementAttrs;
      sup: ElementAttrs;
      table: ElementAttrs;
      tbody: ElementAttrs;
      td: ElementAttrs;
      textarea: ElementAttrs;
      tfoot: ElementAttrs;
      th: ElementAttrs;
      thead: ElementAttrs;
      time: ElementAttrs;
      title: ElementAttrs;
      tr: ElementAttrs;
      track: ElementAttrs;
      u: ElementAttrs;
      ul: ElementAttrs;
      var_:ElementAttrs;
      video: ElementAttrs;
      wbr: ElementAttrs;
    }

    interface Element extends VirtualElement {}
  }

}

Then you can name files with the .tsx extension and use TSX syntax.

@blink1073 @sccolbert @grantnestor

gnestor commented 7 years ago

https://github.com/phosphorjs/phosphor/pull/281 adds support for custom elements in JSX.

A custom element (modeled after React functional/stateless components):

const CustomElement = props => <button onClick={props.onClick}>{props.label}</button>

Rendering a custom element in JSX:

VirtualDOM.render(
    <div>
        <span>Test</span>
        <CustomElement label="Test" onclick={() => { console.log('clicked') }} />
    </div>,
    node
);
gnestor commented 7 years ago

https://github.com/phosphorjs/phosphor/pull/282 switches from no-case to camel-case for element attribute and event names in order support rendering React functional/stateless components using Phosphor's virtualdom.

sccolbert commented 7 years ago

Should Button in the example above be CustomElement?

gnestor commented 7 years ago

Yes 😋