Styling

Style Namespace UIKit components with CSS, Tailwind, or CSS-in-JS

Namespace UIKit components provide flexible styling options: Tailwind CSS utilities, CSS with BEM classes or data attributes, CSS-in-JS libraries, and render props for dynamic styling.

Basic Styling

Using className: All Namespace UIKit components accept className props:

<Button className="bg-purple-500 hover:bg-purple-600">
  Custom Button
</Button>

<Accordion className="border-2 border-gray-200 rounded-xl">
  {/* content */}
</Accordion>

Using style: Components also accept inline styles:

<Button style={{ backgroundColor: "#8B5CF6" }}>Styled Button</Button>

Scrollbars

Namespace UIKit scroll slots use @apply scrollbar in component CSS. For your own overflow containers, use the utilities from @thenamespace/uikit/styles:

<div className="scrollbar h-64 overflow-y-auto">{/* long content */}</div>
UtilityEffect
scrollbarNamespace UIKit thumb (reads theme --scrollbar-* variables)
scrollbar-thinNamespace UIKit themed thin scrollbar
scrollbar-defaultOS / browser scrollbars
scrollbar-noneHidden scrollbar

Global and per-subtree control uses data-scrollbar on an ancestor. See Theming for tokens and modes.

State-Based Styling

Namespace UIKit components expose their state through data attributes, similar to CSS pseudo-classes:

/* Target different states */
.button[data-hovered="true"],
.button:hover {
  background: var(--accent-hover);
}

.button[data-pressed="true"],
.button:active {
  transform: scale(0.97);
}

.button[data-focus-visible="true"],
.button:focus-visible {
  outline: 2px solid var(--focus);
}

Render Props

Apply dynamic styling based on component state:

// Dynamic classes
<Button
  className={({ isPressed }) =>
    isPressed ? 'bg-blue-600' : 'bg-blue-500'
  }
>
  Press me
</Button>

// Dynamic content
<Button>
  {({ isHovered, isPressed }) => (
    <>
      <Icon
        icon="hugeicons:heart"
        className={isPressed ? 'text-red-500' : 'text-neutral-400'}
      />
      <span className={isHovered ? 'underline' : ''}>
        Like
      </span>
    </>
  )}
</Button>

BEM Classes

Namespace UIKit uses BEM methodology for consistent class naming:

/* Block */
.button {
}
.accordion {
}

/* Element */
.accordion__trigger {
}
.accordion__panel {
}

/* Modifier */
.button--primary {
}
.button--lg {
}
.accordion--outline {
}

Customizing components globally:

/* global.css */

@layer components {
  /* Override button styles */
  .button {
    @apply font-semibold uppercase;
  }

  .button--primary {
    @apply bg-indigo-600 hover:bg-indigo-700;
  }

  /* Add custom variant */
  .button--gradient {
    @apply bg-gradient-to-r from-purple-500 to-pink-500;
  }
}

Creating Wrapper Components

Create reusable custom components using tailwind-variants—a Tailwind CSS first-class variant API:

import { Button as HeroButton, type ButtonProps } from "@thenamespace/uikit";
import {
  buttonVariants,
  tv,
  type VariantProps,
} from "@thenamespace/uikit/styles";

const customButtonVariants = tv({
  extend: buttonVariants,
  base: "font-medium transition-all",
  variants: {
    intent: {
      primary: "bg-blue-500 hover:bg-blue-600 text-white",
      secondary: "bg-gray-200 hover:bg-gray-300",
      danger: "bg-red-500 hover:bg-red-600 text-white",
    },
    size: {
      small: "text-sm px-2 py-1",
      medium: "text-base px-4 py-2",
      large: "text-lg px-6 py-3",
    },
  },
  defaultVariants: {
    intent: "primary",
    size: "medium",
  },
});

type CustomButtonVariants = VariantProps<typeof customButtonVariants>;
interface CustomButtonProps
  extends Omit<ButtonProps, "className">, CustomButtonVariants {
  className?: string;
}

export function CustomButton({
  intent,
  size,
  className,
  ...props
}: CustomButtonProps) {
  return (
    <HeroButton
      className={customButtonVariants({ intent, size, className })}
      {...props}
    />
  );
}

CSS-in-JS Integration

Styled Components:

import styled from "styled-components";
import { Button } from "@thenamespace/uikit";

const StyledButton = styled(Button)`
  background: linear-gradient(45deg, #fe6b8b 30%, #ff8e53 90%);
  border-radius: 8px;
  color: white;
  padding: 12px 24px;

  &:hover {
    box-shadow: 0 3px 10px rgba(255, 105, 135, 0.3);
  }
`;

Emotion:

import { css } from "@emotion/css";
import { Button } from "@thenamespace/uikit";

const buttonStyles = css`
  background: linear-gradient(45deg, #fe6b8b 30%, #ff8e53 90%);
  border-radius: 8px;
  color: white;
  padding: 12px 24px;

  &:hover {
    box-shadow: 0 3px 10px rgba(255, 105, 135, 0.3);
  }
`;

<Button className={buttonStyles}>Emotion Button</Button>;

Responsive Design

Using Tailwind utilities:

<Button className="text-sm md:text-base lg:text-lg px-3 md:px-4 lg:px-6">
  Responsive Button
</Button>

Or with CSS:

.button {
  font-size: 0.875rem;
  padding: 0.5rem 1rem;
}

@media (min-width: 768px) {
  .button {
    font-size: 1rem;
    padding: 0.75rem 1.5rem;
  }
}

CSS Modules

For scoped styles, use CSS Modules:

/* Button.module.css */
.button {
  background: linear-gradient(135deg, #667eea, #764ba2);
  color: white;
  padding: 12px 24px;
  border-radius: 8px;
}

.button:hover {
  transform: translateY(-2px);
}

.button--primary {
  background: linear-gradient(135deg, #667eea, #764ba2);
  color: white;
  padding: 12px 24px;
  border-radius: 8px;
}
import styles from "./Button.module.css";
import { Button } from "@thenamespace/uikit";

<Button className={styles.button}>Scoped Button</Button>;

Component Classes Reference

Button: .button, .button--{variant}, .button--{size}, .button--icon-only Accordion: .accordion, .accordion__item, .accordion__trigger, .accordion__panel, .accordion--outline

Note: See component docs for complete class references: Button, Accordion

View all component classes in @thenamespace/uikit/styles/components.

Next Steps