or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-processing.mdcompilation.mdindex.mdplugin-development.mdtheme-system.md

plugin-development.mddocs/

0

# Plugin Development

1

2

Comprehensive plugin system for extending Tailwind CSS with custom utilities, variants, and components. The plugin API provides methods for adding CSS rules, creating parametric utilities, and accessing theme values.

3

4

## Capabilities

5

6

### Plugin Creation

7

8

Creates a Tailwind CSS plugin with a handler function and optional configuration.

9

10

```typescript { .api }

11

/**

12

* Creates a Tailwind CSS plugin

13

* @param handler - Function that receives the plugin API

14

* @param config - Optional configuration to merge with user config

15

* @returns Plugin object for use in Tailwind configuration

16

*/

17

function plugin(handler: PluginFn, config?: Partial<Config>): PluginWithConfig;

18

19

/**

20

* Creates a plugin that accepts options

21

* @param pluginFunction - Function that returns a plugin handler based on options

22

* @param configFunction - Function that returns configuration based on options

23

* @returns Options function that creates configured plugins

24

*/

25

plugin.withOptions<T>(

26

pluginFunction: (options?: T) => PluginFn,

27

configFunction?: (options?: T) => Partial<Config>

28

): PluginWithOptions<T>;

29

30

type PluginFn = (api: PluginAPI) => void;

31

32

interface PluginWithConfig {

33

handler: PluginFn;

34

config?: Config;

35

}

36

37

interface PluginWithOptions<T> {

38

(options?: T): PluginWithConfig;

39

__isOptionsFunction: true;

40

}

41

```

42

43

**Usage Examples:**

44

45

```typescript

46

import plugin from "tailwindcss/plugin";

47

48

// Simple plugin

49

const myPlugin = plugin(function({ addUtilities, theme }) {

50

addUtilities({

51

'.btn': {

52

padding: theme('spacing.4'),

53

borderRadius: theme('borderRadius.md'),

54

fontWeight: theme('fontWeight.semibold'),

55

},

56

'.btn-primary': {

57

backgroundColor: theme('colors.blue.500'),

58

color: theme('colors.white'),

59

},

60

});

61

});

62

63

// Plugin with configuration

64

const buttonPlugin = plugin(function({ addComponents, theme }) {

65

addComponents({

66

'.btn': {

67

padding: `${theme('spacing.2')} ${theme('spacing.4')}`,

68

borderRadius: theme('borderRadius.DEFAULT'),

69

fontWeight: theme('fontWeight.medium'),

70

},

71

});

72

}, {

73

theme: {

74

extend: {

75

colors: {

76

'btn-primary': '#3b82f6',

77

},

78

},

79

},

80

});

81

82

// Plugin with options

83

const spacingPlugin = plugin.withOptions<{ prefix?: string }>(

84

(options = {}) => {

85

return ({ addUtilities }) => {

86

const prefix = options.prefix || '';

87

addUtilities({

88

[`.${prefix}spacing-xs`]: { padding: '0.5rem' },

89

[`.${prefix}spacing-sm`]: { padding: '1rem' },

90

[`.${prefix}spacing-md`]: { padding: '1.5rem' },

91

});

92

};

93

}

94

);

95

```

96

97

### Base Styles

98

99

Add base styles that are applied globally to elements.

100

101

```typescript { .api }

102

/**

103

* Add base styles to the generated CSS

104

* @param base - CSS-in-JS object containing base styles

105

*/

106

addBase(base: CssInJs): void;

107

```

108

109

**Usage Example:**

110

111

```typescript

112

plugin(function({ addBase, theme }) {

113

addBase({

114

'h1': {

115

fontSize: theme('fontSize.4xl'),

116

fontWeight: theme('fontWeight.bold'),

117

},

118

'h2': {

119

fontSize: theme('fontSize.3xl'),

120

fontWeight: theme('fontWeight.semibold'),

121

},

122

});

123

});

124

```

125

126

### Variants

127

128

Add custom variants for conditional styling.

129

130

```typescript { .api }

131

/**

132

* Add a simple variant

133

* @param name - Variant name (e.g., 'hocus')

134

* @param variant - CSS selector(s) or CSS-in-JS object

135

*/

136

addVariant(name: string, variant: string | string[] | CssInJs): void;

137

138

/**

139

* Add a parametric variant that accepts values

140

* @param name - Variant name (e.g., 'data')

141

* @param cb - Callback that generates selectors based on values

142

* @param options - Configuration options for the variant

143

*/

144

matchVariant<T = string>(

145

name: string,

146

cb: (value: T | string, extra: { modifier: string | null }) => string | string[],

147

options?: {

148

values?: Record<string, T>;

149

sort?(

150

a: { value: T | string; modifier: string | null },

151

b: { value: T | string; modifier: string | null }

152

): number;

153

}

154

): void;

155

```

156

157

**Usage Examples:**

158

159

```typescript

160

plugin(function({ addVariant, matchVariant }) {

161

// Simple variant

162

addVariant('hocus', ['&:hover', '&:focus']);

163

164

// Variant with CSS-in-JS

165

addVariant('not-first', {

166

'&:not(:first-child)': {},

167

});

168

169

// Parametric variant

170

matchVariant('data', (value) => `&[data-${value}]`);

171

172

// Parametric variant with predefined values

173

matchVariant('theme', (value) => `[data-theme="${value}"] &`, {

174

values: {

175

light: 'light',

176

dark: 'dark',

177

auto: 'auto',

178

},

179

});

180

181

// Custom sorting

182

matchVariant('min', (value) => `@media (min-width: ${value})`, {

183

sort(a, b) {

184

return parseInt(a.value) - parseInt(b.value);

185

},

186

});

187

});

188

```

189

190

### Utilities

191

192

Add utility classes that can be applied directly to elements.

193

194

```typescript { .api }

195

/**

196

* Add static utility classes

197

* @param utilities - CSS-in-JS object containing utility definitions

198

* @param options - Additional options (currently unused)

199

*/

200

addUtilities(

201

utilities: Record<string, CssInJs | CssInJs[]> | Record<string, CssInJs | CssInJs[]>[],

202

options?: {}

203

): void;

204

205

/**

206

* Add parametric utilities that generate classes based on values

207

* @param utilities - Object mapping utility names to generator functions

208

* @param options - Configuration for values, types, and behavior

209

*/

210

matchUtilities(

211

utilities: Record<

212

string,

213

(value: string, extra: { modifier: string | null }) => CssInJs | CssInJs[]

214

>,

215

options?: Partial<{

216

type: string | string[];

217

supportsNegativeValues: boolean;

218

values: Record<string, string> & {

219

__BARE_VALUE__?: (value: NamedUtilityValue) => string | undefined;

220

};

221

modifiers: 'any' | Record<string, string>;

222

}>

223

): void;

224

```

225

226

**Usage Examples:**

227

228

```typescript

229

plugin(function({ addUtilities, matchUtilities, theme }) {

230

// Static utilities

231

addUtilities({

232

'.scrollbar-hide': {

233

'-ms-overflow-style': 'none',

234

'scrollbar-width': 'none',

235

'&::-webkit-scrollbar': {

236

display: 'none',

237

},

238

},

239

'.scrollbar-default': {

240

'-ms-overflow-style': 'auto',

241

'scrollbar-width': 'auto',

242

'&::-webkit-scrollbar': {

243

display: 'block',

244

},

245

},

246

});

247

248

// Parametric utilities

249

matchUtilities(

250

{

251

'text-shadow': (value) => ({

252

textShadow: value,

253

}),

254

'text-stroke': (value) => ({

255

'-webkit-text-stroke-width': value,

256

}),

257

},

258

{

259

values: theme('textShadow'),

260

type: ['length', 'color'],

261

}

262

);

263

264

// Utilities with modifiers and negative values

265

matchUtilities(

266

{

267

'skew-x': (value) => ({

268

transform: `skewX(${value})`,

269

}),

270

},

271

{

272

values: theme('skew'),

273

supportsNegativeValues: true,

274

type: 'angle',

275

}

276

);

277

});

278

```

279

280

### Components

281

282

Add component classes that contain multiple CSS properties.

283

284

```typescript { .api }

285

/**

286

* Add static component classes

287

* @param components - CSS-in-JS object containing component definitions

288

* @param options - Additional options (currently unused)

289

*/

290

addComponents(components: Record<string, CssInJs> | Record<string, CssInJs>[], options?: {}): void;

291

292

/**

293

* Add parametric components that generate classes based on values

294

* @param components - Object mapping component names to generator functions

295

* @param options - Configuration for values, types, and behavior

296

*/

297

matchComponents(

298

components: Record<string, (value: string, extra: { modifier: string | null }) => CssInJs>,

299

options?: Partial<{

300

type: string | string[];

301

supportsNegativeValues: boolean;

302

values: Record<string, string> & {

303

__BARE_VALUE__?: (value: NamedUtilityValue) => string | undefined;

304

};

305

modifiers: 'any' | Record<string, string>;

306

}>

307

): void;

308

```

309

310

**Usage Examples:**

311

312

```typescript

313

plugin(function({ addComponents, matchComponents, theme }) {

314

// Static components

315

addComponents({

316

'.btn': {

317

padding: `${theme('spacing.2')} ${theme('spacing.4')}`,

318

borderRadius: theme('borderRadius.md'),

319

fontWeight: theme('fontWeight.medium'),

320

},

321

'.card': {

322

backgroundColor: theme('colors.white'),

323

boxShadow: theme('boxShadow.lg'),

324

borderRadius: theme('borderRadius.lg'),

325

padding: theme('spacing.6'),

326

},

327

});

328

329

// Parametric components

330

matchComponents(

331

{

332

'btn': (value) => ({

333

backgroundColor: value,

334

color: theme('colors.white'),

335

'&:hover': {

336

backgroundColor: theme(`colors.${value}.600`),

337

},

338

}),

339

},

340

{

341

values: theme('colors'),

342

type: 'color',

343

}

344

);

345

});

346

```

347

348

### Theme Access

349

350

Access theme values within plugins.

351

352

```typescript { .api }

353

/**

354

* Access theme configuration values

355

* @param path - Dot-notation path to theme value (e.g., 'colors.blue.500')

356

* @param defaultValue - Default value if path doesn't exist

357

* @returns Theme value or default

358

*/

359

theme(path: string, defaultValue?: any): any;

360

```

361

362

**Usage Example:**

363

364

```typescript

365

plugin(function({ addUtilities, theme }) {

366

// Access nested theme values

367

const primaryColor = theme('colors.blue.500');

368

const defaultSpacing = theme('spacing.4');

369

const customFont = theme('fontFamily.custom', ['Inter', 'sans-serif']);

370

371

addUtilities({

372

'.custom-button': {

373

backgroundColor: primaryColor,

374

padding: defaultSpacing,

375

fontFamily: customFont.join(', '),

376

},

377

});

378

});

379

```

380

381

### Configuration Access

382

383

Access the full Tailwind configuration within plugins.

384

385

```typescript { .api }

386

/**

387

* Access configuration values

388

* @param path - Dot-notation path to config value

389

* @param defaultValue - Default value if path doesn't exist

390

* @returns Configuration value or default

391

*/

392

config(path?: string, defaultValue?: any): any;

393

```

394

395

### Class Prefixing

396

397

Apply the configured prefix to class names.

398

399

```typescript { .api }

400

/**

401

* Apply the configured prefix to a class name

402

* @param className - Class name to prefix

403

* @returns Prefixed class name

404

*/

405

prefix(className: string): string;

406

```

407

408

**Usage Example:**

409

410

```typescript

411

plugin(function({ addUtilities, prefix }) {

412

addUtilities({

413

[`.${prefix('my-utility')}`]: {

414

customProperty: 'value',

415

},

416

});

417

});

418

```

419

420

## Plugin Types

421

422

```typescript { .api }

423

type CssInJs = Record<string, string | string[] | CssInJs>;

424

425

interface NamedUtilityValue {

426

value: string;

427

fraction: string | null;

428

modifier: string | null;

429

}

430

```