Created
March 25, 2018 19:03
-
-
Save bcherny/7bde28f59519d826a99edd87fb348a4d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // hyperscript and React-inspired DSL | |
| // "react in 50 lines" | |
| void function() { | |
| /////////// tags | |
| type Tagish = string | Tag | |
| type Attrs = { | |
| className: string | |
| [k: string]: any | |
| } | |
| class Tag<T extends string = string> { | |
| constructor( | |
| private type: T, | |
| public children: Tagish[], | |
| private attrs: Partial<Attrs> | |
| ) { } | |
| attr(as: Partial<Attrs>) { | |
| return new Tag( | |
| this.type, | |
| this.children, | |
| { ...this.attrs, ...as } | |
| ) | |
| } | |
| toHTML() { | |
| let html = document.createElement(this.type) | |
| for (let attr in this.attrs) { | |
| html.setAttribute(attr, this.attrs[attr]) | |
| } | |
| return html | |
| } | |
| } | |
| let tag = <T extends string>(type: T) => | |
| (...children: Tagish[]) => | |
| new Tag(type, children, {}) | |
| let div = tag('div') | |
| let a = tag('a') | |
| let dom = a( | |
| div('hello world').attr({ className: 'a' }) | |
| ) | |
| ////////// components | |
| type XProps = { | |
| a: number | |
| } | |
| let x = ({ a }: XProps) => | |
| div( | |
| '(x) a is ', | |
| a.toString(), | |
| y({ a, b: true }) | |
| ) | |
| type YProps = { | |
| a: number | |
| b: boolean | |
| } | |
| let y = ({ a, b }: YProps) => | |
| div('(y) a is ', a.toString(), ' and b is ', b.toString()) | |
| let dom2 = a( | |
| div('hello world').attr({ className: 'a' }), | |
| x({ a: 120 }) | |
| ) | |
| ////////// renderer | |
| function render( | |
| dom: Tagish, | |
| container: Element | |
| ) { | |
| if (typeof dom === 'string') { | |
| container.textContent = dom | |
| } else { | |
| let html = dom.toHTML() | |
| dom.children.forEach(_ => render(_, html)) | |
| container.appendChild(html) | |
| } | |
| } | |
| render(dom2, document.body) | |
| /////////// TODO: JSX parser | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment