npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@konce-pt/react

v0.9.1

Published

Open-source React 19 component library on the Koncept UI design system — the same kpt-* CSS layer and --kpt-* tokens as the Angular port. Zero runtime dependencies.

Readme

Koncept UI — React

Open-source React 19 component library on the Koncept UI design system. 80+ components sharing the exact CSS layer with the Angular port — zero runtime dependencies.

npm version npm downloads minzipped size types license

React dependencies CSS Components


Why Koncept UI React

Koncept UI is a free, MIT-licensed design system. This package is its React 19 port — not a lookalike, but the same rendering contract:

  • 🎯 One CSS layer for both ports — the same kpt-* classes, the same --kpt-* tokens, the same @layer kpt.* ordering. The DOM tree matches the Angular port node for node, so an app can mix the two and nothing shifts by a pixel.
  • 📦 Zero runtime dependencies — no clsx, no radix, no CSS-in-JS. cn, Slot and composeRefs ship with the package.
  • ⚛️ React 19 native — ref is a plain prop (no forwardRef), and every form control renders a native name/form, so <form action={…}> Actions and React Hook Form's register() work without an adapter. Controls are usable controlled and uncontrolled.
  • 📊 Flagship data table — sorting, global and per-column filters, pagination, virtual scroll (5000+ rows), selection, column reorder & freeze, inline editing, summary row, CSV export.
  • 🎨 100% tokenized — every style is a var(--kpt-*) custom property. Light/dark theme, neutral OKLCH palette. Rebrand by swapping one token layer.
  • ♿ Native elements first — <button>, <input>, <label> wherever one exists, so keyboard and screen-reader behaviour comes from the platform. Invalid state travels on aria-invalid, never on a class.
  • 🌍 i18n built in — English (default) & Polish out of the box, runtime locale switch, add any language with one JSON.

Installation

npm i @konce-pt/react @konce-pt/tokens @konce-pt/styles
# or: pnpm add / yarn add

react and react-dom (>=19) are peers you already have. Optional extras:

  • @konce-pt/grid — the mobile-first layout system; its React components live in @konce-pt/react/grid.
  • @konce-pt/validators — Polish-market validators (NIP, REGON, PESEL, IBAN, postal code).
  • leaflet (^1.9) — an optional peer, needed only by @konce-pt/react/map, loaded through a dynamic import().

Setup

The package ships JavaScript only. Load the shared CSS layer once, in your app entry:

import '@konce-pt/tokens/css';
import '@konce-pt/tokens/css/dark';
import '@konce-pt/styles';            // reset, @layer ordering, theme
import '@konce-pt/styles/components'; // the component layer — REQUIRED, this is what styles kpt-*
import '@konce-pt/grid';              // optional — only if you use the layout classes

@konce-pt/styles/components is generated from the same SCSS the Angular port compiles into its own bundle, which is why both ports render identically. The Angular package injects those styles at runtime; React has no other source for them, so this import is not optional.

Dark theme: set <html data-theme="dark"> (or rely on prefers-color-scheme).

No CDK here. Components with a floating panel (KptSelect, KptPopover, KptMenu, KptAutocomplete, KptDatepicker…) portal into document.body through the internal KptOverlay, so @angular/cdk/overlay-prebuilt.css is not needed — positioning lives in the component, the look in @konce-pt/styles/components. Inside an open KptDialog those panels portal into the <dialog> instead, because showModal() moves it to the browser top layer.

Quick start

A login form — controlled values, the error gated on touch, no form library required:

import { useState } from 'react';
import { KptButton, KptFormField, KptInput } from '@konce-pt/react';

export function Login() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [touched, setTouched] = useState<Record<string, boolean>>({});

  const emailError = !email.includes('@') ? 'Enter a valid e-mail address' : null;
  const passwordError = password.length < 8 ? 'At least 8 characters' : null;
  const invalid = Boolean(emailError || passwordError);

  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        console.log({ email, password });
      }}
    >
      <KptFormField label="E-mail" error={touched.email ? emailError : null} required>
        <KptInput
          type="email"
          name="email"
          value={email}
          onValueChange={setEmail}
          onTouch={() => setTouched((t) => ({ ...t, email: true }))}
          invalid={Boolean(emailError)}
        />
      </KptFormField>

      <KptFormField label="Password" error={touched.password ? passwordError : null} required>
        <KptInput
          type="password"
          name="password"
          value={password}
          onValueChange={setPassword}
          onTouch={() => setTouched((t) => ({ ...t, password: true }))}
          invalid={Boolean(passwordError)}
        />
      </KptFormField>

      <KptButton type="submit" disabled={invalid}>Sign in</KptButton>
    </form>
  );
}

KptFormField generates the control id and publishes it through context, so label[for] and input[id] match with no configuration. Drop value/onValueChange and the field becomes uncontrolled — the value lives in the DOM, and a native <form action={…}> or React Hook Form's register() picks it up as-is.

Data table with sorting, filtering, pagination and a custom cell:

<KptDataTable
  columns={columns}
  data={users}
  filterable
  exportable
  pageSize={10}
  selectable="multiple"
  rowKey="id"
  selection={selected}
  onSelectionChange={setSelected}
  cells={{ status: (row, value) => <KptBadge value={String(value)} /> }}
/>

Components (80+)

| Category | Components | | --- | --- | | Forms | KptInput, KptTextarea, KptSelect, KptAutocomplete, KptCheckbox, KptSwitch, KptSwitchGroup, KptRadioGroup, KptSlider, KptRating, KptDatepicker, KptDateRange, KptClock, KptColorPicker, KptFileUpload, KptInputNumber, KptPassword, KptInputOtp, KptChipsInput, KptInputMask, KptListbox, KptKnob, KptRichText, KptFormField | | Buttons & actions | KptButton, KptIconButton, KptButtonGroup, KptFab, KptSplitButton, KptSpeedDial | | Layout | KptAppShell, KptToolbar, KptSidenav, KptCard (+ Header, Footer, Media, Title…), KptDivider, KptPanel, KptFieldset, KptSplitter, KptScrollTop | | Navigation | KptTabs, KptAccordion, KptBreadcrumb, KptStepper, KptMenu, KptMenubar, KptMegamenu, KptContextMenu | | Data | KptDataTable, KptPaginator, KptTree, KptTimeline, KptCarousel, KptDataView, KptPickList, KptOrderList, KptGalleria, KptMeterGroup | | Feedback & overlay | KptAlert, KptDialog, kptToast + KptToastContainer, KptTooltip, KptPopover, KptDrawer, KptBottomSheet, kptConfirm, KptBadge, KptChip, KptAvatar, KptAvatarGroup, KptSpinner, KptProgress, KptSkeleton, KptEmpty, KptImage, KptAuth | | Subpaths | @konce-pt/react/charts (KptChart), /chat (KptChat, KptChatMessage, KptChatTyping, KptChatComposer, KptChatDock), /roadmap (KptRoadmap), /grid (KptGrid, KptCol, KptFlex), /map (KptMap + legend, POI card, search), /icons (full Tabler set) |

The heavy pieces (charts, chat, roadmap, maps, the full icon set) live in subpaths on purpose, so the core entry point stays small. Every component ships an llms.txt API sheet next to its source.

Theming

All visuals are driven by var(--kpt-*) tokens (three tiers: primitives → semantic → component). Override them in a stylesheet imported after @konce-pt/styles:

:root {
  --kpt-color-primary: oklch(0.55 0.2 265);        /* rebrand in one line */
  --kpt-color-primary-hover: oklch(0.5 0.2 265);
}
:root[data-theme='dark'] {
  --kpt-color-primary: oklch(0.7 0.16 265);
}

Common token names: surfaces --kpt-color-surface, --kpt-color-surface-sunken|raised|variant|hover|selected; text --kpt-color-on-surface, --kpt-color-on-surface-muted (aliases --kpt-color-text, --kpt-color-text-muted|subtle|inverse); borders --kpt-color-border, --kpt-color-border-strong; accent roles in full — {primary,danger,success,warning,info} each with -hover, -contrast, -subtle, -border; radii --kpt-radius-sm|md|lg|xl|full|none; elevation --kpt-elevation-1..4 (aliases --kpt-shadow-sm|md|lg). There is no --kpt-color-bg.

Variants and sizes travel on data-* attributes (data-variant, data-size), never on modifier classes — that is what the SCSS reads.

Icons

84 icons are built in and need no configuration — what the components themselves draw plus the staples of an application shell (sun, moon, bell, settings, users, logout, layout-dashboard, home, activity, chart-bar, brand-github …). A typical admin panel needs nothing else.

For the full Tabler Icons set (MIT, 5130 icons) there are two paths, and the difference is the bundle. Every icon is its own export, so importing by name lets the bundler keep just those:

// Production — two icons reach the bundle.
import { LayoutDashboard, Rocket } from '@konce-pt/react/icons';
import { registerKptIcons } from '@konce-pt/react';
registerKptIcons([LayoutDashboard, Rocket]);

// Prototype — every icon, about 1.2 MB.
import { registerKptTablerIcons } from '@konce-pt/react/icons';
registerKptTablerIcons();

registerKptIcons is the one that shrinks: it takes the data as an argument and imports nothing from the Tabler subpath. For the same reason registerKptIcons(tabler) with a namespace import (import * as tabler) registers everything — a namespace object handed to a function blocks static analysis. The registry is global, so one call at the app entry is enough; no provider needed.

Internationalization (i18n)

Component labels ship in English (default) and Polish. Without a provider everything renders in English — a missing provider is never an error. KptI18nProvider sets the language for a subtree:

import { KptI18nProvider, useKptI18n } from '@konce-pt/react';

export function App() {
  return (
    <KptI18nProvider locale="pl">
      <Toolbar />
    </KptI18nProvider>
  );
}

function Toolbar() {
  const { t, setLocale } = useKptI18n();
  return (
    <button onClick={() => setLocale('en')}>
      {t('paginator.range', { start: 1, end: 10, total: 42 })}
    </button>
  );
}

useKptI18n() returns { locale, setLocale, messages, messagesFor, t }. t(key, params?) takes a dotted key with {name} interpolation and falls back to English, then to the key itself.

Add any language with one JSON (shape = the KptMessages contract; missing keys fall back to English):

import de from './i18n/de.json';

<KptI18nProvider locale="de" messages={{ de }}>…</KptI18nProvider>

Any component with labels also accepts locale and dictionary props, which take priority over the provider. Calendar weekday/month names come from the browser's Intl API. The contract and the dictionaries live in @konce-pt/i18n, shared with the Angular port.

Helpers

  • cn(...values) — class-name joining (the clsx role, no dependency).
  • Slot + the asChild prop — render as another element while keeping classes and attributes.
  • composeRefs(...refs) — merge several refs into one callback.

Documentation

License

MIT © konce.pt


🇵🇱 Wersja polska

Koncept UI to darmowy system projektowy na licencji MIT. Ta paczka to jego port na Reacta 19 — nie podobnie wyglądający zamiennik, tylko ten sam kontrakt renderowania.

  • 🎯 Jedna warstwa CSS dla obu portów — te same klasy kpt-*, te same tokeny --kpt-*, ta sama kolejność @layer kpt.*. Drzewo DOM odpowiada wersji Angulara węzeł w węzeł.
  • 📦 Zero zależności runtime — cn, Slot i composeRefs są w paczce.
  • ⚛️ React 19 — ref jako zwykły prop (bez forwardRef), kontrolki działają kontrolowane i niekontrolowane, z natywnym name/form (React 19 Actions i React Hook Form bez adaptera).
  • 📊 Flagowa tabela danych — sortowanie, filtry globalne i kolumnowe, paginacja, virtual scroll, zaznaczanie, przestawianie i zamrażanie kolumn, edycja w miejscu, podsumowanie, eksport CSV.
  • 🎨 100% na tokenach — każdy styl to var(--kpt-*). Motyw jasny/ciemny, neutralna paleta OKLCH.
  • ♿ Natywne elementy — <button>, <input>, <label> wszędzie tam, gdzie istnieją; stan błędu na aria-invalid, nie na klasie.
  • 🌍 Wbudowane i18n — angielski (domyślny) i polski, przełączanie w runtime, dowolny język jednym plikiem JSON.

Instalacja

npm i @konce-pt/react @konce-pt/tokens @konce-pt/styles

react i react-dom (>=19) to peery, które masz już w aplikacji. Opcjonalnie: @konce-pt/grid (układ; komponenty w @konce-pt/react/grid), @konce-pt/validators (walidatory PL: NIP, REGON, PESEL, IBAN, kod pocztowy) oraz leaflet (^1.9) — opcjonalny peer, potrzebny wyłącznie dla @konce-pt/react/map.

Konfiguracja

Paczka wysyła sam JavaScript. CSS ładujesz raz, w wejściu aplikacji:

import '@konce-pt/tokens/css';
import '@konce-pt/tokens/css/dark';
import '@konce-pt/styles';            // reset, kolejność warstw, motyw
import '@konce-pt/styles/components'; // warstwa komponentów — WYMAGANE, to ona styluje kpt-*
import '@konce-pt/grid';              // opcjonalnie — klasy układu

@konce-pt/styles/components powstaje z tego samego SCSS-a, który port Angulara kompiluje do własnego bundla — stąd identyczny wygląd obu portów. Angular wstrzykuje te style w runtime, React nie ma dla nich innego źródła, więc ten import nie jest opcjonalny.

Motyw ciemny: <html data-theme="dark"> (albo prefers-color-scheme). Nadpisania --kpt-color-* w arkuszu importowanym po @konce-pt/styles.

CDK nie jest tu potrzebny. Komponenty z panelem (KptSelect, KptPopover, KptMenu, KptAutocomplete, KptDatepicker…) renderują go przez wewnętrzny KptOverlay do portalu na document.body, więc @angular/cdk/overlay-prebuilt.css nie jest wymagany. W otwartym KptDialog panel trafia do <dialog>, bo showModal() przenosi go do górnej warstwy przeglądarki.

Ikony

84 ikony są wbudowane i nie wymagają konfiguracji — to, co rysują same komponenty, plus staple powłoki aplikacji (sun, moon, bell, settings, users, logout, layout-dashboard, home, activity, chart-bar, brand-github…). Typowy panel administracyjny nie potrzebuje nic więcej.

Pełny zestaw Tabler Icons (MIT, 5130 ikon) ma dwie ścieżki, a różnica jest w bundlu. Każda ikona jest osobnym eksportem, więc import po nazwie zostawia w bundlu wyłącznie użyte:

// Produkcja — do bundla wchodzą dwie ikony.
import { LayoutDashboard, Rocket } from '@konce-pt/react/icons';
import { registerKptIcons } from '@konce-pt/react';
registerKptIcons([LayoutDashboard, Rocket]);

// Prototyp — wszystkie ikony, około 1,2 MB.
import { registerKptTablerIcons } from '@konce-pt/react/icons';
registerKptTablerIcons();

To registerKptIcons odchudza, bo przyjmuje dane argumentem i sam nie importuje pełnego zestawu. Z tego samego powodu registerKptIcons(tabler) z importem przestrzeni nazw (import * as tabler) rejestruje komplet — namespace przekazany do funkcji blokuje analizę statyczną. Rejestr jest globalny, więc wystarczy jedno wywołanie w wejściu aplikacji.

Internacjonalizacja (i18n)

Etykiety są dostępne po angielsku (domyślnie) i polsku. Bez providera wszystko renderuje się po angielsku — brak providera nigdy nie jest błędem. <KptI18nProvider locale="pl"> ustawia język dla poddrzewa, useKptI18n() zwraca { locale, setLocale, messages, messagesFor, t }, a t('paginator.range', { start: 1, end: 10, total: 42 }) interpoluje {nazwa} i spada na EN, potem na sam klucz.

Własny język jednym plikiem JSON (kształt = kontrakt KptMessages; brakujące klucze spadają na EN):

import de from './i18n/de.json';

<KptI18nProvider locale="de" messages={{ de }}>…</KptI18nProvider>

Propsy locale i dictionary na komponencie mają priorytet nad providerem. Nazwy dni i miesięcy w kalendarzach pochodzą z Intl. Kontrakt i słowniki żyją w @konce-pt/i18n, wspólnym z portem Angulara.

Komponenty (80+)

Formularze, przyciski i akcje, layout, nawigacja, dane (z flagową KptDataTable), feedback i overlay — pełna lista w tabeli powyżej. Ciężkie rzeczy (wykresy, czat, roadmapa, mapy, pełny Tabler) siedzą w subpathach @konce-pt/react/{charts,chat,roadmap,grid,map,icons}, żeby nie obciążać rdzenia. Każdy komponent ma obok źródła plik llms.txt z opisem API.

Dokumentacja

Playground z demami: ui.konce.pt/react. Opisy API dla modeli: llms.txt (EN) i llms-pl.txt (PL). Repozytorium: gitlab.com/konce-pt/koncept-ui.

Alerty skanerów łańcucha dostaw (Socket.dev i podobne) — klucze i18n czytane jak domeny oraz domyślne endpointy mapy — omawia sekcja „Skanery bezpieczeństwa" w arkuszu projektu.

Licencja

MIT © konce.pt