Components
YA Popover Bottom
A floating action bar fixed at the bottom of the screen for multi-selection actions
The YaPopoverBottom is a floating action bar component in the YaVendio Design System. It appears at the bottom of the screen when items are selected, displaying a count and providing quick action buttons. Perfect for bulk operations, file managers, and multi-select interfaces.
Quick Start
pnpm dlx shadcn@latest add @yavendio/ya-popover-bottomnpx shadcn@latest add @yavendio/ya-popover-bottomyarn dlx shadcn@latest add @yavendio/ya-popover-bottomimport { useState } from 'react'
import { YaPopoverBottom } from '@/components/ui/ya-popover-bottom'
export default function Example() {
const [open, setOpen] = useState(false)
return (
<YaPopoverBottom
open={open}
onOpenChange={setOpen}
selectedCount={3}
>
<div className="flex gap-2">
<button>Delete</button>
<button>Download</button>
</div>
</YaPopoverBottom>
)
}Basic Usage
const [open, setOpen] = useState(false)
<YaPopoverBottom
open={open}
onOpenChange={setOpen}
selectedCount={3}
>
<YaPopoverBottomPlaceholder>
<span>Action buttons here</span>
</YaPopoverBottomPlaceholder>
</YaPopoverBottom>With Actions
Add action buttons for bulk operations:
<YaPopoverBottom
open={open}
onOpenChange={setOpen}
selectedCount={5}
>
<div className="flex items-center gap-2">
<YaButton variant="secondary" size="sm">
<Copy className="size-4" />
Copy
</YaButton>
<YaButton variant="secondary" size="sm">
<Download className="size-4" />
Download
</YaButton>
<YaButton variant="secondary" size="sm">
<Share className="size-4" />
Share
</YaButton>
<YaButton variant="primary" size="sm" destructive>
<Trash2 className="size-4" />
Delete
</YaButton>
</div>
</YaPopoverBottom>Device Variants
Adapt to different screen sizes:
| Device | Behavior |
|---|---|
desktop | Centered with max-width (640px), rounded corners, margin from bottom |
mobile | Full width, flat bottom corners, attached to screen bottom |
<YaPopoverBottom device="desktop" selectedCount={3}>
{/* Content */}
</YaPopoverBottom>
<YaPopoverBottom device="mobile" selectedCount={3}>
{/* Content */}
</YaPopoverBottom>Custom Label
Customize the selection label:
<YaPopoverBottom
selectedCount={12}
selectedLabel="Products"
>
{/* Actions */}
</YaPopoverBottom>Without Close Button
Hide the close button for custom dismiss behavior:
<YaPopoverBottom
selectedCount={2}
showCloseButton={false}
>
<div className="flex items-center gap-2">
<YaButton variant="secondary" size="sm" onClick={() => setOpen(false)}>
Cancel
</YaButton>
<YaButton variant="primary" size="sm" onClick={() => setOpen(false)}>
Confirm
</YaButton>
</div>
</YaPopoverBottom>File Manager Example
A practical example with file selection:
Click files to select:
const [selectedFiles, setSelectedFiles] = useState<string[]>([])
{selectedFiles.length > 0 && (
<YaPopoverBottom
open={selectedFiles.length > 0}
onOpenChange={(open) => !open && setSelectedFiles([])}
selectedCount={selectedFiles.length}
selectedLabel="Files"
>
<div className="flex items-center gap-2">
<YaButton variant="secondary" size="sm">
<Download className="size-4" />
Download
</YaButton>
<YaButton variant="primary" size="sm" destructive>
<Trash2 className="size-4" />
Delete
</YaButton>
</div>
</YaPopoverBottom>
)}Bulk Actions Example
Icon-only actions for compact toolbars:
<YaPopoverBottom selectedCount={8} selectedLabel="Items">
<div className="flex items-center gap-1">
<YaButton variant="tertiary" size="sm">
<Edit className="size-4" />
</YaButton>
<YaButton variant="tertiary" size="sm">
<Copy className="size-4" />
</YaButton>
<YaButton variant="tertiary" size="sm">
<Download className="size-4" />
</YaButton>
<YaButton variant="tertiary" size="sm" destructive>
<Trash2 className="size-4" />
</YaButton>
</div>
</YaPopoverBottom>Props
YaPopoverBottom
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | true | Controls visibility |
onOpenChange | (open: boolean) => void | - | Callback when visibility changes |
selectedCount | number | 0 | Number of selected items |
selectedLabel | string | 'Selected' | Label for the selection count |
device | 'desktop' | 'mobile' | 'desktop' | Device variant |
showCloseButton | boolean | true | Show the close button |
onClose | () => void | - | Additional close callback |
className | string | - | Additional classes |
children | React.ReactNode | - | Action buttons/content |
YaPopoverBottomPlaceholder
A helper component for placeholder content with dashed border:
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional classes |
children | React.ReactNode | - | Placeholder content |
Accessibility
Best Practices
| Do | Don't |
|---|---|
| Use for multi-selection contexts | Use for single item actions |
| Keep actions relevant to selection | Overload with too many actions |
| Clear selection on destructive actions | Leave hanging after action completion |
Use device="mobile" on small screens | Force desktop layout on mobile |
| Show only when items are selected | Keep visible when selection is empty |
Design Tokens
The component uses these YaVendio tokens:
| Token/Class | Usage |
|---|---|
p-4 | Main padding (16px) |
rounded-xl | Border radius (16px desktop) |
--ya-stone-200 | Border color primitive |
bg-secondary | Close button background |
text-secondary-foreground | Label color |
TypeScript
import { type VariantProps } from 'class-variance-authority'
import { yaPopoverBottomVariants } from '@/components/ui/ya-popover-bottom'
type Device = VariantProps<typeof yaPopoverBottomVariants>['device']