Import Export Popover
v0.1.0Popover combining import/export selects behind one trigger, plus an optional generic secondary action (label/icon/handler) with its own customize surface - not tied to any specific action like print.
Install
npx shadcn@4.1.2 add @signalos/import-export-popoverRequires a configured @signalos registry and a valid SIGNALOS_REGISTRY_TOKEN - get access. Registry dependencies (@signalos/tokens, @signalos/utils, @signalos/button, @signalos/popover, @signalos/select) are pulled automatically.
Preview
Example & code
import-export-popover.example.tsx
// Example: the snippet shown as public example code in the catalog.
import { RefreshCw } from "lucide-react"
import { ImportExportPopover } from "@/components/widgets/import-export-popover/ImportExportPopover"
export default function Example() {
return (
<ImportExportPopover
importOptions={[
{ value: "csv", label: "CSV" },
{ value: "json", label: "JSON" },
]}
exportOptions={[
{ value: "pdf", label: "PDF" },
{ value: "xlsx", label: "XLSX" },
]}
onImport={(value) => console.info("import", value)}
onDownload={({ importValue, exportValue }) =>
console.info("download", { importValue, exportValue })
}
secondaryAction={{
label: "Sync now",
icon: <RefreshCw className="size-4" />,
onRun: async () => {
await fetch("/api/sync", { method: "POST" })
},
}}
/>
)
}
Props
ImportExportOption
| Prop | Type | Default | Description |
|---|---|---|---|
| value* | string | - | |
| label* | string | - |
ImportExportPopoverProps
| Prop | Type | Default | Description |
|---|---|---|---|
| importOptions | ImportExportOption[] | undefined | - | |
| exportOptions | ImportExportOption[] | undefined | - | |
| onImport | ((value: string) => void) | undefined | - | |
| onExport | ((value: string) => void) | undefined | - | |
| onDownload | ((params: { importValue?: string | undefined; exportValue?: string | undefined; }) => void | Promise<void>) | undefined | - | |
| disabled | boolean | undefined | - | |
| isDownloading | boolean | undefined | - | |
| renderExportExtraFields | ((exportValue: string) => ReactNode) | undefined | - | |
| renderSecondaryActionFields | (() => ReactNode) | undefined | - | Renders a secondary action's own customize surface (e.g. a `CustomizeFieldsPanel`) above that action's button. The widget carries no field vocabulary itself - pass whatever the action needs to render. |
| secondaryAction | { label: string; icon?: ReactNode; onRun: () => void | Promise<void>; isRunning?: boolean | undefined; runningLabel?: string | undefined; } | undefined | - | A secondary action shown in its own section (e.g. print, sync, preview). Generic over label/icon so this widget never assumes what the action is. |
| secondaryActionAsExportOption | boolean | undefined | - | When true, the secondary action is offered as an export option (value `"__secondary-action__"`) instead of its own section. |
| data-testid | string | undefined | - | |
| onOpenChange | ((open: boolean) => void) | undefined | - | |
| title | string | undefined | - | Trigger label and popover heading. Defaults to "Import & Export", but falls back to "Export" (or "Import") when only one side is wired up for the current render - pass an explicit value to override either way. |
| description | string | undefined | - | Popover heading description. Defaults based on which of import/export/secondary action are wired up. |
| icon | ReactNode | an import/export icon based on what's wired up | Icon shown on the trigger and popover header. |
| classNames | { trigger?: string | undefined; triggerIcon?: string | undefined; triggerChevron?: string | undefined; popover?: string | undefined; header?: string | undefined; headerIcon?: string | undefined; headerTitle?: string | undefined; headerDescription?: string | undefined; sectionHeading?: string | undefined; secondaryActionButton?: string | undefined; selectTrigger?: string | undefined; selectContent?: string | undefined; selectItem?: string | undefined; customizeFields?: string | undefined; exportExtraFields?: string | undefined; downloadButton?: string | undefined; } | undefined | - |
npm dependencies
lucide-react@^1.7.0Changelog
import-export-popover
0.1.0
- Initial release: a popover combining import/export selects behind one
trigger, generic over a
secondaryAction(label/icon/handler, plusrenderSecondaryActionFieldsfor that action's own customize surface - e.g. aCustomizeFieldsPanel) instead of a built-in "print" concept.secondaryActionAsExportOptionfolds that action into the export select; otherwise it gets its own section. Extracted from an informalImportExportPopoverthat hard-coded print vocabulary and cross-imported another widget's types without a declared registry dependency.