{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "page-states", "title": "Page States", "description": "Generic loading, error, and empty page states with safe error messages.", "registryDependencies": [ "askyourpolicy/ss-registry/stitch-base", "askyourpolicy/ss-registry/alert", "askyourpolicy/ss-registry/empty", "askyourpolicy/ss-registry/spinner" ], "files": [ { "path": "src/components/ui/page-states.tsx", "content": "import { WarningCircleIcon } from \"@phosphor-icons/react\";\nimport type { ComponentProps, ReactNode } from \"react\";\n\nimport { Alert, AlertAction, AlertDescription, AlertTitle } from \"@/components/ui/alert\";\nimport {\n Empty,\n EmptyContent,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n} from \"@/components/ui/empty\";\nimport { Spinner } from \"@/components/ui/spinner\";\nimport { cn } from \"@/lib/utils\";\n\ntype PageLoadingProps = ComponentProps<\"div\"> & {\n label?: string;\n};\n\nfunction PageLoading({ className, label = \"Loading page\", ...props }: PageLoadingProps) {\n return (\n \n \n {label}\n \n );\n}\n\ntype PageErrorProps = Omit, \"children\" | \"title\" | \"variant\"> & {\n action?: ReactNode;\n error?: unknown;\n message?: ReactNode;\n title?: ReactNode;\n};\n\nfunction PageError({\n action,\n className,\n error,\n message,\n title = \"Something went wrong\",\n ...props\n}: PageErrorProps) {\n return (\n \n \n {title}\n {message ?? getErrorMessage(error)}\n {action != null ? {action} : null}\n \n );\n}\n\ntype PageEmptyProps = Omit, \"children\" | \"title\"> & {\n actions?: ReactNode;\n description?: ReactNode;\n icon?: ReactNode;\n title: ReactNode;\n};\n\nfunction PageEmpty({ actions, className, description, icon, title, ...props }: PageEmptyProps) {\n return (\n \n \n {icon != null ? {icon} : null}\n {title}\n {description != null ? {description} : null}\n \n {actions != null ? {actions} : null}\n \n );\n}\n\nfunction getErrorMessage(error: unknown, fallback = \"An unexpected error occurred.\") {\n if (error instanceof Error && error.message.trim()) return error.message;\n if (typeof error === \"string\" && error.trim()) return error;\n if (\n error &&\n typeof error === \"object\" &&\n \"message\" in error &&\n typeof error.message === \"string\" &&\n error.message.trim()\n ) {\n return error.message;\n }\n return fallback;\n}\n\nexport {\n PageEmpty,\n PageError,\n PageLoading,\n getErrorMessage,\n type PageEmptyProps,\n type PageErrorProps,\n type PageLoadingProps,\n};\n", "type": "registry:ui" } ], "type": "registry:ui" }