@konce-pt/angular
v0.6.1
Published
Open-source Angular 22 component library on Signals & Signal Forms — 70+ components, rich data table, zoneless, fully tokenized. Selektory kpt-*, klasy Kpt*.
Downloads
1,402
Maintainers
Readme
Koncept UI — Angular
Open-source Angular 22 component library built on Signals & Signal Forms. 70+ components, a feature-rich data table and app-shell layout — zoneless, standalone, fully tokenized.
Why Koncept UI
Koncept UI is a free, MIT-licensed component library for Angular 22, built from the ground up on a modern signal-based foundation:
- ⚡ Signals everywhere —
input(),output(),model(),computed.OnPush+ zoneless by default. - 📝 Forms on Signal Forms only — components implement
FormValueControl<T>and bind through thefield/Controldirective. NoControlValueAccessor. - 📊 Flagship data table — sorting, global filter, pagination, virtual scroll (5000+ rows), row selection, column reorder & freeze, CSV export, cell templates.
- 🎨 100% tokenized — every style is a
var(--kpt-*)CSS custom property. Light/dark theme, neutral OKLCH palette. Swap the brand by swapping one token layer. - 🧩 Standalone components — no NgModules. Import only what you use; tree-shakeable.
- ♿ Built on Angular CDK — overlays, a11y, focus management, virtual scrolling.
- 🌍 i18n built in — English (default) & Polish out of the box, runtime locale switch, add any language with one JSON.
Installation
npm i @konce-pt/angular @konce-pt/tokens @konce-pt/styles @angular/cdk
# or: pnpm add / yarn add@angular/core, @angular/common and @angular/forms (all ^22) are already in an Angular app; @angular/cdk (^22) is a required peer — overlay components (select, autocomplete, datepicker, date-range, dialog, drawer, tooltip, popover, menu…) build on the CDK Overlay — so install it explicitly (above). Optional: @konce-pt/validators for the Polish-market validators (NIP, REGON, PESEL, IBAN, postal code). Optional: @konce-pt/grid for the mobile-first layout system — its Angular directives live in @konce-pt/angular/grid.
Setup
Angular CLI (recommended)
Add the design tokens, base styles and — if you use overlay components — the CDK overlay CSS to the styles array in angular.json. Order matters: tokens first, your own src/styles.scss last so your overrides win the cascade.
// angular.json → projects.<app>.architect.build.options
"styles": [
"node_modules/@konce-pt/tokens/dist/css/tokens.css",
"node_modules/@konce-pt/tokens/dist/css/tokens.dark.css",
"node_modules/@konce-pt/styles/index.css",
"node_modules/@angular/cdk/overlay-prebuilt.css",
"src/styles.scss"
]Zoneless bootstrap (Angular 22) lives in your app config — no CSS imports in main.ts:
import { provideZonelessChangeDetection } from '@angular/core';
// import { provideKptI18n } from '@konce-pt/angular';
// import { provideKptTablerIcons } from '@konce-pt/angular/icons';
providers: [
provideZonelessChangeDetection(), // required (zoneless)
// provideKptI18n({ locale: 'pl' }), // optional — UI is English by default; set for Polish/other
// provideKptTablerIcons(), // optional — full Tabler icon set
]The UI language defaults to English and works with zero config — provideKptI18n(...) is optional and only needed for Polish (or a custom language). See Internationalization below.
Dark theme: set <html data-theme="dark"> (or rely on prefers-color-scheme).
Why not
import '…css'inmain.ts? Angular CLI (@angular/build) turns side-effect CSS imports into a separate stylesheet that isn't linked fromindex.html, so the app builds without styles. Useangular.json → styles[]instead.
Other bundlers (Vite / webpack)
Non-Angular-CLI bundlers can import the CSS directly (this is how the Koncept UI playground works):
import '@konce-pt/tokens/css';
import '@konce-pt/tokens/css/dark';
import '@konce-pt/styles';
import '@angular/cdk/overlay-prebuilt.css';Quick start
A form powered by Signal Forms — no ControlValueAccessor, no FormsModule:
import { Component, signal } from '@angular/core';
import { form, required, email, FormField } from '@angular/forms/signals';
import { KptFormField, KptInput, KptSelect, KptButton } from '@konce-pt/angular';
@Component({
selector: 'app-login',
imports: [FormField, KptFormField, KptInput, KptSelect, KptButton],
template: `
<kpt-form-field label="E-mail" required>
<kpt-input [formField]="loginForm.email" type="email" placeholder="[email protected]" />
</kpt-form-field>
<kpt-form-field label="Role">
<kpt-select [formField]="loginForm.role" [options]="roles" placeholder="Pick a role…" />
</kpt-form-field>
<kpt-button (click)="submit()">Sign in</kpt-button>
`,
})
export class Login {
readonly model = signal({ email: '', role: null as string | null });
readonly loginForm = form(this.model, (p) => {
required(p.email); email(p.email);
required(p.role);
});
readonly roles = [{ label: 'Admin', value: 'admin' }, { label: 'Editor', value: 'editor' }];
submit() { if (this.loginForm().valid()) console.log(this.model()); }
}Data table with sorting, filtering, pagination and a custom cell template:
<kpt-data-table [columns]="columns" [data]="users()" filterable exportable [pageSize]="10"
selectable="multiple" rowKey="id" [(selection)]="selected">
<ng-template kptCell="status" let-value="value">
<kpt-badge [value]="value" />
</ng-template>
</kpt-data-table>Components (70+)
| Category | Components | | --- | --- | | Forms (Signal Forms) | input, textarea, select, autocomplete, checkbox, switch, radio-group, slider, rating, datepicker, date-range, color-picker, file-upload, input-number, password, input-otp, chips-input, input-mask, listbox, knob, rich-text | | Buttons & actions | button, icon-button, button-group, fab, split-button, speed-dial | | Layout | app-shell, toolbar, sidenav, card, divider, panel, fieldset, splitter, scroll-top | | Navigation | tabs, accordion, breadcrumb, stepper, menu, menubar, megamenu, context-menu | | Data | data-table, paginator, tree, timeline, carousel, data-view, pick-list, order-list, galleria, meter-group | | Feedback & overlay | alert, dialog, toast, tooltip, popover, drawer, bottom-sheet, confirm, badge, chip, avatar, avatar-group, spinner, progress, skeleton, empty, image |
Every component ships an llms.txt API sheet next to its source for quick reference.
Theming
All visuals are driven by var(--kpt-*) tokens (three tiers: primitives → semantic → component). Override them in your src/styles.scss (it's last in styles[], so it wins the cascade):
: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.
Icons
A built-in set is bundled. For the full Tabler Icons set (MIT), opt in via the secondary entry point:
import { provideKptTablerIcons } from '@konce-pt/angular/icons';
// providers: [provideKptTablerIcons()]Internationalization (i18n)
Component labels ship in English (default) and Polish. The KptI18n service is providedIn: 'root', so English works out of the box with no provider. Call provideKptI18n(...) only to start in Polish (or another language), or to register/override dictionaries. All user-facing strings — aria-labels, empty states, paginator, calendars, rich-text menus — read from this signal-based service, so switching locale updates the UI instantly (zoneless-friendly).
import { provideKptI18n } from '@konce-pt/angular';
// providers: [provideKptI18n({ locale: 'pl' })] // optional — Polish UI (EN is the default)Switch at runtime:
import { inject } from '@angular/core';
import { KptI18n } from '@konce-pt/angular';
const i18n = inject(KptI18n);
i18n.setLocale('en');Add any language with one JSON (shape = the KptMessages contract; missing keys fall back to English):
import de from './i18n/de.json';
provideKptI18n({ locale: 'de', messages: { de } });Override individual labels of an existing language:
provideKptI18n({ messages: { en: { paginator: { rowsPerPage: 'Rows per page:' } } } });Calendar weekday/month names come from the browser's Intl API for the active locale. Per-component label inputs (e.g. emptyMessage, acceptLabel) still take precedence over the dictionary.
Documentation
- Storybook — interactive docs for every component.
- Playground — live demos with copyable HTML/TS/SCSS.
llms.txt— LLM-friendly API sheets per component.- Repository: gitlab.com/konce-pt/koncept-ui
License
MIT © konce.pt
🇵🇱 Wersja polska
Koncept UI to darmowa biblioteka komponentów na licencji MIT dla Angulara 22, zbudowana od podstaw na nowoczesnym fundamencie sygnałów.
- ⚡ Sygnały wszędzie —
input(),output(),model(),computed.OnPush+ zoneless domyślnie. - 📝 Formularze wyłącznie na Signal Forms — komponenty implementują
FormValueControl<T>, bezControlValueAccessor. - 📊 Flagowa tabela danych — sortowanie, filtr, paginacja, virtual scroll, zaznaczanie, przestawianie/zamrażanie kolumn, eksport CSV, szablony komórek.
- 🎨 100% na tokenach — każdy styl to
var(--kpt-*). Motyw jasny/ciemny, neutralna paleta OKLCH. - 🧩 Standalone — bez NgModules, tree-shaking.
- 🌍 Wbudowane i18n — angielski (domyślny) i polski, przełączanie języka w runtime, dowolny język jednym plikiem JSON.
Instalacja
npm i @konce-pt/angular @konce-pt/tokens @konce-pt/styles @angular/cdk@angular/core, @angular/common i @angular/forms (^22) są już w aplikacji Angulara; @angular/cdk (^22) to wymagany peer — komponenty overlay (select, autocomplete, datepicker, date-range, dialog, drawer, tooltip, popover, menu…) bazują na CDK Overlay — więc instaluj go jawnie (powyżej). Opcjonalnie: @konce-pt/validators (walidatory PL: NIP, REGON, PESEL, IBAN, kod pocztowy).
Konfiguracja
Angular CLI (zalecane) — dodaj CSS do tablicy styles w angular.json; kolejność ważna, src/styles.scss na końcu:
"styles": [
"node_modules/@konce-pt/tokens/dist/css/tokens.css",
"node_modules/@konce-pt/tokens/dist/css/tokens.dark.css",
"node_modules/@konce-pt/styles/index.css",
"node_modules/@angular/cdk/overlay-prebuilt.css",
"src/styles.scss"
]W Angular CLI nie używaj
import '…css'wmain.ts— bundler wrzuca taki CSS do osobnego, niepodlinkowanego arkusza i aplikacja jest bez stylów. Dla Vite/webpack import wmain.tsdziała (tak robi playground).
Zoneless bootstrap (Angular 22) w konfiguracji aplikacji — bez importów CSS w main.ts:
import { provideZonelessChangeDetection } from '@angular/core';
// import { provideKptI18n } from '@konce-pt/angular';
// import { provideKptTablerIcons } from '@konce-pt/angular/icons';
providers: [
provideZonelessChangeDetection(), // wymagane (zoneless)
// provideKptI18n({ locale: 'pl' }), // opcjonalne — UI domyślnie po angielsku; ustaw dla PL/innego
// provideKptTablerIcons(), // opcjonalne — pełny zestaw Tabler
]Język UI to domyślnie angielski i działa bez żadnej konfiguracji — provideKptI18n(...) jest opcjonalny, potrzebny tylko dla polskiego (lub własnego języka); szczegóły w sekcji i18n niżej.
Motyw ciemny: <html data-theme="dark">; nadpisania --kpt-color-* w styles.scss. Pełny zestaw ikon Tabler: provideKptTablerIcons() z @konce-pt/angular/icons.
Układ strony: @konce-pt/grid (osobna paczka CSS) plus dyrektywy [kptGrid], [kptCol], [kptFlex] z @konce-pt/angular/grid — siatka mobile-first, utilities flexbox i opcjonalne container queries.
Internacjonalizacja (i18n)
Etykiety komponentów są dostępne po angielsku (domyślnie) i polsku. Serwis KptI18n jest providedIn: 'root', więc angielski działa od razu, bez providera. provideKptI18n(...) wołasz tylko, by wystartować po polsku (lub w innym języku) albo zarejestrować/nadpisać słowniki. Wszystkie napisy (aria-label, stany puste, paginator, kalendarze, menu edytora) pochodzą z tego serwisu opartego o sygnały — zmiana języka odświeża UI natychmiast (zoneless).
import { provideKptI18n } from '@konce-pt/angular';
// providers: [provideKptI18n({ locale: 'pl' })] // opcjonalne — polski interfejs (EN domyślnie)Przełączanie w runtime: inject(KptI18n).setLocale('en').
Własny język jednym plikiem JSON (kształt = kontrakt KptMessages; brakujące klucze spadają na EN):
import de from './i18n/de.json';
provideKptI18n({ locale: 'de', messages: { de } });Nadpisanie pojedynczych etykiet: provideKptI18n({ messages: { pl: { paginator: { rowsPerPage: 'Na stronie:' } } } }).
Nazwy dni/miesięcy w kalendarzach pochodzą z Intl wg locale. Inputy etykiet per-komponent (np. emptyMessage) mają priorytet nad słownikiem.
Komponenty (70+)
Formularze (Signal Forms), przyciski i akcje, layout, nawigacja, dane (z flagową kpt-data-table), feedback i overlay — pełna lista w tabeli powyżej. Każdy komponent ma plik llms.txt z opisem API obok źródła.
Dokumentacja
Storybook (interaktywne docs), playground (dema z kopiowaniem kodu), llms.txt (opisy API). Repozytorium: gitlab.com/konce-pt/koncept-ui.
Licencja
MIT © konce.pt
