or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-api.mdindex.mdlite-mode.mdutilities.md

core-api.mddocs/

0

# Core Variant API

1

2

The core variant API provides the main functionality for creating styled components with variants, slots, compound variants, and default values. This is the primary interface for building reusable component styles.

3

4

## Main Functions

5

6

### tv

7

8

The primary function for creating variant-enabled styled components.

9

10

```typescript { .api }

11

const tv: TV;

12

```

13

14

The tv function accepts a configuration object and returns a styled component function that can be called with variant props to generate class names.

15

16

### createTV

17

18

Creates a custom tv instance with specific configuration.

19

20

```typescript { .api }

21

function createTV(config: TVConfig): TV;

22

```

23

24

**Parameters:**

25

- `config` - Configuration object for tailwind-merge integration

26

27

**Returns:** A tv function instance with the specified configuration

28

29

## TV Configuration Options

30

31

The tv function accepts a configuration object with the following options:

32

33

```typescript { .api }

34

interface TVOptions<V, S, B, EV, ES> {

35

extend?: TVReturnType;

36

base?: B;

37

slots?: S;

38

variants?: V;

39

compoundVariants?: TVCompoundVariants<V, S, B, EV, ES>[];

40

compoundSlots?: TVCompoundSlots<V, S, B>[];

41

defaultVariants?: TVDefaultVariants<V, S, EV, ES>;

42

}

43

```

44

45

### base

46

47

Base classes applied to all variants of the component.

48

49

```typescript

50

const button = tv({

51

base: "font-medium rounded-lg transition-colors focus:outline-none focus:ring-2"

52

});

53

```

54

55

### variants

56

57

Named variant groups with their corresponding classes.

58

59

```typescript

60

const button = tv({

61

base: "font-medium rounded-lg",

62

variants: {

63

color: {

64

primary: "bg-blue-500 text-white hover:bg-blue-600",

65

secondary: "bg-gray-500 text-white hover:bg-gray-600",

66

danger: "bg-red-500 text-white hover:bg-red-600",

67

},

68

size: {

69

sm: "px-3 py-1.5 text-sm",

70

md: "px-4 py-2 text-base",

71

lg: "px-6 py-3 text-lg",

72

},

73

disabled: {

74

true: "opacity-50 cursor-not-allowed",

75

false: "cursor-pointer",

76

},

77

},

78

});

79

```

80

81

### slots

82

83

Named component parts that can each have their own styling variants.

84

85

```typescript

86

const card = tv({

87

slots: {

88

base: "rounded-lg border shadow-sm",

89

header: "px-6 py-4 border-b",

90

body: "px-6 py-4",

91

footer: "px-6 py-4 border-t bg-gray-50",

92

},

93

variants: {

94

size: {

95

sm: {

96

base: "max-w-sm",

97

header: "px-4 py-2 text-sm",

98

body: "px-4 py-2 text-sm",

99

footer: "px-4 py-2 text-sm",

100

},

101

lg: {

102

base: "max-w-4xl",

103

header: "px-8 py-6 text-xl",

104

body: "px-8 py-6",

105

footer: "px-8 py-6",

106

},

107

},

108

},

109

});

110

111

// Usage with slots

112

const { base, header, body, footer } = card({ size: "lg" });

113

```

114

115

### compoundVariants

116

117

Conditional styles applied when specific variant combinations are active.

118

119

```typescript

120

const button = tv({

121

base: "font-medium rounded-lg",

122

variants: {

123

color: {

124

primary: "bg-blue-500 text-white",

125

secondary: "bg-gray-500 text-white",

126

},

127

size: {

128

sm: "px-3 py-1.5 text-sm",

129

lg: "px-6 py-3 text-lg",

130

},

131

},

132

compoundVariants: [

133

{

134

color: "primary",

135

size: "lg",

136

class: "shadow-lg shadow-blue-500/25",

137

},

138

{

139

color: ["primary", "secondary"],

140

size: "sm",

141

class: "font-semibold",

142

},

143

],

144

});

145

```

146

147

### compoundSlots

148

149

Conditional slot styles applied when specific variant combinations are active.

150

151

```typescript

152

const card = tv({

153

slots: {

154

base: "rounded-lg border",

155

header: "px-6 py-4 border-b",

156

},

157

variants: {

158

color: {

159

primary: { base: "border-blue-200" },

160

danger: { base: "border-red-200" },

161

},

162

},

163

compoundSlots: [

164

{

165

color: "primary",

166

slots: ["header"],

167

class: "bg-blue-50 text-blue-900",

168

},

169

],

170

});

171

```

172

173

### defaultVariants

174

175

Default variant values applied when no specific variants are provided.

176

177

```typescript

178

const button = tv({

179

variants: {

180

color: {

181

primary: "bg-blue-500",

182

secondary: "bg-gray-500",

183

},

184

size: {

185

sm: "text-sm px-3 py-1.5",

186

md: "text-base px-4 py-2",

187

},

188

},

189

defaultVariants: {

190

color: "primary",

191

size: "md",

192

},

193

});

194

195

// Uses default variants (primary, md)

196

const defaultButton = button();

197

```

198

199

### extend

200

201

Compose and extend existing tv components.

202

203

```typescript

204

const baseButton = tv({

205

base: "font-medium rounded-lg",

206

variants: {

207

size: {

208

sm: "px-3 py-1.5 text-sm",

209

md: "px-4 py-2 text-base",

210

},

211

},

212

});

213

214

const iconButton = tv({

215

extend: baseButton,

216

base: "inline-flex items-center gap-2",

217

variants: {

218

iconPosition: {

219

left: "flex-row",

220

right: "flex-row-reverse",

221

},

222

},

223

});

224

```

225

226

## Usage Examples

227

228

### Basic Component

229

230

```typescript

231

const alert = tv({

232

base: "p-4 rounded-md border",

233

variants: {

234

variant: {

235

info: "bg-blue-50 border-blue-200 text-blue-800",

236

success: "bg-green-50 border-green-200 text-green-800",

237

warning: "bg-yellow-50 border-yellow-200 text-yellow-800",

238

error: "bg-red-50 border-red-200 text-red-800",

239

},

240

},

241

defaultVariants: {

242

variant: "info",

243

},

244

});

245

246

// Usage

247

const infoAlert = alert(); // Uses default 'info' variant

248

const errorAlert = alert({ variant: "error" });

249

```

250

251

### Multi-Slot Component

252

253

```typescript

254

const modal = tv({

255

slots: {

256

overlay: "fixed inset-0 bg-black/50 flex items-center justify-center",

257

content: "bg-white rounded-lg shadow-xl max-w-md w-full mx-4",

258

header: "px-6 py-4 border-b border-gray-200",

259

body: "px-6 py-4",

260

footer: "px-6 py-4 border-t border-gray-200 flex justify-end gap-3",

261

},

262

variants: {

263

size: {

264

sm: {

265

content: "max-w-sm",

266

header: "px-4 py-3 text-sm",

267

body: "px-4 py-3 text-sm",

268

footer: "px-4 py-3",

269

},

270

lg: {

271

content: "max-w-2xl",

272

header: "px-8 py-6 text-xl",

273

body: "px-8 py-6",

274

footer: "px-8 py-6",

275

},

276

},

277

},

278

});

279

280

// Usage

281

const { overlay, content, header, body, footer } = modal({ size: "lg" });

282

```

283

284

## Type Definitions

285

286

```typescript { .api }

287

type TVReturnType<V extends TVVariants<S>, S extends TVSlots, B extends ClassValue, EV extends TVVariants<ES>, ES extends TVSlots, E extends TVReturnType = undefined> = {

288

(props?: TVProps<V, S, EV, ES>): HasSlots<S, ES> extends true

289

? {

290

[K in keyof (ES extends undefined ? {} : ES)]: (slotProps?: TVProps<V, S, EV, ES>) => string;

291

} & {

292

[K in keyof (S extends undefined ? {} : S)]: (slotProps?: TVProps<V, S, EV, ES>) => string;

293

} & {

294

[K in TVSlotsWithBase<{}, B>]: (slotProps?: TVProps<V, S, EV, ES>) => string;

295

}

296

: string;

297

} & TVReturnProps<V, S, B, EV, ES, E>;

298

299

type TVProps<V extends TVVariants<S>, S extends TVSlots, EV extends TVVariants<ES>, ES extends TVSlots> =

300

EV extends undefined

301

? V extends undefined

302

? ClassProp<ClassValue>

303

: {

304

[K in keyof V]?: StringToBoolean<keyof V[K]> | undefined;

305

} & ClassProp<ClassValue>

306

: V extends undefined

307

? {

308

[K in keyof EV]?: StringToBoolean<keyof EV[K]> | undefined;

309

} & ClassProp<ClassValue>

310

: {

311

[K in keyof V | keyof EV]?:

312

| (K extends keyof V ? StringToBoolean<keyof V[K]> : never)

313

| (K extends keyof EV ? StringToBoolean<keyof EV[K]> : never)

314

| undefined;

315

} & ClassProp<ClassValue>;

316

317

type TVCompoundVariants<V extends TVVariants<S>, S extends TVSlots, B extends ClassValue, EV extends TVVariants<ES>, ES extends TVSlots> = Array<

318

{

319

[K in keyof V | keyof EV]?:

320

| (K extends keyof V ? StringToBoolean<keyof V[K]> : never)

321

| (K extends keyof EV ? StringToBoolean<keyof EV[K]> : never)

322

| (K extends keyof V ? StringToBoolean<keyof V[K]>[] : never);

323

} & ClassProp<SlotsClassValue<S, B> | ClassValue>

324

>;

325

326

type TVCompoundSlots<V extends TVVariants<S>, S extends TVSlots, B extends ClassValue> = Array<

327

V extends undefined

328

? {

329

slots: Array<TVSlotsWithBase<S, B>>;

330

} & ClassProp

331

: {

332

slots: Array<TVSlotsWithBase<S, B>>;

333

} & {

334

[K in keyof V]?: StringToBoolean<keyof V[K]> | StringToBoolean<keyof V[K]>[];

335

} & ClassProp

336

>;

337

338

type TVDefaultVariants<V extends TVVariants<S>, S extends TVSlots, EV extends TVVariants<ES>, ES extends TVSlots> = {

339

[K in keyof V | keyof EV]?:

340

| (K extends keyof V ? StringToBoolean<keyof V[K]> : never)

341

| (K extends keyof EV ? StringToBoolean<keyof EV[K]> : never);

342

};

343

```