* Processes the docs CSS. Removes empty rules, merges adjacent rules, removes unused selectors, and * rewrites imports.
(css, usedClasses)
| 270 | * rewrites imports. |
| 271 | */ |
| 272 | function processCSS(css, usedClasses) { |
| 273 | let ast = postcss.parse(css); |
| 274 | |
| 275 | ast.walkRules(rule => { |
| 276 | if (rule.nodes.length === 0 || rule.nodes.every(node => node.type === 'comment')) { |
| 277 | rule.remove(); |
| 278 | } else { |
| 279 | let prev = rule.prev(); |
| 280 | if (prev?.type === 'rule' && prev.selector === rule.selector) { |
| 281 | rule.nodes[0].raws.before = '\n' + rule.nodes[0].raws.before; |
| 282 | prev.nodes.push(...rule.nodes); |
| 283 | rule.remove(); |
| 284 | } else if ( |
| 285 | rule.selectors.every( |
| 286 | s => |
| 287 | !s.startsWith('.react-aria-') && |
| 288 | s[0] === '.' && |
| 289 | !usedClasses.has(s.slice(1).split(' ')[0]) |
| 290 | ) |
| 291 | ) { |
| 292 | console.log('Removing unused rule ' + rule.selector); |
| 293 | rule.remove(); |
| 294 | } else { |
| 295 | // Convert rems to use the standard 16px base font size instead of Spectrum's 14px |
| 296 | rule.walkDecls(decl => { |
| 297 | if (decl.updated) return; |
| 298 | decl.value = decl.value.replace(/([\d+.]+)rem/g, (_, v) => { |
| 299 | let px = Number(v) * 14; |
| 300 | return px / 16 + 'rem'; |
| 301 | }); |
| 302 | decl.updated = true; |
| 303 | }); |
| 304 | } |
| 305 | } |
| 306 | }); |
| 307 | |
| 308 | ast.walkAtRules('import', rule => { |
| 309 | rule.params = rule.params |
| 310 | .replace(/\.mdx(["'])/, '.css$1') |
| 311 | .replace('@react-aria/example-theme', './theme.css') |
| 312 | .replace(/\s*layer\(.*?\)/, ''); |
| 313 | if (rule.prev()?.type === 'atrule') { |
| 314 | rule.raws.before = '\n'; |
| 315 | } |
| 316 | }); |
| 317 | |
| 318 | ast.walkAtRules('media', rule => { |
| 319 | if (rule.nodes.length === 0 || rule.nodes.every(node => node.type === 'comment')) { |
| 320 | rule.remove(); |
| 321 | } |
| 322 | }); |
| 323 | |
| 324 | return ast.toString().trim() + '\n'; |
| 325 | } |
| 326 | |
| 327 | /** Generates a storybook story for a "Reusable wrappers" example from the docs. */ |
| 328 | function generateStory(filename, imports, code, skipImports = false) { |