Display
Show More
A hairline divider carrying an inline toggle pill (or plain label) to reveal collapsed content. Built on react-aria-components and styled with the quebi design system.
dividertoggleexpandcollapseinteractive
Default
A horizontal hairline with a centered toggle pill.
Controlled selection
Toggle the selected state to swap the label and reveal content.
First line is always visible.
As text
Render a plain muted label instead of an interactive pill.
12 more replies
Vertical
A vertical rule with the toggle centered between two columns.
Left
Right
Disabled
Source
Copy this into your project. Resolve its dependencies from the registryDependencies in the component's API entry.
"use client"
import { composeRenderProps, ToggleButton } from "react-aria-components"
import { tv } from "tailwind-variants"
import { cn } from "@/lib/utils"
/**
* ShowMore — quebi design system
*
* A divider that carries a "show more" affordance: a pill toggle button (or
* plain label) centered on a hairline rule. Use it to gate collapsed content
* (long threads, extra results) behind a single inline control.
*
* The rule is a cyan/10 hairline; the toggle is a quebi outline pill that
* lifts to the brand teal on hover and selection. No drop shadows.
*/
const showMoreStyles = tv({
base: "text-sm leading-6 before:border-cyan-500/10 after:border-cyan-500/10",
variants: {
orientation: {
vertical: "mx-1 h-auto self-stretch",
horizontal: "my-0.5 h-px w-full self-stretch",
},
},
compoundVariants: [
{
orientation: "vertical",
className:
"mx-2 flex flex-col items-center before:mb-2 before:flex-1 before:border-l after:mt-2 after:flex-1 after:border-r",
},
{
orientation: "horizontal",
className:
"my-2 flex items-center self-stretch before:me-2 before:flex-1 before:border-t after:ms-2 after:flex-1 after:border-t",
},
],
defaultVariants: {
orientation: "horizontal",
},
})
const togglePillStyles = tv({
base: [
"inline-flex items-center justify-center gap-2",
"rounded-full border border-solid border-cyan-500/20 bg-transparent",
"px-3 py-2 text-sm font-sans font-semibold whitespace-nowrap select-none cursor-pointer",
"text-white",
"transition-all duration-200 ease-out hover:scale-[1.02] active:scale-100",
"hover:border-quebi-brand hover:text-quebi-brand",
"outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-quebi-brand/50 focus-visible:ring-offset-2 focus-visible:ring-offset-quebi-bg",
"selected:border-quebi-brand selected:bg-quebi-brand selected:text-quebi-bg selected:hover:bg-quebi-brand-hover selected:hover:border-quebi-brand-hover selected:hover:text-quebi-bg selected:hover:shadow-quebi-glow-strong",
"disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100",
],
})
interface ShowMoreProps extends Omit<React.ComponentProps<typeof ToggleButton>, "className"> {
className?: string
orientation?: "horizontal" | "vertical"
as?: "text" | "button"
text?: string
}
const ShowMore = ({
as = "button",
orientation = "horizontal",
className,
text,
...props
}: ShowMoreProps) => {
return (
<div className={showMoreStyles({ orientation, className })}>
{as === "button" ? (
<ToggleButton {...props} className={togglePillStyles()}>
{composeRenderProps(props.children, (children) => children)}
</ToggleButton>
) : (
<span className={cn("text-quebi-fg-muted")}>{text}</span>
)}
</div>
)
}
export type { ShowMoreProps }
export { ShowMore }