tablo_ui/components/primitives/separator.rs
1// SYNC: topcoat-ui-registry@0.11.0 sha256:7ba5a7628128e1811e960884bd56da34f754c1d516230b4442dfbc1cb97e73e9 — do not hand-edit. Sync via `cargo xtask sync-topcoat-ui` (ADR-0007).
2use topcoat::{
3 Result,
4 view::{Attributes, PromotedStr, StaticClass, View, class, component, view},
5};
6
7/// The direction a [`separator`] runs in.
8///
9/// [`Default`] is `SeparatorOrientation::Horizontal`, used when no
10/// orientation is given.
11#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
12#[allow(dead_code)]
13pub enum SeparatorOrientation {
14 /// A rule across the full width of its container.
15 #[default]
16 Horizontal,
17 /// A rule down the full height of its container.
18 Vertical,
19}
20
21impl SeparatorOrientation {
22 /// Classes that set the rule's thickness and stretch it along its orientation.
23 fn classes(self) -> StaticClass {
24 match self {
25 Self::Horizontal => class!("h-px w-full"),
26 Self::Vertical => class!("h-full w-px"),
27 }
28 }
29
30 /// The value of the `aria-orientation` attribute, or `None` for the
31 /// horizontal default assistive technology already assumes.
32 fn aria(self) -> Option<PromotedStr> {
33 match self {
34 Self::Horizontal => None,
35 Self::Vertical => Some(PromotedStr(&"vertical")),
36 }
37 }
38}
39
40/// Classes for a separator that keeps its thickness in a flex layout.
41const SEPARATOR: StaticClass = class!("shrink-0 border-0 bg-border");
42
43/// A thin rule between groups of content.
44///
45/// Uses an `<hr>` element. Its length comes from its container, so a vertical separator
46/// needs a container with a height. Pass `aria-hidden="true"` for a purely decorative
47/// rule. `attrs` are forwarded to the `<hr>`, with extra classes added to its classes.
48///
49/// ```ignore
50/// view! {
51/// <div class="flex flex-col gap-4">
52/// <p>"Everyone with access to this workspace."</p>
53/// separator()
54/// <div class="flex h-5 items-center gap-3">
55/// <a href="/docs">"Docs"</a>
56/// separator(orientation: SeparatorOrientation::Vertical)
57/// <a href="/blog">"Blog"</a>
58/// </div>
59/// </div>
60/// }
61/// ```
62#[component]
63pub async fn separator(
64 /// The direction the rule runs in.
65 #[default]
66 orientation: SeparatorOrientation,
67 /// Extra attributes for the `<hr>` element.
68 #[default]
69 mut attrs: Attributes,
70) -> Result<impl View> {
71 Ok(view! {
72 <hr
73 class=(class!(SEPARATOR, orientation.classes(), attrs.remove("class")))
74 aria-orientation=(orientation.aria())
75 (attrs)
76 >
77 })
78}