Skip to main content

UX Standards — 08C: Toolbar Button Popup/Behavior Reference

Governs: The exact popup, dialog, or behavior triggered by each UDT toolbar button. Parent rules: See 08-UDT-TOOLBAR.md and 00-OVERVIEW-AND-CSS-RULES.md first.


Purpose

Every toolbar button either:

  1. Performs an immediate action (no UI shown)
  2. Opens a Dialog (blocking, user must confirm/cancel)
  3. Opens a floating panel (non-blocking, table stays interactive)
  4. Opens a Dropdown (immediate inline menu)
  5. Opens a Sheet (slide-over panel)

This document maps each button to its exact behavior.


Button Behavior Map

1. Reset & Refresh (RefreshCw)

PropertyValue
TypeImmediate action — no UI
BehaviorResets: row selection, sorting, column filters, global filter (search), column visibility to default, column order to default. Then calls onRefresh() to refetch data.
FeedbackTable reloads with spinner on icon
UndoNone — this is destructive of filter/sort state
// What "Reset & Refresh" resets:
table.resetRowSelection();
table.resetSorting();
table.resetColumnFilters();
table.setGlobalFilter('');
setSearchValue('');
onColumnVisibilityChange?.(defaultColumnVisibility);
onColumnOrderChange?.(defaultColumnOrder);
onClearFilters?.(); // clears advanced filter state
onRefresh?.(); // triggers data refetch

2. Column Selector (Columns3 icon)

PropertyValue
TypeResizableDialog (draggable + resizable, non-blocking)
Trigger tooltip"Manage columns"
Opens"Manage Columns" dialog — draggable title bar, resizable edges
Default size400 × 450 px
Min size300 × 300 px
Max size600 × 700 px
Header"Manage Columns" + "Drag to reorder. Click eye to toggle. (N of N visible)"
Bulk actionsShow All (Eye) / Hide All (EyeOff) / Reset (RotateCcw) — outline sm buttons
Column itemsGripVertical drag handle + label + Eye/EyeOff toggle or "Required" badge
Required columnsenableHiding: false → show "Required" label, not eye icon
Drag-to-reorder@dnd-kit/core with verticalListSortingStrategy
Auto-applyYes — changes apply immediately on toggle (autoApply=true)
Blocks tableNo — table remains interactive
Doc07C-UDT-COLUMN-VISIBILITY-AND-DEFAULTS.md

3. Row Density (Rows3)

PropertyValue
TypeDropdownMenu (inline menu)
OptionsCompact / Default ✓ / Large
BehaviorImmediate — applies density to table rows on click
StateCheckmark on currently active density
[Rows3 icon ▼]
┌──────────────────┐
│ Compact │
│ Default ✓ │
│ Large │
└──────────────────┘

4. Global Search (Search input field)

PropertyValue
TypeInline input — no popup
Widthh-8 w-48 lg:w-64
IconsSearch left (decorative), X right (clear, only when value present)
BehaviorFilters all visible columns in real-time as user types (global filter on TanStack Table)
Placeholder"Search..." or custom searchPlaceholder prop
ClearClicking X clears the value and resets global filter

5. Advanced Filters (Filter)

PropertyValue
TypeFloating panel (non-blocking — table stays interactive)
OpensAdvanced Filter dialog — draggable, resizable
BadgeRed badge showing count of active advanced filter conditions
ClosesClick Cancel or Apply Filters inside the panel
Doc09B-ADVANCED-FILTER-POPUP.md

6. Clear Filters (FilterX)

PropertyValue
TypeImmediate action — no UI
BehaviorClears both: (a) column-level filters, (b) advanced filter conditions. Keeps search/sort.
Disabled whenNo filters active (shown with text-muted-foreground/40)
Tooltip when disabled"Clear Filters (none active)"

7. Clear Sort (ChevronsUpDown / ArrowDownUp)

PropertyValue
TypeImmediate action — no UI
BehaviorCalls table.resetSorting(). When onSortClick prop provided, calls that instead (for server-side sort reset).
IconChevronsUpDown when no sort active; ArrowDownUp when sort active
BadgeShows count of sorted columns
Disabled whenNo sort active

8. Import (Upload)

PropertyValue
TypeDialog (blocking — 6-step modal wizard)
OpensImport Wizard: ImportDialog component
StepsTemplate → Upload → Map Fields → Options → Preview → Confirm
Sizemax-w-4xl max-h-[90vh]
Doc10-IMPORT-WIZARD-MODAL.md

9. Export (Download)

PropertyValue
TypeDropdownMenu then Dialog (two-step)
Step 1Format dropdown: CSV / TSV / Excel / JSON / XML / PDF
Step 2Export Data dialog: Records (All/Selected) + Columns (Visible/All)
Dialog sizesm:max-w-md
Doc08B-EXPORT-DIALOG.md
[Download ▼]
┌─────────┐
│ CSV │ → opens Export Dialog
│ TSV │ → opens Export Dialog
│ Excel │ → opens Export Dialog
│ ─────── │
│ JSON │ → opens Export Dialog
│ XML │ → opens Export Dialog
│ ─────── │
│ PDF │ → opens Export Dialog or print preview
└─────────┘

10. View (Eye)

PropertyValue
TypeSheet slide-over OR Dialog (page-specific)
BehaviorOpens a read-only detail view of the selected record(s)
SelectionRequires 1+ rows selected
Single selectionOpens that record's detail view
Multi selectionOpens first selected record with prev/next navigation
Common implementationSheet from right (sm:max-w-xl) with all record fields displayed
// Typical View Sheet:
<Sheet open={viewOpen} onOpenChange={setViewOpen}>
<SheetContent side="right" className="sm:max-w-xl flex flex-col">
<SheetHeader>
<SheetTitle>{record.name}</SheetTitle>
<SheetDescription>View record details</SheetDescription>
</SheetHeader>
<div className="flex-1 overflow-y-auto py-4">
<RecordDetailView record={record} />
</div>
<div className="border-t pt-4 flex justify-between">
<Button variant="outline" onClick={() => setViewOpen(false)}>Close</Button>
{canEdit && <Button onClick={handleEdit}>Edit</Button>}
</div>
</SheetContent>
</Sheet>

11. Add (Plus)

PropertyValue
TypeDialog (blocking) OR navigation to new record page
BehaviorOpens a create form for a new record of this doctype
No selection requiredButton always enabled (when canCreate permission)
Common implementationDialog sm:max-w-2xl with form, or router.push('/new')
// Add dialog pattern:
<Dialog open={addOpen} onOpenChange={setAddOpen}>
<DialogContent className="sm:max-w-2xl">
<DialogHeader>
<DialogTitle>Add {doctype}</DialogTitle>
</DialogHeader>
<CreateForm
onSuccess={(newRecord) => {
setAddOpen(false);
refetch();
toast.success(`${doctype} created`);
}}
/>
</DialogContent>
</Dialog>

12. Copy (Copy)

PropertyValue
TypeImmediate action — no UI
BehaviorCopies the selected row's data as formatted text to clipboard
SelectionRequires exactly 1 row
Disabled when0 rows or 2+ rows selected
Feedbacktoast.success('Copied to clipboard')
FormatTab-delimited: Field1\tValue1\tField2\tValue2...

Note: This copies the entire row to clipboard. For cell-level copying, use the right-click context menu (see 07B-UDT-CELL-SELECTION-AND-COPY.md).


13. Duplicate (Files)

PropertyValue
TypeDialog (confirmation) OR immediate
BehaviorCreates a copy of the selected record(s) with all field values copied
SelectionRequires 1+ rows
Confirmation"Duplicate N record(s)? This will create N new records."
After actionTable refreshes, new record(s) shown (may scroll to top)
// Confirmation dialog for bulk duplicate:
<AlertDialog>
<AlertDialogContent>
<AlertDialogTitle>Duplicate {selectedCount} record(s)?</AlertDialogTitle>
<AlertDialogDescription>
This will create {selectedCount} new record(s) with all field values copied.
</AlertDialogDescription>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction onClick={handleDuplicate}>Duplicate</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>

14. Bulk Edit (SquarePen)

PropertyValue
TypeDialog (sm:max-w-md, blocking)
Title"Bulk Edit"
Description"Edit N selected rows. Select fields to modify."
Tooltip"Bulk edit N records" (dynamic count in tooltip)
BehaviorShows ALL table fields as checkboxes. User checks a field to reveal its input. Only checked fields are updated.
SelectionRequires 2+ rows (selectedRows.length > 1)
Field typestext (Input), number (Input type=number), select (Select dropdown), boolean (Yes/No Select)
Apply disabledWhen no fields are checked OR while isLoading
Feedbacktoast.success('Updated N records')
ComponentBulkEditDialog from @/components/bulk-edit-dialog

UI Pattern — Checkbox-activated fields: Each field shows as a checkbox row. The input is HIDDEN until the field is checked:

┌──────────────────────────────────────────────┐
│ Bulk Edit [✕] │
│ Edit 2 selected rows. Select fields to │
│ modify. │
├──────────────────────────────────────────────┤
│ ☐ select │ ← unchecked = just label shown
│ ☐ username │
│ ☐ fullName │
│ ☐ email │
│ ☐ phone_number │
│ ☐ status │ ← when checked: input appears below
│ ☑ status │
│ [Active ▼] │ ← Select input revealed when checked
│ ☐ tenant_name │
│ ↕ (scrollable) │
├──────────────────────────────────────────────┤
│ [Cancel] [Apply to 2 rows] │
└──────────────────────────────────────────────┘

"Apply to N rows" button is grayed/disabled until at least one field checkbox is checked.


15. Edit (Pencil)

PropertyValue
TypeDialog (blocking) OR navigation to edit page
BehaviorOpens the full edit form for the selected record
SelectionRequires 1+ rows; if multiple, opens first with prev/next navigation
Common implementationDialog sm:max-w-2xl with pre-filled form

16. Delete (Trash2)

PropertyValue
TypeAlertDialog (blocking confirmation)
BehaviorPermanently deletes selected record(s) after confirmation
SelectionRequires 1+ rows
Confirmation text"Delete N record(s)? This action cannot be undone."
Primary CTAvariant="destructive" — "Delete N Record(s)"
After actionTable refreshes, deleted records removed
<AlertDialog open={deleteOpen} onOpenChange={setDeleteOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
Delete {selectedCount} record{selectedCount !== 1 ? 's' : ''}?
</AlertDialogTitle>
<AlertDialogDescription>
This action cannot be undone. {selectedCount > 1
? `These ${selectedCount} records will be permanently deleted.`
: 'This record will be permanently deleted.'}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
onClick={handleDelete}
>
Delete {selectedCount} Record{selectedCount !== 1 ? 's' : ''}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>

17. Upload Attachment (Paperclip)

PropertyValue
TypeDialog (blocking)
BehaviorOpens file picker to upload file(s) attached to the selected record
SelectionRequires 1+ rows
EnabledOnly when showAttachmentActions={true} on toolbar
Common implementationDialog with drag-and-drop zone + file list

18. Download Attachment (FileDown)

PropertyValue
TypeImmediate action OR Dialog if multiple attachments
BehaviorDownloads the attachment(s) from the selected record
SelectionRequires exactly 1 row
Single attachmentDownloads immediately (no UI)
Multiple attachmentsOpens a small Dialog listing available files to download

19. Send Email (Mail)

PropertyValue
TypeDialog (blocking)
BehaviorOpens email compose dialog pre-addressed to selected user(s)
SelectionRequires 1+ rows
EnabledOnly when showEmailAction={true} on toolbar

20. Help (HelpCircle)

PropertyValue
TypeSheet (right slide-over) OR persistent popup window
BehaviorOpens contextual help content for the current page/doctype
Common implementationSheet with FAQ content, OR openPersistentPopup('help', '/help/product-setup', 'help-window')

Summary Quick Reference

ButtonPopup TypeBlocks Table?Selection Required
Reset & RefreshNone (immediate)NoNo
Column SelectorPopoverNoNo
Row DensityDropdownMenuNoNo
SearchInline inputNoNo
Advanced FiltersFloating panelNoNo
Clear FiltersNone (immediate)NoNo
Clear SortNone (immediate)NoNo
ImportDialog (wizard, 6 steps)YesNo
ExportDropdownMenu → DialogYesNo
ViewSheet (right)Yes1+ rows
AddDialogYesNo
CopyNone (immediate)NoExactly 1
DuplicateAlertDialogYes1+ rows
Bulk EditDialogYes2+ rows
EditDialogYes1+ rows
DeleteAlertDialog (destructive)Yes1+ rows
Upload AttachmentDialogYes1+ rows
Download AttachmentNone or DialogVariesExactly 1
Send EmailDialogYes1+ rows
HelpSheet or popupNoNo