Grid Theming With Tailwind
Tailwind can be used to style LyteNyte Grid. This guide explains how to set up Tailwind and apply it to grid elements.
This guide uses Tailwind as an atomic CSS framework for styling LyteNyte Grid because it is the most popular option. The approach described here also works with other atomic CSS frameworks, such as UnoCSS.
We highly recommend reading the general Grid Theming guide first to understand the styling options available in LyteNyte Grid.
This guide assumes you are using Tailwind v4. Translating the examples back to Tailwind v3 is straightforward.
Tailwind Theming Setup
Start by setting up Tailwind. The exact steps depend on your React framework. See Tailwind's Installation guide for framework-specific details.
This guide assumes you have Tailwind configured with the default setup, and a CSS file that contains:
@import "tailwindcss";
If you are not sure which framework to use, we recommend starting with Vite. The project setup is simple and Tailwind is supported by an official plugin.
Applying Tailwind Classes
LyteNyte Grid exposes a set of headless components that you use to build the grid view.
These components accept standard HTML and React props, including className.
As a result, styling the grid with Tailwind is as simple as applying utility classes.
The example below demonstrates this using the standard Tailwind color palette:
Styling With Tailwind
In the example, Tailwind classes are applied in the usual way.
No special configuration is required. For example, the Grid.Cell component is styled as follows:
<Grid.Cellkey={c.id}cell={c}className="flex items-center bg-gray-50 px-2 text-sm text-gray-800"/>
Class Variance Authority
Directly applying classes to elements works well for simple styling, but it does not scale when there is a lot of conditional styling being applied. Tailwind utility helpers can make conditional styles easier to manage. The approach here uses three libraries:
Start by creating a tw utility function that combines clsx and tailwind-merge:
import type { ClassValue } from "clsx";import clsx from "clsx";import { twMerge } from "tailwind-merge";export function tw(...c: ClassValue[]) {return twMerge(clsx(...c));}
If you already use a Tailwind-based framework such as shadcn/ui, a similar tw function
may already exist, often named cn in shadcn/ui projects.
Next, define grid-cell variants using class-variance-authority:
const cellStyles = cva("flex items-center bg-gray-50 px-2 text-sm text-gray-800", {variants: {number: {true: "justify-end tabular-nums",},rowBase: {true: "flex items-center border-b border-gray-200 bg-white px-2 text-sm text-gray-800 group-data-[ln-alternate=true]:bg-gray-100 dark:border-gray-100 dark:bg-gray-50 dark:text-gray-600 dark:group-data-[ln-alternate=true]:bg-gray-100/30",},header: {true: "capitalize bg-gray-100 text-gray-700",},},});
The cellStyles function now returns the base classes and applies
variants on top for different grid-cell states.
The example below shows how to combine Tailwind, tw, and cva to provide
rich, composable grid styles:
Tailwind Styling With CVA
Notice how the CVA-generated style is applied to the grid cell:
<Grid.Cellkey={c.id}cell={c}className={tw(cellStyles({number: c.column.type === "number",rowBase: true,}),)}/>
This pattern keeps styles consistent and makes it easy to maintain variants over a shared base.
Styling Elements Not Directly Exposed
The Grid Theming guide explains that some elements are not directly exposed through LyteNyte Grid's public component interface. You must style these elements using data attributes or other selectors.
You can still target these elements with Tailwind by using more advanced selector syntax. This section shows how to style the row-detail element and the cell selection ranges with Tailwind.
Styling Row Detail
To style the row-detail element with Tailwind, target the element that has the
data-ln-row-detail attribute. You can do this without a separate
CSS file by using Tailwind's arbitrary variant selector syntax.
Tailwind Styling Row Detail
The selector (shown below) looks complex but it is straightforward. The & symbol refers to the current
element. The [data-ln-row-detail="true"] portion selects the descendant that has the matching
data attribute. Finally, >div selects the div that is a direct descendant. If you are
unfamiliar with this syntax, see Tailwind's guide on
arbitrary variants.
<Grid.Rowrow={row}key={row.id}className={tw('[&_[data-ln-row-detail="true"]>div]:rounded-lg','[&_[data-ln-row-detail="true"]>div]:border','[&_[data-ln-row-detail="true"]>div]:border-gray-500','[&_[data-ln-row-detail="true"]]:p-7',)}/>
This example styles the row-detail element inline. You can also move these styles into a separate CSS file and target the same data attribute selectors there. Tailwind compiles down to vanilla CSS, so both approaches work.
Styling Cell Selection Ranges
You can style cell-selection rectangles using arbitrary Tailwind selectors in a similar way. In this case, you place the selector on the rows container rather than on each row. The example below demonstrates this:
Cell Selection Styling With Tailwind
Here we use a descendant selector to target every cell selection rectangle. This is a direct inline approach, but you can also move these rules to a separate CSS file if you prefer.
<Grid.RowsContainerclassName={tw('**:not-data-[ln-cell-selection-is-unit="true"]:data-[ln-cell-selection-rect]:bg-ln-primary-30 **:data-[ln-cell-selection-rect]:border-ln-primary-50','**:not-data-[ln-cell-selection-is-unit="true"]:data-[ln-cell-selection-border-top=true]:border-t','**:not-data-[ln-cell-selection-is-unit="true"]:data-[ln-cell-selection-border-bottom=true]:border-b','**:not-data-[ln-cell-selection-is-unit="true"]:data-[ln-cell-selection-border-start=true]:border-l','**:not-data-[ln-cell-selection-is-unit="true"]:data-[ln-cell-selection-border-end=true]:border-r','**:data-[ln-cell-selection-is-unit="true"]:outline **:data-[ln-cell-selection-is-unit="true"]:outline-ln-primary-50 **:data-[ln-cell-selection-is-unit="true"]:-outline-offset-1',)}>
Mixing Tailwind and Pre-built Themes
Fully theming LyteNyte Grid from scratch can require a significant amount of styling. If you want the grid to match your design system exactly, you may choose to define every style yourself. However, starting from a pre-built theme and then adjusting styles with Tailwind is often more efficient.
Because Tailwind does not restrict other CSS, you can combine a pre-built LyteNyte Grid theme with Tailwind utilities. This is how many of the demos on the 1771 Technologies website are built. The example below shows Tailwind working alongside the provided grid themes:
Pre-built Themes With Tailwind
Theme Variables
When you use one of the provided pre-built themes, it helps to define Tailwind theme variables so you can reuse the same colors across your application. The CSS below shows the theme variables you can map into Tailwind:
@theme {--color-ln-gray-00: var(--lng1771-gray-00);--color-ln-gray-02: var(--lng1771-gray-02);--color-ln-gray-05: var(--lng1771-gray-05);--color-ln-gray-10: var(--lng1771-gray-10);--color-ln-gray-20: var(--lng1771-gray-20);--color-ln-gray-30: var(--lng1771-gray-30);--color-ln-gray-40: var(--lng1771-gray-40);--color-ln-gray-50: var(--lng1771-gray-50);--color-ln-gray-60: var(--lng1771-gray-60);--color-ln-gray-70: var(--lng1771-gray-70);--color-ln-gray-80: var(--lng1771-gray-80);--color-ln-gray-90: var(--lng1771-gray-90);--color-ln-gray-100: var(--lng1771-gray-100);--color-ln-primary-05: var(--lng1771-primary-05);--color-ln-primary-10: var(--lng1771-primary-10);--color-ln-primary-30: var(--lng1771-primary-30);--color-ln-primary-50: var(--lng1771-primary-50);--color-ln-primary-70: var(--lng1771-primary-70);--color-ln-primary-90: var(--lng1771-primary-90);--color-ln-focus-outline: var(--lng1771-focus-outline);--color-ln-pill-plain-fill: var(--lng1771-pill-plain-fill);--color-ln-pill-column-fill: var(--lng1771-pill-column-fill);--color-ln-pill-column-stroke: var(--lng1771-pill-column-stroke);--color-ln-pill-pivot-fill: var(--lng1771-pill-pivot-fill);--color-ln-pill-pivot-stroke: var(--lng1771-pill-pivot-stroke);--color-ln-pill-group-fill: var(--lng1771-pill-group-fill);--color-ln-pill-group-stroke: var(--lng1771-pill-group-stroke);--color-ln-pill-icon-color: var(--lng1771-pill-icon-color);}
Shadcn and LyteNyte Grid
Shadcn/ui is a popular library for bootstrapping applications.
Shadcn/ui uses Tailwind but defines its own theme tokens instead of relying on the default
Tailwind color palette. LyteNyte Grid includes a pre-made shadcn/ui theme. To apply
it, add the lng-grid lng1771-shadcn classes to an element above the grid.
LyteNyte With Shadcn/ui Theme
The shadcn/ui theme is designed to work with shadcn/ui tokens. A typical set is shown below. These tokens are usually already defined in any shadcn/ui project. See the shadcn/ui theming page for more details:
:root {--color-background: oklch(0.145 0 0);--color-foreground: oklch(0.985 0 0);--color-card: oklch(0.205 0 0);--color-card-foreground: oklch(0.985 0 0);--color-popover: oklch(0.205 0 0);--color-popover-foreground: oklch(0.985 0 0);--color-primary: oklch(0.922 0 0);--color-primary-foreground: oklch(0.205 0 0);--color-secondary: oklch(0.269 0 0);--color-secondary-foreground: oklch(0.985 0 0);--color-muted: oklch(0.269 0 0);--color-muted-foreground: oklch(0.708 0 0);--color-accent: oklch(0.269 0 0);--color-accent-foreground: oklch(0.985 0 0);--color-destructive: oklch(0.704 0.191 22.216);--color-border: oklch(1 0 0 / 10%);--color-input: oklch(1 0 0 / 15%);--color-ring: oklch(0.556 0 0);--color-chart-1: oklch(0.488 0.243 264.376);--color-chart-2: oklch(0.696 0.17 162.48);--color-chart-3: oklch(0.769 0.188 70.08);--color-chart-4: oklch(0.627 0.265 303.9);--color-chart-5: oklch(0.645 0.246 16.439);--color-sidebar: oklch(0.205 0 0);--color-sidebar-foreground: oklch(0.985 0 0);--color-sidebar-primary: oklch(0.488 0.243 264.376);--color-sidebar-primary-foreground: oklch(0.985 0 0);--color-sidebar-accent: oklch(0.269 0 0);--color-sidebar-accent-foreground: oklch(0.985 0 0);--color-sidebar-border: oklch(1 0 0 / 10%);--color-sidebar-ring: oklch(0.556 0 0);}
Next Steps
This guide covered the basics of styling LyteNyte Grid with Tailwind. For more details, see:
- Installation With Shadcn: learn how to use LyteNyte Grid with shadcn/ui.
- Grid Theming: review the general theming guide to learn more about styling LyteNyte Grid.
- Columns: see how column configuration affects what the grid displays.
- Cell Renderers: define custom cell renderers for more control over cell content.
Grid Theming
LyteNyte Grid is a headless data grid. This guide explains how to theme LyteNyte Grid using vanilla CSS or pre-built themes to create a visually polished data grid.
Grid Theming With CSS Modules
LyteNyte Grid can be styled using CSS modules. CSS modules provide scoped class names for writing isolated CSS.