Skip to content

Getting started

flootlets is a small library of accessible, themeable SolidJS components for Astro, Solid SSR and static sites: the essential building blocks, plus product, price and cart pieces for shops.

  • Tailwind CSS v4 and shadcn/ui conventions. Components are styled with Tailwind classes, shadcn’s variant names and theme variables, so any shadcn theme works and anything can be restyled with a class.
  • Your classes win. The class you pass is merged last with tailwind-merge, so class="rounded-full" replaces the component’s radius instead of fighting it.
  • Server-rendered first. Works in Astro, SolidStart and static builds: static components ship no JavaScript.
  • Accessible by default, and checked with axe in tests.

flootlets needs Tailwind CSS v4 in your app (in Astro: npx astro add tailwind). Install the package:

Terminal window
bun add flootlets solid-js # or: npm install / pnpm add

and in your main CSS file, import the theme after Tailwind and let Tailwind see the components’ classes:

@import 'tailwindcss';
@import 'flootlets/theme.css';
@source '../node_modules/flootlets/dist';

Or copy the components into your app with the shadcn CLI and own the code. See Installation for both.

import { Button, Price } from 'flootlets';
export function AddToCart() {
return (
<>
<Price amount={{ amount: 2920, currency: 'MYR' }} locale="en-MY" />
<Button onClick={() => console.log('added')}>Add to cart</Button>
</>
);
}

Add the Solid integration (npx astro add solid). flootlets ships its JSX source under the solid export condition, so Astro compiles it correctly for both the server and the browser.

---
import '../styles/global.css'; // the CSS file from Install
import { Price, Badge } from 'flootlets';
import AddToCart from '../components/AddToCart';
---
<!-- Static: rendered to HTML, no JavaScript sent. -->
<Price amount={{ amount: 2920, currency: 'MYR' }} locale="en-MY" />
<Badge variant="success">In stock</Badge>
<!-- Interactive: hydrated in the browser as an island. -->
<AddToCart client:visible />

Only add client:* to components that respond to the visitor (clicks, typing). Everything else stays plain HTML.

Prices are an integer amount in the currency’s smallest unit plus an ISO 4217 currency, the shape most payment and commerce APIs use (gnerkulfloot’s included). RM 29.20 is { amount: 2920, currency: 'MYR' }; ¥500 is { amount: 500, currency: 'JPY' }. Pass the same locale wherever a price renders: a locale taken from the server’s or browser’s environment would differ between the two and break hydration.

flootlets 0.2.3 · Changelog