or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

built-in-plugins.mdconfiguration.mdcore-processing.mdhelpers.mdindex.mdparser-system.mdplugin-system.mdstyle-system.mdutilities.md

plugin-system.mddocs/

0

# Plugin System

1

2

WindiCSS features a powerful plugin system that allows you to extend the framework with custom utilities, components, variants, and base styles. The plugin API provides a comprehensive set of utilities for creating flexible and reusable extensions.

3

4

## Capabilities

5

6

### Plugin Creation

7

8

Main plugin creation function for developing WindiCSS extensions.

9

10

```typescript { .api }

11

/**

12

* Creates a WindiCSS plugin

13

* @param handler - Function that receives plugin utilities and defines the plugin behavior

14

* @param config - Optional configuration to merge with the processor config

15

* @returns Plugin object that can be added to the plugins array

16

*/

17

function plugin(

18

handler: (utils: PluginUtils) => void,

19

config?: Config

20

): PluginOutput;

21

22

interface PluginOutput {

23

handler: (utils: PluginUtils) => void;

24

config?: Config;

25

}

26

```

27

28

**Usage Examples:**

29

30

```typescript

31

import plugin from "windicss/plugin";

32

33

// Basic plugin

34

const buttonPlugin = plugin(({ addComponents }) => {

35

addComponents({

36

'.btn': {

37

padding: '0.5rem 1rem',

38

borderRadius: '0.375rem',

39

fontWeight: '500',

40

transition: 'all 0.2s'

41

},

42

'.btn-primary': {

43

backgroundColor: '#3b82f6',

44

color: '#ffffff'

45

}

46

});

47

});

48

49

// Plugin with configuration

50

const customPlugin = plugin(({ addUtilities, theme }) => {

51

addUtilities({

52

'.gradient-text': {

53

background: `linear-gradient(45deg, ${theme('colors.blue.500')}, ${theme('colors.purple.500')})`,

54

WebkitBackgroundClip: 'text',

55

WebkitTextFillColor: 'transparent'

56

}

57

});

58

}, {

59

theme: {

60

extend: {

61

colors: {

62

brand: '#ff6b6b'

63

}

64

}

65

}

66

});

67

```

68

69

### Plugin with Options

70

71

Creates configurable plugins that accept options for customization.

72

73

```typescript { .api }

74

/**

75

* Creates a plugin that accepts options for customization

76

* @param pluginFunction - Function that takes options and returns a plugin handler

77

* @param configFunction - Optional function that takes options and returns config

78

* @returns Function that accepts options and returns a plugin

79

*/

80

plugin.withOptions<T>(

81

pluginFunction: (options: T) => (utils: PluginUtils) => void,

82

configFunction?: (options: T) => Config

83

): PluginWithOptions<T>;

84

85

interface PluginWithOptions<T> {

86

(options?: T): PluginOutput;

87

__isOptionsFunction: true;

88

}

89

```

90

91

**Usage Examples:**

92

93

```typescript

94

// Plugin with options

95

const flexboxPlugin = plugin.withOptions<{

96

gap?: boolean;

97

grid?: boolean;

98

}>((options = {}) => ({ addUtilities }) => {

99

const utilities: Record<string, any> = {

100

'.flex-center': {

101

display: 'flex',

102

alignItems: 'center',

103

justifyContent: 'center'

104

}

105

};

106

107

if (options.gap) {

108

utilities['.flex-gap'] = {

109

display: 'flex',

110

gap: '1rem'

111

};

112

}

113

114

if (options.grid) {

115

utilities['.grid-center'] = {

116

display: 'grid',

117

placeItems: 'center'

118

};

119

}

120

121

addUtilities(utilities);

122

});

123

124

// Usage with options

125

const processor = new Processor({

126

plugins: [

127

flexboxPlugin({ gap: true, grid: true })

128

]

129

});

130

```

131

132

### Plugin Utilities Interface

133

134

Complete interface provided to plugin handlers for adding utilities, components, and more.

135

136

```typescript { .api }

137

interface PluginUtils {

138

/** Add utility classes */

139

addUtilities(utilities: Record<string, any>, options?: PluginUtilOptions): Style[];

140

/** Add component classes */

141

addComponents(components: Record<string, any>, options?: PluginUtilOptions): Style[];

142

/** Add base/global styles */

143

addBase(baseStyles: Record<string, any>): Style[];

144

/** Add custom variant */

145

addVariant(name: string, generator: VariantGenerator): Style | Style[];

146

/** Add dynamic utility generator */

147

addDynamic(key: string, generator: UtilityGenerator, options?: PluginUtilOptions): UtilityGenerator;

148

/** Access theme values */

149

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

150

/** Access config values */

151

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

152

/** Escape CSS selector */

153

e(selector: string): string;

154

/** Add prefix to selector */

155

prefix(selector: string): string;

156

/** Access variant utilities */

157

variants(path: string, defaultValue?: string[]): string[];

158

}

159

160

interface PluginUtilOptions {

161

/** Whether to respect the configured prefix */

162

respectPrefix?: boolean;

163

/** Whether to respect the important configuration */

164

respectImportant?: boolean;

165

/** Whether to respect existing selector */

166

respectSelector?: boolean;

167

/** CSS layer for the utilities */

168

layer?: "base" | "components" | "utilities";

169

/** Variants to apply to utilities */

170

variants?: string[];

171

/** Order for CSS generation */

172

order?: number;

173

/** Group name for organization */

174

group?: string;

175

/** Completions for IDE support */

176

completions?: string[];

177

}

178

```

179

180

### Adding Utilities

181

182

Add custom utility classes to WindiCSS.

183

184

```typescript { .api }

185

/**

186

* Adds custom utility classes

187

* @param utilities - Object with CSS selectors as keys and style objects as values

188

* @param options - Options for utility generation

189

* @returns Array of generated Style objects

190

*/

191

addUtilities(

192

utilities: Record<string, any> | Array<Record<string, any>>,

193

options?: PluginUtilOptions

194

): Style[];

195

```

196

197

**Usage Examples:**

198

199

```typescript

200

const utilitiesPlugin = plugin(({ addUtilities }) => {

201

// Basic utilities

202

addUtilities({

203

'.scroll-smooth': {

204

scrollBehavior: 'smooth'

205

},

206

'.scroll-auto': {

207

scrollBehavior: 'auto'

208

}

209

});

210

211

// Utilities with variants and layer

212

addUtilities({

213

'.backdrop-blur': {

214

backdropFilter: 'blur(8px)'

215

},

216

'.backdrop-blur-sm': {

217

backdropFilter: 'blur(4px)'

218

}

219

}, {

220

respectPrefix: true,

221

respectImportant: true,

222

layer: 'utilities',

223

variants: ['responsive', 'hover']

224

});

225

226

// Responsive utilities

227

addUtilities({

228

'.container-xs': {

229

maxWidth: '480px',

230

marginLeft: 'auto',

231

marginRight: 'auto'

232

},

233

'.container-sm': {

234

maxWidth: '640px',

235

marginLeft: 'auto',

236

marginRight: 'auto'

237

}

238

});

239

});

240

```

241

242

### Adding Components

243

244

Add custom component classes with higher specificity than utilities.

245

246

```typescript { .api }

247

/**

248

* Adds custom component classes

249

* @param components - Object with CSS selectors as keys and style objects as values

250

* @param options - Options for component generation

251

* @returns Array of generated Style objects

252

*/

253

addComponents(

254

components: Record<string, any> | Array<Record<string, any>>,

255

options?: PluginUtilOptions

256

): Style[];

257

```

258

259

**Usage Examples:**

260

261

```typescript

262

const componentsPlugin = plugin(({ addComponents, theme }) => {

263

addComponents({

264

// Button components

265

'.btn': {

266

padding: '0.5rem 1rem',

267

borderRadius: theme('borderRadius.md'),

268

fontWeight: theme('fontWeight.medium'),

269

transition: 'all 0.15s ease-in-out',

270

cursor: 'pointer',

271

border: 'none',

272

'&:focus': {

273

outline: 'none',

274

boxShadow: '0 0 0 3px rgba(59, 130, 246, 0.1)'

275

}

276

},

277

'.btn-sm': {

278

padding: '0.25rem 0.75rem',

279

fontSize: theme('fontSize.sm')

280

},

281

'.btn-lg': {

282

padding: '0.75rem 1.5rem',

283

fontSize: theme('fontSize.lg')

284

},

285

286

// Card component

287

'.card': {

288

backgroundColor: theme('colors.white'),

289

borderRadius: theme('borderRadius.lg'),

290

boxShadow: theme('boxShadow.md'),

291

padding: theme('spacing.6')

292

}

293

});

294

});

295

```

296

297

### Adding Base Styles

298

299

Add global base styles that apply to HTML elements.

300

301

```typescript { .api }

302

/**

303

* Adds base/global styles

304

* @param baseStyles - Object with selectors and style objects

305

* @returns Array of generated Style objects

306

*/

307

addBase(baseStyles: Record<string, any>): Style[];

308

```

309

310

**Usage Examples:**

311

312

```typescript

313

const basePlugin = plugin(({ addBase, theme }) => {

314

addBase({

315

// Global styles

316

'html': {

317

scrollBehavior: 'smooth'

318

},

319

'body': {

320

fontFamily: theme('fontFamily.sans'),

321

lineHeight: theme('lineHeight.normal'),

322

color: theme('colors.gray.900'),

323

backgroundColor: theme('colors.gray.50')

324

},

325

326

// Custom elements

327

'h1, h2, h3, h4, h5, h6': {

328

fontWeight: theme('fontWeight.semibold'),

329

marginBottom: theme('spacing.4')

330

},

331

'p': {

332

marginBottom: theme('spacing.4')

333

},

334

335

// CSS custom properties

336

':root': {

337

'--primary-color': theme('colors.blue.500'),

338

'--secondary-color': theme('colors.green.500')

339

}

340

});

341

});

342

```

343

344

### Adding Dynamic Utilities

345

346

Add dynamic utility generators that create utilities based on arbitrary values.

347

348

```typescript { .api }

349

/**

350

* Adds dynamic utility generator

351

* @param key - Pattern to match for generating utilities

352

* @param generator - Function that generates styles based on matched values

353

* @param options - Options for utility generation

354

* @returns The generator function

355

*/

356

addDynamic(

357

key: string,

358

generator: UtilityGenerator,

359

options?: PluginUtilOptions

360

): UtilityGenerator;

361

362

type UtilityGenerator = (props: {

363

Utility: any;

364

Style: any;

365

Property: any;

366

Keyframes: any;

367

}) => Style | Style[] | undefined;

368

```

369

370

**Usage Examples:**

371

372

```typescript

373

const dynamicPlugin = plugin(({ addDynamic }) => {

374

// Custom spacing utilities

375

addDynamic('p-custom', ({ Utility, Style, Property }) => {

376

const match = Utility.raw.match(/^p-custom-(.+)$/);

377

if (match) {

378

const value = match[1];

379

return new Style(Utility.class, [

380

new Property('padding', `${value}px`)

381

]);

382

}

383

});

384

385

// Custom color utilities with opacity

386

addDynamic('bg-custom', ({ Utility, Style, Property }) => {

387

const match = Utility.raw.match(/^bg-custom-([a-zA-Z]+)-(\d+)$/);

388

if (match) {

389

const [, color, opacity] = match;

390

const opacityValue = parseInt(opacity) / 100;

391

return new Style(Utility.class, [

392

new Property('background-color', `rgba(var(--color-${color}), ${opacityValue})`)

393

]);

394

}

395

});

396

});

397

```

398

399

### Adding Variants

400

401

Add custom variants for conditional styling.

402

403

```typescript { .api }

404

/**

405

* Adds custom variant

406

* @param name - Name of the variant

407

* @param generator - Function that generates the variant style wrapper

408

* @returns Generated variant style

409

*/

410

addVariant(name: string, generator: VariantGenerator): Style | Style[];

411

412

type VariantGenerator = (utils: VariantUtils) => Style;

413

414

interface VariantUtils {

415

modifySelectors(modifier: (args: { className: string }) => string): Style;

416

atRule(name: string): Style;

417

pseudoClass(name: string): Style;

418

pseudoElement(name: string): Style;

419

parent(name: string): Style;

420

child(name: string): Style;

421

separator: string;

422

style: Style;

423

}

424

```

425

426

**Usage Examples:**

427

428

```typescript

429

const variantsPlugin = plugin(({ addVariant }) => {

430

// Custom pseudo-class variant

431

addVariant('hocus', ({ pseudoClass }) => {

432

return pseudoClass('hover, &:focus');

433

});

434

435

// Custom media query variant

436

addVariant('supports-grid', ({ atRule }) => {

437

return atRule('@supports (display: grid)');

438

});

439

440

// Custom parent selector variant

441

addVariant('group-hover', ({ modifySelectors }) => {

442

return modifySelectors(({ className }) => {

443

return `.group:hover .${className}`;

444

});

445

});

446

447

// Custom sibling variant

448

addVariant('sibling-checked', ({ modifySelectors }) => {

449

return modifySelectors(({ className }) => {

450

return `input[type="checkbox"]:checked ~ .${className}`;

451

});

452

});

453

});

454

```

455

456

### Accessing Theme and Config

457

458

Access theme values and configuration within plugins.

459

460

```typescript { .api }

461

/**

462

* Access theme values by path

463

* @param path - Dot-separated path to theme value

464

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

465

* @returns Theme value or default

466

*/

467

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

468

469

/**

470

* Access configuration values by path

471

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

472

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

473

* @returns Config value or default

474

*/

475

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

476

```

477

478

**Usage Examples:**

479

480

```typescript

481

const themePlugin = plugin(({ addUtilities, theme, config }) => {

482

// Access theme values

483

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

484

const borderRadius = theme('borderRadius.lg');

485

const fontFamily = theme('fontFamily.sans');

486

487

// Access config values

488

const prefix = config('prefix', '');

489

const separator = config('separator', ':');

490

const important = config('important', false);

491

492

addUtilities({

493

'.brand-card': {

494

backgroundColor: primaryColor,

495

borderRadius: borderRadius,

496

fontFamily: fontFamily.join(', '),

497

color: theme('colors.white'),

498

padding: theme('spacing.6')

499

}

500

});

501

});

502

```

503

504

### Built-in Plugin Examples

505

506

WindiCSS includes several built-in plugins that demonstrate the plugin system capabilities.

507

508

```typescript { .api }

509

import aspectRatio from "windicss/plugin/aspect-ratio";

510

import filters from "windicss/plugin/filters";

511

import forms from "windicss/plugin/forms";

512

import lineClamp from "windicss/plugin/line-clamp";

513

import typography from "windicss/plugin/typography";

514

import scrollSnap from "windicss/plugin/scroll-snap";

515

```

516

517

**Usage Example:**

518

519

```typescript

520

import Processor from "windicss";

521

import typography from "windicss/plugin/typography";

522

import forms from "windicss/plugin/forms";

523

524

const processor = new Processor({

525

plugins: [

526

typography({

527

modifiers: ['sm', 'lg', 'xl'],

528

className: 'prose'

529

}),

530

forms

531

]

532

});

533

```