mirror of
https://github.com/temetro/temetro.git
synced 2026-08-07 09:23:11 +00:00
869038477a
Add the COSS Pagination primitive and page the patients list at 10 rows/page (search resets to page 1; the page is clamped at render so a shrinking list never strands you past the last page). Replace the flat "secondary" status badge with semantic colours: active → success, inpatient → info, discharged → outline. Includes the i18n keys for pagination, the AI setup notice, and the patient record-history / PDF export features. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
131 lines
3.0 KiB
TypeScript
131 lines
3.0 KiB
TypeScript
"use client";
|
|
|
|
import { mergeProps } from "@base-ui/react/merge-props";
|
|
import { useRender } from "@base-ui/react/use-render";
|
|
import {
|
|
ChevronLeftIcon,
|
|
ChevronRightIcon,
|
|
MoreHorizontalIcon,
|
|
} from "lucide-react";
|
|
import type * as React from "react";
|
|
import { cn } from "@/lib/utils";
|
|
import { type Button, buttonVariants } from "@/components/ui/button";
|
|
|
|
export function Pagination({
|
|
className,
|
|
...props
|
|
}: React.ComponentProps<"nav">): React.ReactElement {
|
|
return (
|
|
<nav
|
|
aria-label="pagination"
|
|
className={cn("mx-auto flex w-full justify-center", className)}
|
|
data-slot="pagination"
|
|
{...props}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export function PaginationContent({
|
|
className,
|
|
...props
|
|
}: React.ComponentProps<"ul">): React.ReactElement {
|
|
return (
|
|
<ul
|
|
className={cn("flex flex-row items-center gap-1", className)}
|
|
data-slot="pagination-content"
|
|
{...props}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export function PaginationItem({
|
|
...props
|
|
}: React.ComponentProps<"li">): React.ReactElement {
|
|
return <li data-slot="pagination-item" {...props} />;
|
|
}
|
|
|
|
export type PaginationLinkProps = {
|
|
isActive?: boolean;
|
|
size?: React.ComponentProps<typeof Button>["size"];
|
|
} & useRender.ComponentProps<"a">;
|
|
|
|
export function PaginationLink({
|
|
className,
|
|
isActive,
|
|
size = "icon",
|
|
render,
|
|
...props
|
|
}: PaginationLinkProps): React.ReactElement {
|
|
const defaultProps = {
|
|
"aria-current": isActive ? ("page" as const) : undefined,
|
|
className: render
|
|
? className
|
|
: cn(
|
|
buttonVariants({
|
|
size,
|
|
variant: isActive ? "outline" : "ghost",
|
|
}),
|
|
className,
|
|
),
|
|
"data-active": isActive,
|
|
"data-slot": "pagination-link",
|
|
};
|
|
|
|
return useRender({
|
|
defaultTagName: "a",
|
|
props: mergeProps<"a">(defaultProps, props),
|
|
render,
|
|
});
|
|
}
|
|
|
|
export function PaginationPrevious({
|
|
className,
|
|
...props
|
|
}: React.ComponentProps<typeof PaginationLink>): React.ReactElement {
|
|
return (
|
|
<PaginationLink
|
|
aria-label="Go to previous page"
|
|
className={cn("max-sm:aspect-square max-sm:p-0", className)}
|
|
size="default"
|
|
{...props}
|
|
>
|
|
<ChevronLeftIcon className="sm:-ms-1" />
|
|
<span className="max-sm:hidden">Previous</span>
|
|
</PaginationLink>
|
|
);
|
|
}
|
|
|
|
export function PaginationNext({
|
|
className,
|
|
...props
|
|
}: React.ComponentProps<typeof PaginationLink>): React.ReactElement {
|
|
return (
|
|
<PaginationLink
|
|
aria-label="Go to next page"
|
|
className={cn("max-sm:aspect-square max-sm:p-0", className)}
|
|
size="default"
|
|
{...props}
|
|
>
|
|
<span className="max-sm:hidden">Next</span>
|
|
<ChevronRightIcon className="sm:-me-1" />
|
|
</PaginationLink>
|
|
);
|
|
}
|
|
|
|
export function PaginationEllipsis({
|
|
className,
|
|
...props
|
|
}: React.ComponentProps<"span">): React.ReactElement {
|
|
return (
|
|
<span
|
|
aria-hidden
|
|
className={cn("flex min-w-7 justify-center", className)}
|
|
data-slot="pagination-ellipsis"
|
|
{...props}
|
|
>
|
|
<MoreHorizontalIcon className="size-5 sm:size-4" />
|
|
<span className="sr-only">More pages</span>
|
|
</span>
|
|
);
|
|
}
|