How to change child child value?
https://stackblitz.com/edit/github-gp2gff?file=src%2FApp.tsx
I'm trying to make some kind of parser, but I don't know how to fix this problem. Any help?
16 Replies
Is there anyway to make changes to
resolve().children
?
I could do resolve().innerHTML = "Change"
but that does not log the new updated value in the CustomLink
component.
Is there basically anyway way to update the children before resolving it 🤔
I think this can be done in React, using CloneElement or something
I'm guessing the way solidjs works, this is not possible
Could anyone confirm thismm yes so two things: 1. jsx resolves to DOM-elements directly, as you can see when you log resolved(): it is an actual span, that's why the innerHTML works, but it also means without some hackery, you can not interface w the component by resolving the children. 2. the console.log in CustomLink will always log once, even if you would have changed props of resolve() somehow, since the component is only run when it is mount.
it is however possible to do what u wanna do (at least if what u wanna do is what i think u wanna do)
i tried to make my own custom renderer/parser type thing for https://github.com/bigmistqke/plasticinecms
for which i wanted to write cms-schemas with jsx
the secret sauce was https://github.com/bigmistqke/plasticinecms/blob/master/src/plasticine/helpers/register.ts where i would wrap all my ui-elements in this register function, which would wrap the JSX in an object+callback-function.
a simplified version of this could be: https://stackblitz.com/edit/github-gp2gff-ez3jnk?file=src%2FApp.tsx
it works, but it will give u some type-errors.
mm tried to write a more generalized version typesafe version, but i am getting a bit lost lol
wanna add it to solid-primitives? 🙂
cool idea!
i think i cracked the code: https://stackblitz.com/edit/github-gp2gff-ez3jnk?file=src%2FApp.tsx
idk how you could generalize it that it could become a part of solid-primitives, feel like it might always be a bit specific to ur set-up. mb u wanna have a look at it @thetarnav ?
https://stackblitz.com/edit/github-gp2gff-wcrbbx?file=src%2FApp.tsx fixed types and allowed for multiple elements + html elements to be added in the parser.
important to note that my implementation seems to lose reactivity from outside of parser https://stackblitz.com/edit/github-gp2gff-snknsc?file=src%2FApp.tsx
ok lol enough procrastination 🤣
Object.assign
might be the killer
it flattens getters to values
mergeProps
is actually a good replacement xdinstead of Object.assign?
u were right. good old spreading of the props lol, without the spread it's fine. https://stackblitz.com/edit/github-gp2gff-ubyara?file=src%2FApp.tsx
i think this could be a nice abstraction for solid-primitives https://stackblitz.com/edit/github-gp2gff-p7n21p?file=src%2FApp.tsx,src%2FParser.tsx pretty flexible and hides a lot of the ugliness. added an extra parameter for the tokenize/wrap-function where u can add metadata for the token, this u can then use inside the Parser to do something with. in the case of the blitz i make it perform a sum by having an Increment- and Decrement-token, but I think it's pretty flexible in what u can do with it. wdyt @thetarnav ?
I like this.
This is a similar pattern that we used at solid-aria.
It would be great to "standarize" it this way.
Not sure if
tokenize
should just render the element if not wrapped with the parser. This seems like something that could be configurable. In case of solid-aria, the child elements were only used for configuration with jsx, they had no way to render anything. so it doesn't make sense to just render them. Similarly to how <Route> works in solid-router or <Match> in solid.
The parser should have some way of filtering tokenized components from other stuff. Like if you pass is an element does it have to break?
I think it would be better to move createParser
to the CustomParser component definition. Because in a sense parsing is just a way to transform prop.children
into tokens that you can use how you want.
So it could have a form of a function, similar to children()
Also the validation is weird. Just as you might pass normal elements to the parser, or other components, you also have to lie to typescript about the received data from children. I guess the tokens might be just unknown
by default, and user would validate them how (if) he wanted or just typecast to whatever.
tokenize
should probably accept another generic for the meta data. Also it probably doesn't have to be an object.
This is like a discord pr review, cool 😎haha lol ye really hijacked this question here
think it would be better to move createParser to the CustomParser component definition. Because in a sense parsing is just a way to transform prop.children into tokens that you can use how you want.
So it could have a form of a function, similar to children()
yes that's a good one. might be handy to with what i was dealing w right now: how to deal with nested components.
https://stackblitz.com/edit/github-gp2gff-ebp4b6?file=src%2FApp.tsx,src%2FParser.tsx i have this now going for nested components, where all the parsing is done in the Parser
but it would be kinda cool if you could do that logic inside Nested instead, and then manipulate what its props is from the pov of Parser.true,
tokenize
should have a way to run logic as it's being parsed, so that it could parse it's children first ans pass them to the parenthttps://stackblitz.com/edit/github-gp2gff-jrqg6w?file=src%2FApp.tsx,src%2FParser.tsx here we go. childrenTokens now validates/filters its children by checking for a Symbol, and we pass the same props of the Token-component to a callback function in tokenize. can be handy for doing some imperative code too, like doing some threejs-calls. would be fun to try a threejs-renderer out with this set-up.
https://codesandbox.io/p/github/bigmistqke/solid-three-parser/draft/funny-rgb?file=%2Fsrc%2FApp.tsx&selection=%5B%7B%22endColumn%22%3A51%2C%22endLineNumber%22%3A21%2C%22startColumn%22%3A51%2C%22startLineNumber%22%3A21%7D%5D made a rough ThreeParser with it. I removed the JSX-component and moved the callback-function as the first parameter of tokenize. With childrenTokens you can easily move the parser-logic to the tokens itself. P.ex the logic to hook up nested children i could extract to a function that is just passed into all the three-components that need it, the root-element Canvas where the scene is set and all its children are added but also all other three-components that can have children.
You could use it to also render out JSX, so it could also be used as the component-function if you would like to. right now the callback does not have any parameters itself, u just call it
token.callback()
, when calling the component-props are just passed in inside tokenize(). maybe we could have it pass props too and that they are merged with the component-parameters, or maybe they are two seperate parameters that come into the component: compononent-props and parser-parameters or something?
I think after the three-renderer I wanna make a simplified version of plasticine with it, since with that one I wanted to use the callback-function to write html-templates, and the parser was there to inject data, so it's nice how different of a usecase that is to test the flexibility of the api.i created a pr btw, we can continue the convo over there https://github.com/solidjs-community/solid-primitives/pull/276
GitHub
feat: solid-primitives-parser by bigmistqke · Pull Request #276 · s...
A primitive to tokenize your solid-components to enable custom parsing/custom renderers.
It exists out of two parts, tokenize() and childrenTokens():
const token = tokenize(callback, meta)
takes ...