1. Components
  2. principles

Principles

How JK-UI works and why it's built this way

It's a close adaptation of Flexiwind for ReactJS, built on the React Aria Library. Most components come from Intent UI.
The main reason it exists: I switch between Laravel (Blade/Livewire) and React, and I wanted a consistent way to structure components (props, variants, customization) so I don’t get lost between different styles and conventions.

How It Works

TailwindCSS v4 + React Aria Components

This setup is straightforward:
  • React Aria Components
  • TailwindCSS v4

CSS Variable-Based Theming

Everything uses CSS variables, which makes customization simple:
@utility ui-solid-primary {
    --ui-solid-bg: var(--color-primary-600);
    --ui-solid-text: var(--color-white);

    &:is(.dark *) {
        --ui-solid-bg: var(--color-primary-500);
    }
}
And use like this
<span className="ui-solid ui-solid-primary">...</span>
Or even like this if you prefere :
<span className="ui-solid [--ui-solid-bg:var(--color-primary-600)] [-ui-solid-text:var(--color-white)] dark:[--ui-solid-bg:var(--color-primary-500)]">...</span>

Utility Classes

TailwindCSS v4's @utility directive creates reusable utility classes:
@utility ui-solid {
  @apply bg-(--ui-solid-bg) text-(--ui-solid-text);
}

@utility ui-soft {
  @apply bg-(--ui-soft-bg) text-(--ui-soft-text);
}

@utility ui-outline {
  @apply text-(--ui-outline-text) border border-(--ui-outline-border);
}
Components use tailwind-variants to compose these utilities with type safety.

Variant & Intent System

Components use a two-level styling system:

Variants

The visual style:
  • solid: Filled background
  • soft: Subtle background
  • outline: Border only
  • subtle: Very subtle background with border

Intents

The color/semantic meaning:
  • primary, secondary, accent
  • success, warning, danger, info
  • gray, neutral
Example:
<Badge variant="solid" intent="primary">Primary</Badge>
<Badge variant="soft" intent="soft-success">Success</Badge>
<Badge variant="outline" intent="outline-danger">Danger</Badge>
TypeScript ensures valid combinations, and the same system works across components.

Design Choices

Composition

CSS Variables

All design tokens use CSS variables:
  • Colors: --color-primary-600
  • Spacing: --spacing(value)
  • Radius: --ui-radius
  • Component-specific: --ui-solid-bg, --ui-soft-text
This makes customization straightforward—just change the CSS variables.

Type Safety

TypeScript ensures valid combinations:
<Badge variant="solid" intent="primary" /> // ✅ Valid
<Badge variant="solid" intent="outline-primary" /> // ❌ Type error

Customization

Add New Variants

@utility ui-gradient-primary {
    background: linear-gradient(to right, var(--color-primary-600), var(--color-primary-400));
    --ui-gradient-text: var(--color-white);
}
This setup works well for me, but feel free to adapt it to your needs. Everything is customizable via CSS variables, so you can make it your own.