From 63ceaf98ff9b06467f8e612e9166076a58afacfe Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 3 Aug 2026 19:52:41 -0700 Subject: [PATCH 1/2] Add documentation reference for Component and Table usage --- docs/docs/reference/component.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 docs/docs/reference/component.md diff --git a/docs/docs/reference/component.md b/docs/docs/reference/component.md new file mode 100644 index 0000000..964f92f --- /dev/null +++ b/docs/docs/reference/component.md @@ -0,0 +1,25 @@ +# Component + +Components are reusable message elements that can render content in both plain text and HTML. Subclasses implement `to_plain_text` and `render`, and can then be passed to methods such as `Context.reply`. matrix.py includes a built-in Table component for displaying labeled fields in a configurable column layout. + +```python +from matrix import Bot, Table + +bot = Bot() + + +@bot.command() +async def weather(ctx): + weather = Table(title="Los Angeles") + + weather.add_field("Description", "Clear Sky") + weather.add_field("Visibility", "10000m | 32808ft") + weather.add_field("Temperature", "71.33°F | 21.85°C") + weather.add_field("Feels Like", "71.33°F | 21.85°C") + weather.add_field("Atmospheric Pressure", "1012 hPa") + weather.add_field("Humidity", "66%") + + await ctx.reply(component=weather) +``` + +::: matrix.component.Component From afcfd26785cfe3c01da199113453d25ac5d8546a Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 3 Aug 2026 20:09:10 -0700 Subject: [PATCH 2/2] Add comprehensive documentation for Component and Table usage --- docs/docs/guides/component.md | 141 +++++++++++++++++++++++++++++++ docs/docs/reference/component.md | 2 + docs/mkdocs.yml | 2 + 3 files changed, 145 insertions(+) create mode 100644 docs/docs/guides/component.md diff --git a/docs/docs/guides/component.md b/docs/docs/guides/component.md new file mode 100644 index 0000000..1485b68 --- /dev/null +++ b/docs/docs/guides/component.md @@ -0,0 +1,141 @@ +# What is a Component? + +A component is a reusable message element that supplies both the plain-text body and +the formatted HTML body of a message: + +* `to_plain_text()` returns the plain-text version. +* `render()` returns the HTML version. + +Pass a component to `Context.reply` or `Room.send` with the `component` keyword: + +```python +await ctx.reply(component=table) +# Equivalent when sending directly through a room: +await ctx.room.send(component=table) +``` + +See also the [`Component`](../reference/component.md) reference. + +# Using a Table + +matrix.py includes a built-in `Table` component for displaying labeled fields: + +```python +from matrix import Bot, Table + +bot = Bot() + + +@bot.command() +async def user_info(ctx): + table = Table(title="User Info") + + table.add_field("Name", "Astra") + table.add_field("Role", "Engineer") + + await ctx.reply(component=table) +``` + +Each field is added with `add_field`: + +```python +table.add_field("Name", "Astra") +``` + +The first argument is the field name, and the second is its value. + +# Setting the Column Count + +Tables use two columns by default. You can change this with `column_count`: + +```python +table = Table( + title="Server Info", + column_count=3, +) + +table.add_field("Name", "Example") +table.add_field("Status", "Online") +table.add_field("Users", "42") +``` + +Fields are placed into rows using the configured number of columns. An incomplete +final row is automatically padded with empty cells. Fields are kept in the order in +which they are added. + +The column count must be greater than zero: + +```python +Table(title="Invalid", column_count=0) +# Raises ValueError +``` + +# Plain-Text Rendering + +Use `to_plain_text` to render a component without HTML: + +```python +table = Table(title="User Info") +table.add_field("Name", "Astra") +table.add_field("Role", "Engineer") + +text = table.to_plain_text() +``` + +The result is: + +```text +User Info +Name: Astra +Role: Engineer +``` + +# HTML Rendering + +Use `render` to generate the HTML representation: + +```python +html = table.render() +``` + +Calling `str` on a table produces the same result: + +```python +html = str(table) +``` + +Table titles, field names, and field values are automatically HTML-escaped. + +For example, a field added with a value of `""` is rendered as +`<online>`, so user-provided values cannot be interpreted as HTML markup. + +# Creating a Custom Component + +To create another kind of component, subclass `Component` and implement both +rendering methods: + +```python +from html import escape + +from matrix.component import Component + + +class Status(Component): + def __init__(self, name: str, online: bool): + self.name = name + self.online = online + + def to_plain_text(self) -> str: + state = "online" if self.online else "offline" + return f"{self.name}: {state}" + + def render(self) -> str: + state = "online" if self.online else "offline" + return f"{escape(self.name)}: {escape(state)}" +``` + +Custom components can be sent in exactly the same way as a `Table`: + +```python +await ctx.reply(component=Status("Astra", online=True)) +``` diff --git a/docs/docs/reference/component.md b/docs/docs/reference/component.md index 964f92f..56e788f 100644 --- a/docs/docs/reference/component.md +++ b/docs/docs/reference/component.md @@ -23,3 +23,5 @@ async def weather(ctx): ``` ::: matrix.component.Component + +::: matrix.component.Table diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 580780c..609137d 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -94,12 +94,14 @@ nav: - Events: guides/events.md - Checks: guides/checks.md - Error Handling: guides/error-handling.md + - Components: guides/component.md - Bigger Bot: guides/bigger-bot.md - Reference: - Bot: reference/bot.md - Checks: reference/checks.md - Command: reference/command.md - Config: reference/config.md + - Component: reference/component.md - Content: reference/content.md - Context: reference/context.md - Errors: reference/errors.md