-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add support for adding dom element properties #11
base: master
Are you sure you want to change the base?
Conversation
Hey @ntilwalli, I'll make some questions just to understand your use case: since this |
@staltz, thanks for the response. I'm not clear on the question. Are you wondering why this My use-case is wanting to set custom attributes on my input elements to have lambda values, as far as I can tell that's not possible (only strings and numbers are valid attribute values). I use this functionality for my custom forms implementation. By attaching reducer lambdas directly to Basically during intent I want to access a value on the element that is not encodable in an attribute or Having Did I answer your question? |
I see now, thanks. Because we're using React (and its huge ecosystem), I'm keen to see what can we do on the React side before we look into implementing this into cycle/react(-dom). Like you said, this was implemented in That said, I couldn't find anything about |
The term It would ideally be added to the functionality of The reference to |
I see, you want parity between snabbdom and cycle/react hyperscript as much as possible, to facilitate migration. I think there's something decent that can be created here, which isn't quite a fork of cycle/react. There could be a library, perhaps |
Yeah, that's a good idea, but you seem to imply that it can be accomplished by a How can snabbdom's |
Yeah, honestly figuring out the "tricks" that were needed in cycle/react were not obvious at all. I could be wrong, but I believe in your case the implementation is possible as a composition of React components. E.g. I think one good way to go about this is modifying this PR until we figure out what parts can be put in a separate library. I'm curious myself to try this out, good that you have tests for it already. |
I got this far: I created file 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 = 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.domProps;
return createElement(Comp, p);
}
}
return DomProps;
}
// ...
function hyperscriptProps<P = any>(
type: ElementType<P> | keyof ReactHTML,
props: PropsLike<P>,
): ReactElement<P> {
if (!props.sel) {
return createElement(type, props);
} else {
return createElement(domPropify(incorporate(type)), props);
}
} The tests are a bit "broken" because there is actually no This is the test (broken because I'm using it.only('applies domProps to element when given', (done) => {
function main(sources: {react: ReactSource}) {
const inc$ = sources.react.select('button').events('press');
const count$ = inc$.fold((acc: number, ev: any) => acc + ev.target.blah, 0);
const vdom$ = count$.map((i: number) =>
h2(Touchable, {sel: 'button'}, [h2('div', [h2('h1', {}, '' + i)])]),
);
return {react: vdom$};
}
let turn = 0;
const RootComponent = makeCycleReactComponent(() => {
const source = new ReactSource();
const sink = main({react: source}).react;
return {source, sink};
});
const r = renderer.create(createElement(RootComponent));
const root = r.root;
const check = () => {
const to = root.findByType(Touchable);
const view = to.props.children;
const text = view.props.children;
assert.strictEqual(text.props.children, `${turn * 3}`);
to.instance.press();
turn++;
if (turn === 3) {
done();
}
};
setTimeout(check, 50);
setTimeout(check, 100);
setTimeout(check, 150);
}); I'll go to sleep now but I thought this might be useful to you. |
0e857f1
to
e839997
Compare
Dunno if cypress tests are appropriate but I added one (can remove if there's a leaner way). As of now that test is really wonky. I had to use a |
I integrated your
Is anything missing? |
You could consider implementing all those HOC functions as just one function. It might not be a big problem for performance, but it might still affect performance. And/or you could consider allowing third-party HOCs much like snabbdom allows third-party "modules". Maybe someone has a codebase with custom snabbdom modules that they'd like to support an alternative to when migrating to cycle/react. Just to make sure though, you intend to make a separate library for
|
I would have no issue making this a separate package, but given the updated modules orientation around the latest implementation (and it's seamlessness with the current approach), I wonder, why not just merge directly? There would be a very minor perf hit due to the testing of modules enablement on each render, but prob inconsequential since it's
Suggestions/critiques are welcome. |
99e0242
to
af1e440
Compare
d2f4e66
to
ad494e1
Compare
Hey @ntilwalli, your new solution is overall smaller and slicker, but I'm hesitant to do deep changes in It would be best if Cycle React could do only what it proposed to do in the readme:
A "Snabbdom-like abstraction for cycle/react" is a departure from the features listed above, deserving its own module. |
3b66b1f
to
51678d7
Compare
@staltz I've integrated your feedback. |
This feature is an attempt to offer the same dom
props
functionality offered by VNodes in@cycle/dom
. I've chosen to name the special propdomProps
but that could obviously be changed. I would find this feature useful but dunno if it's more appropriate as a fork. I use this feature to sometimes tag elements with lambdas that I want applied in some reducers. As it currently stands (if my understanding is correct) only attributes are supported which limits element-specific data to strings and numbers only.Usage:
Not necessarily expecting a merge, just looking for simple feedback for now.
This PR follows #10