Particular.Tech
Developerui

Resource row

List row for a project, deployment, or database with status and metadata.

acme-web

acme.dev

Ready
acme-api

api.acme.dev

Building
acme-docs

docs.acme.dev

Error

Installation

npx shadcn@latest add @particular/resource-row
npm dependencies
  • cn@^0.4.0
Installs these registry items

Source

ui/resource-row.tsx
import * as React from "react"
import { cn } from "cn"

import {
  Item,
  ItemActions,
  ItemContent,
  ItemDescription,
  ItemMedia,
  ItemTitle,
} from "@/components/ui/item"
import { StatusIndicator, type Status } from "@/components/ui/status-indicator"

function ResourceRow({
  title,
  description,
  status,
  meta,
  media,
  actions,
  className,
  ...props
}: Omit<React.ComponentProps<typeof Item>, "title"> & {
  title: React.ReactNode
  description?: React.ReactNode
  status?: Status
  /** Short facts rendered inline: branch, commit, region, environment. */
  meta?: React.ReactNode[]
  media?: React.ReactNode
  actions?: React.ReactNode
}) {
  return (
    <Item
      data-slot="resource-row"
      variant="outline"
      className={cn("flex-nowrap gap-4 rounded-none border-x-0 border-t-0 last:border-b-0", className)}
      {...props}
    >
      {media && <ItemMedia>{media}</ItemMedia>}
      <ItemContent className="min-w-0">
        <ItemTitle className="max-w-full truncate">{title}</ItemTitle>
        {description && <ItemDescription className="truncate">{description}</ItemDescription>}
      </ItemContent>
      {status && <StatusIndicator status={status} className="hidden w-28 shrink-0 md:inline-flex" />}
      {meta && meta.length > 0 && (
        <div className="hidden min-w-0 shrink-0 items-center gap-3 text-xs text-muted-foreground lg:flex">
          {meta.map((entry, index) => (
            <span key={index} className="inline-flex min-w-0 items-center gap-1.5 [&_svg]:size-3.5 [&_svg]:shrink-0">
              {entry}
            </span>
          ))}
        </div>
      )}
      {status && <StatusIndicator status={status} label={false} className="md:hidden" />}
      {actions && <ItemActions className="shrink-0">{actions}</ItemActions>}
    </Item>
  )
}

function ResourceList({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div data-slot="resource-list" className={cn("overflow-hidden rounded-lg border bg-card", className)} {...props} />
  )
}

export { ResourceRow, ResourceList }