Flowbite - Kompletny Przewodnik po UI Toolkit dla Tailwind CSS
Czym jest Flowbite?
Flowbite to open-source biblioteka komponentów zbudowana na Tailwind CSS, oferująca ponad 50 gotowych do użycia komponentów UI oraz 450+ bloków (gotowych sekcji stron). W przeciwieństwie do wielu bibliotek, Flowbite jest dostępny dla praktycznie każdego frameworka JavaScript - React, Vue, Svelte, Angular, a także jako vanilla JavaScript i czysty HTML.
Flowbite powstał z myślą o przyspieszeniu developmentu - zamiast budować każdy komponent od zera, możesz skopiować gotowy kod lub zainstalować paczkę i mieć działający navbar, modal czy datepicker w minuty. Wszystkie komponenty są w pełni responsive, wspierają dark mode i są zoptymalizowane pod dostępność.
Filozofia Flowbite
Flowbite oferuje dwa podejścia:
- Copy-paste HTML/CSS - Każdy komponent ma kod do skopiowania, działający z czystym Tailwind CSS
- Paczki JavaScript - Dla interaktywnych komponentów (dropdown, modal, datepicker) potrzebujesz JS
To sprawia, że Flowbite jest niezwykle elastyczny - możesz użyć tylko kilku komponentów lub zbudować całą aplikację na tej bibliotece.
Flowbite vs Inne Biblioteki
| Cecha | Flowbite | DaisyUI | Tailwind UI | shadcn/ui |
|---|---|---|---|---|
| Cena | Darmowy + Pro | Darmowy | $299+ | Darmowy |
| Frameworki | Wszystkie | Tailwind only | React | React |
| Bloki sekcji | 450+ | Brak | 500+ | ~50 |
| Figma | Tak (Pro) | Tak | Tak | Nie |
| Dark mode | Wbudowany | Wbudowany | Wbudowany | Manual |
| Licencja | MIT | MIT | Commercial | MIT |
| JavaScript | Opcjonalny | CSS only | React | React |
| TypeScript | Pełne | N/A | Pełne | Pełne |
Kiedy wybrać Flowbite?
Wybierz Flowbite, gdy:
- Potrzebujesz wsparcia dla wielu frameworków
- Chcesz gotowe bloki (hero, pricing, features)
- Szukasz darmowej alternatywy dla Tailwind UI
- Budujesz dashboard lub admin panel
- Potrzebujesz datepickera, carousel, wyedge drawer
Rozważ alternatywy, gdy:
- Potrzebujesz tylko CSS bez JS (DaisyUI)
- Chcesz pełnej kontroli nad kodem (shadcn/ui)
- Budget pozwala na płatne rozwiązanie (Tailwind UI)
Instalacja
Vanilla JavaScript / HTML
# npm
npm install flowbite
# yarn
yarn add flowbite
# pnpm
pnpm add flowbite// tailwind.config.js
module.exports = {
content: [
"./node_modules/flowbite/**/*.js"
],
plugins: [
require('flowbite/plugin')
]
}<!-- Dodaj skrypt przed </body> -->
<script src="../path/to/flowbite/dist/flowbite.min.js"></script>
<!-- Lub z CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.2.1/flowbite.min.js"></script>React
npm install flowbite flowbite-react// tailwind.config.js
module.exports = {
content: [
'./node_modules/flowbite-react/lib/**/*.js',
],
plugins: [
require('flowbite/plugin')
],
}Vue 3
npm install flowbite flowbite-vue// tailwind.config.js
module.exports = {
content: [
'./node_modules/flowbite-vue/**/*.{js,jsx,ts,tsx}',
'./node_modules/flowbite/**/*.js'
],
plugins: [
require('flowbite/plugin')
],
}Svelte
npm install flowbite flowbite-svelte// tailwind.config.js
module.exports = {
content: [
'./node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}'
],
plugins: [
require('flowbite/plugin')
],
}Angular
npm install flowbite// tailwind.config.js
module.exports = {
content: [
"./node_modules/flowbite/**/*.js"
],
plugins: [
require('flowbite/plugin')
]
}// angular.json - dodaj skrypt
"scripts": [
"node_modules/flowbite/dist/flowbite.min.js"
]Komponenty React
Alert
import { Alert } from 'flowbite-react'
import { HiInformationCircle, HiX } from 'react-icons/hi'
function AlertExamples() {
return (
<div className="flex flex-col gap-4">
{/* Podstawowy */}
<Alert color="info">
<span className="font-medium">Info alert!</span> Change a few things up and try submitting again.
</Alert>
{/* Różne kolory */}
<Alert color="failure">
<span className="font-medium">Danger alert!</span> Something went wrong.
</Alert>
<Alert color="success">
<span className="font-medium">Success alert!</span> Your purchase is complete.
</Alert>
<Alert color="warning">
<span className="font-medium">Warning alert!</span> Please check your input.
</Alert>
{/* Z ikoną */}
<Alert color="info" icon={HiInformationCircle}>
<span className="font-medium">Info!</span> This is an informational alert.
</Alert>
{/* Z dismiss button */}
<Alert
color="success"
onDismiss={() => console.log('Alert dismissed!')}
>
<span className="font-medium">Success!</span> You can dismiss this alert.
</Alert>
{/* Z border */}
<Alert color="info" withBorderAccent>
<span className="font-medium">Info!</span> Alert with border accent.
</Alert>
{/* Z dodatkową treścią */}
<Alert
color="info"
additionalContent={
<div className="mt-2 mb-4 text-sm text-cyan-700 dark:text-cyan-800">
More info about this alert goes here. This example text is going to run a bit longer
so that you can see how spacing works.
</div>
}
icon={HiInformationCircle}
>
<span className="font-medium">More information</span>
</Alert>
{/* Rounded */}
<Alert color="info" rounded>
Rounded alert!
</Alert>
</div>
)
}Navbar
import { Navbar, Button } from 'flowbite-react'
function NavbarExample() {
return (
<Navbar fluid rounded>
<Navbar.Brand href="https://flowbite.com/">
<img
src="/logo.svg"
className="mr-3 h-6 sm:h-9"
alt="Flowbite Logo"
/>
<span className="self-center whitespace-nowrap text-xl font-semibold dark:text-white">
Flowbite
</span>
</Navbar.Brand>
<div className="flex md:order-2">
<Button>Get started</Button>
<Navbar.Toggle />
</div>
<Navbar.Collapse>
<Navbar.Link href="/" active>
Home
</Navbar.Link>
<Navbar.Link href="/about">About</Navbar.Link>
<Navbar.Link href="/services">Services</Navbar.Link>
<Navbar.Link href="/pricing">Pricing</Navbar.Link>
<Navbar.Link href="/contact">Contact</Navbar.Link>
</Navbar.Collapse>
</Navbar>
)
}
// Z dropdown
import { Dropdown, Avatar } from 'flowbite-react'
function NavbarWithDropdown() {
return (
<Navbar fluid rounded>
<Navbar.Brand href="/">
<span className="self-center whitespace-nowrap text-xl font-semibold dark:text-white">
Brand
</span>
</Navbar.Brand>
<div className="flex md:order-2">
<Dropdown
arrowIcon={false}
inline
label={
<Avatar
alt="User settings"
img="/avatar.png"
rounded
/>
}
>
<Dropdown.Header>
<span className="block text-sm">John Doe</span>
<span className="block truncate text-sm font-medium">
john@example.com
</span>
</Dropdown.Header>
<Dropdown.Item>Dashboard</Dropdown.Item>
<Dropdown.Item>Settings</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item>Sign out</Dropdown.Item>
</Dropdown>
<Navbar.Toggle />
</div>
<Navbar.Collapse>
<Navbar.Link href="/" active>Home</Navbar.Link>
<Navbar.Link href="/about">About</Navbar.Link>
<Navbar.Link href="/services">Services</Navbar.Link>
</Navbar.Collapse>
</Navbar>
)
}Modal
import { useState } from 'react'
import { Button, Modal } from 'flowbite-react'
import { HiOutlineExclamationCircle } from 'react-icons/hi'
function ModalExample() {
const [openModal, setOpenModal] = useState(false)
return (
<>
<Button onClick={() => setOpenModal(true)}>Open modal</Button>
<Modal show={openModal} onClose={() => setOpenModal(false)}>
<Modal.Header>Terms of Service</Modal.Header>
<Modal.Body>
<div className="space-y-6">
<p className="text-base leading-relaxed text-gray-500 dark:text-gray-400">
With less than a month to go before the European Union enacts new consumer privacy laws
for its citizens, companies around the world are updating their terms of service.
</p>
<p className="text-base leading-relaxed text-gray-500 dark:text-gray-400">
The European Union's General Data Protection Regulation (G.D.P.R.) goes into effect on
May 25 and is meant to ensure a common set of data rights.
</p>
</div>
</Modal.Body>
<Modal.Footer>
<Button onClick={() => setOpenModal(false)}>I accept</Button>
<Button color="gray" onClick={() => setOpenModal(false)}>
Decline
</Button>
</Modal.Footer>
</Modal>
</>
)
}
// Confirmation Modal
function DeleteConfirmModal() {
const [openModal, setOpenModal] = useState(false)
return (
<>
<Button color="failure" onClick={() => setOpenModal(true)}>
Delete account
</Button>
<Modal show={openModal} size="md" onClose={() => setOpenModal(false)} popup>
<Modal.Header />
<Modal.Body>
<div className="text-center">
<HiOutlineExclamationCircle className="mx-auto mb-4 h-14 w-14 text-gray-400 dark:text-gray-200" />
<h3 className="mb-5 text-lg font-normal text-gray-500 dark:text-gray-400">
Are you sure you want to delete this product?
</h3>
<div className="flex justify-center gap-4">
<Button color="failure" onClick={() => setOpenModal(false)}>
Yes, I'm sure
</Button>
<Button color="gray" onClick={() => setOpenModal(false)}>
No, cancel
</Button>
</div>
</div>
</Modal.Body>
</Modal>
</>
)
}
// Różne rozmiary
function SizedModals() {
const [size, setSize] = useState('md')
const [openModal, setOpenModal] = useState(false)
return (
<>
<div className="flex flex-wrap gap-4">
{['sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl', '5xl', '6xl', '7xl'].map((s) => (
<Button
key={s}
onClick={() => {
setSize(s)
setOpenModal(true)
}}
>
{s}
</Button>
))}
</div>
<Modal show={openModal} size={size} onClose={() => setOpenModal(false)}>
<Modal.Header>Modal {size}</Modal.Header>
<Modal.Body>
<p>This is a {size} modal.</p>
</Modal.Body>
</Modal>
</>
)
}Carousel
import { Carousel } from 'flowbite-react'
function CarouselExample() {
return (
<div className="h-56 sm:h-64 xl:h-80 2xl:h-96">
<Carousel>
<img src="/carousel-1.svg" alt="Slide 1" />
<img src="/carousel-2.svg" alt="Slide 2" />
<img src="/carousel-3.svg" alt="Slide 3" />
<img src="/carousel-4.svg" alt="Slide 4" />
<img src="/carousel-5.svg" alt="Slide 5" />
</Carousel>
</div>
)
}
// Bez kontrolek
function CarouselWithoutControls() {
return (
<div className="h-56 sm:h-64 xl:h-80 2xl:h-96">
<Carousel slide={false}>
<img src="/carousel-1.svg" alt="Slide 1" />
<img src="/carousel-2.svg" alt="Slide 2" />
<img src="/carousel-3.svg" alt="Slide 3" />
</Carousel>
</div>
)
}
// Z custom indicators
function CarouselCustomIndicators() {
return (
<div className="h-56 sm:h-64 xl:h-80 2xl:h-96">
<Carousel
indicators={false}
leftControl={
<span className="group-hover:bg-white/50 group-focus:outline-none group-focus:ring-4 group-focus:ring-white">
←
</span>
}
rightControl={
<span className="group-hover:bg-white/50 group-focus:outline-none group-focus:ring-4 group-focus:ring-white">
→
</span>
}
>
<img src="/carousel-1.svg" alt="Slide 1" />
<img src="/carousel-2.svg" alt="Slide 2" />
</Carousel>
</div>
)
}
// Auto-slide
function AutoSlideCarousel() {
return (
<div className="h-56 sm:h-64 xl:h-80 2xl:h-96">
<Carousel slideInterval={3000}>
<img src="/carousel-1.svg" alt="Slide 1" />
<img src="/carousel-2.svg" alt="Slide 2" />
<img src="/carousel-3.svg" alt="Slide 3" />
</Carousel>
</div>
)
}Sidebar
import { Sidebar } from 'flowbite-react'
import {
HiArrowSmRight,
HiChartPie,
HiInbox,
HiShoppingBag,
HiTable,
HiUser,
} from 'react-icons/hi'
function SidebarExample() {
return (
<Sidebar aria-label="Default sidebar example">
<Sidebar.Items>
<Sidebar.ItemGroup>
<Sidebar.Item href="#" icon={HiChartPie}>
Dashboard
</Sidebar.Item>
<Sidebar.Item href="#" icon={HiInbox} label="3">
Inbox
</Sidebar.Item>
<Sidebar.Item href="#" icon={HiUser}>
Users
</Sidebar.Item>
<Sidebar.Item href="#" icon={HiShoppingBag}>
Products
</Sidebar.Item>
<Sidebar.Item href="#" icon={HiArrowSmRight}>
Sign In
</Sidebar.Item>
<Sidebar.Item href="#" icon={HiTable}>
Sign Up
</Sidebar.Item>
</Sidebar.ItemGroup>
</Sidebar.Items>
</Sidebar>
)
}
// Z collapse (submenu)
function SidebarWithCollapse() {
return (
<Sidebar aria-label="Sidebar with multi-level dropdown">
<Sidebar.Items>
<Sidebar.ItemGroup>
<Sidebar.Item href="#" icon={HiChartPie}>
Dashboard
</Sidebar.Item>
<Sidebar.Collapse icon={HiShoppingBag} label="E-commerce">
<Sidebar.Item href="#">Products</Sidebar.Item>
<Sidebar.Item href="#">Billing</Sidebar.Item>
<Sidebar.Item href="#">Invoice</Sidebar.Item>
</Sidebar.Collapse>
<Sidebar.Item href="#" icon={HiInbox}>
Inbox
</Sidebar.Item>
<Sidebar.Item href="#" icon={HiUser}>
Users
</Sidebar.Item>
</Sidebar.ItemGroup>
</Sidebar.Items>
</Sidebar>
)
}
// Z logo
function SidebarWithLogo() {
return (
<Sidebar aria-label="Sidebar with logo">
<Sidebar.Logo href="#" img="/logo.svg" imgAlt="Flowbite logo">
Flowbite
</Sidebar.Logo>
<Sidebar.Items>
<Sidebar.ItemGroup>
<Sidebar.Item href="#" icon={HiChartPie}>
Dashboard
</Sidebar.Item>
<Sidebar.Item href="#" icon={HiUser}>
Users
</Sidebar.Item>
</Sidebar.ItemGroup>
</Sidebar.Items>
</Sidebar>
)
}
// Z CTA
function SidebarWithCTA() {
return (
<Sidebar aria-label="Sidebar with CTA">
<Sidebar.Items>
<Sidebar.ItemGroup>
<Sidebar.Item href="#" icon={HiChartPie}>
Dashboard
</Sidebar.Item>
</Sidebar.ItemGroup>
</Sidebar.Items>
<Sidebar.CTA>
<div className="mb-3 flex items-center">
<Badge color="warning">Beta</Badge>
<button
aria-label="Close"
className="-m-1.5 ml-auto inline-flex h-6 w-6 rounded-lg bg-gray-100 p-1 text-cyan-900 hover:bg-gray-200"
type="button"
>
<HiX className="h-4 w-4" />
</button>
</div>
<p className="mb-3 text-sm text-cyan-900">
Preview the new Flowbite dashboard navigation!
</p>
<a
className="text-sm text-cyan-900 underline hover:text-cyan-800"
href="#"
>
Turn on now
</a>
</Sidebar.CTA>
</Sidebar>
)
}Drawer (Offcanvas)
import { useState } from 'react'
import { Button, Drawer } from 'flowbite-react'
function DrawerExample() {
const [isOpen, setIsOpen] = useState(false)
return (
<>
<Button onClick={() => setIsOpen(true)}>Open drawer</Button>
<Drawer open={isOpen} onClose={() => setIsOpen(false)}>
<Drawer.Header title="Drawer" />
<Drawer.Items>
<p className="mb-6 text-sm text-gray-500 dark:text-gray-400">
Supercharge your hiring by taking advantage of our limited-time sale.
</p>
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
<Button>Learn more</Button>
<Button color="gray" outline>
Get access
</Button>
</div>
</Drawer.Items>
</Drawer>
</>
)
}
// Drawer z różnych stron
function DrawerPositions() {
const [leftOpen, setLeftOpen] = useState(false)
const [rightOpen, setRightOpen] = useState(false)
const [topOpen, setTopOpen] = useState(false)
const [bottomOpen, setBottomOpen] = useState(false)
return (
<div className="flex gap-4">
<Button onClick={() => setLeftOpen(true)}>Left</Button>
<Drawer open={leftOpen} onClose={() => setLeftOpen(false)} position="left">
<Drawer.Header title="Left Drawer" />
<Drawer.Items>
<p>Content from the left</p>
</Drawer.Items>
</Drawer>
<Button onClick={() => setRightOpen(true)}>Right</Button>
<Drawer open={rightOpen} onClose={() => setRightOpen(false)} position="right">
<Drawer.Header title="Right Drawer" />
<Drawer.Items>
<p>Content from the right</p>
</Drawer.Items>
</Drawer>
<Button onClick={() => setTopOpen(true)}>Top</Button>
<Drawer open={topOpen} onClose={() => setTopOpen(false)} position="top">
<Drawer.Header title="Top Drawer" />
<Drawer.Items>
<p>Content from the top</p>
</Drawer.Items>
</Drawer>
<Button onClick={() => setBottomOpen(true)}>Bottom</Button>
<Drawer open={bottomOpen} onClose={() => setBottomOpen(false)} position="bottom">
<Drawer.Header title="Bottom Drawer" />
<Drawer.Items>
<p>Content from the bottom</p>
</Drawer.Items>
</Drawer>
</div>
)
}Datepicker
import { Datepicker } from 'flowbite-react'
function DatepickerExamples() {
return (
<div className="flex flex-col gap-4">
{/* Podstawowy */}
<Datepicker />
{/* Z domyślną datą */}
<Datepicker defaultDate={new Date(2024, 0, 15)} />
{/* Z minimalną i maksymalną datą */}
<Datepicker
minDate={new Date(2024, 0, 1)}
maxDate={new Date(2024, 11, 31)}
/>
{/* Inline */}
<Datepicker inline />
{/* Z tytułem */}
<Datepicker title="Select Date" />
{/* Auto hide */}
<Datepicker autoHide={false} />
{/* Controlled */}
<Datepicker
onSelectedDateChanged={(date) => console.log(date)}
/>
{/* Z labelami */}
<Datepicker
showClearButton
showTodayButton
labelClearButton="Clear"
labelTodayButton="Today"
/>
{/* Różne języki */}
<Datepicker language="pl-PL" />
{/* Tydzień zaczyna się od poniedziałku */}
<Datepicker weekStart={1} />
</div>
)
}Dropdown
import { Dropdown, Button } from 'flowbite-react'
function DropdownExamples() {
return (
<div className="flex gap-4">
{/* Podstawowy */}
<Dropdown label="Dropdown">
<Dropdown.Item>Dashboard</Dropdown.Item>
<Dropdown.Item>Settings</Dropdown.Item>
<Dropdown.Item>Earnings</Dropdown.Item>
<Dropdown.Item>Sign out</Dropdown.Item>
</Dropdown>
{/* Z dividerem */}
<Dropdown label="Actions">
<Dropdown.Item>Edit</Dropdown.Item>
<Dropdown.Item>Export</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item>Delete</Dropdown.Item>
</Dropdown>
{/* Z headerem */}
<Dropdown label="User menu">
<Dropdown.Header>
<span className="block text-sm">John Doe</span>
<span className="block truncate text-sm font-medium">
john@example.com
</span>
</Dropdown.Header>
<Dropdown.Item>Profile</Dropdown.Item>
<Dropdown.Item>Settings</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item>Sign out</Dropdown.Item>
</Dropdown>
{/* Z ikonami */}
<Dropdown label="Options">
<Dropdown.Item icon={HiViewGrid}>Dashboard</Dropdown.Item>
<Dropdown.Item icon={HiCog}>Settings</Dropdown.Item>
<Dropdown.Item icon={HiCurrencyDollar}>Earnings</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item icon={HiLogout}>Sign out</Dropdown.Item>
</Dropdown>
{/* Inline (bez border) */}
<Dropdown inline label="Inline dropdown">
<Dropdown.Item>Item 1</Dropdown.Item>
<Dropdown.Item>Item 2</Dropdown.Item>
</Dropdown>
{/* Różne rozmiary */}
<Dropdown label="Small" size="sm">
<Dropdown.Item>Item</Dropdown.Item>
</Dropdown>
<Dropdown label="Large" size="lg">
<Dropdown.Item>Item</Dropdown.Item>
</Dropdown>
{/* Różne pozycje */}
<Dropdown label="Top" placement="top">
<Dropdown.Item>Opens at top</Dropdown.Item>
</Dropdown>
<Dropdown label="Left" placement="left">
<Dropdown.Item>Opens at left</Dropdown.Item>
</Dropdown>
</div>
)
}Accordion
import { Accordion } from 'flowbite-react'
function AccordionExample() {
return (
<Accordion>
<Accordion.Panel>
<Accordion.Title>What is Flowbite?</Accordion.Title>
<Accordion.Content>
<p className="mb-2 text-gray-500 dark:text-gray-400">
Flowbite is an open-source library of interactive components built on top of Tailwind CSS.
</p>
<p className="text-gray-500 dark:text-gray-400">
Check out the{' '}
<a
href="https://flowbite.com/docs/getting-started/introduction/"
className="text-cyan-600 hover:underline dark:text-cyan-500"
>
getting started guide
</a>{' '}
and start building websites.
</p>
</Accordion.Content>
</Accordion.Panel>
<Accordion.Panel>
<Accordion.Title>Is there a Figma file?</Accordion.Title>
<Accordion.Content>
<p className="mb-2 text-gray-500 dark:text-gray-400">
Yes! You can get the Figma file in Flowbite Pro.
</p>
</Accordion.Content>
</Accordion.Panel>
<Accordion.Panel>
<Accordion.Title>What frameworks are supported?</Accordion.Title>
<Accordion.Content>
<p className="mb-2 text-gray-500 dark:text-gray-400">
React, Vue, Svelte, Angular, and vanilla JavaScript.
</p>
</Accordion.Content>
</Accordion.Panel>
</Accordion>
)
}
// Zawsze otwarte (wszystkie panele)
function AccordionAlwaysOpen() {
return (
<Accordion alwaysOpen>
<Accordion.Panel>
<Accordion.Title>Panel 1</Accordion.Title>
<Accordion.Content>
<p>Content 1</p>
</Accordion.Content>
</Accordion.Panel>
<Accordion.Panel>
<Accordion.Title>Panel 2</Accordion.Title>
<Accordion.Content>
<p>Content 2</p>
</Accordion.Content>
</Accordion.Panel>
</Accordion>
)
}
// Bez border
function AccordionFlush() {
return (
<Accordion flush>
<Accordion.Panel>
<Accordion.Title>Panel without borders</Accordion.Title>
<Accordion.Content>
<p>Cleaner look</p>
</Accordion.Content>
</Accordion.Panel>
</Accordion>
)
}Table
import { Table, Checkbox, Button } from 'flowbite-react'
function TableExample() {
return (
<div className="overflow-x-auto">
<Table>
<Table.Head>
<Table.HeadCell className="p-4">
<Checkbox />
</Table.HeadCell>
<Table.HeadCell>Product name</Table.HeadCell>
<Table.HeadCell>Color</Table.HeadCell>
<Table.HeadCell>Category</Table.HeadCell>
<Table.HeadCell>Price</Table.HeadCell>
<Table.HeadCell>
<span className="sr-only">Edit</span>
</Table.HeadCell>
</Table.Head>
<Table.Body className="divide-y">
<Table.Row className="bg-white dark:border-gray-700 dark:bg-gray-800">
<Table.Cell className="p-4">
<Checkbox />
</Table.Cell>
<Table.Cell className="whitespace-nowrap font-medium text-gray-900 dark:text-white">
Apple MacBook Pro 17"
</Table.Cell>
<Table.Cell>Sliver</Table.Cell>
<Table.Cell>Laptop</Table.Cell>
<Table.Cell>$2999</Table.Cell>
<Table.Cell>
<a href="#" className="font-medium text-cyan-600 hover:underline dark:text-cyan-500">
Edit
</a>
</Table.Cell>
</Table.Row>
<Table.Row className="bg-white dark:border-gray-700 dark:bg-gray-800">
<Table.Cell className="p-4">
<Checkbox />
</Table.Cell>
<Table.Cell className="whitespace-nowrap font-medium text-gray-900 dark:text-white">
Microsoft Surface Pro
</Table.Cell>
<Table.Cell>White</Table.Cell>
<Table.Cell>Laptop PC</Table.Cell>
<Table.Cell>$1999</Table.Cell>
<Table.Cell>
<a href="#" className="font-medium text-cyan-600 hover:underline dark:text-cyan-500">
Edit
</a>
</Table.Cell>
</Table.Row>
<Table.Row className="bg-white dark:border-gray-700 dark:bg-gray-800">
<Table.Cell className="p-4">
<Checkbox />
</Table.Cell>
<Table.Cell className="whitespace-nowrap font-medium text-gray-900 dark:text-white">
Magic Mouse 2
</Table.Cell>
<Table.Cell>Black</Table.Cell>
<Table.Cell>Accessories</Table.Cell>
<Table.Cell>$99</Table.Cell>
<Table.Cell>
<a href="#" className="font-medium text-cyan-600 hover:underline dark:text-cyan-500">
Edit
</a>
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
</div>
)
}
// Striped
function StripedTable() {
return (
<Table striped>
<Table.Head>
<Table.HeadCell>Name</Table.HeadCell>
<Table.HeadCell>Email</Table.HeadCell>
</Table.Head>
<Table.Body className="divide-y">
<Table.Row>
<Table.Cell>John Doe</Table.Cell>
<Table.Cell>john@example.com</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>Jane Smith</Table.Cell>
<Table.Cell>jane@example.com</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
)
}
// Hoverable
function HoverableTable() {
return (
<Table hoverable>
<Table.Head>
<Table.HeadCell>Product</Table.HeadCell>
<Table.HeadCell>Price</Table.HeadCell>
</Table.Head>
<Table.Body className="divide-y">
<Table.Row className="bg-white dark:border-gray-700 dark:bg-gray-800">
<Table.Cell>Product 1</Table.Cell>
<Table.Cell>$99</Table.Cell>
</Table.Row>
<Table.Row className="bg-white dark:border-gray-700 dark:bg-gray-800">
<Table.Cell>Product 2</Table.Cell>
<Table.Cell>$149</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
)
}Forms
import { Label, TextInput, Textarea, Select, Checkbox, Radio, FileInput, ToggleSwitch, RangeSlider, Button } from 'flowbite-react'
import { HiMail, HiLockClosed } from 'react-icons/hi'
function FormExamples() {
return (
<form className="flex max-w-md flex-col gap-4">
{/* Text Input */}
<div>
<div className="mb-2 block">
<Label htmlFor="email" value="Your email" />
</div>
<TextInput
id="email"
type="email"
placeholder="name@flowbite.com"
required
icon={HiMail}
/>
</div>
{/* Password */}
<div>
<div className="mb-2 block">
<Label htmlFor="password" value="Your password" />
</div>
<TextInput
id="password"
type="password"
required
icon={HiLockClosed}
/>
</div>
{/* Input sizes */}
<TextInput sizing="sm" placeholder="Small" />
<TextInput sizing="md" placeholder="Medium (default)" />
<TextInput sizing="lg" placeholder="Large" />
{/* Input with helper text */}
<div>
<div className="mb-2 block">
<Label htmlFor="username" value="Username" />
</div>
<TextInput
id="username"
placeholder="Bonnie"
helperText="We'll never share your details."
/>
</div>
{/* Input with validation */}
<div>
<div className="mb-2 block">
<Label htmlFor="success" value="Success input" color="success" />
</div>
<TextInput
id="success"
color="success"
helperText={
<span className="font-medium">Well done!</span>
}
/>
</div>
<div>
<div className="mb-2 block">
<Label htmlFor="failure" value="Error input" color="failure" />
</div>
<TextInput
id="failure"
color="failure"
helperText={
<span className="font-medium">Oops!</span>
}
/>
</div>
{/* Textarea */}
<div>
<div className="mb-2 block">
<Label htmlFor="comment" value="Your message" />
</div>
<Textarea
id="comment"
placeholder="Leave a comment..."
rows={4}
/>
</div>
{/* Select */}
<div>
<div className="mb-2 block">
<Label htmlFor="countries" value="Select your country" />
</div>
<Select id="countries" required>
<option>United States</option>
<option>Canada</option>
<option>France</option>
<option>Germany</option>
</Select>
</div>
{/* Checkbox */}
<div className="flex items-center gap-2">
<Checkbox id="remember" />
<Label htmlFor="remember">Remember me</Label>
</div>
{/* Radio */}
<fieldset className="flex max-w-md flex-col gap-4">
<legend className="mb-4">Choose your delivery</legend>
<div className="flex items-center gap-2">
<Radio id="standard" name="delivery" value="standard" defaultChecked />
<Label htmlFor="standard">Standard (5-7 days)</Label>
</div>
<div className="flex items-center gap-2">
<Radio id="express" name="delivery" value="express" />
<Label htmlFor="express">Express (1-2 days)</Label>
</div>
</fieldset>
{/* File Input */}
<div>
<div className="mb-2 block">
<Label htmlFor="file" value="Upload file" />
</div>
<FileInput id="file" />
</div>
{/* Toggle Switch */}
<ToggleSwitch
checked={true}
label="Enable notifications"
onChange={() => {}}
/>
{/* Range Slider */}
<div>
<div className="mb-2 block">
<Label htmlFor="default-range" value="Default range" />
</div>
<RangeSlider id="default-range" />
</div>
<Button type="submit">Submit</Button>
</form>
)
}Card
import { Card, Button } from 'flowbite-react'
function CardExamples() {
return (
<div className="flex flex-wrap gap-4">
{/* Podstawowa karta */}
<Card className="max-w-sm">
<h5 className="text-2xl font-bold tracking-tight text-gray-900 dark:text-white">
Noteworthy technology acquisitions 2021
</h5>
<p className="font-normal text-gray-700 dark:text-gray-400">
Here are the biggest enterprise technology acquisitions of 2021.
</p>
</Card>
{/* Karta z przyciskiem */}
<Card className="max-w-sm">
<h5 className="text-2xl font-bold tracking-tight text-gray-900 dark:text-white">
Noteworthy technology acquisitions 2021
</h5>
<p className="font-normal text-gray-700 dark:text-gray-400">
Here are the biggest enterprise technology acquisitions.
</p>
<Button>
Read more
<svg
className="-mr-1 ml-2 h-4 w-4"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</Button>
</Card>
{/* Karta z obrazkiem */}
<Card
className="max-w-sm"
imgAlt="Meaningful alt text"
imgSrc="/card-image.jpg"
>
<h5 className="text-2xl font-bold tracking-tight text-gray-900 dark:text-white">
Noteworthy technology acquisitions 2021
</h5>
<p className="font-normal text-gray-700 dark:text-gray-400">
Here are the biggest enterprise technology acquisitions.
</p>
</Card>
{/* Horizontal card */}
<Card
className="max-w-sm"
imgAlt="Meaningful alt text"
imgSrc="/card-image.jpg"
horizontal
>
<h5 className="text-2xl font-bold tracking-tight text-gray-900 dark:text-white">
Horizontal card
</h5>
<p className="font-normal text-gray-700 dark:text-gray-400">
This is a horizontal card layout.
</p>
</Card>
{/* Decorative image */}
<Card
className="max-w-sm"
renderImage={() => (
<img
width={500}
height={500}
src="/card-image.jpg"
alt="image 1"
/>
)}
>
<h5 className="text-2xl font-bold tracking-tight text-gray-900 dark:text-white">
Custom image render
</h5>
</Card>
</div>
)
}Toast
import { Toast } from 'flowbite-react'
import { HiCheck, HiExclamation, HiX, HiFire } from 'react-icons/hi'
function ToastExamples() {
return (
<div className="flex flex-col gap-4">
{/* Success toast */}
<Toast>
<div className="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-green-100 text-green-500 dark:bg-green-800 dark:text-green-200">
<HiCheck className="h-5 w-5" />
</div>
<div className="ml-3 text-sm font-normal">Item moved successfully.</div>
<Toast.Toggle />
</Toast>
{/* Error toast */}
<Toast>
<div className="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-red-100 text-red-500 dark:bg-red-800 dark:text-red-200">
<HiX className="h-5 w-5" />
</div>
<div className="ml-3 text-sm font-normal">Item has been deleted.</div>
<Toast.Toggle />
</Toast>
{/* Warning toast */}
<Toast>
<div className="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-orange-100 text-orange-500 dark:bg-orange-700 dark:text-orange-200">
<HiExclamation className="h-5 w-5" />
</div>
<div className="ml-3 text-sm font-normal">Improve password difficulty.</div>
<Toast.Toggle />
</Toast>
{/* Custom icon */}
<Toast>
<div className="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-cyan-100 text-cyan-500 dark:bg-cyan-800 dark:text-cyan-200">
<HiFire className="h-5 w-5" />
</div>
<div className="ml-3 text-sm font-normal">
Set yourself free.
</div>
<Toast.Toggle />
</Toast>
{/* Interactive toast */}
<Toast>
<div className="flex items-start">
<div className="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-blue-100 text-blue-500 dark:bg-blue-900 dark:text-blue-300">
<HiExclamation className="h-5 w-5" />
</div>
<div className="ml-3 text-sm font-normal">
<span className="mb-1 text-sm font-semibold text-gray-900 dark:text-white">
Update available
</span>
<div className="mb-2 text-sm font-normal">
A new software version is available for download.
</div>
<div className="flex gap-2">
<Button size="xs">Update</Button>
<Button size="xs" color="light">Not now</Button>
</div>
</div>
<Toast.Toggle />
</div>
</Toast>
</div>
)
}Flowbite Blocks
Flowbite oferuje 450+ gotowych bloków (sekcji stron), które można skopiować i użyć. Oto kategorie:
Dostępne kategorie bloków:
- Marketing: Hero, Feature, CTA, Content, Testimonial, Blog, Newsletter, Contact
- Application: Sidebar, Navbar, Footer, CRUD tables, User cards
- Publisher: Article, Blog post, Comment sections
- E-commerce: Product cards, Cart, Checkout, Pricing
Przykład Hero Block (Copy-paste HTML)
<section class="bg-white dark:bg-gray-900">
<div class="grid max-w-screen-xl px-4 py-8 mx-auto lg:gap-8 xl:gap-0 lg:py-16 lg:grid-cols-12">
<div class="mr-auto place-self-center lg:col-span-7">
<h1 class="max-w-2xl mb-4 text-4xl font-extrabold tracking-tight leading-none md:text-5xl xl:text-6xl dark:text-white">
Payments tool for software companies
</h1>
<p class="max-w-2xl mb-6 font-light text-gray-500 lg:mb-8 md:text-lg lg:text-xl dark:text-gray-400">
From checkout to global sales tax compliance, companies around the world use Flowbite to simplify their payment stack.
</p>
<a href="#" class="inline-flex items-center justify-center px-5 py-3 mr-3 text-base font-medium text-center text-white rounded-lg bg-primary-700 hover:bg-primary-800 focus:ring-4 focus:ring-primary-300 dark:focus:ring-primary-900">
Get started
<svg class="w-5 h-5 ml-2 -mr-1" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z" clip-rule="evenodd"></path>
</svg>
</a>
<a href="#" class="inline-flex items-center justify-center px-5 py-3 text-base font-medium text-center text-gray-900 border border-gray-300 rounded-lg hover:bg-gray-100 focus:ring-4 focus:ring-gray-100 dark:text-white dark:border-gray-700 dark:hover:bg-gray-700 dark:focus:ring-gray-800">
Speak to Sales
</a>
</div>
<div class="hidden lg:mt-0 lg:col-span-5 lg:flex">
<img src="https://flowbite.s3.amazonaws.com/blocks/marketing-ui/hero/phone-mockup.png" alt="mockup">
</div>
</div>
</section>Przykład Pricing Block
<section class="bg-white dark:bg-gray-900">
<div class="py-8 px-4 mx-auto max-w-screen-xl lg:py-16 lg:px-6">
<div class="mx-auto max-w-screen-md text-center mb-8 lg:mb-12">
<h2 class="mb-4 text-4xl tracking-tight font-extrabold text-gray-900 dark:text-white">
Designed for business teams like yours
</h2>
<p class="mb-5 font-light text-gray-500 sm:text-xl dark:text-gray-400">
Here at Flowbite we focus on markets where technology, innovation, and capital can unlock long-term value.
</p>
</div>
<div class="space-y-8 lg:grid lg:grid-cols-3 sm:gap-6 xl:gap-10 lg:space-y-0">
<!-- Pricing Card -->
<div class="flex flex-col p-6 mx-auto max-w-lg text-center text-gray-900 bg-white rounded-lg border border-gray-100 shadow dark:border-gray-600 xl:p-8 dark:bg-gray-800 dark:text-white">
<h3 class="mb-4 text-2xl font-semibold">Starter</h3>
<p class="font-light text-gray-500 sm:text-lg dark:text-gray-400">
Best option for personal use & for your next project.
</p>
<div class="flex justify-center items-baseline my-8">
<span class="mr-2 text-5xl font-extrabold">$29</span>
<span class="text-gray-500 dark:text-gray-400">/month</span>
</div>
<!-- List -->
<ul role="list" class="mb-8 space-y-4 text-left">
<li class="flex items-center space-x-3">
<svg class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
</svg>
<span>Individual configuration</span>
</li>
<li class="flex items-center space-x-3">
<svg class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
</svg>
<span>No setup, or hidden fees</span>
</li>
</ul>
<a href="#" class="text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:ring-primary-200 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:text-white dark:focus:ring-primary-900">
Get started
</a>
</div>
<!-- More cards... -->
</div>
</div>
</section>Dark Mode
Flowbite w pełni wspiera dark mode poprzez klasę dark::
// tailwind.config.js
module.exports = {
darkMode: 'class',
// ...
}// Przełącznik dark mode
import { useState, useEffect } from 'react'
import { DarkThemeToggle } from 'flowbite-react'
function DarkModeToggle() {
return (
<DarkThemeToggle />
)
}
// Lub własna implementacja
function CustomDarkModeToggle() {
const [isDark, setIsDark] = useState(false)
useEffect(() => {
if (isDark) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
}, [isDark])
return (
<button onClick={() => setIsDark(!isDark)}>
{isDark ? '🌙' : '☀️'}
</button>
)
}Flowbite Icons
Flowbite oferuje też zestaw 500+ darmowych ikon SVG:
npm install flowbite-iconsimport { HiOutlineSearch, HiOutlineMenu, HiOutlineUser } from 'flowbite-icons-react/outline'
import { HiSearch, HiMenu, HiUser } from 'flowbite-icons-react/solid'
function IconsExample() {
return (
<div className="flex gap-4">
{/* Outline icons */}
<HiOutlineSearch className="w-6 h-6" />
<HiOutlineMenu className="w-6 h-6" />
<HiOutlineUser className="w-6 h-6" />
{/* Solid icons */}
<HiSearch className="w-6 h-6" />
<HiMenu className="w-6 h-6" />
<HiUser className="w-6 h-6" />
</div>
)
}Cennik
Open Source (Darmowy)
- 50+ komponentów
- Podstawowe bloki
- Pełne wsparcie dla frameworków
- Dokumentacja
- Licencja MIT
Flowbite Pro ($149+)
- 450+ bloków premium
- Kompletny zestaw Figma
- Admin dashboard
- E-commerce templates
- CRM templates
- Priorytetowe wsparcie
- Aktualizacje na całe życie
FAQ - Najczęściej Zadawane Pytania
Czy Flowbite wymaga JavaScript?
Dla statycznych komponentów (buttons, cards, typography) - nie. Dla interaktywnych (dropdown, modal, datepicker) - tak.
Czy Flowbite działa z Next.js?
Tak! flowbite-react jest w pełni kompatybilny z Next.js App Router.
Jak dodać własne style do komponentów?
Użyj prop className lub theme:
<Button className="my-custom-class">
Custom styled
</Button>
// Lub z theme
<Button theme={{ base: "my-custom-base-class" }}>
Theme styled
</Button>Czy mogę użyć Flowbite z Vite?
Tak, Flowbite działa ze wszystkimi bundlerami - Vite, Webpack, esbuild, etc.
Jaka jest różnica między Flowbite a DaisyUI?
Flowbite oferuje JavaScript komponenty dla interaktywności (modal, dropdown), DaisyUI to tylko CSS. Flowbite wspiera wiele frameworków, DaisyUI działa wszędzie gdzie jest Tailwind.
Podsumowanie
Flowbite to wszechstronny UI toolkit dla Tailwind CSS oferujący:
- 50+ darmowych komponentów
- 450+ bloków w wersji Pro
- Wsparcie dla React, Vue, Svelte, Angular i vanilla JS
- Wbudowany dark mode
- Pełną responsywność
- Świetną dokumentację
Jest to doskonały wybór dla deweloperów szukających gotowych komponentów, którzy nie chcą budować wszystkiego od zera.