or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

component-enhancement.mdindex.mdkeyframes.mdplugins.mdstate-management.mdstyle-components.md

plugins.mddocs/

0

# Plugin System

1

2

Extensible plugin architecture that allows customization of Radium's style processing behavior through a modular system of processing functions.

3

4

## Capabilities

5

6

### Plugin Interface

7

8

Plugins are functions that process style objects and return modifications to component props, styles, or global state.

9

10

```javascript { .api }

11

/**

12

* Plugin function interface

13

* @param config - Plugin configuration object with utilities and current state

14

* @returns Plugin result with optional modifications to component

15

*/

16

interface Plugin {

17

(config: PluginConfig): PluginResult | void;

18

}

19

20

interface PluginConfig {

21

/** Component name (may not be available if minified) */

22

componentName: string;

23

/** Current Radium configuration */

24

config: RadiumConfig;

25

/** Current element props (can be modified by previous plugins) */

26

props: object;

27

/** Current element style (can be modified by previous plugins) */

28

style: object;

29

30

// Utility functions

31

/** Add CSS to global stylesheet */

32

addCSS: (css: string) => { remove: () => void };

33

/** Add !important to all values in style object */

34

appendImportantToEachValue: (style: object) => object;

35

/** Convert CSS rules object to string */

36

cssRuleSetToString: (selector: string, rules: object, userAgent?: string) => string;

37

/** Get component field value */

38

getComponentField: (key: string) => any;

39

/** Get global state value */

40

getGlobalState: (key: string) => any;

41

/** Get element state (hover, focus, active) */

42

getState: (stateKey: string, elementKey?: string) => any;

43

/** Generate hash from string */

44

hash: (data: string) => string;

45

/** Check if value is nested style object */

46

isNestedStyle: (value: any) => boolean;

47

/** Merge array of style objects */

48

mergeStyles: (styles: object[]) => object;

49

/** Set component state */

50

setState: (stateKey: string, value: any, elementKey?: string) => void;

51

/** Environment detection utilities */

52

ExecutionEnvironment: {

53

canUseEventListeners: boolean;

54

canUseDOM: boolean;

55

};

56

}

57

58

interface PluginResult {

59

/** Fields to merge into component instance */

60

componentFields?: object;

61

/** Values to merge into global state */

62

globalState?: object;

63

/** Props to merge into element */

64

props?: object;

65

/** Style object to replace current style */

66

style?: object;

67

}

68

```

69

70

### Built-in Plugins

71

72

Radium includes a comprehensive set of built-in plugins that handle core functionality.

73

74

```javascript { .api }

75

interface BuiltinPlugins {

76

/** Validates style properties and detects common issues */

77

checkProps: Plugin;

78

/** Processes keyframe animation objects */

79

keyframes: Plugin;

80

/** Merges arrays of style objects intelligently */

81

mergeStyleArray: Plugin;

82

/** Adds vendor prefixes to CSS properties */

83

prefix: Plugin;

84

/** Extracts nested style objects for processing */

85

removeNestedStyles: Plugin;

86

/** Handles :hover, :focus, :active pseudo-classes */

87

resolveInteractionStyles: Plugin;

88

/** Processes @media query styles */

89

resolveMediaQueries: Plugin;

90

/** Handles :visited pseudo-class styles */

91

visited: Plugin;

92

}

93

```

94

95

**Usage Examples:**

96

97

```javascript

98

import Radium from 'radium';

99

100

// Access built-in plugins

101

const { Plugins } = Radium;

102

103

// Default plugin order

104

const defaultPlugins = [

105

Plugins.mergeStyleArray,

106

Plugins.checkProps,

107

Plugins.resolveMediaQueries,

108

Plugins.resolveInteractionStyles,

109

Plugins.keyframes,

110

Plugins.visited,

111

Plugins.removeNestedStyles,

112

Plugins.prefix,

113

Plugins.checkProps // Run again after processing

114

];

115

```

116

117

### Custom Plugins

118

119

Create custom plugins to extend Radium's functionality.

120

121

**Usage Examples:**

122

123

```javascript

124

// Simple logging plugin

125

function loggingPlugin({ componentName, style }) {

126

console.log(`Styling component: ${componentName}`, style);

127

// Return nothing - no modifications

128

}

129

130

// Style transformation plugin

131

function uppercaseTextPlugin({ style }) {

132

if (style.textTransform === 'uppercase-all') {

133

return {

134

style: {

135

...style,

136

textTransform: 'uppercase',

137

fontWeight: 'bold',

138

letterSpacing: '1px'

139

}

140

};

141

}

142

}

143

144

// Plugin that adds CSS to global stylesheet

145

function globalStylesPlugin({ addCSS, hash }) {

146

const css = `

147

.custom-utility {

148

display: flex;

149

align-items: center;

150

justify-content: center;

151

}

152

`;

153

154

const id = hash(css);

155

if (!document.getElementById(id)) {

156

const { remove } = addCSS(css);

157

// Store remove function if needed later

158

}

159

}

160

161

// Use custom plugins

162

const MyComponent = Radium({

163

plugins: [

164

Plugins.mergeStyleArray,

165

loggingPlugin,

166

uppercaseTextPlugin,

167

Plugins.checkProps,

168

Plugins.resolveMediaQueries,

169

Plugins.resolveInteractionStyles,

170

globalStylesPlugin,

171

Plugins.prefix,

172

Plugins.checkProps

173

]

174

})(BaseComponent);

175

```

176

177

### Plugin Execution Order

178

179

Plugins are executed in the order they appear in the configuration array. Each plugin receives the result of previous plugins.

180

181

**Usage Examples:**

182

183

```javascript

184

// Plugin execution order matters

185

const orderedPlugins = [

186

// 1. First, merge style arrays

187

Plugins.mergeStyleArray,

188

189

// 2. Validate initial styles

190

Plugins.checkProps,

191

192

// 3. Process special style objects that create new styles

193

Plugins.resolveMediaQueries,

194

Plugins.resolveInteractionStyles,

195

Plugins.keyframes,

196

Plugins.visited,

197

198

// 4. Extract nested styles

199

Plugins.removeNestedStyles,

200

201

// 5. Add vendor prefixes

202

Plugins.prefix,

203

204

// 6. Final validation

205

Plugins.checkProps

206

];

207

```

208

209

### Plugin Development

210

211

Guidelines for developing custom plugins.

212

213

```javascript { .api }

214

/**

215

* Plugin development template

216

*/

217

function customPlugin({

218

componentName,

219

config,

220

props,

221

style,

222

addCSS,

223

getState,

224

setState,

225

isNestedStyle,

226

mergeStyles

227

}) {

228

// 1. Check if plugin should run

229

if (!shouldProcessStyle(style)) {

230

return; // No modifications

231

}

232

233

// 2. Process style object

234

const processedStyle = processStyle(style);

235

236

// 3. Add any necessary CSS

237

if (needsGlobalCSS(processedStyle)) {

238

addCSS(generateCSS(processedStyle));

239

}

240

241

// 4. Return modifications

242

return {

243

style: processedStyle,

244

props: {

245

...props,

246

'data-processed': true

247

}

248

};

249

}

250

```

251

252

**Usage Examples:**

253

254

```javascript

255

// Responsive utilities plugin

256

function responsiveUtilitiesPlugin({ style, addCSS, hash }) {

257

const responsiveProps = ['responsiveWidth', 'responsiveHeight'];

258

const hasResponsiveProps = responsiveProps.some(prop => style[prop]);

259

260

if (!hasResponsiveProps) return;

261

262

const newStyle = { ...style };

263

264

if (style.responsiveWidth) {

265

const breakpoints = style.responsiveWidth;

266

Object.keys(breakpoints).forEach(breakpoint => {

267

const css = `

268

@media (min-width: ${breakpoint}) {

269

.responsive-width-${hash(breakpoint)} {

270

width: ${breakpoints[breakpoint]};

271

}

272

}

273

`;

274

addCSS(css);

275

});

276

277

newStyle.className = `responsive-width-${hash(JSON.stringify(breakpoints))}`;

278

delete newStyle.responsiveWidth;

279

}

280

281

return { style: newStyle };

282

}

283

```

284

285

### Plugin Configuration

286

287

Plugins can be configured globally or per-component.

288

289

**Usage Examples:**

290

291

```javascript

292

// Global plugin configuration

293

const GlobalRadium = Radium({

294

plugins: [

295

...Radium.Plugins,

296

customPlugin

297

]

298

});

299

300

// Per-component configuration

301

const SpecialComponent = Radium({

302

plugins: [

303

Plugins.mergeStyleArray,

304

specialComponentPlugin,

305

Plugins.prefix

306

]

307

})(BaseComponent);

308

309

// Runtime configuration via props

310

<MyComponent

311

radiumConfig={{

312

plugins: [...customPlugins]

313

}}

314

/>

315

```

316

317

## Built-in Plugin Details

318

319

### mergeStyleArray

320

321

Intelligently merges arrays of style objects with deep merging for nested styles.

322

323

```javascript { .api }

324

interface MergeStyleArrayPlugin {

325

/** Processes style arrays into single style object */

326

(config: PluginConfig): PluginResult;

327

}

328

```

329

330

### checkProps

331

332

Validates style properties and usage patterns, warning about common issues.

333

334

```javascript { .api }

335

interface CheckPropsPlugin {

336

/** Validates style objects and usage patterns */

337

(config: PluginConfig): void;

338

}

339

```

340

341

### resolveMediaQueries

342

343

Processes `@media` query styles and applies them based on current media conditions.

344

345

```javascript { .api }

346

interface ResolveMediaQueriesPlugin {

347

/** Processes @media query styles */

348

(config: PluginConfig): PluginResult;

349

}

350

```

351

352

### resolveInteractionStyles

353

354

Handles `:hover`, `:focus`, and `:active` pseudo-class styles by setting up event listeners.

355

356

```javascript { .api }

357

interface ResolveInteractionStylesPlugin {

358

/** Handles pseudo-class styles */

359

(config: PluginConfig): PluginResult;

360

}

361

```

362

363

### prefix

364

365

Adds vendor prefixes to CSS properties and values based on browser detection.

366

367

```javascript { .api }

368

interface PrefixPlugin {

369

/** Adds vendor prefixes to styles */

370

(config: PluginConfig): PluginResult;

371

}

372

```

373

374

## Types

375

376

```javascript { .api }

377

interface Plugin {

378

(config: PluginConfig): PluginResult | void;

379

}

380

381

interface PluginConfig {

382

componentName: string;

383

config: RadiumConfig;

384

props: object;

385

style: object;

386

addCSS: (css: string) => { remove: () => void };

387

appendImportantToEachValue: (style: object) => object;

388

cssRuleSetToString: (selector: string, rules: object, userAgent?: string) => string;

389

getComponentField: (key: string) => any;

390

getGlobalState: (key: string) => any;

391

getState: (stateKey: string, elementKey?: string) => any;

392

hash: (data: string) => string;

393

isNestedStyle: (value: any) => boolean;

394

mergeStyles: (styles: object[]) => object;

395

setState: (stateKey: string, value: any, elementKey?: string) => void;

396

ExecutionEnvironment: {

397

canUseEventListeners: boolean;

398

canUseDOM: boolean;

399

};

400

}

401

402

interface PluginResult {

403

componentFields?: object;

404

globalState?: object;

405

props?: object;

406

style?: object;

407

}

408

```