0
# Sheet Registries
1
2
Global and scoped stylesheet management for organizing multiple stylesheets in applications, with support for both centralized registry and reference-counted lifecycle management.
3
4
## Capabilities
5
6
### SheetsRegistry Class
7
8
Registry to manage multiple stylesheets with automatic ordering and CSS aggregation.
9
10
```javascript { .api }
11
class SheetsRegistry {
12
/** Array of registered stylesheets */
13
registry: StyleSheet[];
14
15
/** Current highest index number */
16
readonly index: number;
17
18
/** Register a stylesheet in the registry */
19
add<RuleName extends string | number | symbol>(sheet: StyleSheet<RuleName>): void;
20
21
/** Reset the registry, removing all stylesheets */
22
reset(): void;
23
24
/** Remove a stylesheet from the registry */
25
remove<RuleName extends string | number | symbol>(sheet: StyleSheet<RuleName>): void;
26
27
/** Convert all stylesheets to a single CSS string */
28
toString(options?: ToCssOptions): string;
29
}
30
```
31
32
**Usage Examples:**
33
34
```javascript
35
import { SheetsRegistry } from "jss";
36
import jss from "jss";
37
38
// Create a custom registry
39
const registry = new SheetsRegistry();
40
41
// Create stylesheets
42
const buttonSheet = jss.createStyleSheet({
43
button: { background: 'blue' }
44
});
45
46
const headerSheet = jss.createStyleSheet({
47
header: { fontSize: '24px' }
48
});
49
50
// Add to registry
51
registry.add(buttonSheet);
52
registry.add(headerSheet);
53
54
// Get combined CSS for server-side rendering
55
const css = registry.toString();
56
console.log(css);
57
58
// Check current index
59
console.log(`Registry has ${registry.index} stylesheets`);
60
61
// Remove stylesheet
62
registry.remove(buttonSheet);
63
64
// Clear all
65
registry.reset();
66
```
67
68
### SheetsManager Class
69
70
WeakMap-based manager for stylesheet lifecycle with automatic reference counting and DOM management.
71
72
```javascript { .api }
73
class SheetsManager {
74
/** Number of managed stylesheets */
75
readonly size: number;
76
77
/** Retrieve stylesheet by key */
78
get(key: object): StyleSheet | null;
79
80
/** Add stylesheet with associated key */
81
add(key: object, sheet: StyleSheet): void;
82
83
/** Increment references and attach sheet to DOM */
84
manage(key: object): StyleSheet | null;
85
86
/** Decrement references and detach sheet when count reaches zero */
87
unmanage(key: object): void;
88
}
89
```
90
91
**Usage Examples:**
92
93
```javascript
94
import { SheetsManager } from "jss";
95
import jss from "jss";
96
97
// Create manager (typically used in React-like frameworks)
98
const manager = new SheetsManager();
99
100
// Component or theme objects as keys
101
const ComponentA = { name: 'ComponentA' };
102
const ComponentB = { name: 'ComponentB' };
103
104
// Create stylesheets
105
const sheetA = jss.createStyleSheet({
106
root: { color: 'blue' }
107
});
108
109
const sheetB = jss.createStyleSheet({
110
container: { padding: '20px' }
111
});
112
113
// Add sheets with keys
114
manager.add(ComponentA, sheetA);
115
manager.add(ComponentB, sheetB);
116
117
// Manage lifecycle - first call attaches to DOM
118
const managedSheetA = manager.manage(ComponentA); // Sheet attached
119
console.log(managedSheetA === sheetA); // true
120
121
// Multiple manages increment reference count
122
manager.manage(ComponentA); // Ref count: 2, still attached
123
124
// Unmanage decrements reference count
125
manager.unmanage(ComponentA); // Ref count: 1, still attached
126
manager.unmanage(ComponentA); // Ref count: 0, sheet detached
127
128
// Retrieve sheet
129
const retrieved = manager.get(ComponentA);
130
console.log(retrieved === sheetA); // true
131
132
// Check manager size
133
console.log(`Manager has ${manager.size} sheets`);
134
```
135
136
### Global Sheets Registry
137
138
Default global registry instance used by the DOM renderer for centralized stylesheet management.
139
140
```javascript { .api }
141
/** Global sheets registry instance */
142
const sheets: SheetsRegistry;
143
```
144
145
**Usage Example:**
146
147
```javascript
148
import { sheets } from "jss";
149
import jss from "jss";
150
151
// Create and attach stylesheet
152
const sheet = jss.createStyleSheet({
153
button: { background: 'red' }
154
});
155
sheet.attach(); // Automatically added to global registry
156
157
// Access global registry
158
console.log(`Global registry has ${sheets.index} sheets`);
159
160
// Get all CSS from global registry
161
const globalCss = sheets.toString();
162
console.log(globalCss);
163
164
// Note: sheets are automatically added to global registry when attached
165
// via DomRenderer, typically you don't need to manually manage this
166
```
167
168
### Server-Side Rendering
169
170
Using registries for server-side rendering with isolated stylesheet collections.
171
172
**Usage Example:**
173
174
```javascript
175
import { SheetsRegistry, create } from "jss";
176
177
// Server-side request handler
178
function handleRequest(req, res) {
179
// Create isolated registry for this request
180
const sheets = new SheetsRegistry();
181
182
// Create JSS instance for this request
183
const jss = create();
184
185
// Create stylesheets during rendering
186
const appSheet = jss.createStyleSheet({
187
app: { fontFamily: 'Arial' }
188
});
189
190
const buttonSheet = jss.createStyleSheet({
191
button: { background: 'blue' }
192
});
193
194
// Register sheets
195
sheets.add(appSheet);
196
sheets.add(buttonSheet);
197
198
// Render your app here...
199
const appHtml = renderApp();
200
201
// Get all CSS for this request
202
const css = sheets.toString();
203
204
// Return HTML with embedded CSS
205
const html = `
206
<!DOCTYPE html>
207
<html>
208
<head>
209
<style>${css}</style>
210
</head>
211
<body>
212
${appHtml}
213
</body>
214
</html>
215
`;
216
217
res.send(html);
218
}
219
```
220
221
### Registry Options
222
223
CSS output formatting options for registry toString methods.
224
225
```javascript { .api }
226
interface ToCssOptions {
227
/** Number of spaces for indentation */
228
indent?: number;
229
/** Whether to format CSS with line breaks */
230
format?: boolean;
231
/** Whether to include empty rules */
232
allowEmpty?: boolean;
233
/** Filter by attached status (SheetsRegistry only) */
234
attached?: boolean;
235
}
236
```
237
238
**Usage Example:**
239
240
```javascript
241
import { SheetsRegistry } from "jss";
242
243
const registry = new SheetsRegistry();
244
// ... add sheets ...
245
246
// Formatted CSS output
247
const formattedCss = registry.toString({
248
format: true,
249
indent: 2,
250
allowEmpty: false
251
});
252
253
// Only attached sheets
254
const attachedCss = registry.toString({
255
attached: true
256
});
257
258
// Minified CSS
259
const minifiedCss = registry.toString({
260
format: false
261
});
262
```
263
264
### Advanced Usage Patterns
265
266
Common patterns for registry usage in different scenarios.
267
268
**React Integration Pattern:**
269
270
```javascript
271
import React from 'react';
272
import { SheetsManager } from 'jss';
273
274
// Create manager at module level
275
const manager = new SheetsManager();
276
277
function MyComponent({ theme }) {
278
const [sheet, setSheet] = React.useState(null);
279
280
React.useEffect(() => {
281
// Use theme object as key
282
let managedSheet = manager.get(theme);
283
284
if (!managedSheet) {
285
// Create new sheet for this theme
286
const newSheet = jss.createStyleSheet({
287
root: {
288
color: theme.primaryColor,
289
background: theme.backgroundColor
290
}
291
});
292
293
manager.add(theme, newSheet);
294
managedSheet = newSheet;
295
}
296
297
// Manage lifecycle
298
const activeSheet = manager.manage(theme);
299
setSheet(activeSheet);
300
301
return () => {
302
// Cleanup
303
manager.unmanage(theme);
304
};
305
}, [theme]);
306
307
if (!sheet) return null;
308
309
return (
310
<div className={sheet.classes.root}>
311
Themed component
312
</div>
313
);
314
}
315
```
316
317
### RuleList Class
318
319
Container for managing CSS rules within stylesheets. This is primarily an internal API used by StyleSheet but exported for advanced use cases.
320
321
```javascript { .api }
322
class RuleList {
323
/** Add a rule to the list */
324
add(name: string, decl: JssStyle, options?: RuleOptions): Rule | null;
325
326
/** Replace an existing rule */
327
replace(name: string, decl: JssStyle, options?: RuleOptions): Rule | null;
328
329
/** Get a rule by name or selector */
330
get(nameOrSelector: string): Rule;
331
332
/** Remove a rule from the list */
333
remove(rule: Rule): void;
334
335
/** Get index of a rule */
336
indexOf(rule: Rule): number;
337
338
/** Process all rules through plugins */
339
process(): void;
340
341
/** Register a rule with class name mapping */
342
register(rule: Rule, className?: string): void;
343
344
/** Unregister a rule */
345
unregister(rule: Rule): void;
346
347
/** Update rules with new data */
348
update(name: string, data: {}): void;
349
update(data: {}): void;
350
351
/** Convert all rules to CSS string */
352
toString(options?: ToCssOptions): string;
353
}
354
```
355
356
**Usage Example:**
357
358
```javascript
359
import { RuleList } from "jss";
360
361
// Advanced usage - typically handled internally by StyleSheet
362
const ruleList = new RuleList({
363
classes: {},
364
generateId: jss.generateId,
365
Renderer: jss.options.Renderer,
366
jss: jss
367
});
368
369
// Add rules
370
ruleList.add('button', { background: 'blue' });
371
ruleList.add('text', { color: 'red' });
372
373
// Get CSS output
374
const css = ruleList.toString();
375
```