1. Overview
The Oorian Tailwind CSS Library provides a complete Java wrapper around Tailwind CSS, the popular utility-first CSS framework. It enables Oorian developers to use Tailwind's utility classes and component patterns entirely in Java, following the Oorian philosophy of pure server-side development.
Key Features
- Full Java API for Tailwind CSS utility classes: spacing, typography, colors, flexbox, grid, and more
- Pre-built component classes: buttons, cards, forms, alerts, badges, navigation, and modals
- Type-safe enums for colors, sizes, breakpoints, and responsive prefixes
- Responsive design support with breakpoint-aware utility methods
- Dark mode utilities with
TwDarkModesupport - Layout components:
TwContainer,TwFlex,TwGrid - Fluent method chaining on all setter methods
- CDN or local resource loading via
Tailwind.initialize(HtmlPage)
2. Getting Started
Required Files
The Tailwind CSS extension consists of three components:
| File | Description |
|---|---|
oorian-tailwindcss-x.y.z.jar |
The Oorian Tailwind CSS library JAR. Add this to your web application's classpath (e.g., WEB-INF/lib). Available from the downloads page. |
oorian-tailwindcss-x.y.z.js |
The Oorian-to-Tailwind bridge script. This client-side file connects the Java API to Tailwind CSS. Deploy it to your web application's public folder. Available from the downloads page. |
tailwindcss (CDN or local) |
The Tailwind CSS framework. By default, this is loaded from the Tailwind Play CDN for development. For production, use a pre-built CSS file. |
CDN Mode (Default): By default, the library loads Tailwind CSS from cdn.tailwindcss.com (the Play CDN). This is convenient for development but should not be used in production. Disable CDN mode with Tailwind.setUseCdn(false) and provide a pre-built CSS file for production deployments.
Initialize the Library
In your page's createBody() method, call Tailwind.initialize(this) to add all required resources and the initialization script.
@Override
protected void createBody(Body body)
{
Tailwind.initialize(this);
}
That's it! The initialize() call adds the Tailwind CSS framework and bridge script to the page head, and the initialization script to the body. No JavaScript code is needed.
Custom Configuration (Optional)
If your files are in non-default locations, set the paths before calling initialize():
Tailwind.setTailwindRootPath("/assets/tailwind");
Tailwind.setOorianTailwindJsPath("/assets/oorian");
Tailwind.setUseCdn(false);
Tailwind.initialize(this);
Create a Component
After initializing the library, create Tailwind components and add them to the page body.
TwButton btn = new TwButton("Click Me");
btn.setColor(TwButton.COLOR_BLUE);
btn.setSize(TwButton.SIZE_MEDIUM);
body.addElement(btn);
4. Form Components
TwFormGroup
The recommended pattern is to wrap each label + control pair in a TwFormGroup for consistent spacing, optional error/help messages, and horizontal layout support.
TwFormGroup emailGroup = new TwFormGroup();
emailGroup.setLabel(new TwLabel("Email Address"));
emailGroup.setControl(
new TwInput("you@example.com")
.setInputType(TwInput.TYPE_EMAIL)
.setName("email")
.setRequired(true)
);
emailGroup.setHelpMessage("We'll never share your email.");
// Horizontal layout (label beside control)
emailGroup.setHorizontal(true);
TwInput
Text input supporting nine input types, three sizes, error state, read-only mode, and disabled state.
TwInput password = new TwInput();
password.setInputType(TwInput.TYPE_PASSWORD)
.setPlaceholder("Enter password")
.setName("password")
.setRequired(true)
.setSize(TwInput.SIZE_LARGE);
// Show error state
password.setHasError(true); // Switches border to red
Input types: TYPE_TEXT, TYPE_EMAIL, TYPE_PASSWORD, TYPE_NUMBER, TYPE_TEL, TYPE_URL, TYPE_SEARCH, TYPE_DATE, TYPE_TIME
TwSelect
TwSelect select = new TwSelect();
select.setName("country");
select.addPlaceholder("Choose a country...");
select.addOption("United States", "us");
select.addOption("Canada", "ca");
select.addOption("Mexico", "mx", true); // Pre-selected
// Change selection programmatically
select.setSelectedValue("ca");
TwTextarea
TwTextarea textarea = new TwTextarea("Enter your message...");
textarea.setRows(6)
.setName("message")
.setResizable(false)
.setRequired(true);
TwCheckbox and TwRadio
// Checkbox with description
TwCheckbox terms = new TwCheckbox("Accept Terms");
terms.setName("terms")
.setDescription("I agree to the terms and conditions.")
.setRequired(true)
.setColor("green");
// Radio buttons in a group
TwRadio small = new TwRadio("Small");
small.setName("size").setValue("sm").setChecked(true);
TwRadio medium = new TwRadio("Medium");
medium.setName("size").setValue("md");
TwToggle
TwToggle notifications = new TwToggle("Enable notifications");
notifications.setName("notifications")
.setChecked(true)
.setDescription("Receive email notifications for new messages.")
.setColor("green")
.setSize(TwToggle.SIZE_LARGE)
.setLabelOnLeft(true);
TwLabel
TwLabel label = new TwLabel("Username", "username-input");
label.setRequired(true); // Shows red asterisk
label.setHelpText("optional"); // Shows "(optional)" in gray
5. Layout Components
TwContainer
Centers content with responsive max-width constraints. Defaults to XL (1280px) centered with px-4 padding.
TwContainer container = new TwContainer();
container.setMaxWidth(TwContainer.SIZE_LG); // 1024px max
container.setPaddingX("6");
// Full-width container (no max-width)
TwContainer full = new TwContainer();
full.setMaxWidth(TwContainer.SIZE_FULL);
Sizes: SIZE_SM (640px), SIZE_MD (768px), SIZE_LG (1024px), SIZE_XL (1280px, default), SIZE_2XL (1536px), SIZE_FULL
TwGrid
Responsive CSS grid system with breakpoint-specific column counts and gap control.
// Responsive 3-column grid
TwGrid grid = new TwGrid();
grid.setCols(1); // Default: 1 column on mobile
grid.setMdCols(2); // 2 columns at md breakpoint (768px)
grid.setLgCols(3); // 3 columns at lg breakpoint (1024px)
grid.setGap("6"); // gap-6 between items
// Independent horizontal/vertical gaps
grid.setGapX("4");
grid.setGapY("8");
TwDivider
// Simple horizontal line
TwDivider divider = new TwDivider();
// Labeled divider: ---- OR ----
TwDivider labeled = new TwDivider("OR");
labeled.setColor("gray-300");
// Vertical divider
TwDivider vertical = new TwDivider();
vertical.setOrientation(TwDivider.ORIENTATION_VERTICAL);
TwSpacer
// Vertical space (default)
TwSpacer spacer = new TwSpacer(TwSpacer.SIZE_XL); // h-8
// Horizontal space
TwSpacer hSpacer = new TwSpacer();
hSpacer.setOrientation(TwSpacer.ORIENTATION_HORIZONTAL).setSize("4");
// Flex-grow spacer (fills remaining space)
TwSpacer flexSpacer = new TwSpacer();
flexSpacer.setFlex(true);
6. Cards, Alerts, and Badges
TwCard
Flexible content container with optional image, title, subtitle, body, header, and footer sections.
// Card with image, title, and body text
TwCard card = new TwCard("Featured Article", "A brief description of the article content.");
card.setImageUrl("/images/hero.jpg")
.setImageAlt("Hero image")
.setSubtitle("Published January 2026")
.setShadow(TwCard.SHADOW_LG)
.setBordered(true)
.setHoverable(true);
// Card with custom header, body, and footer content
TwCard custom = new TwCard();
custom.setHeaderContent(headerElement);
custom.setBodyContent(bodyElement);
custom.setFooterContent(footerElement);
Shadow levels: SHADOW_NONE, SHADOW_SM, SHADOW_MD (default), SHADOW_LG, SHADOW_XL
TwAlert
Status messages with four alert types, optional icons, and dismissible support.
TwAlert success = new TwAlert("Record saved successfully!", TwAlert.TYPE_SUCCESS);
success.setDismissible(true);
TwAlert error = new TwAlert("Failed to load data.");
error.setType(TwAlert.TYPE_ERROR)
.setIcon(errorIconElement);
Types: TYPE_SUCCESS (green), TYPE_ERROR (red), TYPE_WARNING (yellow), TYPE_INFO (blue, default)
TwBadge
Small status indicators supporting eight colors, pill shape, outline style, and three sizes.
TwBadge status = new TwBadge("Active", TwBadge.COLOR_GREEN);
TwBadge count = new TwBadge("12");
count.setPill(true)
.setColor(TwBadge.COLOR_RED)
.setSize(TwBadge.SIZE_SMALL);
TwBadge outline = new TwBadge("Draft");
outline.setOutline(true)
.setColor(TwBadge.COLOR_INDIGO);
Colors: COLOR_GRAY (default), COLOR_RED, COLOR_YELLOW, COLOR_GREEN, COLOR_BLUE, COLOR_INDIGO, COLOR_PURPLE, COLOR_PINK
8. Feedback Components
TwModal
Dialog overlay with configurable size, close button, and backdrop click behavior.
TwModal modal = new TwModal("Confirm Delete");
modal.setBody(confirmMessageElement);
modal.setFooter(buttonRowElement);
modal.setSize(TwModal.SIZE_SMALL);
modal.setCloseOnBackdropClick(false);
// Programmatically open/close
modal.setOpen(true); // Removes "hidden" class
modal.setOpen(false); // Adds "hidden" class
Sizes: SIZE_SMALL (max-w-sm), SIZE_MEDIUM (max-w-lg, default), SIZE_LARGE (max-w-2xl), SIZE_FULL (max-w-full)
TwProgress
TwProgress progress = new TwProgress(65);
progress.setColor("green")
.setSize(TwProgress.SIZE_LARGE)
.setShowLabel(true) // Shows "65%"
.setStriped(true)
.setAnimated(true);
// Indeterminate loading bar
TwProgress loading = new TwProgress();
loading.setIndeterminate(true);
TwSpinner
TwSpinner spinner = new TwSpinner("Loading data...");
spinner.setSize(TwSpinner.SIZE_LARGE)
.setColor("indigo");
Sizes: SIZE_SMALL (h-4), SIZE_MEDIUM (h-6, default), SIZE_LARGE (h-8), SIZE_XL (h-12)
TwToast
Toast notifications with positioning, auto-dismiss, action buttons, and type-specific icons.
TwToast toast = new TwToast("Changes saved successfully!");
toast.setType(TwToast.TYPE_SUCCESS);
toast.setPosition(TwToast.POSITION_BOTTOM_RIGHT);
toast.setAutoDismissMs(3000); // 3 seconds
toast.setDismissible(true);
// Toast with action button
TwToast undo = new TwToast("Item deleted.");
undo.setType(TwToast.TYPE_WARNING);
undo.setAction("Undo", "/undo?id=42");
Positions: POSITION_TOP_RIGHT (default), POSITION_TOP_LEFT, POSITION_TOP_CENTER, POSITION_BOTTOM_RIGHT, POSITION_BOTTOM_LEFT, POSITION_BOTTOM_CENTER
TwSkeleton
Loading placeholders with configurable shape, dimensions, and pulse animation.
// Text skeleton
TwSkeleton line = new TwSkeleton();
line.setShape(TwSkeleton.SHAPE_TEXT); // Rounded, h-4
line.setWidth("full");
// Circle skeleton (avatar placeholder)
TwSkeleton avatar = new TwSkeleton("48px", "48px");
avatar.setShape(TwSkeleton.SHAPE_CIRCLE);
// Static skeleton (no animation)
TwSkeleton staticBox = new TwSkeleton("200px", "100px");
staticBox.setAnimate(false);
Shapes: SHAPE_RECTANGLE (default), SHAPE_CIRCLE, SHAPE_TEXT
9. Display Components
TwTable
Data tables with striped rows, hover effects, borders, and compact mode.
TwTable table = new TwTable();
table.setHeaders("Name", "Email", "Role");
table.addRow("Alice Johnson", "alice@example.com", "Admin");
table.addRow("Bob Smith", "bob@example.com", "Editor");
table.addRow("Carol White", "carol@example.com", "Viewer");
table.setStriped(true)
.setHoverable(true)
.setBordered(true)
.setCompact(false);
TwList
Styled lists supporting ordered/unordered types, multiple bullet styles, dividers, borders, items with descriptions, and custom element items.
// Divided bordered list
TwList list = new TwList();
list.setListStyle(TwList.STYLE_NONE);
list.setDivided(true);
list.setBordered(true);
list.addItem("Dashboard", "View analytics and reports");
list.addItem("Users", "Manage user accounts");
list.addItem(customElement); // Custom element as item
List styles: STYLE_DISC, STYLE_CIRCLE, STYLE_SQUARE, STYLE_DECIMAL, STYLE_NONE
TwAvatar
User avatars with image, initials, or placeholder; six sizes; three shapes; and four status indicators.
// Image avatar with online status
TwAvatar avatar = new TwAvatar("/images/user.jpg");
avatar.setAlt("Alice Johnson")
.setSize(TwAvatar.SIZE_LG)
.setStatus(TwAvatar.STATUS_ONLINE);
// Initials avatar
TwAvatar initials = new TwAvatar();
initials.setInitials("JD")
.setBgColor("indigo")
.setShape(TwAvatar.SHAPE_ROUNDED);
Sizes: SIZE_XS (24px), SIZE_SM (32px), SIZE_MD (40px, default), SIZE_LG (48px), SIZE_XL (64px), SIZE_2XL (80px)
Shapes: SHAPE_CIRCLE (default), SHAPE_ROUNDED, SHAPE_SQUARE
Status: STATUS_ONLINE (green), STATUS_OFFLINE (gray), STATUS_AWAY (yellow), STATUS_BUSY (red)
TwAccordion
Collapsible content sections with expand/collapse toggle, multiple-open support, and bordered/flush styles.
TwAccordion accordion = new TwAccordion();
accordion.addItem("What is Oorian?", "A server-side Java web framework...");
accordion.addItem("How do I get started?", "Install the library and...");
accordion.addItem("Is it free?", customContentElement);
accordion.setDefaultOpenIndex(0);
accordion.setAllowMultiple(true);
accordion.setBordered(true);
// accordion.setFlush(true); // No outer borders
10. Real-World Patterns
Complete Login Form
@Page("/login")
public class LoginPage extends HtmlPage
{
@Override
protected void createHead(Head head)
{
head.setTitle("Login");
Tailwind.addAllResources(head);
}
@Override
protected void createBody(Body body)
{
TwContainer container = new TwContainer();
container.setMaxWidth(TwContainer.SIZE_SM);
TwCard card = new TwCard();
card.setCardTitle("Sign In");
card.setShadow(TwCard.SHADOW_LG);
// Email field
TwFormGroup emailGroup = new TwFormGroup();
emailGroup.setLabel(new TwLabel("Email"));
emailGroup.setControl(
new TwInput("you@example.com")
.setInputType(TwInput.TYPE_EMAIL)
.setName("email")
.setRequired(true)
);
// Password field
TwFormGroup passGroup = new TwFormGroup();
passGroup.setLabel(new TwLabel("Password"));
passGroup.setControl(
new TwInput()
.setInputType(TwInput.TYPE_PASSWORD)
.setName("password")
.setRequired(true)
);
// Remember me toggle
TwToggle remember = new TwToggle("Remember me");
remember.setName("remember");
// Submit button
TwButton loginBtn = new TwButton("Sign In");
loginBtn.setFullWidth(true)
.setButtonType("submit")
.setSize(TwButton.SIZE_LARGE);
// Assemble the body content
Div formContent = new Div();
formContent.addElement(emailGroup);
formContent.addElement(passGroup);
formContent.addElement(remember);
formContent.addElement(new TwSpacer(TwSpacer.SIZE_MD));
formContent.addElement(loginBtn);
card.setBodyContent(formContent);
container.addElement(new TwSpacer(TwSpacer.SIZE_2XL));
container.addElement(card);
body.addElement(container);
}
}
Dashboard Card Grid
// Responsive card grid for a dashboard
TwGrid grid = new TwGrid();
grid.setCols(1).setSmCols(2).setLgCols(4).setGap("6");
String[] titles = {"Users", "Revenue", "Orders", "Growth"};
String[] values = {"12,450", "$84,200", "1,024", "+12.5%"};
for (int i = 0; i < titles.length; i++)
{
TwCard card = new TwCard(titles[i], values[i]);
card.setShadow(TwCard.SHADOW_SM);
card.setHoverable(true);
grid.addElement(card);
}
body.addElement(grid);
Toolbar with Icon Buttons
TwButtonGroup toolbar = new TwButtonGroup();
toolbar.addButton(new TwIconButton(TwIconButton.ICON_EDIT)
.setAriaLabel("Edit").setVariant(TwIconButton.VARIANT_GHOST));
toolbar.addButton(new TwIconButton(TwIconButton.ICON_DOWNLOAD)
.setAriaLabel("Download").setVariant(TwIconButton.VARIANT_GHOST));
toolbar.addButton(new TwIconButton(TwIconButton.ICON_DELETE)
.setAriaLabel("Delete").setVariant(TwIconButton.VARIANT_DANGER));
Tip: All TailwindLib components inherit from StyledElement, so you can always add additional Tailwind utility classes with addClass(). For example, card.addClass("mt-8 hover:scale-105").
11. API Reference
Core Classes
| Class | Package | Key Methods |
|---|---|---|
Tailwind | com.oorian.tailwind | addAllResources(Head), addTailwindJavascript(Head), addOorianTailwindJavascript(Head), setUseCdn(boolean), setTailwindRootPath(String), setOorianTailwindJsPath(String), isUseCdn(), getTailwindJs(), getOorianTailwindJs() |
TailwindComponent<T> | com.oorian.tailwind | getComponentType(), removeClassesWithPrefix(String), ensureId() |
TailwindInitScript | com.oorian.tailwind | addCode(String); static field ID |
Button Components
| Class | Key Methods |
|---|---|
TwButton | setText(String), setVariant(String), setColor(String), setSize(String), setFullWidth(boolean), setLeftIcon(Element), setRightIcon(Element), setButtonType(String) |
TwIconButton | setIcon(String), setCustomIconSvg(String), setSize(String), setVariant(String), setAriaLabel(String), setRounded(boolean) |
TwLink | setLinkText(String), setHref(String), setVariant(String), setSize(String), setUnderline(boolean), setExternal(boolean), setIconBefore(Element), setIconAfter(Element) |
TwButtonGroup | addButton(String, String), addButton(Element), setOrientation(String), clearButtons() |
Form Components
| Class | Key Methods |
|---|---|
TwInput | setInputType(String), setSize(String), setPlaceholder(String), setValue(String), setName(String), setRequired(boolean), setReadOnly(boolean), setHasError(boolean) |
TwSelect | addOption(String, String), addOption(String, String, boolean), addPlaceholder(String), setSelectedValue(String), clearOptions(), setSize(String), setName(String), setRequired(boolean), setHasError(boolean) |
TwTextarea | setPlaceholder(String), setValue(String), setRows(int), setName(String), setSize(String), setRequired(boolean), setReadOnly(boolean), setResizable(boolean), setHasError(boolean) |
TwCheckbox | setLabel(String), setName(String), setValue(String), setChecked(boolean), setRequired(boolean), setDescription(String), setColor(String), setSize(String) |
TwRadio | setLabel(String), setName(String), setValue(String), setChecked(boolean), setRequired(boolean), setDescription(String), setColor(String), setSize(String) |
TwToggle | setLabel(String), setName(String), setChecked(boolean), setDescription(String), setColor(String), setSize(String), setLabelOnLeft(boolean) |
TwLabel | setLabelText(String), setFor(String), setRequired(boolean), setHelpText(String) |
TwFormGroup | setLabel(TwLabel), setControl(Element), setErrorMessage(String), setHelpMessage(String), setHorizontal(boolean) |
Layout Components
| Class | Key Methods |
|---|---|
TwContainer | setMaxWidth(String), setCentered(boolean), setPaddingX(String) |
TwGrid | setCols(int), setSmCols(int), setMdCols(int), setLgCols(int), setXlCols(int), setGap(String), setGapX(String), setGapY(String) |
TwDivider | setOrientation(String), setLabel(String), setColor(String), setMarginY(String), setMarginX(String) |
TwSpacer | setSize(String), setOrientation(String), setFlex(boolean) |
Card, Alert, and Badge Components
| Class | Key Methods |
|---|---|
TwCard | setCardTitle(String), setSubtitle(String), setBody(String), setImageUrl(String), setImageAlt(String), setShadow(String), setBordered(boolean), setHoverable(boolean), setHeaderContent(Element), setBodyContent(Element), setFooterContent(Element) |
TwAlert | setMessage(String), setType(String), setDismissible(boolean), setIcon(Element) |
TwBadge | setText(String), setColor(String), setSize(String), setPill(boolean), setOutline(boolean) |
Navigation Components
| Class | Key Methods |
|---|---|
TwTabs | addTab(String, String), addTab(String, String, String), addDisabledTab(String, String), setActiveTab(String), setTabStyle(String), setFullWidth(boolean), setColor(String) |
TwBreadcrumb | addItem(String, String), addItem(String, String, String), setSeparator(String), setHomeIcon(String) |
TwDropdown | setTriggerText(String), setTriggerElement(Element), addItem(String, String), addItem(String, String, String), addDisabledItem(String), addDivider(), setAlignment(String), setShowChevron(boolean) |
TwPagination | setTotalPages(int), setCurrentPage(int), setBaseUrl(String), setSize(String), setMaxVisiblePages(int), setShowFirstLast(boolean), setShowPrevNext(boolean), setColor(String) |
Feedback Components
| Class | Key Methods |
|---|---|
TwModal | setModalTitle(String), setBody(Element), setFooter(Element), setSize(String), setShowCloseButton(boolean), setCloseOnBackdropClick(boolean), setOpen(boolean) |
TwProgress | setValue(int), setMax(int), setSize(String), setColor(String), setShowLabel(boolean), setStriped(boolean), setAnimated(boolean), setIndeterminate(boolean) |
TwSpinner | setSize(String), setColor(String), setLabel(String) |
TwToast | setMessage(String), setType(String), setPosition(String), setDismissible(boolean), setAutoDismissMs(int), setAction(String, String) |
TwSkeleton | setShape(String), setWidth(String), setHeight(String), setAnimate(boolean) |
Display Components
| Class | Key Methods |
|---|---|
TwTable | setHeaders(String...), addRow(String...), clearRows(), setStriped(boolean), setHoverable(boolean), setBordered(boolean), setCompact(boolean) |
TwList | addItem(String), addItem(String, String), addItem(Element), clearItems(), setListType(String), setListStyle(String), setDivided(boolean), setBordered(boolean) |
TwAvatar | setImageSrc(String), setAlt(String), setInitials(String), setSize(String), setShape(String), setStatus(String), setBgColor(String) |
TwAccordion | addItem(String, String), addItem(String, Element), clearItems(), setAllowMultiple(boolean), setBordered(boolean), setFlush(boolean), setDefaultOpenIndex(int) |