Mantine, biblioteka, w której wszystko już jest
Budowa panelu administracyjnego zaczyna się zwykle od tygodnia składania rzeczy, które w każdym projekcie wyglądają tak samo: tabela z sortowaniem, wybór daty, pole z podpowiedziami, okno modalne, powiadomienia, formularz z walidacją.
Mantine daje niemal to wszystko w jednej paczce: ponad sto dwadzieścia komponentów, kilkadziesiąt haków użytkowych i osobny system formularzy. Nie ma tu filozofii kopiowania kodu ani doboru części z kilku bibliotek, tylko jeden zestaw pokrywający większość potrzeb. Jeden wyjątek wart zapamiętania od razu to właśnie tabela: komponent Table daje wygląd, a sortowanie i stronicowanie dopisujesz sam.
Co dostajesz w komplecie
Warto wiedzieć, co odróżnia tę bibliotekę od zestawów komponentów wizualnych, bo różnica nie leży w liczbie przycisków.
Komponenty złożone to główna wartość. Kalendarz z zakresem dat, pole wyboru z wyszukiwaniem i wielokrotnym wyborem, edytor tekstu sformatowanego, wykresy. To rzeczy, które samodzielnie zajmują tygodnie, a tutaj są gotowe i przetestowane, przy czym część z nich mieszka w osobnych paczkach niż zestaw podstawowy.
Haki użytkowe to druga część, często pomijana w opisach. Obsługa kliknięcia poza elementem, odczyt rozmiaru okna, przechowywanie w pamięci lokalnej, opóźnianie wartości, skróty klawiszowe. Paczka z hakami działa niezależnie od komponentów, więc da się jej używać nawet bez reszty biblioteki.
pnpm add @mantine/core @mantine/hooksTrzecia część to system formularzy z walidacją, obsługą pól zagnieżdżonych i list. To osobna paczka, ale zintegrowana z komponentami, więc pole z błędem walidacji wygląda poprawnie bez dodatkowej pracy, a komunikat trafia we właściwe miejsce pod polem.
Motywy i style
Konfiguracja motywu obejmuje kolory, odstępy, promienie zaokrągleń i typografię, a komponenty z niej korzystają.
import { MantineProvider, createTheme } from '@mantine/core'
import '@mantine/core/styles.css'
const motyw = createTheme({
primaryColor: 'indigo',
defaultRadius: 'md',
fontFamily: 'Inter, sans-serif',
})
export function App({ children }) {
return <MantineProvider theme={motyw}>{children}</MantineProvider>
}Paleta kolorów działa tu inaczej niż w większości bibliotek. Kolor definiujesz jako dziesięć odcieni, a komponenty wybierają właściwy w zależności od kontekstu i trybu jasnego albo ciemnego. To znaczy, że tryb ciemny działa bez osobnej konfiguracji.
Do stylowania własnych komponentów zalecane są moduły CSS. Wcześniejsze wersje opierały się na rozwiązaniu opartym o style w JavaScripcie, które przestało być rekomendowane, więc przy nowym projekcie warto od razu zacząć od modułów.
Zmienne motywu są dostępne jako zmienne CSS, więc własne style korzystają z tych samych wartości co komponenty. To rozwiązuje najczęstszy problem przy mieszaniu biblioteki z własnym kodem, czyli rozjazd między kolorami z konfiguracji a wpisanymi na sztywno.
Formularze
To obszar, w którym ta biblioteka wypada wyraźnie lepiej od zestawów skupionych na wyglądzie.
import { useForm } from '@mantine/form'
const formularz = useForm({
mode: 'uncontrolled',
initialValues: { email: '', wiek: 18 },
validate: {
email: (wartosc) => (/^\S+@\S+$/.test(wartosc) ? null : 'Niepoprawny adres'),
wiek: (wartosc) => (wartosc >= 18 ? null : 'Wymagane pełnoletnie'),
},
})
<form onSubmit={formularz.onSubmit(zapisz)}>
<TextInput label="Adres e-mail" {...formularz.getInputProps('email')} />
<NumberInput label="Wiek" {...formularz.getInputProps('wiek')} />
</form>Tryb niekontrolowany, ustawiony w konfiguracji, ma znaczenie praktyczne przy większych formularzach. Zmiana wartości w jednym polu nie powoduje przerysowania całości, co przy trzydziestu polach jest różnicą między płynnym pisaniem a zauważalnym opóźnieniem.
Walidacja pól zagnieżdżonych i list działa bez sztuczek, co przy formularzach z powtarzalnymi sekcjami, na przykład pozycjami zamówienia, oszczędza sporo kodu.
Warto natomiast wiedzieć, że przy bardzo złożonych formularzach i przy potrzebie walidacji zgodnej ze schematem używanym po stronie serwera sensowniejsze bywa połączenie tego rozwiązania z osobną biblioteką walidacyjną, żeby reguły były wspólne dla obu stron.
Praca z Next.js
Biblioteka działa w Next.js, przy czym komponenty wymagają dyrektywy klienta, bo korzystają ze stanu i efektów.
To znaczy, że dostawca motywu i wszystko, co pod nim, jest częścią kliencką. Przy routerze aplikacji rozsądny układ polega na opakowaniu treści dostawcą w układzie i pozostawieniu komponentów serwerowych tam, gdzie nie potrzeba interaktywności.
Druga rzecz to style. Arkusz biblioteki trzeba zaimportować w układzie głównym, a przy renderowaniu po stronie serwera potrzebny jest fragment odpowiadający za wstrzyknięcie zmiennych motywu przed pierwszym renderowaniem. Bez niego pojawia się mignięcie niepoprawnymi kolorami, znane z każdej biblioteki z motywami.
Trzecia to rozmiar. Sto dwadzieścia komponentów w paczce nie znaczy, że wszystkie trafią do wyniku, bo importy są selektywne. Warto natomiast sprawdzić, ile faktycznie waży paczka po zbudowaniu, zwłaszcza przy stronie publicznej, gdzie liczy się czas ładowania.
Komponenty, które oszczędzają najwięcej
Warto wiedzieć, które elementy tej biblioteki zwracają się najszybciej, bo to one uzasadniają wybór.
Wybór daty jest na pierwszym miejscu. Zakresy, wykluczone dni, ograniczenia minimalne i maksymalne, obsługa stref czasowych i lokalizacja to obszar, w którym własna implementacja kończy się zwykle wersją działającą tylko w jednym przypadku użycia.
Pole wyboru z wyszukiwaniem jest na drugim. Wielokrotny wybór, tworzenie nowych pozycji, ładowanie danych na żądanie i obsługa klawiaturą to lista wymagań, którą trudno spełnić bez tygodnia pracy.
Edytor tekstu sformatowanego i wykresy są na trzecim, przy czym oba są nakładkami na cudze biblioteki i mieszkają w osobnych paczkach. Dostajesz wygląd zgodny z motywem i spójne zachowanie zamiast składania tego samodzielnie.
Powiadomienia i okna modalne wypadają niżej, bo są prostsze, natomiast ich wartość leży w spójności. Piętnaście miejsc wywołujących powiadomienie tym samym wywołaniem wygląda i zachowuje się tak samo, a piętnaście własnych implementacji nie.
Tabela z danymi jest natomiast tym, czego w komplecie nie ma, i to najczęstsze nieporozumienie przy wyborze tej biblioteki. Komponent Table odpowiada za wygląd, warianty i pojemnik z przewijaniem, natomiast sortowanie, stronicowanie, zaznaczanie wierszy i rozwijane szczegóły napiszesz sam albo weźmiesz z dodatku społecznościowego, na przykład mantine-datatable. To osobny projekt spoza zespołu Mantine, więc jego harmonogram wydań jest niezależny od reszty.
Reszta zestawu to komponenty podstawowe, które w każdej bibliotece wyglądają podobnie. Wybór między bibliotekami warto opierać na tych kilku pozycjach, a nie na liczbie wariantów przycisku.
Rozmiar paczki i wydajność
Kompletna biblioteka ma swoją cenę i warto ją znać, zanim trafi na stronę publiczną.
Importy są selektywne, więc do wyniku trafiają tylko użyte komponenty. To działa dobrze przy komponentach podstawowych i gorzej przy złożonych, bo kalendarz z wyborem daty albo edytor tekstu sformatowanego ciągną za sobą sporo kodu niezależnie od tego, ile ich funkcji używasz.
Praktyczna zasada brzmi: sprawdź rozmiar zbudowanej paczki po dodaniu każdego komponentu złożonego. Narzędzie analizujące zawartość paczki pokazuje, co faktycznie zajmuje miejsce, i bywa źródłem zaskoczenia.
Przy panelu administracyjnym za logowaniem to rzadko jest problem, bo użytkownik i tak ładuje aplikację raz i pracuje w niej godzinami. Przy stronie publicznej różnica w czasie ładowania przekłada się wprost na to, ile osób zostanie.
Rozsądny podział polega na oddzieleniu obu przypadków. Strona publiczna zbudowana lżejszymi środkami, panel na kompletnej bibliotece. Wspólny jest wtedy motyw i paleta, a nie zestaw komponentów.
Mantine kontra alternatywy
| Rozwiązanie | Mocna strona | Słabość | Kiedy wybrać |
|---|---|---|---|
| Mantine | Komponenty złożone, formularze, haki w komplecie | Większa paczka, własny sposób stylowania, brak tabeli z danymi | Panel administracyjny, aplikacja z formularzami |
| shadcn/ui | Kod u Ciebie, pełna kontrola, dostępność | Więcej pracy przy komponentach złożonych | Produkt z własnym systemem projektowym |
| daisyUI | Lekkość, motywy, działa w każdym frameworku | Brak logiki i komponentów złożonych | Szybki projekt, dowolny framework |
| HeroUI | Komponenty z animacją i zachowaniem | Mniejszy zbiór komponentów złożonych | Aplikacja, w której liczy się wygląd |
Wybór między pierwszymi dwoma wierszami jest najczęstszy i sprowadza się do jednego pytania: czy potrzebujesz wyboru daty, pola z podpowiedziami i gotowego systemu formularzy, czy raczej przycisków i formularzy o własnym wyglądzie.
Przy panelu administracyjnym, gdzie komponentów złożonych jest dużo, a wygląd ma być poprawny, a nie wyjątkowy, pierwszy wiersz oszczędza tygodnie. Przy produkcie, w którym wygląd jest wyróżnikiem, drugi daje kontrolę, której gotowa biblioteka nie da bez walki z jej stylami.
Najbliższym sąsiadem pod względem zakresu jest Chakra UI, które też instalujesz jako zależność i też daje komponenty złożone z dostępnością w komplecie. Różnica leży w sposobie stylowania: tutaj piszesz moduły CSS, tam podajesz style jako właściwości komponentu. Przy porównaniu jest jedno zastrzeżenie praktyczne: wersja trzecia Chakry to przepisanie od podstaw, więc spora część przykładów krążących w sieci opisuje interfejs, którego już nie ma, i łatwo o tym zapomnieć przy szacowaniu, ile pracy zajmie start.
Warto też rozważyć układ mieszany, o którym rzadko się myśli. Panel wewnętrzny na kompletnej bibliotece i część publiczna zbudowana własnymi komponentami to dwa projekty o różnych wymaganiach, więc jeden zestaw narzędzi dla obu jest założeniem, a nie koniecznością. Wspólna zostaje wtedy paleta i typografia, co wystarcza, żeby produkt wyglądał spójnie.
Dostosowanie wyglądu
Gotowa biblioteka daje spójny wygląd, który jest rozpoznawalny. To zaleta przy narzędziu wewnętrznym i problem przy produkcie, który ma się wyróżniać.
Pierwszy poziom dostosowania to konfiguracja motywu: paleta, promienie, typografia, odstępy. Zmiana tych czterech rzeczy wystarcza, żeby aplikacja przestała wyglądać jak przykład z dokumentacji, a kosztuje pół godziny.
Drugi poziom to domyślne właściwości komponentów. Warianty i rozmiary ustawione raz w motywie obowiązują wszędzie, więc przycisk domyślnie wygląda tak, jak ustaliliście, bez powtarzania właściwości w każdym miejscu.
const motyw = createTheme({
components: {
Button: { defaultProps: { size: 'md', radius: 'sm' } },
TextInput: { defaultProps: { size: 'md' } },
},
})Trzeci poziom to własne style przez moduły CSS, kierowane do wewnętrznych elementów komponentu. Działa i wymaga uwagi przy aktualizacjach, bo struktura wewnętrzna nie jest częścią publicznego kontraktu.
Czwarty to własne komponenty opakowujące te z biblioteki. To podejście najbardziej odporne na zmiany: pięć własnych komponentów używanych w całej aplikacji sprawia, że zmiana wyglądu albo nawet biblioteki dotyka pięciu plików, a nie dwustu.
Rozsądna kolejność jest właśnie taka. Zacznij od motywu, dołóż domyślne właściwości, a po własne style sięgaj wtedy, gdy dwa pierwsze poziomy nie wystarczą.
Typowe błędy
Pierwszy to walka ze stylami biblioteki zamiast konfiguracji motywu. Nadpisywanie klas komponentu własnymi regułami działa, dopóki nie zmieni się wersja albo tryb kolorów.
Drugi to formularze w trybie kontrolowanym przy dużej liczbie pól. Każda zmiana przerysowuje całość, a różnica staje się odczuwalna szybciej, niż się wydaje.
Trzeci to brak fragmentu obsługującego motyw przy renderowaniu po stronie serwera. Efektem jest mignięcie niepoprawnymi kolorami przy pierwszym wyświetleniu, widoczne przy każdym wejściu na stronę.
Czwarty to importowanie wszystkiego z jednego miejsca bez sprawdzenia rozmiaru wyniku. Przy stronie publicznej to bywa różnica między dobrym a złym wynikiem pomiaru czasu ładowania.
Piąty to mieszanie dwóch bibliotek komponentów w jednym projekcie. Dwa systemy stylowania prowadzą do konfliktów, których nikt później nie chce rozplątywać.
Szósty to zakładanie, że komponent gotowy jest dostępny w pełni. Biblioteka wypada tu dobrze, ale własne rozszerzenia i nietypowe użycia trzeba sprawdzić klawiaturą i czytnikiem ekranu.
Aktualizacje i utrzymanie
Biblioteka instalowana jako zależność ma inną charakterystykę utrzymania niż kod kopiowany do projektu, i warto o tym pomyśleć przed wyborem.
Zaletą jest to, że poprawki błędów i usprawnienia dostępności przychodzą z aktualizacją paczki. Nie musisz ich śledzić ani przenosić ręcznie, co przy komponentach złożonych ma realne znaczenie, bo to w nich najczęściej pojawiają się problemy z obsługą klawiaturą.
Wadą jest zależność od cudzego harmonogramu. Zmiana wprowadzająca niezgodność wymaga migracji w Twoim czasie, a nie wtedy, gdy Ci pasuje. Przy głównej wersji zmieniającej sposób stylowania to bywa praca na kilka dni.
Praktyczne zabezpieczenie polega na dwóch rzeczach. Pierwsza to przypięcie wersji i świadome jej podnoszenie, zamiast automatycznych aktualizacji przy każdej instalacji. Druga to własne komponenty opakowujące, dzięki którym zmiana w interfejsie biblioteki dotyka kilku plików zamiast całego projektu.
Warto też sprawdzać dziennik zmian przed podniesieniem wersji. Kilka minut lektury oszczędza godzin szukania przyczyny, gdy coś przestaje działać po aktualizacji zrobionej przy okazji innej pracy.
FAQ
Czym Mantine różni się od shadcn/ui?
To biblioteka instalowana jako zależność, a nie kod kopiowany do projektu. Dostajesz komponenty złożone, których shadcn nie ma w komplecie, kosztem mniejszej kontroli nad kodem i większej paczki. Aktualizacje przychodzą z paczką zamiast wymagać ponownego kopiowania.
Czy nadaje się do stron publicznych?
Tak, choć jej mocną stroną są aplikacje z formularzami i komponentami złożonymi. Przy stronie sprzedażowej, gdzie liczy się czas ładowania i wygląd wyróżniający produkt, lżejsze rozwiązania oparte o Tailwind CSS bywają lepszym wyborem.
Czy trzeba używać systemu formularzy z tej biblioteki?
Nie, komponenty działają z dowolną biblioteką formularzy. System wbudowany integruje się z nimi najlepiej i obsługuje pola zagnieżdżone, natomiast przy walidacji wspólnej z zapleczem sensowniejsze bywa oparcie reguł o schemat używany po obu stronach.
Jak działa tryb ciemny?
Bez osobnej konfiguracji. Kolory definiuje się jako zestaw odcieni, a komponenty wybierają właściwy w zależności od trybu, więc przełączenie działa dla całej aplikacji. Przy własnych stylach warto korzystać ze zmiennych motywu zamiast wartości wpisanych na sztywno.
Czy Mantine ma gotową tabelę z danymi?
Nie w podstawowym zestawie. Komponent Table odpowiada za wygląd, a sortowanie, stronicowanie i zaznaczanie wierszy dopisujesz sam albo bierzesz z dodatku społecznościowego w rodzaju mantine-datatable. Warto to uwzględnić w budżecie projektu, bo przy panelu administracyjnym to zwykle najdroższy pojedynczy element.
Czy da się używać samych haków?
Tak, paczka z hakami jest niezależna i nie wymaga reszty biblioteki. To sensowny wybór w projekcie, który ma własne komponenty, a potrzebuje gotowych rozwiązań na kliknięcie poza elementem, odczyt rozmiaru okna czy opóźnianie wartości.
Dokumentacja stoi na stronie projektu, a kod źródłowy w repozytorium na GitHubie.