-
-
Notifications
You must be signed in to change notification settings - Fork 228
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
proposal: support HTML style component authoring #663
Comments
I think we did talk a bit about this syntax when we were designing block components. I think we opted for the current syntax because it is fewer mental jumps when thinking about it. In this syntax would we support the existing syntax or would this replace it? |
I think it could be a little confusing that the attributes in the struct are StartCased and we would use them lowercased in the proposed syntax. Maybe this would be less confusing?
Also, how much work would it take to make the LSP correctly suggest |
Just had a look out of curiosity, and webcomponents do not support In terms of prop names, could be a use for field tags, but LSP might be difficult:
|
+1 to this idea.
So I changed to something like this to avoid the
Being able to write like below would feel much better
|
I would vote against this idea. I believe that the ViewModel abstraction and it's implementation in the current state are very well thought and give you exactly what you'd expect as a resulting component, coming from go. You get the exact behavior you want with little overhead. Something like this...
... feels very natural to me. In one of my projects we define a ViewModel for a FormPage(.templ) for example with multiple inputs and just iterate over the configured inputs. This way you'd only have to call your component once and you can define a primary entrance point to InputComponent behavior. This also makes working with templ a breeze, since you can create and test the ViewModel inside of a go file. This way the LoginPage can just have some styling and a FormPage inside. Maybe I haven't understood completely what's the benefit here 😅 |
FWIW here's another data point. I have no opinions on the View Model component declaration side of things, but would certainly advocate for bringing the component usage closer to HTML.
IMO the competition of any HTML templating language is not Go, its HTML. At my work we have an in-house (React) variant & constraint based design system, and just skimming through a random page in dev tools, I can see that 90%+ elements are individually wrapped in a React component (e.g. In a system like that, which I believe are increasingly common, you really need a JSX like system, that reduces the friction of switching from native DOM elements to a higher order constructs atop them to almost zero. I think it would be fantastic if Templ could achieve something similar. |
Just to clarify the intent, would the idea be that you could create a struct like the one defined and use it like?
If the goal is to help avoid the boilerplate of passing in the necessary state to the subsequent child templates, I don't see how this would solve for that. The caller would still likely need to pass in the data that would end up as arguments to the underly component.
I gather you could instantiate a component and pass that to the renderer, in which case it would be available as a web component.
I can see this being beneficial because it might be easier for a library to return something in a more reusable format without forcing the caller to pass everything. For example, if I had a component defined that allowed adjusting classes used, I could import the pkg, adjust the css/classes and pass that in without having to change the arguments to my entrypoint component. Offhand, I'm not sure about the HTML syntax, but I do see the benefit of adding instances of structs generated at runtime that can be used. My comment here is to primarily to clarify some details for myself, and hopefully others. |
I thought about this a lot the last couple of days. I researched a lot of component libraries (like shoelace.style which joined font-awesome, or microsofts FAST ui) and thus I might be biased to writing @a-h just as a stupid question from somebody that is not deep in parsing: Do you think it would be possible to allow for the Maybe this is something we shouldn't do? I'm just curious. |
Maybe another point to consider: How to set a default value if a field is not set. In the current version, if I have a templ component like this:
In the above, there is a lot of parameters. It's hard to see what's what when it's called.
Also the last two parameters, I'd like to have them as default values. i.e. With this and #713 , there can be a nice pattern for this? |
@jackielii for your case I would probably use #713 to assign defaults to a struct: type textFieldProps struct {
id, name, label, value, err string
span int
disabled bool
}
templ textField(props textFieldProps) {
{{ props.span = cmp.Or(props.span, 3) }}
<div class={ fmt.Sprintf("sm:col-span-%d", props.span) }>
<label for={ id } class="block text-sm font-medium leading-6 text-gray-900">{ props.label }</label>
<div class="mt-2">
<input type="text" name={ props.name } id={ props.id } value={ props.value } autocomplete={ props.name } disabled?={ props.disabled } class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6 disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-500 disabled:ring-gray-200"/>
</div>
@inputError(props.name, props.err)
</div>
} @textField(textField{ id: "name", name: "name", label: "Name", value: name, err: errs["name"] }) |
Methods on the struct could also work. type TextFieldProps struct {
id, name, label, value, err string
span int
disabled bool
}
func (tfp TextFieldProps) ID() string {
return tfp.id
}
func (tfp TextFieldProps) Name() string {
return tfp.name
}
func (tfp TextFieldProps) Span() int {
if tfp.span > 0 {
return tfp.span
}
return 3
} However, you have to remember to reference the method on the struct, and not access the internal variable. |
Would templ benefit from a similar concept to React of props where, if you have a single argument to a React component, you can use a HTML style to use it?
i.e. given the following TypeScript:
You can use this style in JSX:
In templ, it might look like:
You could then write this:
The struct fields would be populated with attribute values using reflection at generation time to match the attributes to field names. The LSP would warn about unknown fields.
The text was updated successfully, but these errors were encountered: