Utilizziamo i cookie per migliorare la tua esperienza sul sito
CodeWorlds
Torna alle collezioni
Guide41 min read

Preline UI - Kompletny Przewodnik po Darmowych Komponentach Tailwind

Preline UI is an open-source library with 300+ components for Tailwind CSS. Support for React, Vue and HTML with rich documentation and examples.

Preline UI - Kompletny Przewodnik po Darmowych Komponentach Tailwind

Czym jest Preline UI?

Preline UI to open-source biblioteka komponentów zbudowana na Tailwind CSS, oferująca ponad 300 gotowych do użycia komponentów UI. Jest to jedna z najbogatszych darmowych bibliotek Tailwind, która dostarcza zarówno proste elementy jak przyciski i formularze, jak i złożone komponenty jak karuzele, steppery czy datepickery.

Preline UI wyróżnia się wyjątkowo bogatą dokumentacją z setkami przykładów, co sprawia, że jest idealną biblioteką dla deweloperów szukających gotowych rozwiązań bez konieczności pisania kodu od zera. Wszystkie komponenty są w pełni responsive, wspierają dark mode i są zoptymalizowane pod dostępność.

Dlaczego Preline UI?

  1. 300+ komponentów - Jedna z największych darmowych kolekcji
  2. Doskonała dokumentacja - Setki przykładów z kodem
  3. Vanilla JS + React + Vue - Wsparcie dla popularnych frameworków
  4. Dark mode - Wbudowane wsparcie dla ciemnego motywu
  5. Copy-paste - Kopiuj kod i używaj od razu
  6. MIT License - Całkowicie darmowy, nawet komercyjnie

Preline UI vs Inne Biblioteki

CechaPreline UIFlowbiteDaisyUITailwind UI
CenaDarmowy + ProDarmowy + ProDarmowy$299+
Komponenty300+50+50+500+
Bloki/Templates50+ Pro450+ ProBrak500+
FrameworkiHTML, React, VueWszystkieCSS onlyReact
DokumentacjaDoskonałaBardzo dobraDobraŚwietna
Dark modeWbudowanyWbudowanyWbudowanyWbudowany
LicencjaMITMITMITCommercial

Kiedy wybrać Preline UI?

Wybierz Preline UI, gdy:

  • Potrzebujesz dużej liczby darmowych komponentów
  • Cenisz dobrą dokumentację z przykładami
  • Budujesz stronę HTML, React lub Vue
  • Potrzebujesz zaawansowanych komponentów (stepper, tree view)
  • Chcesz szybko prototypować

Rozważ alternatywy, gdy:

  • Potrzebujesz wsparcia dla Angular/Svelte (Flowbite)
  • Wolisz CSS-only bez JavaScript (DaisyUI)
  • Budget pozwala na płatne rozwiązanie (Tailwind UI)

Instalacja

NPM/Yarn

Code
Bash
# npm
npm install preline

# yarn
yarn add preline

# pnpm
pnpm add preline

Konfiguracja Tailwind CSS

JStailwind.config.js
JavaScript
// tailwind.config.js
module.exports = {
  content: [
    './node_modules/preline/dist/*.js',
    './src/**/*.{html,js,jsx,ts,tsx,vue}'
  ],
  plugins: [
    require('preline/plugin'),
  ],
}

Dodanie skryptu JavaScript

Code
HTML
<!-- Przed </body> -->
<script src="./node_modules/preline/dist/preline.js"></script>

<!-- Lub z CDN -->
<script src="https://preline.co/assets/js/preline.js"></script>

React/Next.js Setup

TSapp/layout.tsx
TypeScript
// app/layout.tsx lub pages/_app.tsx
'use client'

import { useEffect } from 'react'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  useEffect(() => {
    import('preline')
  }, [])

  return (
    <html lang="pl">
      <body>{children}</body>
    </html>
  )
}

Vue Setup

JSmain.js
JavaScript
// main.js
import 'preline'

// Lub w komponencie
import { onMounted } from 'vue'

onMounted(() => {
  import('preline')
})

Komponenty - Accordion

Accordion pozwala na rozwijanie i zwijanie sekcji treści.

Code
HTML
<!-- Podstawowy Accordion -->
<div class="hs-accordion-group">
  <div class="hs-accordion active" id="hs-basic-heading-one">
    <button class="hs-accordion-toggle hs-accordion-active:text-blue-600 py-3 inline-flex items-center gap-x-3 w-full font-semibold text-start text-gray-800 hover:text-gray-500 focus:outline-none focus:text-gray-500 rounded-lg disabled:opacity-50 disabled:pointer-events-none dark:hs-accordion-active:text-blue-500 dark:text-neutral-200 dark:hover:text-neutral-400 dark:focus:text-neutral-400" aria-expanded="true" aria-controls="hs-basic-collapse-one">
      <svg class="hs-accordion-active:hidden block size-3.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M5 12h14"></path>
        <path d="M12 5v14"></path>
      </svg>
      <svg class="hs-accordion-active:block hidden size-3.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M5 12h14"></path>
      </svg>
      Accordion #1
    </button>
    <div id="hs-basic-collapse-one" class="hs-accordion-content w-full overflow-hidden transition-[height] duration-300" role="region" aria-labelledby="hs-basic-heading-one">
      <p class="text-gray-800 dark:text-neutral-200">
        This is the first accordion body. It is shown by default.
      </p>
    </div>
  </div>

  <div class="hs-accordion" id="hs-basic-heading-two">
    <button class="hs-accordion-toggle hs-accordion-active:text-blue-600 py-3 inline-flex items-center gap-x-3 w-full font-semibold text-start text-gray-800 hover:text-gray-500 focus:outline-none focus:text-gray-500 rounded-lg disabled:opacity-50 disabled:pointer-events-none dark:hs-accordion-active:text-blue-500 dark:text-neutral-200 dark:hover:text-neutral-400 dark:focus:text-neutral-400" aria-expanded="false" aria-controls="hs-basic-collapse-two">
      <svg class="hs-accordion-active:hidden block size-3.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M5 12h14"></path>
        <path d="M12 5v14"></path>
      </svg>
      <svg class="hs-accordion-active:block hidden size-3.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M5 12h14"></path>
      </svg>
      Accordion #2
    </button>
    <div id="hs-basic-collapse-two" class="hs-accordion-content hidden w-full overflow-hidden transition-[height] duration-300" role="region" aria-labelledby="hs-basic-heading-two">
      <p class="text-gray-800 dark:text-neutral-200">
        This is the second accordion body.
      </p>
    </div>
  </div>
</div>

Accordion z ikonami po prawej stronie

Code
HTML
<div class="hs-accordion-group">
  <div class="hs-accordion active bg-white border -mt-px first:rounded-t-lg last:rounded-b-lg dark:bg-neutral-800 dark:border-neutral-700" id="hs-bordered-heading-one">
    <button class="hs-accordion-toggle hs-accordion-active:text-blue-600 inline-flex items-center justify-between gap-x-3 w-full font-semibold text-start text-gray-800 py-4 px-5 hover:text-gray-500 disabled:opacity-50 disabled:pointer-events-none dark:hs-accordion-active:text-blue-500 dark:text-neutral-200 dark:hover:text-neutral-400" aria-expanded="true" aria-controls="hs-bordered-collapse-one">
      Accordion #1
      <svg class="hs-accordion-active:hidden block size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="m6 9 6 6 6-6"></path>
      </svg>
      <svg class="hs-accordion-active:block hidden size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="m18 15-6-6-6 6"></path>
      </svg>
    </button>
    <div id="hs-bordered-collapse-one" class="hs-accordion-content w-full overflow-hidden transition-[height] duration-300" role="region" aria-labelledby="hs-bordered-heading-one">
      <div class="pb-4 px-5">
        <p class="text-gray-800 dark:text-neutral-200">
          Content for accordion #1
        </p>
      </div>
    </div>
  </div>
</div>

Komponenty - Tabs

Code
HTML
<!-- Podstawowe Tabs -->
<div class="border-b border-gray-200 dark:border-neutral-700">
  <nav class="flex gap-x-1" aria-label="Tabs" role="tablist" aria-orientation="horizontal">
    <button type="button" class="hs-tab-active:font-semibold hs-tab-active:border-blue-600 hs-tab-active:text-blue-600 py-4 px-1 inline-flex items-center gap-x-2 border-b-2 border-transparent text-sm whitespace-nowrap text-gray-500 hover:text-blue-600 focus:outline-none focus:text-blue-600 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-400 dark:hover:text-blue-500 active" id="tabs-with-underline-item-1" aria-selected="true" data-hs-tab="#tabs-with-underline-1" aria-controls="tabs-with-underline-1" role="tab">
      Tab 1
    </button>
    <button type="button" class="hs-tab-active:font-semibold hs-tab-active:border-blue-600 hs-tab-active:text-blue-600 py-4 px-1 inline-flex items-center gap-x-2 border-b-2 border-transparent text-sm whitespace-nowrap text-gray-500 hover:text-blue-600 focus:outline-none focus:text-blue-600 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-400 dark:hover:text-blue-500" id="tabs-with-underline-item-2" aria-selected="false" data-hs-tab="#tabs-with-underline-2" aria-controls="tabs-with-underline-2" role="tab">
      Tab 2
    </button>
    <button type="button" class="hs-tab-active:font-semibold hs-tab-active:border-blue-600 hs-tab-active:text-blue-600 py-4 px-1 inline-flex items-center gap-x-2 border-b-2 border-transparent text-sm whitespace-nowrap text-gray-500 hover:text-blue-600 focus:outline-none focus:text-blue-600 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-400 dark:hover:text-blue-500" id="tabs-with-underline-item-3" aria-selected="false" data-hs-tab="#tabs-with-underline-3" aria-controls="tabs-with-underline-3" role="tab">
      Tab 3
    </button>
  </nav>
</div>

<div class="mt-3">
  <div id="tabs-with-underline-1" role="tabpanel" aria-labelledby="tabs-with-underline-item-1">
    <p class="text-gray-500 dark:text-neutral-400">
      This is the <em class="font-semibold text-gray-800 dark:text-neutral-200">first</em> tab content.
    </p>
  </div>
  <div id="tabs-with-underline-2" class="hidden" role="tabpanel" aria-labelledby="tabs-with-underline-item-2">
    <p class="text-gray-500 dark:text-neutral-400">
      This is the <em class="font-semibold text-gray-800 dark:text-neutral-200">second</em> tab content.
    </p>
  </div>
  <div id="tabs-with-underline-3" class="hidden" role="tabpanel" aria-labelledby="tabs-with-underline-item-3">
    <p class="text-gray-500 dark:text-neutral-400">
      This is the <em class="font-semibold text-gray-800 dark:text-neutral-200">third</em> tab content.
    </p>
  </div>
</div>

Tabs jako Pills (przyciski)

Code
HTML
<nav class="flex gap-x-1" aria-label="Tabs" role="tablist" aria-orientation="horizontal">
  <button type="button" class="hs-tab-active:bg-blue-600 hs-tab-active:text-white py-3 px-4 inline-flex items-center gap-x-2 bg-transparent text-sm font-medium text-center text-gray-500 rounded-lg hover:text-blue-600 focus:outline-none focus:text-blue-600 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-400 dark:hover:text-blue-500 active" id="pills-item-1" aria-selected="true" data-hs-tab="#pills-1" aria-controls="pills-1" role="tab">
    Tab 1
  </button>
  <button type="button" class="hs-tab-active:bg-blue-600 hs-tab-active:text-white py-3 px-4 inline-flex items-center gap-x-2 bg-transparent text-sm font-medium text-center text-gray-500 rounded-lg hover:text-blue-600 focus:outline-none focus:text-blue-600 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-400 dark:hover:text-blue-500" id="pills-item-2" aria-selected="false" data-hs-tab="#pills-2" aria-controls="pills-2" role="tab">
    Tab 2
  </button>
  <button type="button" class="hs-tab-active:bg-blue-600 hs-tab-active:text-white py-3 px-4 inline-flex items-center gap-x-2 bg-transparent text-sm font-medium text-center text-gray-500 rounded-lg hover:text-blue-600 focus:outline-none focus:text-blue-600 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-400 dark:hover:text-blue-500" id="pills-item-3" aria-selected="false" data-hs-tab="#pills-3" aria-controls="pills-3" role="tab">
    Tab 3
  </button>
</nav>

Komponenty - Modal

Code
HTML
<!-- Trigger Button -->
<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:bg-blue-700 disabled:opacity-50 disabled:pointer-events-none" aria-haspopup="dialog" aria-expanded="false" aria-controls="hs-basic-modal" data-hs-overlay="#hs-basic-modal">
  Open modal
</button>

<!-- Modal -->
<div id="hs-basic-modal" class="hs-overlay hidden size-full fixed top-0 start-0 z-[80] overflow-x-hidden overflow-y-auto pointer-events-none" role="dialog" tabindex="-1" aria-labelledby="hs-basic-modal-label">
  <div class="hs-overlay-open:mt-7 hs-overlay-open:opacity-100 hs-overlay-open:duration-500 mt-0 opacity-0 ease-out transition-all sm:max-w-lg sm:w-full m-3 sm:mx-auto">
    <div class="flex flex-col bg-white border shadow-sm rounded-xl pointer-events-auto dark:bg-neutral-800 dark:border-neutral-700 dark:shadow-neutral-700/70">
      <div class="flex justify-between items-center py-3 px-4 border-b dark:border-neutral-700">
        <h3 id="hs-basic-modal-label" class="font-bold text-gray-800 dark:text-white">
          Modal title
        </h3>
        <button type="button" class="size-8 inline-flex justify-center items-center gap-x-2 rounded-full border border-transparent bg-gray-100 text-gray-800 hover:bg-gray-200 focus:outline-none focus:bg-gray-200 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-700 dark:hover:bg-neutral-600 dark:text-neutral-400 dark:focus:bg-neutral-600" aria-label="Close" data-hs-overlay="#hs-basic-modal">
          <span class="sr-only">Close</span>
          <svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <path d="M18 6 6 18"></path>
            <path d="m6 6 12 12"></path>
          </svg>
        </button>
      </div>
      <div class="p-4 overflow-y-auto">
        <p class="text-gray-800 dark:text-neutral-400">
          This is a modal body. You can add any content here.
        </p>
      </div>
      <div class="flex justify-end items-center gap-x-2 py-3 px-4 border-t dark:border-neutral-700">
        <button type="button" class="py-2 px-3 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50 focus:outline-none focus:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-700 dark:focus:bg-neutral-700" data-hs-overlay="#hs-basic-modal">
          Close
        </button>
        <button type="button" class="py-2 px-3 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:bg-blue-700 disabled:opacity-50 disabled:pointer-events-none">
          Save changes
        </button>
      </div>
    </div>
  </div>
</div>

Modal Sizes

Code
HTML
<!-- Small Modal -->
<div id="hs-small-modal" class="hs-overlay hidden">
  <div class="hs-overlay-open:mt-7 hs-overlay-open:opacity-100 mt-0 opacity-0 ease-out transition-all sm:max-w-sm sm:w-full m-3 sm:mx-auto">
    <!-- content -->
  </div>
</div>

<!-- Large Modal -->
<div id="hs-large-modal" class="hs-overlay hidden">
  <div class="hs-overlay-open:mt-7 hs-overlay-open:opacity-100 mt-0 opacity-0 ease-out transition-all lg:max-w-4xl lg:w-full m-3 lg:mx-auto">
    <!-- content -->
  </div>
</div>

<!-- Full Screen Modal -->
<div id="hs-full-screen-modal" class="hs-overlay hidden">
  <div class="hs-overlay-open:mt-7 hs-overlay-open:opacity-100 mt-0 opacity-0 ease-out transition-all max-w-full w-full m-3 mx-auto h-[calc(100%-3.5rem)]">
    <!-- content -->
  </div>
</div>

Komponenty - Dropdown

Code
HTML
<div class="hs-dropdown relative inline-flex">
  <button id="hs-dropdown-default" type="button" class="hs-dropdown-toggle py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50 focus:outline-none focus:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-700 dark:focus:bg-neutral-700" aria-haspopup="menu" aria-expanded="false" aria-label="Dropdown">
    Actions
    <svg class="hs-dropdown-open:rotate-180 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
      <path d="m6 9 6 6 6-6"/>
    </svg>
  </button>

  <div class="hs-dropdown-menu transition-[opacity,margin] duration hs-dropdown-open:opacity-100 opacity-0 hidden min-w-60 bg-white shadow-md rounded-lg mt-2 dark:bg-neutral-800 dark:border dark:border-neutral-700" role="menu" aria-orientation="vertical" aria-labelledby="hs-dropdown-default">
    <div class="p-1 space-y-0.5">
      <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-gray-800 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-300 dark:focus:bg-neutral-700" href="#">
        Newsletter
      </a>
      <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-gray-800 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-300 dark:focus:bg-neutral-700" href="#">
        Purchases
      </a>
      <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-gray-800 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-300 dark:focus:bg-neutral-700" href="#">
        Downloads
      </a>
      <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-gray-800 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-300 dark:focus:bg-neutral-700" href="#">
        Team Account
      </a>
    </div>
  </div>
</div>

Dropdown z ikonami

Code
HTML
<div class="hs-dropdown relative inline-flex">
  <button id="hs-dropdown-with-icons" type="button" class="hs-dropdown-toggle py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-700">
    With icons
    <svg class="hs-dropdown-open:rotate-180 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
      <path d="m6 9 6 6 6-6"/>
    </svg>
  </button>

  <div class="hs-dropdown-menu transition-[opacity,margin] duration hs-dropdown-open:opacity-100 opacity-0 hidden min-w-60 bg-white shadow-md rounded-lg mt-2 divide-y divide-gray-200 dark:bg-neutral-800 dark:border dark:border-neutral-700 dark:divide-neutral-700">
    <div class="p-1 space-y-0.5">
      <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-gray-800 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-300" href="#">
        <svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
          <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
          <polyline points="7 10 12 15 17 10"/>
          <line x1="12" x2="12" y1="15" y2="3"/>
        </svg>
        Downloads
      </a>
      <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-gray-800 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-300" href="#">
        <svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
          <path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/>
          <circle cx="9" cy="7" r="4"/>
          <path d="M22 21v-2a4 4 0 0 0-3-3.87"/>
          <path d="M16 3.13a4 4 0 0 1 0 7.75"/>
        </svg>
        Team Account
      </a>
    </div>
    <div class="p-1 space-y-0.5">
      <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-red-600 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-red-500 dark:hover:bg-neutral-700" href="#">
        <svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
          <path d="M3 6h18"/>
          <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/>
          <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/>
          <line x1="10" x2="10" y1="11" y2="17"/>
          <line x1="14" x2="14" y1="11" y2="17"/>
        </svg>
        Delete
      </a>
    </div>
  </div>
</div>

Komponenty - Tooltip

Code
HTML
<!-- Basic Tooltip -->
<div class="hs-tooltip inline-block">
  <button type="button" class="hs-tooltip-toggle py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50 focus:outline-none focus:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-700 dark:focus:bg-neutral-700">
    Hover me
  </button>
  <span class="hs-tooltip-content hs-tooltip-shown:opacity-100 hs-tooltip-shown:visible opacity-0 transition-opacity inline-block absolute invisible z-10 py-1 px-2 bg-gray-900 text-xs font-medium text-white rounded shadow-sm dark:bg-neutral-700" role="tooltip">
    Tooltip content
  </span>
</div>

<!-- Tooltip z różnymi pozycjami -->
<div class="hs-tooltip inline-block" data-hs-tooltip-placement="top">
  <button type="button" class="hs-tooltip-toggle ...">Top</button>
  <span class="hs-tooltip-content ..." role="tooltip">Top tooltip</span>
</div>

<div class="hs-tooltip inline-block" data-hs-tooltip-placement="bottom">
  <button type="button" class="hs-tooltip-toggle ...">Bottom</button>
  <span class="hs-tooltip-content ..." role="tooltip">Bottom tooltip</span>
</div>

<div class="hs-tooltip inline-block" data-hs-tooltip-placement="left">
  <button type="button" class="hs-tooltip-toggle ...">Left</button>
  <span class="hs-tooltip-content ..." role="tooltip">Left tooltip</span>
</div>

<div class="hs-tooltip inline-block" data-hs-tooltip-placement="right">
  <button type="button" class="hs-tooltip-toggle ...">Right</button>
  <span class="hs-tooltip-content ..." role="tooltip">Right tooltip</span>
</div>

Komponenty - Carousel

Code
HTML
<div data-hs-carousel='{
    "loadingClasses": "opacity-0",
    "isAutoPlay": true
  }' class="relative">
  <div class="hs-carousel relative overflow-hidden w-full min-h-96 bg-white rounded-lg">
    <div class="hs-carousel-body absolute top-0 bottom-0 start-0 flex flex-nowrap transition-transform duration-700 opacity-0">
      <div class="hs-carousel-slide">
        <div class="flex justify-center h-full bg-gray-100 p-6 dark:bg-neutral-900">
          <span class="self-center text-4xl text-gray-800 transition duration-700 dark:text-white">First slide</span>
        </div>
      </div>
      <div class="hs-carousel-slide">
        <div class="flex justify-center h-full bg-gray-200 p-6 dark:bg-neutral-800">
          <span class="self-center text-4xl text-gray-800 transition duration-700 dark:text-white">Second slide</span>
        </div>
      </div>
      <div class="hs-carousel-slide">
        <div class="flex justify-center h-full bg-gray-300 p-6 dark:bg-neutral-700">
          <span class="self-center text-4xl text-gray-800 transition duration-700 dark:text-white">Third slide</span>
        </div>
      </div>
    </div>
  </div>

  <!-- Prev/Next buttons -->
  <button type="button" class="hs-carousel-prev hs-carousel-disabled:opacity-50 disabled:pointer-events-none absolute inset-y-0 start-0 inline-flex justify-center items-center w-[46px] h-full text-gray-800 hover:bg-gray-800/10 focus:outline-none focus:bg-gray-800/10 rounded-s-lg dark:text-white dark:hover:bg-white/10 dark:focus:bg-white/10">
    <span class="text-2xl" aria-hidden="true">
      <svg class="shrink-0 size-5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="m15 18-6-6 6-6"></path>
      </svg>
    </span>
    <span class="sr-only">Previous</span>
  </button>
  <button type="button" class="hs-carousel-next hs-carousel-disabled:opacity-50 disabled:pointer-events-none absolute inset-y-0 end-0 inline-flex justify-center items-center w-[46px] h-full text-gray-800 hover:bg-gray-800/10 focus:outline-none focus:bg-gray-800/10 rounded-e-lg dark:text-white dark:hover:bg-white/10 dark:focus:bg-white/10">
    <span class="sr-only">Next</span>
    <span class="text-2xl" aria-hidden="true">
      <svg class="shrink-0 size-5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="m9 18 6-6-6-6"></path>
      </svg>
    </span>
  </button>

  <!-- Pagination -->
  <div class="hs-carousel-pagination flex justify-center absolute bottom-3 start-0 end-0 space-x-2">
    <span class="hs-carousel-active:bg-blue-700 hs-carousel-active:border-blue-700 size-3 border border-gray-400 rounded-full cursor-pointer dark:border-neutral-600 dark:hs-carousel-active:bg-blue-500 dark:hs-carousel-active:border-blue-500"></span>
    <span class="hs-carousel-active:bg-blue-700 hs-carousel-active:border-blue-700 size-3 border border-gray-400 rounded-full cursor-pointer dark:border-neutral-600 dark:hs-carousel-active:bg-blue-500 dark:hs-carousel-active:border-blue-500"></span>
    <span class="hs-carousel-active:bg-blue-700 hs-carousel-active:border-blue-700 size-3 border border-gray-400 rounded-full cursor-pointer dark:border-neutral-600 dark:hs-carousel-active:bg-blue-500 dark:hs-carousel-active:border-blue-500"></span>
  </div>
</div>

Komponenty - Stepper

Code
HTML
<!-- Basic Stepper -->
<ul class="relative flex flex-row gap-x-2">
  <!-- Completed Step -->
  <li class="shrink basis-0 flex-1 group">
    <div class="min-w-7 min-h-7 w-full inline-flex items-center text-xs align-middle">
      <span class="size-7 flex justify-center items-center shrink-0 bg-blue-600 font-medium text-white rounded-full dark:bg-blue-500">
        <svg class="shrink-0 size-3" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
          <polyline points="20 6 9 17 4 12"></polyline>
        </svg>
      </span>
      <div class="ms-2 w-full h-px flex-1 bg-blue-600 group-last:hidden dark:bg-blue-500"></div>
    </div>
    <div class="mt-3">
      <span class="block text-sm font-medium text-gray-800 dark:text-white">
        Step
      </span>
    </div>
  </li>

  <!-- Current Step -->
  <li class="shrink basis-0 flex-1 group">
    <div class="min-w-7 min-h-7 w-full inline-flex items-center text-xs align-middle">
      <span class="size-7 flex justify-center items-center shrink-0 bg-blue-600 font-medium text-white rounded-full dark:bg-blue-500">
        2
      </span>
      <div class="ms-2 w-full h-px flex-1 bg-gray-200 group-last:hidden dark:bg-neutral-700"></div>
    </div>
    <div class="mt-3">
      <span class="block text-sm font-medium text-blue-600 dark:text-blue-500">
        Step
      </span>
    </div>
  </li>

  <!-- Future Step -->
  <li class="shrink basis-0 flex-1 group">
    <div class="min-w-7 min-h-7 w-full inline-flex items-center text-xs align-middle">
      <span class="size-7 flex justify-center items-center shrink-0 bg-gray-100 font-medium text-gray-800 rounded-full dark:bg-neutral-700 dark:text-white">
        3
      </span>
      <div class="ms-2 w-full h-px flex-1 bg-gray-200 group-last:hidden dark:bg-neutral-700"></div>
    </div>
    <div class="mt-3">
      <span class="block text-sm font-medium text-gray-800 dark:text-white">
        Step
      </span>
    </div>
  </li>
</ul>

Vertical Stepper

Code
HTML
<ul class="relative flex flex-col gap-2">
  <li class="flex items-center gap-x-2 shrink basis-0 flex-1 group">
    <span class="min-w-7 min-h-7 inline-flex justify-center items-center text-xs align-middle">
      <span class="size-7 flex justify-center items-center shrink-0 bg-blue-600 font-medium text-white rounded-full dark:bg-blue-500">
        1
      </span>
    </span>
    <span class="text-sm font-medium text-gray-800 dark:text-white">
      First step completed
    </span>
  </li>
  <li class="flex items-center gap-x-2 shrink basis-0 flex-1 group">
    <span class="min-w-7 min-h-7 inline-flex justify-center items-center text-xs align-middle">
      <span class="size-7 flex justify-center items-center shrink-0 bg-blue-600 font-medium text-white rounded-full dark:bg-blue-500">
        2
      </span>
    </span>
    <span class="text-sm font-medium text-blue-600 dark:text-blue-500">
      Current step
    </span>
  </li>
  <li class="flex items-center gap-x-2 shrink basis-0 flex-1 group">
    <span class="min-w-7 min-h-7 inline-flex justify-center items-center text-xs align-middle">
      <span class="size-7 flex justify-center items-center shrink-0 bg-gray-100 font-medium text-gray-800 rounded-full dark:bg-neutral-700 dark:text-white">
        3
      </span>
    </span>
    <span class="text-sm font-medium text-gray-800 dark:text-white">
      Final step
    </span>
  </li>
</ul>

Komponenty - Form Elements

Input

Code
HTML
<!-- Basic Input -->
<div class="max-w-sm">
  <label for="input-label" class="block text-sm font-medium mb-2 dark:text-white">Email</label>
  <input type="email" id="input-label" class="py-3 px-4 block w-full border-gray-200 rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600" placeholder="you@example.com">
</div>

<!-- Input with helper text -->
<div class="max-w-sm">
  <label for="input-label-with-helper-text" class="block text-sm font-medium mb-2 dark:text-white">Email</label>
  <input type="email" id="input-label-with-helper-text" class="py-3 px-4 block w-full border-gray-200 rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600" placeholder="you@example.com" aria-describedby="hs-input-helper-text">
  <p class="text-sm text-gray-500 mt-2" id="hs-input-helper-text">We'll never share your details.</p>
</div>

<!-- Input with validation -->
<div class="max-w-sm">
  <label for="with-validation" class="block text-sm font-medium mb-2 dark:text-white">Email</label>
  <input type="email" id="with-validation" class="py-3 px-4 block w-full border-red-500 rounded-lg text-sm focus:border-red-500 focus:ring-red-500 dark:bg-neutral-900 dark:border-red-600 dark:text-neutral-400" aria-describedby="email-error">
  <p class="text-sm text-red-600 mt-2" id="email-error">Please enter a valid email address.</p>
</div>

<!-- Input with success -->
<div class="max-w-sm">
  <label for="with-success" class="block text-sm font-medium mb-2 dark:text-white">Email</label>
  <input type="email" id="with-success" class="py-3 px-4 block w-full border-teal-500 rounded-lg text-sm focus:border-teal-500 focus:ring-teal-500 dark:bg-neutral-900 dark:border-teal-600 dark:text-neutral-400" aria-describedby="email-success">
  <p class="text-sm text-teal-600 mt-2" id="email-success">Looks good!</p>
</div>

Select

Code
HTML
<div class="max-w-sm">
  <label for="countries" class="block text-sm font-medium mb-2 dark:text-white">Country</label>
  <select id="countries" class="py-3 px-4 pe-9 block w-full border-gray-200 rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600">
    <option selected>Open this select menu</option>
    <option value="US">United States</option>
    <option value="CA">Canada</option>
    <option value="FR">France</option>
  </select>
</div>

Checkbox

Code
HTML
<div class="flex">
  <input type="checkbox" class="shrink-0 mt-0.5 border-gray-200 rounded text-blue-600 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:checked:bg-blue-500 dark:checked:border-blue-500 dark:focus:ring-offset-gray-800" id="hs-default-checkbox">
  <label for="hs-default-checkbox" class="text-sm text-gray-500 ms-3 dark:text-neutral-400">Default checkbox</label>
</div>

Radio

Code
HTML
<div class="flex gap-x-6">
  <div class="flex">
    <input type="radio" name="radio-group" class="shrink-0 mt-0.5 border-gray-200 rounded-full text-blue-600 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:checked:bg-blue-500 dark:checked:border-blue-500 dark:focus:ring-offset-gray-800" id="radio-1" checked>
    <label for="radio-1" class="text-sm text-gray-500 ms-2 dark:text-neutral-400">Default</label>
  </div>
  <div class="flex">
    <input type="radio" name="radio-group" class="shrink-0 mt-0.5 border-gray-200 rounded-full text-blue-600 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:checked:bg-blue-500 dark:checked:border-blue-500 dark:focus:ring-offset-gray-800" id="radio-2">
    <label for="radio-2" class="text-sm text-gray-500 ms-2 dark:text-neutral-400">Checked</label>
  </div>
</div>

Toggle Switch

Code
HTML
<input type="checkbox" id="hs-basic-usage" class="relative w-[3.25rem] h-7 p-px bg-gray-100 border-transparent text-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:ring-blue-600 disabled:opacity-50 disabled:pointer-events-none checked:bg-none checked:text-blue-600 checked:border-blue-600 focus:checked:border-blue-600 dark:bg-neutral-800 dark:border-neutral-700 dark:checked:bg-blue-500 dark:checked:border-blue-500 dark:focus:ring-offset-gray-600

before:inline-block before:size-6 before:bg-white checked:before:bg-white before:translate-x-0 checked:before:translate-x-full before:rounded-full before:shadow before:transform before:ring-0 before:transition before:ease-in-out before:duration-200 dark:before:bg-neutral-400 dark:checked:before:bg-white">
<label for="hs-basic-usage" class="text-sm text-gray-500 ms-3 dark:text-neutral-400">Toggle switch</label>

Komponenty - Buttons

Code
HTML
<!-- Solid Buttons -->
<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:bg-blue-700 disabled:opacity-50 disabled:pointer-events-none">
  Primary
</button>

<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-gray-500 text-white hover:bg-gray-600 focus:outline-none focus:bg-gray-600 disabled:opacity-50 disabled:pointer-events-none">
  Secondary
</button>

<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-teal-500 text-white hover:bg-teal-600 focus:outline-none focus:bg-teal-600 disabled:opacity-50 disabled:pointer-events-none">
  Success
</button>

<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-red-500 text-white hover:bg-red-600 focus:outline-none focus:bg-red-600 disabled:opacity-50 disabled:pointer-events-none">
  Danger
</button>

<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-yellow-500 text-white hover:bg-yellow-600 focus:outline-none focus:bg-yellow-600 disabled:opacity-50 disabled:pointer-events-none">
  Warning
</button>

<!-- Outline Buttons -->
<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-blue-600 text-blue-600 hover:border-blue-500 hover:text-blue-500 focus:outline-none focus:border-blue-500 focus:text-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:border-blue-500 dark:text-blue-500 dark:hover:text-blue-400 dark:hover:border-blue-400">
  Outline Primary
</button>

<!-- Ghost Buttons -->
<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent text-blue-600 hover:bg-blue-100 hover:text-blue-800 focus:outline-none focus:bg-blue-100 focus:text-blue-800 disabled:opacity-50 disabled:pointer-events-none dark:text-blue-500 dark:hover:bg-blue-800/30 dark:hover:text-blue-400 dark:focus:bg-blue-800/30 dark:focus:text-blue-400">
  Ghost
</button>

<!-- Soft Buttons -->
<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-blue-100 text-blue-800 hover:bg-blue-200 focus:outline-none focus:bg-blue-200 disabled:opacity-50 disabled:pointer-events-none dark:text-blue-400 dark:bg-blue-800/30 dark:hover:bg-blue-800/20 dark:focus:bg-blue-800/20">
  Soft
</button>

<!-- White Button -->
<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50 focus:outline-none focus:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-700 dark:focus:bg-neutral-700">
  White
</button>

<!-- Button with icon -->
<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:bg-blue-700 disabled:opacity-50 disabled:pointer-events-none">
  <svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
    <path d="M5 12h14"></path>
    <path d="M12 5v14"></path>
  </svg>
  Add item
</button>

<!-- Button sizes -->
<button type="button" class="py-2 px-3 inline-flex items-center gap-x-2 text-xs font-medium rounded-lg border border-transparent bg-blue-600 text-white hover:bg-blue-700">
  Small
</button>

<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-blue-600 text-white hover:bg-blue-700">
  Default
</button>

<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-base font-medium rounded-lg border border-transparent bg-blue-600 text-white hover:bg-blue-700">
  Large
</button>

Komponenty - Alerts

Code
HTML
<!-- Info Alert -->
<div class="bg-blue-100 border border-blue-200 text-sm text-blue-800 rounded-lg p-4 dark:bg-blue-800/10 dark:border-blue-900 dark:text-blue-500" role="alert" tabindex="-1" aria-labelledby="hs-with-description-label">
  <div class="flex">
    <div class="shrink-0">
      <svg class="shrink-0 size-4 mt-0.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <circle cx="12" cy="12" r="10"></circle>
        <path d="M12 16v-4"></path>
        <path d="M12 8h.01"></path>
      </svg>
    </div>
    <div class="ms-4">
      <h3 id="hs-with-description-label" class="text-sm font-semibold">
        Info
      </h3>
      <div class="mt-1 text-sm text-blue-700 dark:text-blue-400">
        A simple info alert with an example link.
      </div>
    </div>
  </div>
</div>

<!-- Success Alert -->
<div class="bg-teal-100 border border-teal-200 text-sm text-teal-800 rounded-lg p-4 dark:bg-teal-800/10 dark:border-teal-900 dark:text-teal-500" role="alert" tabindex="-1">
  <span class="font-bold">Success</span> Your purchase was successful.
</div>

<!-- Warning Alert -->
<div class="bg-yellow-100 border border-yellow-200 text-sm text-yellow-800 rounded-lg p-4 dark:bg-yellow-800/10 dark:border-yellow-900 dark:text-yellow-500" role="alert" tabindex="-1">
  <span class="font-bold">Warning</span> Please check your input.
</div>

<!-- Error Alert -->
<div class="bg-red-100 border border-red-200 text-sm text-red-800 rounded-lg p-4 dark:bg-red-800/10 dark:border-red-900 dark:text-red-500" role="alert" tabindex="-1">
  <span class="font-bold">Error</span> Something went wrong.
</div>

<!-- Dismissible Alert -->
<div id="dismiss-alert" class="hs-removing:translate-x-5 hs-removing:opacity-0 transition duration-300 bg-teal-50 border border-teal-200 text-sm text-teal-800 rounded-lg p-4 dark:bg-teal-800/10 dark:border-teal-900 dark:text-teal-500" role="alert" tabindex="-1">
  <div class="flex">
    <div class="shrink-0">
      <svg class="shrink-0 size-4 mt-0.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z"></path>
        <path d="m9 12 2 2 4-4"></path>
      </svg>
    </div>
    <div class="ms-2">
      <div class="text-sm font-medium">
        Successfully uploaded.
      </div>
    </div>
    <div class="ps-3 ms-auto">
      <div class="-mx-1.5 -my-1.5">
        <button type="button" class="inline-flex bg-teal-50 rounded-lg p-1.5 text-teal-500 hover:bg-teal-100 focus:outline-none focus:bg-teal-100 dark:bg-transparent dark:hover:bg-teal-800/50 dark:focus:bg-teal-800/50" data-hs-remove-element="#dismiss-alert">
          <span class="sr-only">Dismiss</span>
          <svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <path d="M18 6 6 18"></path>
            <path d="m6 6 12 12"></path>
          </svg>
        </button>
      </div>
    </div>
  </div>
</div>

Dark Mode

Preline UI wspiera dark mode przez Tailwind CSS dark variant:

JStailwind.config.js
JavaScript
// tailwind.config.js
module.exports = {
  darkMode: 'class',
  // ...
}
Code
HTML
<!-- Przełącznik dark mode -->
<button type="button" class="hs-dark-mode-active:hidden block hs-dark-mode group flex items-center text-gray-600 hover:text-blue-600 font-medium dark:text-neutral-400 dark:hover:text-neutral-500" data-hs-theme-click-value="dark">
  <svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
    <path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"></path>
  </svg>
</button>
<button type="button" class="hs-dark-mode-active:block hidden hs-dark-mode group flex items-center text-gray-600 hover:text-blue-600 font-medium dark:text-neutral-400 dark:hover:text-neutral-500" data-hs-theme-click-value="light">
  <svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
    <circle cx="12" cy="12" r="4"></circle>
    <path d="M12 2v2"></path>
    <path d="M12 20v2"></path>
    <path d="m4.93 4.93 1.41 1.41"></path>
    <path d="m17.66 17.66 1.41 1.41"></path>
    <path d="M2 12h2"></path>
    <path d="M20 12h2"></path>
    <path d="m6.34 17.66-1.41 1.41"></path>
    <path d="m19.07 4.93-1.41 1.41"></path>
  </svg>
</button>

Integracja z React/Next.js

TScomponents/Modal.tsx
TypeScript
// components/Modal.tsx
'use client'

import { useEffect } from 'react'

interface ModalProps {
  id: string
  title: string
  children: React.ReactNode
  isOpen: boolean
  onClose: () => void
}

export function Modal({ id, title, children, isOpen, onClose }: ModalProps) {
  useEffect(() => {
    // Reinitialize Preline after mounting
    import('preline').then((module) => {
      if (typeof window !== 'undefined' && (window as any).HSOverlay) {
        (window as any).HSOverlay.autoInit()
      }
    })
  }, [])

  return (
    <div
      id={id}
      className={`hs-overlay ${isOpen ? 'open' : 'hidden'} size-full fixed top-0 start-0 z-[80] overflow-x-hidden overflow-y-auto pointer-events-none`}
      role="dialog"
      tabIndex={-1}
      aria-labelledby={`${id}-label`}
    >
      <div className="hs-overlay-open:mt-7 hs-overlay-open:opacity-100 hs-overlay-open:duration-500 mt-0 opacity-0 ease-out transition-all sm:max-w-lg sm:w-full m-3 sm:mx-auto">
        <div className="flex flex-col bg-white border shadow-sm rounded-xl pointer-events-auto dark:bg-neutral-800 dark:border-neutral-700 dark:shadow-neutral-700/70">
          <div className="flex justify-between items-center py-3 px-4 border-b dark:border-neutral-700">
            <h3 id={`${id}-label`} className="font-bold text-gray-800 dark:text-white">
              {title}
            </h3>
            <button
              type="button"
              className="size-8 inline-flex justify-center items-center gap-x-2 rounded-full border border-transparent bg-gray-100 text-gray-800 hover:bg-gray-200 focus:outline-none focus:bg-gray-200 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-700 dark:hover:bg-neutral-600 dark:text-neutral-400 dark:focus:bg-neutral-600"
              aria-label="Close"
              onClick={onClose}
            >
              <span className="sr-only">Close</span>
              <svg className="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                <path d="M18 6 6 18"></path>
                <path d="m6 6 12 12"></path>
              </svg>
            </button>
          </div>
          <div className="p-4 overflow-y-auto">
            {children}
          </div>
        </div>
      </div>
    </div>
  )
}

Cennik

Open Source (Darmowy)

  • 300+ komponentów
  • MIT License
  • Pełna dokumentacja
  • Dark mode
  • Responsive

Preline Pro ($79+)

  • 50+ premium templates
  • Admin dashboards
  • Landing pages
  • E-commerce templates
  • Figma files
  • Priorytetowe wsparcie

FAQ - Najczęściej Zadawane Pytania

Czy Preline UI wymaga JavaScript?

Dla statycznych komponentów (buttons, alerts, cards) - nie. Dla interaktywnych (accordion, tabs, modal, dropdown) - tak.

Czy Preline UI działa z Next.js App Router?

Tak! Musisz zaimportować Preline w useEffect w głównym layout/komponentach.

Jak dodać własne style do komponentów?

Możesz nadpisywać klasy Tailwind bezpośrednio w HTML - Preline używa standardowych klas Tailwind.

Jaka jest różnica między Preline UI a Flowbite?

Preline oferuje więcej komponentów (300+ vs 50+) i lepszą dokumentację. Flowbite ma lepsze wsparcie dla frameworków i więcej bloków Pro.

Czy mogę używać Preline komercyjnie?

Tak, licencja MIT pozwala na komercyjne użycie bez opłat.

Podsumowanie

Preline UI to jedna z najbogatszych darmowych bibliotek komponentów dla Tailwind CSS. Oferuje:

  • 300+ darmowych komponentów
  • Doskonałą dokumentację z przykładami
  • Wsparcie dla HTML, React i Vue
  • Wbudowany dark mode
  • Pełną responsywność
  • Licencję MIT

Jest to doskonały wybór dla deweloperów szukających obszernej biblioteki komponentów bez konieczności płacenia.


Preline UI - Complete Guide to Free Tailwind Components

What is Preline UI?

Preline UI is an open-source component library built on Tailwind CSS, offering over 300 ready-to-use UI components. It is one of the richest free Tailwind libraries, providing both simple elements like buttons and forms, as well as complex components like carousels, steppers, and datepickers.

Preline UI stands out with its exceptionally rich documentation featuring hundreds of examples, making it an ideal library for developers looking for ready-made solutions without having to write code from scratch. All components are fully responsive, support dark mode, and are optimized for accessibility.

Why Preline UI?

  1. 300+ components - One of the largest free collections
  2. Excellent documentation - Hundreds of examples with code
  3. Vanilla JS + React + Vue - Support for popular frameworks
  4. Dark mode - Built-in dark theme support
  5. Copy-paste - Copy the code and use it right away
  6. MIT License - Completely free, even for commercial use

Preline UI vs other libraries

FeaturePreline UIFlowbiteDaisyUITailwind UI
PriceFree + ProFree + ProFree$299+
Components300+50+50+500+
Blocks/Templates50+ Pro450+ ProNone500+
FrameworksHTML, React, VueAllCSS onlyReact
DocumentationExcellentVery goodGoodGreat
Dark modeBuilt-inBuilt-inBuilt-inBuilt-in
LicenseMITMITMITCommercial

When to choose Preline UI?

Choose Preline UI when:

  • You need a large number of free components
  • You value good documentation with examples
  • You are building an HTML, React, or Vue site
  • You need advanced components (stepper, tree view)
  • You want to prototype quickly

Consider alternatives when:

  • You need Angular/Svelte support (Flowbite)
  • You prefer CSS-only without JavaScript (DaisyUI)
  • Your budget allows for a paid solution (Tailwind UI)

Installation

NPM/Yarn

Code
Bash
# npm
npm install preline

# yarn
yarn add preline

# pnpm
pnpm add preline

Tailwind CSS configuration

JStailwind.config.js
JavaScript
// tailwind.config.js
module.exports = {
  content: [
    './node_modules/preline/dist/*.js',
    './src/**/*.{html,js,jsx,ts,tsx,vue}'
  ],
  plugins: [
    require('preline/plugin'),
  ],
}

Adding the JavaScript script

Code
HTML
<!-- Before </body> -->
<script src="./node_modules/preline/dist/preline.js"></script>

<!-- Or from CDN -->
<script src="https://preline.co/assets/js/preline.js"></script>

React/Next.js setup

TSapp/layout.tsx
TypeScript
// app/layout.tsx or pages/_app.tsx
'use client'

import { useEffect } from 'react'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  useEffect(() => {
    import('preline')
  }, [])

  return (
    <html lang="pl">
      <body>{children}</body>
    </html>
  )
}

Vue setup

JSmain.js
JavaScript
// main.js
import 'preline'

// Or in a component
import { onMounted } from 'vue'

onMounted(() => {
  import('preline')
})

Components - Accordion

Accordion allows you to expand and collapse content sections.

Code
HTML
<!-- Basic Accordion -->
<div class="hs-accordion-group">
  <div class="hs-accordion active" id="hs-basic-heading-one">
    <button class="hs-accordion-toggle hs-accordion-active:text-blue-600 py-3 inline-flex items-center gap-x-3 w-full font-semibold text-start text-gray-800 hover:text-gray-500 focus:outline-none focus:text-gray-500 rounded-lg disabled:opacity-50 disabled:pointer-events-none dark:hs-accordion-active:text-blue-500 dark:text-neutral-200 dark:hover:text-neutral-400 dark:focus:text-neutral-400" aria-expanded="true" aria-controls="hs-basic-collapse-one">
      <svg class="hs-accordion-active:hidden block size-3.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M5 12h14"></path>
        <path d="M12 5v14"></path>
      </svg>
      <svg class="hs-accordion-active:block hidden size-3.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M5 12h14"></path>
      </svg>
      Accordion #1
    </button>
    <div id="hs-basic-collapse-one" class="hs-accordion-content w-full overflow-hidden transition-[height] duration-300" role="region" aria-labelledby="hs-basic-heading-one">
      <p class="text-gray-800 dark:text-neutral-200">
        This is the first accordion body. It is shown by default.
      </p>
    </div>
  </div>

  <div class="hs-accordion" id="hs-basic-heading-two">
    <button class="hs-accordion-toggle hs-accordion-active:text-blue-600 py-3 inline-flex items-center gap-x-3 w-full font-semibold text-start text-gray-800 hover:text-gray-500 focus:outline-none focus:text-gray-500 rounded-lg disabled:opacity-50 disabled:pointer-events-none dark:hs-accordion-active:text-blue-500 dark:text-neutral-200 dark:hover:text-neutral-400 dark:focus:text-neutral-400" aria-expanded="false" aria-controls="hs-basic-collapse-two">
      <svg class="hs-accordion-active:hidden block size-3.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M5 12h14"></path>
        <path d="M12 5v14"></path>
      </svg>
      <svg class="hs-accordion-active:block hidden size-3.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M5 12h14"></path>
      </svg>
      Accordion #2
    </button>
    <div id="hs-basic-collapse-two" class="hs-accordion-content hidden w-full overflow-hidden transition-[height] duration-300" role="region" aria-labelledby="hs-basic-heading-two">
      <p class="text-gray-800 dark:text-neutral-200">
        This is the second accordion body.
      </p>
    </div>
  </div>
</div>

Accordion with icons on the right side

Code
HTML
<div class="hs-accordion-group">
  <div class="hs-accordion active bg-white border -mt-px first:rounded-t-lg last:rounded-b-lg dark:bg-neutral-800 dark:border-neutral-700" id="hs-bordered-heading-one">
    <button class="hs-accordion-toggle hs-accordion-active:text-blue-600 inline-flex items-center justify-between gap-x-3 w-full font-semibold text-start text-gray-800 py-4 px-5 hover:text-gray-500 disabled:opacity-50 disabled:pointer-events-none dark:hs-accordion-active:text-blue-500 dark:text-neutral-200 dark:hover:text-neutral-400" aria-expanded="true" aria-controls="hs-bordered-collapse-one">
      Accordion #1
      <svg class="hs-accordion-active:hidden block size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="m6 9 6 6 6-6"></path>
      </svg>
      <svg class="hs-accordion-active:block hidden size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="m18 15-6-6-6 6"></path>
      </svg>
    </button>
    <div id="hs-bordered-collapse-one" class="hs-accordion-content w-full overflow-hidden transition-[height] duration-300" role="region" aria-labelledby="hs-bordered-heading-one">
      <div class="pb-4 px-5">
        <p class="text-gray-800 dark:text-neutral-200">
          Content for accordion #1
        </p>
      </div>
    </div>
  </div>
</div>

Components - Tabs

Code
HTML
<!-- Basic Tabs -->
<div class="border-b border-gray-200 dark:border-neutral-700">
  <nav class="flex gap-x-1" aria-label="Tabs" role="tablist" aria-orientation="horizontal">
    <button type="button" class="hs-tab-active:font-semibold hs-tab-active:border-blue-600 hs-tab-active:text-blue-600 py-4 px-1 inline-flex items-center gap-x-2 border-b-2 border-transparent text-sm whitespace-nowrap text-gray-500 hover:text-blue-600 focus:outline-none focus:text-blue-600 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-400 dark:hover:text-blue-500 active" id="tabs-with-underline-item-1" aria-selected="true" data-hs-tab="#tabs-with-underline-1" aria-controls="tabs-with-underline-1" role="tab">
      Tab 1
    </button>
    <button type="button" class="hs-tab-active:font-semibold hs-tab-active:border-blue-600 hs-tab-active:text-blue-600 py-4 px-1 inline-flex items-center gap-x-2 border-b-2 border-transparent text-sm whitespace-nowrap text-gray-500 hover:text-blue-600 focus:outline-none focus:text-blue-600 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-400 dark:hover:text-blue-500" id="tabs-with-underline-item-2" aria-selected="false" data-hs-tab="#tabs-with-underline-2" aria-controls="tabs-with-underline-2" role="tab">
      Tab 2
    </button>
    <button type="button" class="hs-tab-active:font-semibold hs-tab-active:border-blue-600 hs-tab-active:text-blue-600 py-4 px-1 inline-flex items-center gap-x-2 border-b-2 border-transparent text-sm whitespace-nowrap text-gray-500 hover:text-blue-600 focus:outline-none focus:text-blue-600 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-400 dark:hover:text-blue-500" id="tabs-with-underline-item-3" aria-selected="false" data-hs-tab="#tabs-with-underline-3" aria-controls="tabs-with-underline-3" role="tab">
      Tab 3
    </button>
  </nav>
</div>

<div class="mt-3">
  <div id="tabs-with-underline-1" role="tabpanel" aria-labelledby="tabs-with-underline-item-1">
    <p class="text-gray-500 dark:text-neutral-400">
      This is the <em class="font-semibold text-gray-800 dark:text-neutral-200">first</em> tab content.
    </p>
  </div>
  <div id="tabs-with-underline-2" class="hidden" role="tabpanel" aria-labelledby="tabs-with-underline-item-2">
    <p class="text-gray-500 dark:text-neutral-400">
      This is the <em class="font-semibold text-gray-800 dark:text-neutral-200">second</em> tab content.
    </p>
  </div>
  <div id="tabs-with-underline-3" class="hidden" role="tabpanel" aria-labelledby="tabs-with-underline-item-3">
    <p class="text-gray-500 dark:text-neutral-400">
      This is the <em class="font-semibold text-gray-800 dark:text-neutral-200">third</em> tab content.
    </p>
  </div>
</div>

Tabs as pills (buttons)

Code
HTML
<nav class="flex gap-x-1" aria-label="Tabs" role="tablist" aria-orientation="horizontal">
  <button type="button" class="hs-tab-active:bg-blue-600 hs-tab-active:text-white py-3 px-4 inline-flex items-center gap-x-2 bg-transparent text-sm font-medium text-center text-gray-500 rounded-lg hover:text-blue-600 focus:outline-none focus:text-blue-600 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-400 dark:hover:text-blue-500 active" id="pills-item-1" aria-selected="true" data-hs-tab="#pills-1" aria-controls="pills-1" role="tab">
    Tab 1
  </button>
  <button type="button" class="hs-tab-active:bg-blue-600 hs-tab-active:text-white py-3 px-4 inline-flex items-center gap-x-2 bg-transparent text-sm font-medium text-center text-gray-500 rounded-lg hover:text-blue-600 focus:outline-none focus:text-blue-600 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-400 dark:hover:text-blue-500" id="pills-item-2" aria-selected="false" data-hs-tab="#pills-2" aria-controls="pills-2" role="tab">
    Tab 2
  </button>
  <button type="button" class="hs-tab-active:bg-blue-600 hs-tab-active:text-white py-3 px-4 inline-flex items-center gap-x-2 bg-transparent text-sm font-medium text-center text-gray-500 rounded-lg hover:text-blue-600 focus:outline-none focus:text-blue-600 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-400 dark:hover:text-blue-500" id="pills-item-3" aria-selected="false" data-hs-tab="#pills-3" aria-controls="pills-3" role="tab">
    Tab 3
  </button>
</nav>

Components - Modal

Code
HTML
<!-- Trigger Button -->
<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:bg-blue-700 disabled:opacity-50 disabled:pointer-events-none" aria-haspopup="dialog" aria-expanded="false" aria-controls="hs-basic-modal" data-hs-overlay="#hs-basic-modal">
  Open modal
</button>

<!-- Modal -->
<div id="hs-basic-modal" class="hs-overlay hidden size-full fixed top-0 start-0 z-[80] overflow-x-hidden overflow-y-auto pointer-events-none" role="dialog" tabindex="-1" aria-labelledby="hs-basic-modal-label">
  <div class="hs-overlay-open:mt-7 hs-overlay-open:opacity-100 hs-overlay-open:duration-500 mt-0 opacity-0 ease-out transition-all sm:max-w-lg sm:w-full m-3 sm:mx-auto">
    <div class="flex flex-col bg-white border shadow-sm rounded-xl pointer-events-auto dark:bg-neutral-800 dark:border-neutral-700 dark:shadow-neutral-700/70">
      <div class="flex justify-between items-center py-3 px-4 border-b dark:border-neutral-700">
        <h3 id="hs-basic-modal-label" class="font-bold text-gray-800 dark:text-white">
          Modal title
        </h3>
        <button type="button" class="size-8 inline-flex justify-center items-center gap-x-2 rounded-full border border-transparent bg-gray-100 text-gray-800 hover:bg-gray-200 focus:outline-none focus:bg-gray-200 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-700 dark:hover:bg-neutral-600 dark:text-neutral-400 dark:focus:bg-neutral-600" aria-label="Close" data-hs-overlay="#hs-basic-modal">
          <span class="sr-only">Close</span>
          <svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <path d="M18 6 6 18"></path>
            <path d="m6 6 12 12"></path>
          </svg>
        </button>
      </div>
      <div class="p-4 overflow-y-auto">
        <p class="text-gray-800 dark:text-neutral-400">
          This is a modal body. You can add any content here.
        </p>
      </div>
      <div class="flex justify-end items-center gap-x-2 py-3 px-4 border-t dark:border-neutral-700">
        <button type="button" class="py-2 px-3 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50 focus:outline-none focus:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-700 dark:focus:bg-neutral-700" data-hs-overlay="#hs-basic-modal">
          Close
        </button>
        <button type="button" class="py-2 px-3 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:bg-blue-700 disabled:opacity-50 disabled:pointer-events-none">
          Save changes
        </button>
      </div>
    </div>
  </div>
</div>

Modal sizes

Code
HTML
<!-- Small Modal -->
<div id="hs-small-modal" class="hs-overlay hidden">
  <div class="hs-overlay-open:mt-7 hs-overlay-open:opacity-100 mt-0 opacity-0 ease-out transition-all sm:max-w-sm sm:w-full m-3 sm:mx-auto">
    <!-- content -->
  </div>
</div>

<!-- Large Modal -->
<div id="hs-large-modal" class="hs-overlay hidden">
  <div class="hs-overlay-open:mt-7 hs-overlay-open:opacity-100 mt-0 opacity-0 ease-out transition-all lg:max-w-4xl lg:w-full m-3 lg:mx-auto">
    <!-- content -->
  </div>
</div>

<!-- Full Screen Modal -->
<div id="hs-full-screen-modal" class="hs-overlay hidden">
  <div class="hs-overlay-open:mt-7 hs-overlay-open:opacity-100 mt-0 opacity-0 ease-out transition-all max-w-full w-full m-3 mx-auto h-[calc(100%-3.5rem)]">
    <!-- content -->
  </div>
</div>

Components - Dropdown

Code
HTML
<div class="hs-dropdown relative inline-flex">
  <button id="hs-dropdown-default" type="button" class="hs-dropdown-toggle py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50 focus:outline-none focus:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-700 dark:focus:bg-neutral-700" aria-haspopup="menu" aria-expanded="false" aria-label="Dropdown">
    Actions
    <svg class="hs-dropdown-open:rotate-180 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
      <path d="m6 9 6 6 6-6"/>
    </svg>
  </button>

  <div class="hs-dropdown-menu transition-[opacity,margin] duration hs-dropdown-open:opacity-100 opacity-0 hidden min-w-60 bg-white shadow-md rounded-lg mt-2 dark:bg-neutral-800 dark:border dark:border-neutral-700" role="menu" aria-orientation="vertical" aria-labelledby="hs-dropdown-default">
    <div class="p-1 space-y-0.5">
      <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-gray-800 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-300 dark:focus:bg-neutral-700" href="#">
        Newsletter
      </a>
      <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-gray-800 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-300 dark:focus:bg-neutral-700" href="#">
        Purchases
      </a>
      <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-gray-800 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-300 dark:focus:bg-neutral-700" href="#">
        Downloads
      </a>
      <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-gray-800 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-300 dark:focus:bg-neutral-700" href="#">
        Team Account
      </a>
    </div>
  </div>
</div>

Dropdown with icons

Code
HTML
<div class="hs-dropdown relative inline-flex">
  <button id="hs-dropdown-with-icons" type="button" class="hs-dropdown-toggle py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-700">
    With icons
    <svg class="hs-dropdown-open:rotate-180 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
      <path d="m6 9 6 6 6-6"/>
    </svg>
  </button>

  <div class="hs-dropdown-menu transition-[opacity,margin] duration hs-dropdown-open:opacity-100 opacity-0 hidden min-w-60 bg-white shadow-md rounded-lg mt-2 divide-y divide-gray-200 dark:bg-neutral-800 dark:border dark:border-neutral-700 dark:divide-neutral-700">
    <div class="p-1 space-y-0.5">
      <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-gray-800 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-300" href="#">
        <svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
          <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
          <polyline points="7 10 12 15 17 10"/>
          <line x1="12" x2="12" y1="15" y2="3"/>
        </svg>
        Downloads
      </a>
      <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-gray-800 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-300" href="#">
        <svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
          <path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/>
          <circle cx="9" cy="7" r="4"/>
          <path d="M22 21v-2a4 4 0 0 0-3-3.87"/>
          <path d="M16 3.13a4 4 0 0 1 0 7.75"/>
        </svg>
        Team Account
      </a>
    </div>
    <div class="p-1 space-y-0.5">
      <a class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm text-red-600 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:text-red-500 dark:hover:bg-neutral-700" href="#">
        <svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
          <path d="M3 6h18"/>
          <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/>
          <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/>
          <line x1="10" x2="10" y1="11" y2="17"/>
          <line x1="14" x2="14" y1="11" y2="17"/>
        </svg>
        Delete
      </a>
    </div>
  </div>
</div>

Components - Tooltip

Code
HTML
<!-- Basic Tooltip -->
<div class="hs-tooltip inline-block">
  <button type="button" class="hs-tooltip-toggle py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50 focus:outline-none focus:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-700 dark:focus:bg-neutral-700">
    Hover me
  </button>
  <span class="hs-tooltip-content hs-tooltip-shown:opacity-100 hs-tooltip-shown:visible opacity-0 transition-opacity inline-block absolute invisible z-10 py-1 px-2 bg-gray-900 text-xs font-medium text-white rounded shadow-sm dark:bg-neutral-700" role="tooltip">
    Tooltip content
  </span>
</div>

<!-- Tooltip with different positions -->
<div class="hs-tooltip inline-block" data-hs-tooltip-placement="top">
  <button type="button" class="hs-tooltip-toggle ...">Top</button>
  <span class="hs-tooltip-content ..." role="tooltip">Top tooltip</span>
</div>

<div class="hs-tooltip inline-block" data-hs-tooltip-placement="bottom">
  <button type="button" class="hs-tooltip-toggle ...">Bottom</button>
  <span class="hs-tooltip-content ..." role="tooltip">Bottom tooltip</span>
</div>

<div class="hs-tooltip inline-block" data-hs-tooltip-placement="left">
  <button type="button" class="hs-tooltip-toggle ...">Left</button>
  <span class="hs-tooltip-content ..." role="tooltip">Left tooltip</span>
</div>

<div class="hs-tooltip inline-block" data-hs-tooltip-placement="right">
  <button type="button" class="hs-tooltip-toggle ...">Right</button>
  <span class="hs-tooltip-content ..." role="tooltip">Right tooltip</span>
</div>

Components - Carousel

Code
HTML
<div data-hs-carousel='{
    "loadingClasses": "opacity-0",
    "isAutoPlay": true
  }' class="relative">
  <div class="hs-carousel relative overflow-hidden w-full min-h-96 bg-white rounded-lg">
    <div class="hs-carousel-body absolute top-0 bottom-0 start-0 flex flex-nowrap transition-transform duration-700 opacity-0">
      <div class="hs-carousel-slide">
        <div class="flex justify-center h-full bg-gray-100 p-6 dark:bg-neutral-900">
          <span class="self-center text-4xl text-gray-800 transition duration-700 dark:text-white">First slide</span>
        </div>
      </div>
      <div class="hs-carousel-slide">
        <div class="flex justify-center h-full bg-gray-200 p-6 dark:bg-neutral-800">
          <span class="self-center text-4xl text-gray-800 transition duration-700 dark:text-white">Second slide</span>
        </div>
      </div>
      <div class="hs-carousel-slide">
        <div class="flex justify-center h-full bg-gray-300 p-6 dark:bg-neutral-700">
          <span class="self-center text-4xl text-gray-800 transition duration-700 dark:text-white">Third slide</span>
        </div>
      </div>
    </div>
  </div>

  <!-- Prev/Next buttons -->
  <button type="button" class="hs-carousel-prev hs-carousel-disabled:opacity-50 disabled:pointer-events-none absolute inset-y-0 start-0 inline-flex justify-center items-center w-[46px] h-full text-gray-800 hover:bg-gray-800/10 focus:outline-none focus:bg-gray-800/10 rounded-s-lg dark:text-white dark:hover:bg-white/10 dark:focus:bg-white/10">
    <span class="text-2xl" aria-hidden="true">
      <svg class="shrink-0 size-5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="m15 18-6-6 6-6"></path>
      </svg>
    </span>
    <span class="sr-only">Previous</span>
  </button>
  <button type="button" class="hs-carousel-next hs-carousel-disabled:opacity-50 disabled:pointer-events-none absolute inset-y-0 end-0 inline-flex justify-center items-center w-[46px] h-full text-gray-800 hover:bg-gray-800/10 focus:outline-none focus:bg-gray-800/10 rounded-e-lg dark:text-white dark:hover:bg-white/10 dark:focus:bg-white/10">
    <span class="sr-only">Next</span>
    <span class="text-2xl" aria-hidden="true">
      <svg class="shrink-0 size-5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="m9 18 6-6-6-6"></path>
      </svg>
    </span>
  </button>

  <!-- Pagination -->
  <div class="hs-carousel-pagination flex justify-center absolute bottom-3 start-0 end-0 space-x-2">
    <span class="hs-carousel-active:bg-blue-700 hs-carousel-active:border-blue-700 size-3 border border-gray-400 rounded-full cursor-pointer dark:border-neutral-600 dark:hs-carousel-active:bg-blue-500 dark:hs-carousel-active:border-blue-500"></span>
    <span class="hs-carousel-active:bg-blue-700 hs-carousel-active:border-blue-700 size-3 border border-gray-400 rounded-full cursor-pointer dark:border-neutral-600 dark:hs-carousel-active:bg-blue-500 dark:hs-carousel-active:border-blue-500"></span>
    <span class="hs-carousel-active:bg-blue-700 hs-carousel-active:border-blue-700 size-3 border border-gray-400 rounded-full cursor-pointer dark:border-neutral-600 dark:hs-carousel-active:bg-blue-500 dark:hs-carousel-active:border-blue-500"></span>
  </div>
</div>

Components - Stepper

Code
HTML
<!-- Basic Stepper -->
<ul class="relative flex flex-row gap-x-2">
  <!-- Completed Step -->
  <li class="shrink basis-0 flex-1 group">
    <div class="min-w-7 min-h-7 w-full inline-flex items-center text-xs align-middle">
      <span class="size-7 flex justify-center items-center shrink-0 bg-blue-600 font-medium text-white rounded-full dark:bg-blue-500">
        <svg class="shrink-0 size-3" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
          <polyline points="20 6 9 17 4 12"></polyline>
        </svg>
      </span>
      <div class="ms-2 w-full h-px flex-1 bg-blue-600 group-last:hidden dark:bg-blue-500"></div>
    </div>
    <div class="mt-3">
      <span class="block text-sm font-medium text-gray-800 dark:text-white">
        Step
      </span>
    </div>
  </li>

  <!-- Current Step -->
  <li class="shrink basis-0 flex-1 group">
    <div class="min-w-7 min-h-7 w-full inline-flex items-center text-xs align-middle">
      <span class="size-7 flex justify-center items-center shrink-0 bg-blue-600 font-medium text-white rounded-full dark:bg-blue-500">
        2
      </span>
      <div class="ms-2 w-full h-px flex-1 bg-gray-200 group-last:hidden dark:bg-neutral-700"></div>
    </div>
    <div class="mt-3">
      <span class="block text-sm font-medium text-blue-600 dark:text-blue-500">
        Step
      </span>
    </div>
  </li>

  <!-- Future Step -->
  <li class="shrink basis-0 flex-1 group">
    <div class="min-w-7 min-h-7 w-full inline-flex items-center text-xs align-middle">
      <span class="size-7 flex justify-center items-center shrink-0 bg-gray-100 font-medium text-gray-800 rounded-full dark:bg-neutral-700 dark:text-white">
        3
      </span>
      <div class="ms-2 w-full h-px flex-1 bg-gray-200 group-last:hidden dark:bg-neutral-700"></div>
    </div>
    <div class="mt-3">
      <span class="block text-sm font-medium text-gray-800 dark:text-white">
        Step
      </span>
    </div>
  </li>
</ul>

Vertical stepper

Code
HTML
<ul class="relative flex flex-col gap-2">
  <li class="flex items-center gap-x-2 shrink basis-0 flex-1 group">
    <span class="min-w-7 min-h-7 inline-flex justify-center items-center text-xs align-middle">
      <span class="size-7 flex justify-center items-center shrink-0 bg-blue-600 font-medium text-white rounded-full dark:bg-blue-500">
        1
      </span>
    </span>
    <span class="text-sm font-medium text-gray-800 dark:text-white">
      First step completed
    </span>
  </li>
  <li class="flex items-center gap-x-2 shrink basis-0 flex-1 group">
    <span class="min-w-7 min-h-7 inline-flex justify-center items-center text-xs align-middle">
      <span class="size-7 flex justify-center items-center shrink-0 bg-blue-600 font-medium text-white rounded-full dark:bg-blue-500">
        2
      </span>
    </span>
    <span class="text-sm font-medium text-blue-600 dark:text-blue-500">
      Current step
    </span>
  </li>
  <li class="flex items-center gap-x-2 shrink basis-0 flex-1 group">
    <span class="min-w-7 min-h-7 inline-flex justify-center items-center text-xs align-middle">
      <span class="size-7 flex justify-center items-center shrink-0 bg-gray-100 font-medium text-gray-800 rounded-full dark:bg-neutral-700 dark:text-white">
        3
      </span>
    </span>
    <span class="text-sm font-medium text-gray-800 dark:text-white">
      Final step
    </span>
  </li>
</ul>

Components - Form elements

Input

Code
HTML
<!-- Basic Input -->
<div class="max-w-sm">
  <label for="input-label" class="block text-sm font-medium mb-2 dark:text-white">Email</label>
  <input type="email" id="input-label" class="py-3 px-4 block w-full border-gray-200 rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600" placeholder="you@example.com">
</div>

<!-- Input with helper text -->
<div class="max-w-sm">
  <label for="input-label-with-helper-text" class="block text-sm font-medium mb-2 dark:text-white">Email</label>
  <input type="email" id="input-label-with-helper-text" class="py-3 px-4 block w-full border-gray-200 rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600" placeholder="you@example.com" aria-describedby="hs-input-helper-text">
  <p class="text-sm text-gray-500 mt-2" id="hs-input-helper-text">We'll never share your details.</p>
</div>

<!-- Input with validation -->
<div class="max-w-sm">
  <label for="with-validation" class="block text-sm font-medium mb-2 dark:text-white">Email</label>
  <input type="email" id="with-validation" class="py-3 px-4 block w-full border-red-500 rounded-lg text-sm focus:border-red-500 focus:ring-red-500 dark:bg-neutral-900 dark:border-red-600 dark:text-neutral-400" aria-describedby="email-error">
  <p class="text-sm text-red-600 mt-2" id="email-error">Please enter a valid email address.</p>
</div>

<!-- Input with success -->
<div class="max-w-sm">
  <label for="with-success" class="block text-sm font-medium mb-2 dark:text-white">Email</label>
  <input type="email" id="with-success" class="py-3 px-4 block w-full border-teal-500 rounded-lg text-sm focus:border-teal-500 focus:ring-teal-500 dark:bg-neutral-900 dark:border-teal-600 dark:text-neutral-400" aria-describedby="email-success">
  <p class="text-sm text-teal-600 mt-2" id="email-success">Looks good!</p>
</div>

Select

Code
HTML
<div class="max-w-sm">
  <label for="countries" class="block text-sm font-medium mb-2 dark:text-white">Country</label>
  <select id="countries" class="py-3 px-4 pe-9 block w-full border-gray-200 rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600">
    <option selected>Open this select menu</option>
    <option value="US">United States</option>
    <option value="CA">Canada</option>
    <option value="FR">France</option>
  </select>
</div>

Checkbox

Code
HTML
<div class="flex">
  <input type="checkbox" class="shrink-0 mt-0.5 border-gray-200 rounded text-blue-600 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:checked:bg-blue-500 dark:checked:border-blue-500 dark:focus:ring-offset-gray-800" id="hs-default-checkbox">
  <label for="hs-default-checkbox" class="text-sm text-gray-500 ms-3 dark:text-neutral-400">Default checkbox</label>
</div>

Radio

Code
HTML
<div class="flex gap-x-6">
  <div class="flex">
    <input type="radio" name="radio-group" class="shrink-0 mt-0.5 border-gray-200 rounded-full text-blue-600 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:checked:bg-blue-500 dark:checked:border-blue-500 dark:focus:ring-offset-gray-800" id="radio-1" checked>
    <label for="radio-1" class="text-sm text-gray-500 ms-2 dark:text-neutral-400">Default</label>
  </div>
  <div class="flex">
    <input type="radio" name="radio-group" class="shrink-0 mt-0.5 border-gray-200 rounded-full text-blue-600 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:checked:bg-blue-500 dark:checked:border-blue-500 dark:focus:ring-offset-gray-800" id="radio-2">
    <label for="radio-2" class="text-sm text-gray-500 ms-2 dark:text-neutral-400">Checked</label>
  </div>
</div>

Toggle switch

Code
HTML
<input type="checkbox" id="hs-basic-usage" class="relative w-[3.25rem] h-7 p-px bg-gray-100 border-transparent text-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:ring-blue-600 disabled:opacity-50 disabled:pointer-events-none checked:bg-none checked:text-blue-600 checked:border-blue-600 focus:checked:border-blue-600 dark:bg-neutral-800 dark:border-neutral-700 dark:checked:bg-blue-500 dark:checked:border-blue-500 dark:focus:ring-offset-gray-600

before:inline-block before:size-6 before:bg-white checked:before:bg-white before:translate-x-0 checked:before:translate-x-full before:rounded-full before:shadow before:transform before:ring-0 before:transition before:ease-in-out before:duration-200 dark:before:bg-neutral-400 dark:checked:before:bg-white">
<label for="hs-basic-usage" class="text-sm text-gray-500 ms-3 dark:text-neutral-400">Toggle switch</label>

Components - Buttons

Code
HTML
<!-- Solid Buttons -->
<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:bg-blue-700 disabled:opacity-50 disabled:pointer-events-none">
  Primary
</button>

<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-gray-500 text-white hover:bg-gray-600 focus:outline-none focus:bg-gray-600 disabled:opacity-50 disabled:pointer-events-none">
  Secondary
</button>

<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-teal-500 text-white hover:bg-teal-600 focus:outline-none focus:bg-teal-600 disabled:opacity-50 disabled:pointer-events-none">
  Success
</button>

<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-red-500 text-white hover:bg-red-600 focus:outline-none focus:bg-red-600 disabled:opacity-50 disabled:pointer-events-none">
  Danger
</button>

<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-yellow-500 text-white hover:bg-yellow-600 focus:outline-none focus:bg-yellow-600 disabled:opacity-50 disabled:pointer-events-none">
  Warning
</button>

<!-- Outline Buttons -->
<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-blue-600 text-blue-600 hover:border-blue-500 hover:text-blue-500 focus:outline-none focus:border-blue-500 focus:text-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:border-blue-500 dark:text-blue-500 dark:hover:text-blue-400 dark:hover:border-blue-400">
  Outline Primary
</button>

<!-- Ghost Buttons -->
<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent text-blue-600 hover:bg-blue-100 hover:text-blue-800 focus:outline-none focus:bg-blue-100 focus:text-blue-800 disabled:opacity-50 disabled:pointer-events-none dark:text-blue-500 dark:hover:bg-blue-800/30 dark:hover:text-blue-400 dark:focus:bg-blue-800/30 dark:focus:text-blue-400">
  Ghost
</button>

<!-- Soft Buttons -->
<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-blue-100 text-blue-800 hover:bg-blue-200 focus:outline-none focus:bg-blue-200 disabled:opacity-50 disabled:pointer-events-none dark:text-blue-400 dark:bg-blue-800/30 dark:hover:bg-blue-800/20 dark:focus:bg-blue-800/20">
  Soft
</button>

<!-- White Button -->
<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50 focus:outline-none focus:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-700 dark:focus:bg-neutral-700">
  White
</button>

<!-- Button with icon -->
<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:bg-blue-700 disabled:opacity-50 disabled:pointer-events-none">
  <svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
    <path d="M5 12h14"></path>
    <path d="M12 5v14"></path>
  </svg>
  Add item
</button>

<!-- Button sizes -->
<button type="button" class="py-2 px-3 inline-flex items-center gap-x-2 text-xs font-medium rounded-lg border border-transparent bg-blue-600 text-white hover:bg-blue-700">
  Small
</button>

<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-transparent bg-blue-600 text-white hover:bg-blue-700">
  Default
</button>

<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-base font-medium rounded-lg border border-transparent bg-blue-600 text-white hover:bg-blue-700">
  Large
</button>

Components - Alerts

Code
HTML
<!-- Info Alert -->
<div class="bg-blue-100 border border-blue-200 text-sm text-blue-800 rounded-lg p-4 dark:bg-blue-800/10 dark:border-blue-900 dark:text-blue-500" role="alert" tabindex="-1" aria-labelledby="hs-with-description-label">
  <div class="flex">
    <div class="shrink-0">
      <svg class="shrink-0 size-4 mt-0.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <circle cx="12" cy="12" r="10"></circle>
        <path d="M12 16v-4"></path>
        <path d="M12 8h.01"></path>
      </svg>
    </div>
    <div class="ms-4">
      <h3 id="hs-with-description-label" class="text-sm font-semibold">
        Info
      </h3>
      <div class="mt-1 text-sm text-blue-700 dark:text-blue-400">
        A simple info alert with an example link.
      </div>
    </div>
  </div>
</div>

<!-- Success Alert -->
<div class="bg-teal-100 border border-teal-200 text-sm text-teal-800 rounded-lg p-4 dark:bg-teal-800/10 dark:border-teal-900 dark:text-teal-500" role="alert" tabindex="-1">
  <span class="font-bold">Success</span> Your purchase was successful.
</div>

<!-- Warning Alert -->
<div class="bg-yellow-100 border border-yellow-200 text-sm text-yellow-800 rounded-lg p-4 dark:bg-yellow-800/10 dark:border-yellow-900 dark:text-yellow-500" role="alert" tabindex="-1">
  <span class="font-bold">Warning</span> Please check your input.
</div>

<!-- Error Alert -->
<div class="bg-red-100 border border-red-200 text-sm text-red-800 rounded-lg p-4 dark:bg-red-800/10 dark:border-red-900 dark:text-red-500" role="alert" tabindex="-1">
  <span class="font-bold">Error</span> Something went wrong.
</div>

<!-- Dismissible Alert -->
<div id="dismiss-alert" class="hs-removing:translate-x-5 hs-removing:opacity-0 transition duration-300 bg-teal-50 border border-teal-200 text-sm text-teal-800 rounded-lg p-4 dark:bg-teal-800/10 dark:border-teal-900 dark:text-teal-500" role="alert" tabindex="-1">
  <div class="flex">
    <div class="shrink-0">
      <svg class="shrink-0 size-4 mt-0.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z"></path>
        <path d="m9 12 2 2 4-4"></path>
      </svg>
    </div>
    <div class="ms-2">
      <div class="text-sm font-medium">
        Successfully uploaded.
      </div>
    </div>
    <div class="ps-3 ms-auto">
      <div class="-mx-1.5 -my-1.5">
        <button type="button" class="inline-flex bg-teal-50 rounded-lg p-1.5 text-teal-500 hover:bg-teal-100 focus:outline-none focus:bg-teal-100 dark:bg-transparent dark:hover:bg-teal-800/50 dark:focus:bg-teal-800/50" data-hs-remove-element="#dismiss-alert">
          <span class="sr-only">Dismiss</span>
          <svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <path d="M18 6 6 18"></path>
            <path d="m6 6 12 12"></path>
          </svg>
        </button>
      </div>
    </div>
  </div>
</div>

Dark mode

Preline UI supports dark mode through the Tailwind CSS dark variant:

JStailwind.config.js
JavaScript
// tailwind.config.js
module.exports = {
  darkMode: 'class',
  // ...
}
Code
HTML
<!-- Dark mode toggle -->
<button type="button" class="hs-dark-mode-active:hidden block hs-dark-mode group flex items-center text-gray-600 hover:text-blue-600 font-medium dark:text-neutral-400 dark:hover:text-neutral-500" data-hs-theme-click-value="dark">
  <svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
    <path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"></path>
  </svg>
</button>
<button type="button" class="hs-dark-mode-active:block hidden hs-dark-mode group flex items-center text-gray-600 hover:text-blue-600 font-medium dark:text-neutral-400 dark:hover:text-neutral-500" data-hs-theme-click-value="light">
  <svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
    <circle cx="12" cy="12" r="4"></circle>
    <path d="M12 2v2"></path>
    <path d="M12 20v2"></path>
    <path d="m4.93 4.93 1.41 1.41"></path>
    <path d="m17.66 17.66 1.41 1.41"></path>
    <path d="M2 12h2"></path>
    <path d="M20 12h2"></path>
    <path d="m6.34 17.66-1.41 1.41"></path>
    <path d="m19.07 4.93-1.41 1.41"></path>
  </svg>
</button>

React/Next.js integration

TScomponents/Modal.tsx
TypeScript
// components/Modal.tsx
'use client'

import { useEffect } from 'react'

interface ModalProps {
  id: string
  title: string
  children: React.ReactNode
  isOpen: boolean
  onClose: () => void
}

export function Modal({ id, title, children, isOpen, onClose }: ModalProps) {
  useEffect(() => {
    // Reinitialize Preline after mounting
    import('preline').then((module) => {
      if (typeof window !== 'undefined' && (window as any).HSOverlay) {
        (window as any).HSOverlay.autoInit()
      }
    })
  }, [])

  return (
    <div
      id={id}
      className={`hs-overlay ${isOpen ? 'open' : 'hidden'} size-full fixed top-0 start-0 z-[80] overflow-x-hidden overflow-y-auto pointer-events-none`}
      role="dialog"
      tabIndex={-1}
      aria-labelledby={`${id}-label`}
    >
      <div className="hs-overlay-open:mt-7 hs-overlay-open:opacity-100 hs-overlay-open:duration-500 mt-0 opacity-0 ease-out transition-all sm:max-w-lg sm:w-full m-3 sm:mx-auto">
        <div className="flex flex-col bg-white border shadow-sm rounded-xl pointer-events-auto dark:bg-neutral-800 dark:border-neutral-700 dark:shadow-neutral-700/70">
          <div className="flex justify-between items-center py-3 px-4 border-b dark:border-neutral-700">
            <h3 id={`${id}-label`} className="font-bold text-gray-800 dark:text-white">
              {title}
            </h3>
            <button
              type="button"
              className="size-8 inline-flex justify-center items-center gap-x-2 rounded-full border border-transparent bg-gray-100 text-gray-800 hover:bg-gray-200 focus:outline-none focus:bg-gray-200 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-700 dark:hover:bg-neutral-600 dark:text-neutral-400 dark:focus:bg-neutral-600"
              aria-label="Close"
              onClick={onClose}
            >
              <span className="sr-only">Close</span>
              <svg className="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                <path d="M18 6 6 18"></path>
                <path d="m6 6 12 12"></path>
              </svg>
            </button>
          </div>
          <div className="p-4 overflow-y-auto">
            {children}
          </div>
        </div>
      </div>
    </div>
  )
}

Pricing

Open Source (free)

  • 300+ components
  • MIT License
  • Full documentation
  • Dark mode
  • Responsive

Preline Pro ($79+)

  • 50+ premium templates
  • Admin dashboards
  • Landing pages
  • E-commerce templates
  • Figma files
  • Priority support

FAQ - Frequently asked questions

Does Preline UI require JavaScript?

For static components (buttons, alerts, cards) - no. For interactive ones (accordion, tabs, modal, dropdown) - yes.

Does Preline UI work with Next.js App Router?

Yes! You need to import Preline in a useEffect in your main layout/components.

How do I add custom styles to components?

You can override Tailwind classes directly in the HTML - Preline uses standard Tailwind classes.

What is the difference between Preline UI and Flowbite?

Preline offers more components (300+ vs 50+) and better documentation. Flowbite has better framework support and more Pro blocks.

Can I use Preline commercially?

Yes, the MIT license allows commercial use at no cost.

Summary

Preline UI is one of the richest free component libraries for Tailwind CSS. It offers:

  • 300+ free components
  • Excellent documentation with examples
  • Support for HTML, React, and Vue
  • Built-in dark mode
  • Full responsiveness
  • MIT License

It is an excellent choice for developers looking for an extensive component library without having to pay.