Skip to content

Conversation

@msaktype
Copy link
Owner

What

an optional way to generate part-specific Tailwind class strings (e.g. icon, label) alongside the existing className / style output.

The goal is to better support multi-part components (shadcn/ui-style patterns) while keeping WindCtrl’s core mental model intact: variants and traits describe component state, and that state can naturally affect both the root and any slots.

Why

WindCtrl already provides a strong model for state-driven styling through:

  • Variants for mutually exclusive design choices
  • Traits for stackable, boolean-like states

This works well for single-root components, but real-world component libraries (e.g. shadcn/ui-style patterns) often consist of multiple visual parts such as a root element, icons, labels, etc.

Without first-class slot support, users are forced to either:

  • duplicate logic across multiple windctrl() instances, or
  • manually compose class strings for sub-elements, losing the benefits of variants and traits.

Slots are introduced to solve this by allowing variants and traits to express how a given state affects both the root and specific component parts, while preserving WindCtrl’s state-first mental model.

Example

const button = windctrl({
  base: { root: "inline-flex items-center", slots: { icon: "shrink-0" } },
  variants: {
    size: {
      sm: { root: "h-8", slots: { icon: "h-3 w-3" } },
      md: { root: "h-10", slots: { icon: "h-4 w-4" } },
    },
  },
  traits: {
    loading: { root: "opacity-70", slots: { icon: "animate-spin" } },
  },
});

const s = button({ size: "sm", traits: ["loading"] });
// s.className -> "... h-8 opacity-70"
// s.slots.icon -> "shrink-0 h-3 w-3 animate-spin"

className: string;
style?: CSSProperties;
slots?: Record<string, string>;
slots?: Partial<Record<TSlotKeys, string>>;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this too strict? 🤔
we can avoid typo perfectly but the slot name will be static

@msaktype msaktype changed the base branch from main to dev December 23, 2025 01:05
@msaktype msaktype marked this pull request as ready for review December 23, 2025 02:54
@msaktype msaktype merged commit 770d72d into dev Dec 23, 2025
@msaktype msaktype deleted the feat-slot branch December 23, 2025 02:54
@msaktype msaktype mentioned this pull request Dec 23, 2025
Merged
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants