## Components
`@rest` can be used to specify additional named attributes.
```neovim {"update":true,"path":"_/code/17359144908861.ex","timestamp":1735914493891}
<pre>
<span class="-variable"><span class="-function">attr</span></span> <span class="SpecialChar">:message</span><span class="Delimiter">,</span> <span class="SpecialChar">:string</span><span class="Delimiter">,</span> <span class="SpecialChar">required: </span><span class="-boolean">true</span>
<span class="-variable"><span class="-function">attr</span></span> <span class="SpecialChar">:rest</span><span class="Delimiter">,</span> <span class="SpecialChar">:global</span>
<span class="Comment"><span class="-spell"># Can also provide defaults</span></span>
<span class="-variable"><span class="-function">attr</span></span> <span class="SpecialChar">:rest</span><span class="Delimiter">,</span> <span class="SpecialChar">:global</span><span class="Delimiter">,</span> <span class="SpecialChar">default: </span><span class="Special">%</span><span class="Delimiter">{</span><span class="SpecialChar">class: </span><span class="String">"bg-blue-200"</span><span class="Delimiter">}</span>
<span class="Comment"><span class="-spell"># Can also limit which fields are included</span></span>
<span class="-variable"><span class="-function">attr</span></span> <span class="SpecialChar">:rest</span><span class="Delimiter">,</span> <span class="SpecialChar">:global</span><span class="Delimiter">,</span> <span class="SpecialChar">include: </span><span class="SpecialChar">~</span><span class="SpecialChar"><span class="-_sigil_name">w</span></span><span class="Delimiter"><span class="SpecialChar">(</span></span>form<span class="Delimiter"><span class="SpecialChar">)</span></span>
<span class="-variable"><span class="-function"><span class="-keyword">def</span></span></span> <span class="-variable"><span class="-function"><span class="-function">notification</span></span></span><span class="Delimiter">(</span><span class="-variable">assigns</span><span class="Delimiter">)</span><span class="-keyword">do</span>
<span class="SpecialChar">~</span><span class="SpecialChar"><span class="-_sigil_name">H</span></span><span class="SpecialChar">"""</span>
<span class="Tag"><</span><span class="Tag">span</span> <span class="Tag">{</span><span class="Operator"><span class="-constant">@</span></span><span class="-constant"><span class="-variable"><span class="-constant">rest</span></span></span><span class="Tag">}</span><span class="Tag">></span><span class="Tag">{</span><span class="Tag">@message</span><span class="Tag">}</span><span class="Tag"></</span><span class="Tag">span</span><span class="Tag">></span>
<span class="SpecialChar">"""</span>
<span class="-keyword">end</span>
<span class="Comment"><span class="-spell"># Later</span></span>
<span class="SpecialChar">~</span><span class="SpecialChar"><span class="-_sigil_name">H</span></span><span class="SpecialChar">"""</span>
<span class="Tag"><</span><span class="Delimiter">.</span><span class="-function">notification</span> <span class="Tag">message</span><span class="Operator">=</span><span class="String">"<span class="String">You've got mail!</span>"</span> <span class="Tag">class</span><span class="Operator">=</span><span class="String">"<span class="String">bg-green-200</span>"</span> <span class="Tag">phx-click</span><span class="Operator">=</span><span class="String">"<span class="String">close</span>"</span> <span class="Tag">/></span>
<span class="SpecialChar">"""</span>
</pre>
```
^17359144908861
Can also specify prefixes to include automatically:
```neovim {"update":true,"path":"_/code/17359144908670.ex","timestamp":1735914493459}
<pre>
<span class="-variable"><span class="-function"><span class="-keyword">use</span></span></span> <span class="-module">Phoenix.Component</span><span class="Delimiter">,</span> <span class="SpecialChar">global_prefixes: </span><span class="SpecialChar">~</span><span class="SpecialChar"><span class="-_sigil_name">w</span></span><span class="Delimiter"><span class="SpecialChar">(</span></span>x-<span class="Delimiter"><span class="SpecialChar">)</span></span>
</pre>
```
^17359144908670
## Slots
```neovim {"update":true,"path":"_/code/1735914673281.ex","timestamp":1735914685442}
<pre>
<span class="-variable"><span class="-function">slot</span></span> <span class="SpecialChar">:inner_block</span><span class="Delimiter">,</span> <span class="SpecialChar">required: </span><span class="-boolean">true</span>
<span class="-variable"><span class="-function"><span class="-keyword">def</span></span></span> <span class="-variable"><span class="-function"><span class="-function">button</span></span></span><span class="Delimiter">(</span><span class="-variable">assigns</span><span class="Delimiter">)</span> <span class="-keyword">do</span>
<span class="SpecialChar">~</span><span class="SpecialChar"><span class="-_sigil_name">H</span></span><span class="SpecialChar">"""</span>
<span class="Tag"><</span><span class="Tag">button</span><span class="Tag">></span>
<span class="Tag">{</span><span class="Tag">render_slot(@inner_block)</span><span class="Tag">}</span>
<span class="Tag"></</span><span class="Tag">button</span><span class="Tag">></span>
<span class="SpecialChar">"""</span>
<span class="-keyword">end</span>
</pre>
```
^1735914673281
Like the attr/3 macro, using the slot/3 macro will provide compile-time validations. For example, invoking button/1 without a slot of HEEx content will result in a compilation warning being emitted:
Can also pass non-default options though (inner_block is the default one):
```neovim {"update":true,"path":"_/code/1735915098301.ex","timestamp":1735915143049}
<pre>
<span class="-variable"><span class="-function">slot</span></span> <span class="SpecialChar">:inner_block</span><span class="Delimiter">,</span> <span class="SpecialChar">required: </span><span class="-boolean">true</span>
<span class="-variable"><span class="-function">attr</span></span> <span class="SpecialChar">:entries</span><span class="Delimiter">,</span> <span class="SpecialChar">:list</span><span class="Delimiter">,</span> <span class="SpecialChar">default: </span><span class="Delimiter">[</span><span class="Delimiter">]</span>
<span class="-variable"><span class="-function"><span class="-keyword">def</span></span></span> <span class="-variable"><span class="-function"><span class="-function">unordered_list</span></span></span><span class="Delimiter">(</span><span class="-variable">assigns</span><span class="Delimiter">)</span> <span class="-keyword">do</span>
<span class="SpecialChar">~</span><span class="SpecialChar"><span class="-_sigil_name">H</span></span><span class="SpecialChar">"""</span>
<span class="Tag"><</span><span class="Tag">ul</span> :for<span class="Operator">=</span><span class="Tag">{</span><span class="-variable">entry</span> <span class="Operator"><-</span> <span class="Operator"><span class="-constant">@</span></span><span class="-constant"><span class="-variable"><span class="-constant">entries</span></span></span><span class="Tag">}</span><span class="Tag">></span>
<span class="Tag"><</span><span class="Tag">li</span><span class="Tag">></span><span class="Tag">{</span><span class="Tag">render_slot(@inner_block,</span> <span class="Tag">entry)</span><span class="Tag">}</span><span class="Tag"></</span><span class="Tag">li</span><span class="Tag">></span>
<span class="Tag"></</span><span class="Tag">ul</span><span class="Tag">></span>
<span class="SpecialChar">"""</span>
<span class="-keyword">end</span>
<span class="Comment"><span class="-spell"># ... later</span></span>
<span class="SpecialChar">~</span><span class="SpecialChar"><span class="-_sigil_name">H</span></span><span class="SpecialChar">"""</span>
<span class="Tag"><</span><span class="Delimiter">.</span><span class="-function">unordered_list</span> :let<span class="Operator">=</span><span class="Tag">{</span><span class="-variable">fruit</span><span class="Tag">}</span> <span class="Tag">entries</span><span class="Operator">=</span><span class="Tag">{</span><span class="SpecialChar">~</span><span class="SpecialChar"><span class="-_sigil_name">w</span></span><span class="Delimiter"><span class="SpecialChar">(</span></span>apples bananas cherries<span class="Delimiter"><span class="SpecialChar">)</span></span><span class="Tag">}</span><span class="Tag">></span>
I like <span class="Tag"><</span><span class="Tag">b</span><span class="Tag">></span><span class="Tag">{</span><span class="Tag">fruit</span><span class="Tag">}</span><span class="Tag"></</span><span class="Tag">b</span><span class="Tag">></span>!
<span class="Tag"></</span><span class="Delimiter">.</span><span class="-function">unordered_list</span><span class="Tag">></span>
<span class="SpecialChar">"""</span>
</pre>
```
^1735915098301
And other named slots
```neovim {"update":true,"path":"_/code/1735915452280.ex","timestamp":1735915948505}
<pre>
<span class="-variable"><span class="-function">slot</span></span> <span class="SpecialChar">:header</span>
<span class="-variable"><span class="-function">slot</span></span> <span class="SpecialChar">:inner_block</span><span class="Delimiter">,</span> <span class="SpecialChar">required: </span><span class="-boolean">true</span>
<span class="-variable"><span class="-function">slot</span></span> <span class="SpecialChar">:footer</span><span class="Delimiter">,</span> <span class="SpecialChar">required: </span><span class="-boolean">true</span>
<span class="-variable"><span class="-function"><span class="-keyword">def</span></span></span> <span class="-variable"><span class="-function"><span class="-function">modal</span></span></span><span class="Delimiter">(</span><span class="-variable">assigns</span><span class="Delimiter">)</span> <span class="-keyword">do</span>
<span class="SpecialChar">~</span><span class="SpecialChar"><span class="-_sigil_name">H</span></span><span class="SpecialChar">"""</span>
<span class="Tag"><</span><span class="Tag">div</span> <span class="Tag">class</span><span class="Operator">=</span><span class="String">"<span class="String">modal</span>"</span><span class="Tag">></span>
<span class="Tag"><</span><span class="Tag">div</span> <span class="Tag">class</span><span class="Operator">=</span><span class="String">"<span class="String">modal-header</span>"</span><span class="Tag">></span>
<span class="Tag">{</span><span class="Tag">render_slot(@header)</span> <span class="Tag">||</span> "<span class="Tag">Modal</span>"<span class="Tag">}</span>
<span class="Tag"></</span><span class="Tag">div</span><span class="Tag">></span>
<span class="Tag"><</span><span class="Tag">div</span> <span class="Tag">class</span><span class="Operator">=</span><span class="String">"<span class="String">modal-body</span>"</span><span class="Tag">></span>
<span class="Tag">{</span><span class="Tag">render_slot(@inner_block)</span><span class="Tag">}</span>
<span class="Tag"></</span><span class="Tag">div</span><span class="Tag">></span>
<span class="Tag"><</span><span class="Tag">div</span> <span class="Tag">class</span><span class="Operator">=</span><span class="String">"<span class="String">modal-footer</span>"</span><span class="Tag">></span>
<span class="Tag">{</span><span class="Tag">render_slot(@footer)</span><span class="Tag">}</span>
<span class="Tag"></</span><span class="Tag">div</span><span class="Tag">></span>
<span class="Tag"></</span><span class="Tag">div</span><span class="Tag">></span>
<span class="SpecialChar">"""</span>
<span class="-keyword">end</span>
<span class="Comment"><span class="-spell"># ....</span></span>
<span class="SpecialChar">~</span><span class="SpecialChar"><span class="-_sigil_name">H</span></span><span class="SpecialChar">"""</span>
<span class="Tag"><</span><span class="Delimiter">.</span><span class="-function">modal</span><span class="Tag">></span>
This is the body, everything not in a named slot is rendered in the default slot.
<span class="Tag"><:</span><span class="Tag">footer</span><span class="Tag">></span>
This is the bottom of the modal.
<span class="Tag"></:</span><span class="Tag">footer</span><span class="Tag">></span>
<span class="Tag"></</span><span class="Delimiter">.</span><span class="-function">modal</span><span class="Tag">></span>
<span class="SpecialChar">"""</span>
<span class="Comment"><span class="-spell"># More complicated example</span></span>
<span class="-variable"><span class="-function">slot</span></span> <span class="SpecialChar">:column</span><span class="Delimiter">,</span> <span class="SpecialChar">doc: </span><span class="String">"Columns with column labels"</span> <span class="-keyword">do</span>
<span class="-variable"><span class="-function">attr</span></span> <span class="SpecialChar">:label</span><span class="Delimiter">,</span> <span class="SpecialChar">:string</span><span class="Delimiter">,</span> <span class="SpecialChar">required: </span><span class="-boolean">true</span><span class="Delimiter">,</span> <span class="SpecialChar">doc: </span><span class="String">"Column label"</span>
<span class="-keyword">end</span>
<span class="-variable"><span class="-function">attr</span></span> <span class="SpecialChar">:rows</span><span class="Delimiter">,</span> <span class="SpecialChar">:list</span><span class="Delimiter">,</span> <span class="SpecialChar">default: </span><span class="Delimiter">[</span><span class="Delimiter">]</span>
<span class="-variable"><span class="-function"><span class="-keyword">def</span></span></span> <span class="-variable"><span class="-function"><span class="-function">table</span></span></span><span class="Delimiter">(</span><span class="-variable">assigns</span><span class="Delimiter">)</span> <span class="-keyword">do</span>
<span class="SpecialChar">~</span><span class="SpecialChar"><span class="-_sigil_name">H</span></span><span class="SpecialChar">"""</span>
<span class="Tag"><</span><span class="Tag">table</span><span class="Tag">></span>
<span class="Tag"><</span><span class="Tag">tr</span><span class="Tag">></span>
<span class="Tag"><</span><span class="Tag">th</span> :for<span class="Operator">=</span><span class="Tag">{</span><span class="-variable">col</span> <span class="Operator"><-</span> <span class="Operator"><span class="-constant">@</span></span><span class="-constant"><span class="-variable"><span class="-constant">column</span></span></span><span class="Tag">}</span><span class="Tag">></span><span class="Tag">{</span><span class="Tag">col.label</span><span class="Tag">}</span><span class="Tag"></</span><span class="Tag">th</span><span class="Tag">></span>
<span class="Tag"></</span><span class="Tag">tr</span><span class="Tag">></span>
<span class="Tag"><</span><span class="Tag">tr</span> :for<span class="Operator">=</span><span class="Tag">{</span><span class="-variable">row</span> <span class="Operator"><-</span> <span class="Operator"><span class="-constant">@</span></span><span class="-constant"><span class="-variable"><span class="-constant">rows</span></span></span><span class="Tag">}</span><span class="Tag">></span>
<span class="Tag"><</span><span class="Tag">td</span> :for<span class="Operator">=</span><span class="Tag">{</span><span class="-variable">col</span> <span class="Operator"><-</span> <span class="Operator"><span class="-constant">@</span></span><span class="-constant"><span class="-variable"><span class="-constant">column</span></span></span><span class="Tag">}</span><span class="Tag">></span><span class="Tag">{</span><span class="Tag">render_slot(col,</span> <span class="Tag">row)</span><span class="Tag">}</span><span class="Tag"></</span><span class="Tag">td</span><span class="Tag">></span>
<span class="Tag"></</span><span class="Tag">tr</span><span class="Tag">></span>
<span class="Tag"></</span><span class="Tag">table</span><span class="Tag">></span>
<span class="SpecialChar">"""</span>
<span class="-keyword">end</span>
<span class="SpecialChar">~</span><span class="SpecialChar"><span class="-_sigil_name">H</span></span><span class="SpecialChar">"""</span>
<span class="Tag"><</span><span class="Delimiter">.</span><span class="-function">table</span> <span class="Tag">rows</span><span class="Operator">=</span><span class="Tag">{</span><span class="Delimiter">[</span><span class="Special">%</span><span class="Tag"><span class="Delimiter">{</span></span><span class="SpecialChar">name: </span><span class="String">"Jane"</span><span class="Delimiter">,</span> <span class="SpecialChar">age: </span><span class="String">"34"</span><span class="Tag"><span class="Delimiter">}</span></span><span class="Delimiter">,</span> <span class="Special">%</span><span class="Tag"><span class="Delimiter">{</span></span><span class="SpecialChar">name: </span><span class="String">"Bob"</span><span class="Delimiter">,</span> <span class="SpecialChar">age: </span><span class="String">"51"</span><span class="Tag"><span class="Delimiter">}</span></span><span class="Delimiter">]</span><span class="Tag">}</span><span class="Tag">></span>
<span class="Tag"><:</span><span class="Tag">column</span> :let<span class="Operator">=</span><span class="Tag">{</span><span class="-variable">user</span><span class="Tag">}</span> <span class="Tag">label</span><span class="Operator">=</span><span class="String">"<span class="String">Name</span>"</span><span class="Tag">></span>
<span class="Tag">{</span><span class="Tag">user.name</span><span class="Tag">}</span>
<span class="Tag"></:</span><span class="Tag">column</span><span class="Tag">></span>
<span class="Tag"><:</span><span class="Tag">column</span> :let<span class="Operator">=</span><span class="Tag">{</span><span class="-variable">user</span><span class="Tag">}</span> <span class="Tag">label</span><span class="Operator">=</span><span class="String">"<span class="String">Age</span>"</span><span class="Tag">></span>
<span class="Tag">{</span><span class="Tag">user.age</span><span class="Tag">}</span>
<span class="Tag"></:</span><span class="Tag">column</span><span class="Tag">></span>
<span class="Tag"></</span><span class="Delimiter">.</span><span class="-function">table</span><span class="Tag">></span>
<span class="SpecialChar">"""</span>
</pre>
```
^1735915452280