kovax-react 0.6 is on npm. If you already use kovax-react 0.5 with ThemeProvider and CSS-variable theming, this release is the “admin panel polish” follow-up: a pagination component you can drop next to tables and search results, plus responsive hooks that read the same breakpoint.* tokens as themeToken and your stylesheets — no duplicate 768px constants in JS.
- 📦 npm:
kovax-react@0.6.0 - 🧑💻 Repo: github.com/MrKamura/kovax
- 🧪 Live docs & playground: mrkamura.github.io/kovax
TL;DR
| Area | What shipped |
|---|---|
Pagination |
Semantic nav, prev/next, numbered pages, ellipsis windows, aria-current="page", motion from duration.* / easing.*, honors prefers-reduced-motion
|
| Tree-shaking | Optional kovax-react/pagination entry exports Pagination + getPaginationItems
|
| Responsive |
useMediaQuery, useBreakpointUp, breakpointMinMediaQuery, breakpointMinWidth, breakpointMinMediaQueryFromToken — all aligned with breakpoints (sm … 2xl in em) |
| Docs | Pagination.md, playground Components → Pagination, Documentation topic with EN/RU UI copy |
No new runtime peer dependencies beyond what you already use for kovax-react.
Install
npm install kovax-react@0.6.0
Wrap your app in ThemeProvider as before — Pagination and the media-query hooks pick up the same CSS variables and token scale as the rest of the library.
Why another minor release?
After 0.5, two gaps showed up in real apps:
- Lists and tables need a pager — not just “page 3 of 40” text, but keyboard-friendly controls, clear current-page state, and ellipsis when there are dozens of pages.
-
Breakpoints were defined twice — once in design tokens / CSS, again as magic numbers in React. That drifts the moment someone tweaks
breakpoint.md.
0.6 closes both without pulling in a routing or data-fetching layer: you keep page / pageCount controlled in parent state (or your router) and wire onPageChange.
Pagination
Basics
import { Pagination } from "kovax-react";
import { useState } from "react";
export function SearchResultsPager() {
const [page, setPage] = useState(1);
return (
<Pagination
page={page}
pageCount={40}
onPageChange={setPage}
variant="outline"
size="sm"
aria-label="Search results"
/>
);
}
Props worth knowing:
-
variant:soft(default) oroutline -
size:sm|md -
siblingCount: how many page numbers sit beside the current page (default1); increase for wider “windows” on dense UIs -
disabled: freeze controls while a request is in flight -
i18n:
previousAriaLabel,nextAriaLabel,getPageAriaLabel, optional visiblepreviousLabel/nextLabel
<Pagination
page={page}
pageCount={12}
onPageChange={setPage}
siblingCount={2}
previousAriaLabel="Previous"
nextAriaLabel="Next"
getPageAriaLabel={(p) => `Page ${p}`}
/>
The component renders nothing when pageCount < 1, so you can skip conditional JSX around empty result sets.
Accessibility and motion
- Root is a
navwith youraria-label(required for a meaningful landmark). - Active page uses
aria-current="page". - Ellipsis markers are
aria-hidden; navigation stays on real buttons. - Hover/active feedback uses theme motion tokens; when the user prefers reduced motion, scale animations are skipped.
Custom layout, same gap logic
Need your own button components or a mobile-specific strip? Export the algorithm:
import { getPaginationItems } from "kovax-react/pagination";
const items = getPaginationItems(page, pageCount, 1);
// → (number | "ellipsis")[]
return (
<nav aria-label="Results">
{items.map((item, i) =>
item === "ellipsis" ? (
<span key={`e-${i}`} aria-hidden>…span>
) : (
<button
key={item}
type="button"
aria-current={item === page ? "page" : undefined}
onClick={() => setPage(item)}
>
{item}
button>
),
)}
nav>
);
Smaller bundles
Full barrel:
import { Pagination, getPaginationItems } from "kovax-react";
Pagination-only entry (same API, less to parse if you only ship a pager):
import { Pagination, getPaginationItems } from "kovax-react/pagination";
Full prop reference: Pagination.md.
Breakpoints in JavaScript
Design tokens already expose em breakpoints (sm 30em, md 48em, lg 62em, …). They respect root font size — a nicer default than hard-coded pixels for accessibility.
Hooks and helpers:
| API | Role |
|---|---|
useBreakpointUp("md") |
true when viewport ≥ token md
|
useMediaQuery(query, options?) |
Generic matchMedia subscription |
breakpointMinMediaQuery("md") |
"(min-width: 48em)" string for CSS-in-JS or tests |
breakpointMinWidth("md") |
Raw token value (48em) |
breakpointMinMediaQueryFromToken("breakpoint.md") |
Same as above via themeToken path |
import {
useBreakpointUp,
useMediaQuery,
breakpointMinMediaQuery,
themeToken,
} from "kovax-react";
const isMdUp = useBreakpointUp("md");
const isWide = useMediaQuery(`(min-width: ${themeToken("breakpoint.lg")})`);
const mqForCss = breakpointMinMediaQuery("md"); // "(min-width: 48em)"
SSR and hydration
useMediaQuery is built on useSyncExternalStore, so server and first client paint can agree via defaultMatches:
// Desktop-first layout: fewer “flash from mobile to desktop” warnings
const isLgUp = useBreakpointUp("lg", { defaultMatches: true });
On the server, getServerSnapshot returns defaultMatches (default false). After hydration, the real matchMedia result takes over and listeners update on resize.
Token docs (including breakpoint table): Tokens.md.
Example: responsive columns without duplicating constants
import { Grid, useBreakpointUp } from "kovax-react";
export function ProductGrid({ children }: { children: React.ReactNode }) {
const threeCols = useBreakpointUp("lg");
return (
<Grid columns={threeCols ? 3 : 1} gap={16}>
{children}
Grid>
);
}
Try it in the playground
The live site is still statically prerendered (SEO-friendly routes, sitemap). For 0.6, open:
- Components → Pagination — variants, sizes, ellipsis, disabled state, code tabs
- Components → Design tokens — breakpoint scale next to spacing, motion, z-index
- Documentation → Pagination — the same Markdown as the repo, with EN/RU chrome
No local install required to click through examples.
Changelog and what’s next
Full release notes (including a Russian summary block): CHANGELOG.md.
From the 0.5 roadmap, items still on the radar include Breadcrumb, richer Toast patterns, and more overlay polish. Menu already exists on the Popover primitives in the current tree — feedback on API shape is welcome.
If something’s missing, open an issue or PR — or leave a comment here; I read them.
Thanks for reading — happy paging.