gluestack-ui-v4:variants — community gluestack-ui-v4:variants, native_threads, community, ide skills, Claude Code, Cursor, Windsurf

v1.0.0
GitHub

About this Skill

Ideal for Frontend Agents requiring customizable UI component styling with type safety gluestack-ui-v4:variants is a sub-skill for creating custom variants of gluestack-ui v4 components, extending the design system with project-specific styling patterns.

Features

Creates custom variants for existing gluestack-ui v4 components
Extends the design system with project-specific styling patterns
Maintains consistency and type safety
Supports repeating the same style combination across multiple places
Enables project-specific design patterns, such as brand-specific button styles
bogajoss bogajoss
[0]
[0]
Updated: 3/8/2026

Agent Capability Analysis

The gluestack-ui-v4:variants skill by bogajoss is an open-source community AI agent skill for Claude Code and other IDE workflows, helping agents execute tasks with better context, repeatability, and domain-specific guidance.

Ideal Agent Persona

Ideal for Frontend Agents requiring customizable UI component styling with type safety

Core Value

Empowers agents to create custom variants for existing gluestack-ui v4 components, maintaining consistency and type safety through project-specific styling patterns, utilizing className patterns and brand-specific design elements like button styles and card types

Capabilities Granted for gluestack-ui-v4:variants

Creating project-specific button styles with custom variants
Extending the design system with reusable card type components
Maintaining consistency across multiple UI components with custom className patterns

! Prerequisites & Limits

  • Requires gluestack-ui v4 components
  • Limited to project-specific styling patterns
Labs Demo

Browser Sandbox Environment

⚡️ Ready to unleash?

Experience this Agent in a zero-setup browser environment powered by WebContainers. No installation required.

Boot Container Sandbox

gluestack-ui-v4:variants

Install gluestack-ui-v4:variants, an AI agent skill for AI agent workflows and automation. Works with Claude Code, Cursor, and Windsurf with one-command...

SKILL.md
Readonly

Gluestack UI v4 - Creating Component Variants

This sub-skill focuses on creating custom variants for existing gluestack-ui v4 components, allowing you to extend the design system with project-specific styling patterns while maintaining consistency and type safety.

When to Create a Variant

Create a new variant when:

  1. Repeating the same style combination - Multiple places use the same className pattern
  2. Project-specific design patterns - Brand-specific button styles, card types, etc.
  3. Conditional styling - Component appearance changes based on props
  4. Extending existing components - Adding new visual styles to Gluestack components
  5. Theme-specific variations - Different appearances for specific contexts

Don't create variants for:

  • One-off custom styles (use className instead)
  • Simple modifications (use existing props + className)
  • Styles that should be in the global design system

Variant Creation Workflow

Step 1: Analyze the Component

Before creating a variant, understand:

  1. What's the base component? - Button, Card, Badge, etc.
  2. What visual states are needed? - Colors, sizes, borders, shadows
  3. Are there sub-components? - ButtonText, CardHeader, etc.
  4. What props should control variants? - variant, size, state props
  5. Should variants affect children? - Parent variants for sub-components

Step 2: Plan Variant Structure

Define your variant system:

tsx
1// Example: Planning a Badge component with variants 2{ 3 variant: ['default', 'success', 'warning', 'error', 'info'] 4 size: ['sm', 'md', 'lg'] 5 shape: ['rounded', 'pill', 'square'] 6}

Step 3: Implement with tva

Use tva (Tailwind Variant Authority) to create type-safe, composable variants.

Creating Simple Variants

Template: Adding Variants to a Custom Component

tsx
1import React from 'react'; 2import { tva } from '@gluestack-ui/utils/nativewind-utils'; 3import { Box } from '@/components/ui/box'; 4import { Text } from '@/components/ui/text'; 5 6interface BadgeProps { 7 readonly variant?: 'default' | 'success' | 'warning' | 'error' | 'info'; 8 readonly size?: 'sm' | 'md' | 'lg'; 9 readonly shape?: 'rounded' | 'pill' | 'square'; 10 readonly className?: string; 11 readonly children: React.ReactNode; 12} 13 14// Define variant styles 15const badgeStyles = tva({ 16 base: 'inline-flex items-center justify-center font-medium', 17 variants: { 18 variant: { 19 default: 'bg-muted text-muted-foreground', 20 success: 'bg-primary/10 text-primary border border-primary/20', 21 warning: 'bg-accent/10 text-accent-foreground border border-accent/20', 22 error: 'bg-destructive/10 text-destructive border border-destructive/20', 23 info: 'bg-secondary/10 text-secondary-foreground border border-secondary/20', 24 }, 25 size: { 26 sm: 'px-2 py-0.5 text-xs', 27 md: 'px-3 py-1 text-sm', 28 lg: 'px-4 py-1.5 text-base', 29 }, 30 shape: { 31 rounded: 'rounded-md', 32 pill: 'rounded-full', 33 square: 'rounded-none', 34 }, 35 }, 36 defaultVariants: { 37 variant: 'default', 38 size: 'md', 39 shape: 'rounded', 40 }, 41}); 42 43export const Badge = ({ 44 variant, 45 size, 46 shape, 47 className, 48 children 49}: BadgeProps) => { 50 return ( 51 <Box className={badgeStyles({ variant, size, shape, class: className })}> 52 <Text>{children}</Text> 53 </Box> 54 ); 55}; 56 57// Usage: 58// <Badge variant="success" size="lg" shape="pill">Active</Badge> 59// <Badge variant="error" size="sm">Error</Badge>

Key Points:

  • ✅ Uses tva for variant management
  • ✅ Base styles apply to all variants
  • ✅ Multiple variant dimensions (variant, size, shape)
  • ✅ Default variants specified
  • ✅ className override support with class parameter
  • ✅ TypeScript types for variant options

Extending Existing Gluestack Components

Template: Adding Custom Variants to Button

tsx
1import React from 'react'; 2import { tva } from '@gluestack-ui/utils/nativewind-utils'; 3import { Button as GluestackButton, ButtonText } from '@/components/ui/button'; 4 5// Define additional variant styles 6const customButtonStyles = tva({ 7 base: '', 8 variants: { 9 variant: { 10 // Extend existing variants with new ones 11 gradient: 'bg-gradient-to-r from-primary to-accent', 12 glass: 'bg-background/20 backdrop-blur-lg border border-border/50', 13 neon: 'bg-transparent border-2 border-primary shadow-[0_0_15px_rgba(59,130,246,0.5)]', 14 }, 15 size: { 16 // Add custom sizes 17 xs: 'px-2 py-1', 18 xl: 'px-8 py-4', 19 }, 20 }, 21}); 22 23interface CustomButtonProps { 24 readonly variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link' | 'gradient' | 'glass' | 'neon'; 25 readonly size?: 'default' | 'sm' | 'lg' | 'icon' | 'xs' | 'xl'; 26 readonly className?: string; 27 readonly onPress?: () => void; 28 readonly isDisabled?: boolean; 29 readonly children: React.ReactNode; 30} 31 32export const CustomButton = ({ 33 variant = 'default', 34 size = 'default', 35 className, 36 onPress, 37 isDisabled, 38 children, 39}: CustomButtonProps) => { 40 // Use Gluestack Button for built-in variants 41 if (['default', 'destructive', 'outline', 'secondary', 'ghost', 'link'].includes(variant)) { 42 return ( 43 <GluestackButton 44 variant={variant as any} 45 size={['default', 'sm', 'lg', 'icon'].includes(size) ? size as any : 'default'} 46 onPress={onPress} 47 isDisabled={isDisabled} 48 className={className} 49 > 50 {children} 51 </GluestackButton> 52 ); 53 } 54 55 // Use custom variants 56 return ( 57 <GluestackButton 58 onPress={onPress} 59 isDisabled={isDisabled} 60 className={customButtonStyles({ variant: variant as any, size: size as any, class: className })} 61 > 62 {children} 63 </GluestackButton> 64 ); 65}; 66 67// Usage: 68// <CustomButton variant="gradient" size="xl"> 69// <ButtonText>Gradient Button</ButtonText> 70// </CustomButton> 71// 72// <CustomButton variant="neon" size="lg"> 73// <ButtonText>Neon Button</ButtonText> 74// </CustomButton>

Key Points:

  • ✅ Extends existing component
  • ✅ Preserves original variants
  • ✅ Adds new custom variants
  • ✅ Maintains compound component pattern
  • ✅ Type-safe variant options

Parent-Child Variant Relationships

When creating components with sub-components, use parentVariants to style children based on parent state.

Template: Card with Variant-Aware Children

tsx
1import React from 'react'; 2import { tva } from '@gluestack-ui/utils/nativewind-utils'; 3import { Box } from '@/components/ui/box'; 4import { Heading } from '@/components/ui/heading'; 5import { Text } from '@/components/ui/text'; 6 7interface CardProps { 8 readonly variant?: 'default' | 'elevated' | 'outlined' | 'ghost'; 9 readonly colorScheme?: 'neutral' | 'primary' | 'success' | 'error'; 10 readonly className?: string; 11 readonly children: React.ReactNode; 12} 13 14interface CardHeaderProps { 15 readonly className?: string; 16 readonly children: React.ReactNode; 17} 18 19interface CardBodyProps { 20 readonly className?: string; 21 readonly children: React.ReactNode; 22} 23 24// Parent card styles 25const cardStyles = tva({ 26 base: 'rounded-lg overflow-hidden', 27 variants: { 28 variant: { 29 default: 'border border-border bg-card', 30 elevated: 'shadow-hard-2 bg-card', 31 outlined: 'border-2 border-border bg-transparent', 32 ghost: 'bg-transparent', 33 }, 34 colorScheme: { 35 neutral: '', 36 primary: 'border-primary/20', 37 success: 'border-primary/20', 38 error: 'border-destructive/20', 39 }, 40 }, 41 compoundVariants: [ 42 { 43 variant: 'default', 44 colorScheme: 'primary', 45 class: 'bg-primary/5', 46 }, 47 { 48 variant: 'default', 49 colorScheme: 'success', 50 class: 'bg-primary/5', 51 }, 52 { 53 variant: 'default', 54 colorScheme: 'error', 55 class: 'bg-destructive/5', 56 }, 57 ], 58 defaultVariants: { 59 variant: 'default', 60 colorScheme: 'neutral', 61 }, 62}); 63 64// Child styles that respond to parent variants 65const cardHeaderStyles = tva({ 66 base: 'p-4 border-b', 67 parentVariants: { 68 variant: { 69 default: 'border-border', 70 elevated: 'border-border/50', 71 outlined: 'border-border', 72 ghost: 'border-transparent', 73 }, 74 colorScheme: { 75 neutral: '', 76 primary: 'border-primary/20 bg-primary/5', 77 success: 'border-primary/20 bg-primary/5', 78 error: 'border-destructive/20 bg-destructive/5', 79 }, 80 }, 81}); 82 83const cardBodyStyles = tva({ 84 base: 'p-4', 85 parentVariants: { 86 colorScheme: { 87 neutral: '', 88 primary: '', 89 success: '', 90 error: '', 91 }, 92 }, 93}); 94 95// Context to share variant state with children 96const CardContext = React.createContext<Pick<CardProps, 'variant' | 'colorScheme'>>({ 97 variant: 'default', 98 colorScheme: 'neutral', 99}); 100 101export const Card = ({ 102 variant = 'default', 103 colorScheme = 'neutral', 104 className, 105 children 106}: CardProps) => { 107 return ( 108 <CardContext.Provider value={{ variant, colorScheme }}> 109 <Box className={cardStyles({ variant, colorScheme, class: className })}> 110 {children} 111 </Box> 112 </CardContext.Provider> 113 ); 114}; 115 116export const CardHeader = ({ className, children }: CardHeaderProps) => { 117 const { variant, colorScheme } = React.useContext(CardContext); 118 return ( 119 <Box className={cardHeaderStyles({ parentVariants: { variant, colorScheme }, class: className })}> 120 {children} 121 </Box> 122 ); 123}; 124 125export const CardBody = ({ className, children }: CardBodyProps) => { 126 const { variant, colorScheme } = React.useContext(CardContext); 127 return ( 128 <Box className={cardBodyStyles({ parentVariants: { colorScheme }, class: className })}> 129 {children} 130 </Box> 131 ); 132}; 133 134// Usage: 135// <Card variant="elevated" colorScheme="primary"> 136// <CardHeader> 137// <Heading size="lg">Success Card</Heading> 138// </CardHeader> 139// <CardBody> 140// <Text>This card responds to parent variants</Text> 141// </CardBody> 142// </Card>

Key Points:

  • ✅ Parent context shares variant state
  • ✅ Children use parentVariants to style based on parent
  • ✅ Compound variants for complex combinations
  • ✅ Type-safe context usage
  • ✅ Flexible composition

Compound Variants

Use compound variants when combinations of variant options need special styling.

Template: Button with Compound Variants

tsx
1import React from 'react'; 2import { tva } from '@gluestack-ui/utils/nativewind-utils'; 3import { Button, ButtonText, ButtonIcon } from '@/components/ui/button'; 4import { Loader2Icon } from '@/components/ui/icon'; 5 6interface ActionButtonProps { 7 readonly variant?: 'solid' | 'outline' | 'ghost'; 8 readonly colorScheme?: 'primary' | 'secondary' | 'destructive'; 9 readonly size?: 'sm' | 'md' | 'lg'; 10 readonly isLoading?: boolean; 11 readonly isDisabled?: boolean; 12 readonly className?: string; 13 readonly onPress?: () => void; 14 readonly children: React.ReactNode; 15} 16 17const actionButtonStyles = tva({ 18 base: 'rounded-md font-medium transition-colors', 19 variants: { 20 variant: { 21 solid: '', 22 outline: 'border-2 bg-transparent', 23 ghost: 'bg-transparent', 24 }, 25 colorScheme: { 26 primary: '', 27 secondary: '', 28 destructive: '', 29 }, 30 size: { 31 sm: 'px-3 py-1.5 text-sm', 32 md: 'px-4 py-2 text-base', 33 lg: 'px-6 py-3 text-lg', 34 }, 35 }, 36 compoundVariants: [ 37 // Solid + Primary 38 { 39 variant: 'solid', 40 colorScheme: 'primary', 41 class: 'bg-primary text-primary-foreground data-[hover=true]:bg-primary/90', 42 }, 43 // Solid + Destructive 44 { 45 variant: 'solid', 46 colorScheme: 'destructive', 47 class: 'bg-destructive text-white data-[hover=true]:bg-destructive/90', 48 }, 49 // Outline + Primary 50 { 51 variant: 'outline', 52 colorScheme: 'primary', 53 class: 'border-primary text-primary data-[hover=true]:bg-primary/10', 54 }, 55 // Outline + Destructive 56 { 57 variant: 'outline', 58 colorScheme: 'destructive', 59 class: 'border-destructive text-destructive data-[hover=true]:bg-destructive/10', 60 }, 61 // Ghost + Primary 62 { 63 variant: 'ghost', 64 colorScheme: 'primary', 65 class: 'text-primary data-[hover=true]:bg-primary/10', 66 }, 67 // Ghost + Destructive 68 { 69 variant: 'ghost', 70 colorScheme: 'destructive', 71 class: 'text-destructive data-[hover=true]:bg-destructive/10', 72 }, 73 ], 74 defaultVariants: { 75 variant: 'solid', 76 colorScheme: 'primary', 77 size: 'md', 78 }, 79}); 80 81export const ActionButton = ({ 82 variant, 83 colorScheme, 84 size, 85 isLoading = false, 86 isDisabled = false, 87 className, 88 onPress, 89 children, 90}: ActionButtonProps) => { 91 return ( 92 <Button 93 onPress={onPress} 94 isDisabled={isDisabled || isLoading} 95 className={actionButtonStyles({ variant, colorScheme, size, class: className })} 96 > 97 {isLoading && <ButtonIcon as={Loader2Icon} className="animate-spin" />} 98 {children} 99 </Button> 100 ); 101}; 102 103// Usage: 104// <ActionButton variant="solid" colorScheme="primary" size="lg"> 105// <ButtonText>Primary Action</ButtonText> 106// </ActionButton> 107// 108// <ActionButton variant="outline" colorScheme="destructive" isLoading> 109// <ButtonText>Delete</ButtonText> 110// </ActionButton>

Key Points:

  • ✅ Compound variants handle specific combinations
  • ✅ Base variants provide defaults
  • ✅ Hover states with data attributes
  • ✅ Loading state integration
  • ✅ Flexible variant combinations

Common Variant Patterns

Pattern 1: Status Badges

tsx
1const statusBadgeStyles = tva({ 2 base: 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold', 3 variants: { 4 status: { 5 active: 'bg-primary/10 text-primary', 6 inactive: 'bg-muted text-muted-foreground', 7 pending: 'bg-accent/10 text-accent-foreground', 8 completed: 'bg-primary/10 text-primary', 9 failed: 'bg-destructive/10 text-destructive', 10 }, 11 }, 12 defaultVariants: { 13 status: 'inactive', 14 }, 15}); 16 17// Usage: 18// <Box className={statusBadgeStyles({ status: 'active' })}> 19// <Text>Active</Text> 20// </Box>

Pattern 2: Alert Variants

tsx
1const alertStyles = tva({ 2 base: 'rounded-lg border p-4', 3 variants: { 4 severity: { 5 info: 'bg-secondary/10 border-secondary/20 text-secondary-foreground', 6 success: 'bg-primary/10 border-primary/20 text-primary', 7 warning: 'bg-accent/10 border-accent/20 text-accent-foreground', 8 error: 'bg-destructive/10 border-destructive/20 text-destructive', 9 }, 10 }, 11 defaultVariants: { 12 severity: 'info', 13 }, 14}); 15 16// Usage: 17// <Box className={alertStyles({ severity: 'error' })}> 18// <Text>Error message</Text> 19// </Box>

Pattern 3: Interactive Card States

tsx
1const interactiveCardStyles = tva({ 2 base: 'rounded-lg border border-border p-4 transition-all cursor-pointer', 3 variants: { 4 state: { 5 default: 'bg-card data-[hover=true]:bg-muted/50', 6 selected: 'bg-primary/10 border-primary', 7 disabled: 'bg-muted opacity-60 cursor-not-allowed', 8 }, 9 }, 10 defaultVariants: { 11 state: 'default', 12 }, 13}); 14 15// Usage: 16// <Pressable> 17// <Box className={interactiveCardStyles({ state: 'selected' })}> 18// <Text>Selected Card</Text> 19// </Box> 20// </Pressable>

Pattern 4: Size Variants with Consistent Ratios

tsx
1const avatarStyles = tva({ 2 base: 'rounded-full overflow-hidden', 3 variants: { 4 size: { 5 xs: 'w-6 h-6', 6 sm: 'w-8 h-8', 7 md: 'w-12 h-12', 8 lg: 'w-16 h-16', 9 xl: 'w-20 h-20', 10 '2xl': 'w-24 h-24', 11 }, 12 }, 13 defaultVariants: { 14 size: 'md', 15 }, 16}); 17 18// Usage: 19// <Image className={avatarStyles({ size: 'lg' })} source={{ uri: avatarUrl }} />

Best Practices for Variants

✅ Do's

  1. Use semantic variant names

    tsx
    1// ✅ GOOD: Semantic names 2variant: 'primary' | 'secondary' | 'destructive' 3 4// ❌ BAD: Generic names 5variant: 'blue' | 'red' | 'green'
  2. Provide default variants

    tsx
    1// ✅ GOOD: Always specify defaults 2defaultVariants: { 3 variant: 'default', 4 size: 'md', 5}
  3. Use compound variants for combinations

    tsx
    1// ✅ GOOD: Handle specific combinations 2compoundVariants: [ 3 { 4 variant: 'outline', 5 colorScheme: 'primary', 6 class: 'border-primary text-primary', 7 }, 8]
  4. Keep variant dimensions focused

    tsx
    1// ✅ GOOD: Clear separation 2variants: { 3 variant: { ... }, // Visual style 4 size: { ... }, // Size 5 state: { ... }, // Interactive state 6}
  5. Use ONLY semantic tokens in variant styles - NO EXCEPTIONS

    tsx
    1// ✅ CORRECT: Semantic tokens with alpha values 2success: 'bg-primary/10 text-primary border-primary/20' 3error: 'bg-destructive/10 text-destructive border-destructive/20' 4muted: 'bg-muted text-muted-foreground border-border' 5 6// ❌ PROHIBITED: Numbered color tokens 7success: 'bg-green-100 text-green-800 border-green-200' 8error: 'bg-red-100 text-red-800 border-red-200' 9 10// ❌ PROHIBITED: Generic tokens 11muted: 'bg-neutral-100 text-neutral-600 border-neutral-300' 12muted: 'bg-gray-100 text-gray-600 border-gray-300' 13 14// ❌ PROHIBITED: Typography tokens 15text: 'text-typography-900'

❌ Don'ts

  1. Don't create too many variant dimensions

    tsx
    1// ❌ BAD: Too many dimensions 2variants: { 3 variant: { ... }, 4 size: { ... }, 5 color: { ... }, 6 border: { ... }, 7 shadow: { ... }, 8 rounded: { ... }, 9} 10 11// ✅ GOOD: Focused dimensions 12variants: { 13 variant: { ... }, 14 size: { ... }, 15}
  2. Don't mix concerns in variant names

    tsx
    1// ❌ BAD: Mixing visual and semantic 2variant: 'primary' | 'large-primary' | 'small-secondary' 3 4// ✅ GOOD: Separate dimensions 5variant: 'primary' | 'secondary' 6size: 'sm' | 'md' | 'lg'
  3. Don't duplicate existing component props

    tsx
    1// ❌ BAD: Duplicating Button's variant prop 2const CustomButton = ({ variant, ... }: { variant: 'new1' | 'new2' }) 3 4// ✅ GOOD: Extend existing variants 5const CustomButton = ({ variant, ... }: { 6 variant: 'default' | 'outline' | 'new1' | 'new2' 7})

CRITICAL: Semantic Tokens in Variants

ALL variant styles MUST use ONLY semantic tokens. This is NON-NEGOTIABLE.

Correct Variant Token Usage

tsx
1// ✅ CORRECT: All colors are semantic tokens 2const badgeStyles = tva({ 3 base: 'inline-flex items-center rounded-full px-3 py-1', 4 variants: { 5 variant: { 6 default: 'bg-muted text-muted-foreground', 7 primary: 'bg-primary/10 text-primary border border-primary/20', 8 success: 'bg-primary/10 text-primary border border-primary/20', 9 error: 'bg-destructive/10 text-destructive border border-destructive/20', 10 warning: 'bg-accent/10 text-accent-foreground border border-accent/20', 11 }, 12 }, 13});

Prohibited Variant Token Usage

tsx
1// ❌ PROHIBITED: Using numbered color tokens 2const badgeStyles = tva({ 3 variants: { 4 variant: { 5 success: 'bg-green-100 text-green-800 border-green-200', // ❌ NO 6 error: 'bg-red-100 text-red-800 border-red-200', // ❌ NO 7 warning: 'bg-yellow-100 text-yellow-800', // ❌ NO 8 }, 9 }, 10}); 11 12// ❌ PROHIBITED: Using generic tokens 13const badgeStyles = tva({ 14 variants: { 15 variant: { 16 default: 'bg-neutral-100 text-neutral-700', // ❌ NO 17 muted: 'bg-gray-100 text-gray-600', // ❌ NO 18 }, 19 }, 20}); 21 22// ❌ PROHIBITED: Using typography tokens 23const textStyles = tva({ 24 variants: { 25 variant: { 26 heading: 'text-typography-900', // ❌ NO 27 body: 'text-typography-700', // ❌ NO 28 }, 29 }, 30});

Token Replacement Guide for Variants

Prohibited PatternUse Instead
bg-green-100 text-green-800bg-primary/10 text-primary
bg-red-100 text-red-800bg-destructive/10 text-destructive
bg-yellow-100 text-yellow-800bg-accent/10 text-accent-foreground
bg-blue-100 text-blue-800bg-primary/10 text-primary
bg-neutral-100 text-neutral-700bg-muted text-muted-foreground
bg-gray-100 text-gray-900bg-muted text-foreground
text-typography-900text-foreground
text-typography-600text-muted-foreground
border-gray-300border-border

Validation Checklist for Variants

When creating variants, verify:

  • CRITICAL: NO prohibited tokens - No typography-*, neutral-*, gray-*, slate-*, numbered colors
  • All colors are semantic tokens - Every color uses semantic tokens from the approved list
  • Alpha values instead of opacity - Uses /70, /90 instead of opacity-* utilities
  • Variant names are semantic (not color names)
  • Default variants specified
  • Spacing uses scale values (no arbitrary values)
  • TypeScript types match variant options
  • className override supported with class parameter
  • Parent variants used for child components (if applicable)
  • Compound variants for complex combinations (if needed)
  • Data attributes for interactive states
  • Tested with dark mode (semantic tokens ensure compatibility)
  • Documentation/comments for non-obvious variants

Recipe: Converting Repeated Styles to Variants

Before: Repeated className Patterns

tsx
1// ❌ Repeated patterns across codebase 2<Box className="bg-primary/10 border border-primary/20 rounded-full px-3 py-1"> 3 <Text className="text-xs text-primary font-semibold">Active</Text> 4</Box> 5 6<Box className="bg-destructive/10 border border-destructive/20 rounded-full px-3 py-1"> 7 <Text className="text-xs text-destructive font-semibold">Error</Text> 8</Box> 9 10<Box className="bg-accent/10 border border-accent/20 rounded-full px-3 py-1"> 11 <Text className="text-xs text-accent-foreground font-semibold">Pending</Text> 12</Box>

After: Variant-Based Component

tsx
1// ✅ GOOD: Single component with variants 2const StatusPill = ({ status, children }: StatusPillProps) => { 3 const pillStyles = tva({ 4 base: 'inline-flex items-center rounded-full px-3 py-1', 5 variants: { 6 status: { 7 active: 'bg-primary/10 border border-primary/20', 8 error: 'bg-destructive/10 border border-destructive/20', 9 pending: 'bg-accent/10 border border-accent/20', 10 }, 11 }, 12 }); 13 14 const textStyles = tva({ 15 base: 'text-xs font-semibold', 16 parentVariants: { 17 status: { 18 active: 'text-primary', 19 error: 'text-destructive', 20 pending: 'text-accent-foreground', 21 }, 22 }, 23 }); 24 25 return ( 26 <Box className={pillStyles({ status })}> 27 <Text className={textStyles({ parentVariants: { status } })}>{children}</Text> 28 </Box> 29 ); 30}; 31 32// Usage: 33<StatusPill status="active">Active</StatusPill> 34<StatusPill status="error">Error</StatusPill> 35<StatusPill status="pending">Pending</StatusPill>

Troubleshooting

Issue: Variants Not Applying

Problem: Variant classes not showing up

Solution:

  1. Check Tailwind config includes tva patterns
  2. Verify className merge order
  3. Ensure no conflicting inline styles

Issue: Parent Variants Not Working

Problem: Child components don't respond to parent variants

Solution:

  1. Use context to share parent state
  2. Pass parentVariants object correctly
  3. Verify context provider wraps children

Issue: Type Errors with Variants

Problem: TypeScript errors with variant options

Solution:

  1. Define variant types in interface
  2. Use literal types for variant values
  3. Ensure defaultVariants match types

Reference

FAQ & Installation Steps

These questions and steps mirror the structured data on this page for better search understanding.

? Frequently Asked Questions

What is gluestack-ui-v4:variants?

Ideal for Frontend Agents requiring customizable UI component styling with type safety gluestack-ui-v4:variants is a sub-skill for creating custom variants of gluestack-ui v4 components, extending the design system with project-specific styling patterns.

How do I install gluestack-ui-v4:variants?

Run the command: npx killer-skills add bogajoss/native_threads. It works with Cursor, Windsurf, VS Code, Claude Code, and 19+ other IDEs.

What are the use cases for gluestack-ui-v4:variants?

Key use cases include: Creating project-specific button styles with custom variants, Extending the design system with reusable card type components, Maintaining consistency across multiple UI components with custom className patterns.

Which IDEs are compatible with gluestack-ui-v4:variants?

This skill is compatible with Cursor, Windsurf, VS Code, Trae, Claude Code, OpenClaw, Aider, Codex, OpenCode, Goose, Cline, Roo Code, Kiro, Augment Code, Continue, GitHub Copilot, Sourcegraph Cody, and Amazon Q Developer. Use the Killer-Skills CLI for universal one-command installation.

Are there any limitations for gluestack-ui-v4:variants?

Requires gluestack-ui v4 components. Limited to project-specific styling patterns.

How To Install

  1. 1. Open your terminal

    Open the terminal or command line in your project directory.

  2. 2. Run the install command

    Run: npx killer-skills add bogajoss/native_threads. The CLI will automatically detect your IDE or AI agent and configure the skill.

  3. 3. Start using the skill

    The skill is now active. Your AI agent can use gluestack-ui-v4:variants immediately in the current project.

Related Skills

Looking for an alternative to gluestack-ui-v4:variants or another community skill for your workflow? Explore these related open-source skills.

View All

widget-generator

Logo of f
f

f.k.a. Awesome ChatGPT Prompts. Share, discover, and collect prompts from the community. Free and open source — self-host for your organization with complete privacy.

149.6k
0
AI

flags

Logo of vercel
vercel

flags is a Next.js feature management skill that enables developers to efficiently add or modify framework feature flags, streamlining React application development.

138.4k
0
Browser

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
AI

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
AI