Skip to content

Commit

Permalink
feat: add support for adding dom element properties similar to @cycle…
Browse files Browse the repository at this point in the history
…/dom
  • Loading branch information
ntilwalli committed Sep 16, 2020
1 parent 2205231 commit 5ffbba0
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 6 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
/lib
/dist
/.cache
fixtures
support
plugins
node_modules
package-lock.json
pnpm-lock.yaml
Expand Down
6 changes: 5 additions & 1 deletion cypress.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{
"baseUrl": "http://localhost:1234",
"video": false
"chromeWebSecurity": false,
"defaultCommandTimeout": 10000,
"modifyObstructiveCode": false,
"video": false,
"fixturesFolder": false
}
12 changes: 12 additions & 0 deletions cypress/integration/test.spec.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
/// <reference types="cypress" />

const { watchFile } = require("fs")

context('Page load', () => {
beforeEach(() => {
cy.visit('/')
cy.wait(500)
})
describe('React integration', () => {

it('Should mount', () => {
cy.get('#app')
.should('exist', 'success')
})
it('Should have foo property on button', () => {
cy.get('.clicker')
// .its('foo')
// .should('eq', 3)
.then(($el) => {
cy.wrap($el[0].foo).should('eq', 3)
})
})
})
})
5 changes: 4 additions & 1 deletion example/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ function main(sources) {
const reset$ = sources.react
.select(btnSel)
.events('click')
.debug((ev) => {
return ev.target.printer()
})
.mapTo(() => 0);

const count$ = xs
Expand All @@ -22,7 +25,7 @@ function main(sources) {
const vdom$ = count$.map(i =>
h('div', [
h('h1', `Hello ${i} times`),
h('button', {sel: btnSel}, 'Reset'),
h('button', {sel: btnSel, className: 'clicker', domProps: {foo: 3, printer: () => console.log('domProps being used')}}, 'Reset'),
]),
);

Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,11 @@
"compile": "npm run compile-cjs && npm run compile-es6",
"compile-cjs": "tsc --module commonjs --outDir ./lib/cjs",
"compile-es6": "echo 'TODO' : tsc --module es6 --outDir ./lib/es6",
"test": "$(npm bin)/mocha test/*.ts --require ts-node/register --recursive; cypress run",
"test": "$(npm bin)/mocha test/*.ts --require ts-node/register --recursive",
"full-test": "npm test; npm run cypress:run",
"start": "parcel example/index.html",
"serve-test": "start-server-and-test start http://localhost:1234 test"
"serve-test": "start-server-and-test start http://localhost:1234 full-test",
"cypress:open": "cypress open",
"cypress:run": "cypress run"
}
}
80 changes: 78 additions & 2 deletions src/h.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import {
ElementType,
ReactHTML,
Attributes,
Component,
ComponentType,
createRef,
forwardRef
} from 'react';
import {incorporate} from './incorporate';

Expand All @@ -17,6 +21,78 @@ type PropsLike<P> = P & PropsExtensions & Attributes;

type Children = string | Array<ReactNode>;

export function domPropify(Comp: any): ComponentType<any> {
class DomProps extends Component<any, any> {
private ref: any;
private domProps: any;
constructor(props) {
super(props);
this.domProps = this.props.domProps;
this.ref = props.forwardedRef || createRef();
}

public componentDidMount() {
if (this.domProps && this.ref) {
Object.entries(this.domProps).forEach(([key, val]) => {
this.ref.current[key] = val;
});
}
}

render() {
const p: any = {ref: this.ref, ...this.props};
delete p.forwardedRef
delete p.domProps;
return createElement(Comp, p);
}
}

return forwardRef((props, ref) => {
return createElement(DomProps, {...props, forwardedRef: ref});
});
}

export function domHookify(Comp: any): ComponentType<any> {
class DomHooks extends Component<any, any> {
private ref: any;
private hooks: any;
constructor(props) {
super(props);
this.hooks = this.props.domHooks;
this.ref = props.forwardedRef || createRef();
}

public componentDidMount() {
if (this.hooks && this.hooks.insert && this.ref) {
this.hooks.insert({elm: this.ref.current})
}
}

public componentDidUpdate() {
if (this.hooks && this.hooks.update && this.ref) {
this.hooks.update({elm: this.ref.current})
}
}

public componentWillUnmount() {
if (this.hooks && this.hooks.destroy && this.ref) {
this.hooks.destroy({elm: this.ref.current})
}
}

render() {
const p: any = {ref: this.ref, ...this.props};
delete p.forwardedRef
delete p.domHooks;
return createElement(Comp, p);
}
}

return forwardRef((props, ref) => {
return createElement(DomHooks, {...props, forwardedRef: ref});
});
}

function createElementSpreading<P = any>(
type: ElementType<P> | keyof ReactHTML,
props: PropsLike<P> | null,
Expand All @@ -36,7 +112,7 @@ function hyperscriptProps<P = any>(
if (!props.sel) {
return createElement(type, props);
} else {
return createElement(incorporate(type), props);
return createElement(domHookify(domPropify(incorporate(type))), props);
}
}

Expand All @@ -55,7 +131,7 @@ function hyperscriptPropsChildren<P = any>(
if (!props.sel) {
return createElementSpreading(type, props, children);
} else {
return createElementSpreading(incorporate(type), props, children);
return createElementSpreading(domHookify(domPropify(incorporate(type))), props, children);
}
}

Expand Down

0 comments on commit 5ffbba0

Please sign in to comment.