add docs for :attrs dynamic attribute usage

This commit is contained in:
Mike 2025-04-27 09:37:28 -07:00
parent ab45819645
commit d57a3d16f6
2 changed files with 54 additions and 0 deletions

View file

@ -7,6 +7,7 @@
<c-index-sublink><a href="#named-slots" class="no-underline">Named slots</a></c-index-sublink>
<c-index-sublink><a href="#dynamic-attributes" class="no-underline">Dynamic Attributes</a></c-index-sublink>
<c-index-sublink><a href="#attrs" class="no-underline">{% verbatim %}{{ attrs }}{% endverbatim %}</a></c-index-sublink>
<c-index-sublink><a href="#attrs-merging" class="no-underline">Merging with :attrs</a></c-index-sublink>
<c-index-sublink><a href="#vars" class="no-underline">Local state with {{ '<c-vars>'|force_escape }}</a></c-index-sublink>
<c-index-sublink><a href="#boolean-attributes" class="no-underline">Boolean Attributes</a></c-index-sublink>
<c-index-sublink><a href="#dynamic-components" class="no-underline">Dynamic Components</a></c-index-sublink>
@ -209,6 +210,36 @@ context = { 'today': Weather.objects.get(...) }
{% endcotton_verbatim %}{% endverbatim %}
</c-snippet>
<c-hr id="attrs-merging" />
<h2>5.1 Merging Attributes with :attrs</h2>
<p>In addition to using <code>{% verbatim %}{{ attrs }}{% endverbatim %}</code> to output attributes, you can also pass in a dictionary of attributes using the special <code>:attrs</code> dynamic attribute. This is useful when you have a collection of attributes from your view or another component that you want to apply.</p>
<c-snippet label="cotton/input.html">{% cotton_verbatim %}{% verbatim %}
<input type="text" {{ attrs }} />
{% endcotton_verbatim %}{% endverbatim %}
</c-snippet>
<c-snippet label="form_view.html">{% cotton_verbatim %}{% verbatim %}
<!-- In your view -->
context = {
'widget_attrs': {
'placeholder': 'Enter your name',
'data-validate': 'true',
'size': '40'
}
}
<!-- In your template -->
<c-input :attrs="widget_attrs" required />
<!-- html output
<input type="text" placeholder="Enter your name" data-validate="true" size="40" required />
-->
{% endcotton_verbatim %}{% endverbatim %}
</c-snippet>
<c-hr id="vars" />
<h2>6. Defining Local Variables with <code>{{ '<c-vars />'|force_escape }}</code></h2>

View file

@ -8,6 +8,7 @@
<c-index-sublink><a href="#subfolders" class="no-underline">Subfolders</a></c-index-sublink>
<c-index-sublink><a href="#index" class="no-underline">index.html</a></c-index-sublink>
<c-index-sublink><a href="#tag-style" class="no-underline">Tag Style</a></c-index-sublink>
<c-index-sublink><a href="#attribute-proxying" class="no-underline">Attribute Proxying</a></c-index-sublink>
</c-slot>
<h3 id="basics">Basics</h3>
@ -66,6 +67,28 @@ templates/
<li>Components can either be self-closing <code>{{ "<c-my-component />"|force_escape }}</code> or have a closing tag <code>{{ "<c-my-component></c-my-component>"|force_escape }}</code></li>
</c-ul>
<c-hr />
<h3 id="attribute-proxying">Attribute Proxying Pattern</h3>
<p>A powerful pattern enabled by the special <code>:attrs</code> dynamic attribute is the ability to create wrapper components that proxy all their attributes to an inner component:</p>
<c-snippet label="cotton/proxy_component.html">{% cotton_verbatim %}{% verbatim %}
<c-inner-component :attrs="attrs">{{ slot }}</c-inner-component>
{% endcotton_verbatim %}{% endverbatim %}</c-snippet>
<c-snippet label="view.html">{% cotton_verbatim %}{% verbatim %}
<c-proxy-component
class="outer-class"
:count="42"
:enabled="False">
Content passed to inner component
</c-proxy-component>
{% endcotton_verbatim %}{% endverbatim %}</c-snippet>
<p>The attributes are passed through to the inner component with their original types preserved (strings, numbers, booleans, lists, etc.), making this pattern ideal for creating higher-order components.</p>
<p>This pattern is particularly useful for Django form fields, where you might create a component hierarchy that passes Django widget attributes through multiple layers while adding labels, error handling, and styling at each level.</p>
<c-navigation>
<c-slot name="prev">