tablo-ui 0.8.0

The Topcoat components Tablo renders: primitives synced from topcoat-ui-registry, plus its own composites.
Documentation
// SYNC: topcoat-ui-registry@0.11.0 sha256:1bb770c77662b17b71a1a2c574917b177dcaab9e5d73dae274d59405e9f02ae4 — do not hand-edit. Sync via `cargo xtask sync-topcoat-ui` (ADR-0007).
use topcoat::{
    Result,
    view::{Attributes, Child, View, class, component, view},
};

/// A table inside a horizontally scrollable container.
///
/// Extra padding on the left and right aligns the cells with a card's content.
/// Top and bottom borders separate the table from neighboring elements. A border
/// is omitted when the table is the first or last child on that side.
///
/// Pass table sections as children. `attrs` are forwarded to the `<table>`, with extra
/// classes added to its classes.
///
/// ```ignore
/// view! {
///     table(
///         table_header(
///             table_row(
///                 table_head("Environment")
///                 table_head("Status")
///             )
///         )
///         table_body(
///             table_row(
///                 table_cell("production")
///                 table_cell("Live")
///             )
///         )
///     )
/// }
/// ```
#[component]
pub async fn table(
    #[default] mut attrs: Attributes,
    #[default] child: Child<'_>,
) -> Result<impl View> {
    Ok(view! {
        <div data-slot="table" class="w-full overflow-x-auto">
            // Put borders on the table so the caption stays outside them.
            <table
                class=(class!(
                    "w-full caption-bottom border-collapse border-border text-sm",
                    "[:not(:first-child)>&]:border-t [:not(:last-child)>&]:border-b",
                    attrs.remove("class"),
                ))
                (attrs)
            >
                (child)
            </table>
        </div>
    })
}

/// The heading section of a [`table`], holding the row of column headers.
#[component]
pub async fn table_header(
    #[default] mut attrs: Attributes,
    #[default] child: Child<'_>,
) -> Result<impl View> {
    Ok(view! {
        <thead
            class=(class!("bg-foreground/5 [&_tr]:border-b", attrs.remove("class")))
            (attrs)
        >
            (child)
        </thead>
    })
}

/// The body of a table, containing data rows.
#[component]
pub async fn table_body(
    #[default] mut attrs: Attributes,
    #[default] child: Child<'_>,
) -> Result<impl View> {
    Ok(view! {
        <tbody
            class=(class!("[&_tr:last-child]:border-0", attrs.remove("class")))
            (attrs)
        >
            (child)
        </tbody>
    })
}

/// The closing section of a [`table`], for totals and other summaries.
#[component]
pub async fn table_footer(
    #[default] mut attrs: Attributes,
    #[default] child: Child<'_>,
) -> Result<impl View> {
    Ok(view! {
        <tfoot
            class=(class!(
                "border-t border-border bg-foreground/5 font-medium [&>tr]:last:border-b-0",
                attrs.remove("class"),
            ))
            (attrs)
        >
            (child)
        </tfoot>
    })
}

/// A table row with a separator and hover styling.
#[component]
pub async fn table_row(
    #[default] mut attrs: Attributes,
    #[default] child: Child<'_>,
) -> Result<impl View> {
    Ok(view! {
        <tr
            class=(class!(
                "border-b border-border transition-colors hover:bg-foreground/5",
                attrs.remove("class"),
            ))
            (attrs)
        >
            (child)
        </tr>
    })
}

/// A column header in a [`table_header`]'s row.
#[component]
pub async fn table_head(
    #[default] mut attrs: Attributes,
    #[default] child: Child<'_>,
) -> Result<impl View> {
    Ok(view! {
        <th
            class=(class!(
                "p-3 text-left align-middle font-medium whitespace-nowrap",
                "text-muted-foreground first:pl-6 last:pr-6",
                attrs.remove("class"),
            ))
            (attrs)
        >
            (child)
        </th>
    })
}

/// One cell of a [`table_row`].
#[component]
pub async fn table_cell(
    #[default] mut attrs: Attributes,
    #[default] child: Child<'_>,
) -> Result<impl View> {
    Ok(view! {
        <td
            class=(class!(
                "p-3 align-middle whitespace-nowrap first:pl-6 last:pr-6",
                attrs.remove("class"),
            ))
            (attrs)
        >
            (child)
        </td>
    })
}

/// A caption describing the table.
#[component]
pub async fn table_caption(
    #[default] mut attrs: Attributes,
    #[default] child: Child<'_>,
) -> Result<impl View> {
    Ok(view! {
        <caption
            class=(class!("mt-4 text-sm text-muted-foreground", attrs.remove("class")))
            (attrs)
        >
            (child)
        </caption>
    })
}