- Spotify playlist, library, album and artist browsing with in-app playback - Song, playlist and album downloads via spotdl with YouTube and Bandcamp fallbacks - Electron desktop app (castLabs Widevine) with a permanent sidebar layout - Linux and Windows packaging scripts
107 lines
2.5 KiB
TypeScript
107 lines
2.5 KiB
TypeScript
import * as React from "react"
|
|
import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react"
|
|
import styles from "./Pagination.module.css"
|
|
import buttonStyles from "./Button.module.css"
|
|
|
|
const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
|
|
<nav
|
|
role="navigation"
|
|
aria-label="pagination"
|
|
className={`${styles.root} ${className ?? ""}`}
|
|
{...props}
|
|
/>
|
|
)
|
|
Pagination.displayName = "Pagination"
|
|
|
|
const PaginationContent = React.forwardRef<
|
|
HTMLUListElement,
|
|
React.ComponentProps<"ul">
|
|
>(({ className, ...props }, ref) => (
|
|
<ul
|
|
ref={ref}
|
|
className={`${styles.content} ${className ?? ""}`}
|
|
{...props}
|
|
/>
|
|
))
|
|
PaginationContent.displayName = "PaginationContent"
|
|
|
|
const PaginationItem = React.forwardRef<
|
|
HTMLLIElement,
|
|
React.ComponentProps<"li">
|
|
>(({ className, ...props }, ref) => (
|
|
<li ref={ref} className={`${styles.item} ${className ?? ""}`} {...props} />
|
|
))
|
|
PaginationItem.displayName = "PaginationItem"
|
|
|
|
type PaginationLinkProps = {
|
|
isActive?: boolean
|
|
} &
|
|
React.ComponentProps<"a">
|
|
|
|
const PaginationLink = ({
|
|
className,
|
|
isActive,
|
|
...props
|
|
}: PaginationLinkProps) => (
|
|
<a
|
|
aria-current={isActive ? "page" : undefined}
|
|
className={`${buttonStyles.button} ${styles.link} ${isActive ? styles.active : ""} ${className ?? ""}`}
|
|
{...props}
|
|
/>
|
|
)
|
|
PaginationLink.displayName = "PaginationLink"
|
|
|
|
const PaginationPrevious = ({
|
|
className,
|
|
...props
|
|
}: React.ComponentProps<typeof PaginationLink>) => (
|
|
<PaginationLink
|
|
aria-label="Go to previous page"
|
|
className={`${styles.link} ${className ?? ""}`}
|
|
{...props}
|
|
>
|
|
<ChevronLeft className={styles.icon} />
|
|
<span>Previous</span>
|
|
</PaginationLink>
|
|
)
|
|
PaginationPrevious.displayName = "PaginationPrevious"
|
|
|
|
const PaginationNext = ({
|
|
className,
|
|
...props
|
|
}: React.ComponentProps<typeof PaginationLink>) => (
|
|
<PaginationLink
|
|
aria-label="Go to next page"
|
|
className={`${styles.link} ${className ?? ""}`}
|
|
{...props}
|
|
>
|
|
<span>Next</span>
|
|
<ChevronRight className={styles.icon} />
|
|
</PaginationLink>
|
|
)
|
|
PaginationNext.displayName = "PaginationNext"
|
|
|
|
const PaginationEllipsis = ({
|
|
className,
|
|
...props
|
|
}: React.ComponentProps<"span">) => (
|
|
<span
|
|
aria-hidden
|
|
className={`${styles.ellipsis} ${className ?? ""}`}
|
|
{...props}
|
|
>
|
|
<MoreHorizontal className={styles.icon} />
|
|
</span>
|
|
)
|
|
PaginationEllipsis.displayName = "PaginationEllipsis"
|
|
|
|
export {
|
|
Pagination,
|
|
PaginationContent,
|
|
PaginationEllipsis,
|
|
PaginationItem,
|
|
PaginationLink,
|
|
PaginationNext,
|
|
PaginationPrevious,
|
|
}
|