@pre.style/core 3.1.0-alpha.0 → 3.1.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -128,3 +128,41 @@ export function repair(selectors) {
128
128
  };
129
129
  return fix(selectors);
130
130
  }
131
+ // A selector list's specificity: its most specific selector's.
132
+ export function specificity(selectors) {
133
+ let best = [0, 0, 0];
134
+ for (const selector of selectors) {
135
+ const current = ofSelector(selector);
136
+ const difference = current[0] - best[0] || current[1] - best[1] || current[2] - best[2];
137
+ if (difference > 0)
138
+ best = current;
139
+ }
140
+ return best;
141
+ }
142
+ function ofSelector(selector) {
143
+ const total = [0, 0, 0];
144
+ const add = (other) => {
145
+ total[0] += other[0];
146
+ total[1] += other[1];
147
+ total[2] += other[2];
148
+ };
149
+ for (const component of selector) {
150
+ if (component.type === 'id')
151
+ total[0]++;
152
+ else if (component.type === 'class' || component.type === 'attribute')
153
+ total[1]++;
154
+ else if (component.type === 'type' || component.type === 'pseudo-element')
155
+ total[2]++;
156
+ else if (component.type === 'pseudo-class' && component.kind !== 'where') {
157
+ // `:is()`, `:not()`, and `:has()` count as their most specific argument.
158
+ if (component.selectors)
159
+ add(specificity(component.selectors));
160
+ else {
161
+ total[1]++;
162
+ if (component.of)
163
+ add(specificity(component.of));
164
+ }
165
+ }
166
+ }
167
+ return total;
168
+ }
@@ -1,6 +1,7 @@
1
1
  import { pathToFileURL, fileURLToPath } from 'node:url';
2
2
  import { atRuleInfo } from './at-rules.js';
3
3
  import { addDeclarations, addGlobal, dropOverridden, key, parseRules, PreStyleError, valueOf, walk, } from './block.js';
4
+ import { localizeKeyframes } from './keyframes.js';
4
5
  import { compose, isElement } from './selectors.js';
5
6
  // Classes used as context for another class (`.card:hover .title`), or in a
6
7
  // compound with it (`.a.b`), are replaced with a marker: one generated name
@@ -144,6 +145,13 @@ export function parseStylesheet(code, lang, file, id, options) {
144
145
  }
145
146
  for (const target of classes.values())
146
147
  target.atoms = dropOverridden(target.atoms);
148
+ // Keyframes are local to the whole file, as in CSS Modules.
149
+ if (options.keyframeLocalization) {
150
+ const local = localizeKeyframes(parsed.globals);
151
+ parsed.globals = local.globals;
152
+ for (const target of classes.values())
153
+ target.atoms = local.atoms(target.atoms);
154
+ }
147
155
  return parsed;
148
156
  }
149
157
  // Flattens rules into entries, in order: style rules with their full
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pre.style/core",
3
- "version": "3.1.0-alpha.0",
3
+ "version": "3.1.0-alpha.2",
4
4
  "description": "Zero-runtime CSS-in-JS that compiles css and scss blocks into atomic CSS classes.",
5
5
  "keywords": [
6
6
  "atomic-css",
@@ -60,6 +60,10 @@
60
60
  },
61
61
  "prependFiles": {
62
62
  "$ref": "#/definitions/prependFiles"
63
+ },
64
+ "keyframeLocalization": {
65
+ "description": "Give each @keyframes in the library's blocks and stylesheet files a generated name, used only in the block or file that defines it, like styled-components' `keyframes`. The app's setting doesn't apply to libraries.",
66
+ "type": "boolean"
63
67
  }
64
68
  }
65
69
  }
@@ -84,6 +88,10 @@
84
88
  "prependFiles": {
85
89
  "$ref": "#/definitions/prependFiles"
86
90
  },
91
+ "keyframeLocalization": {
92
+ "description": "Give each @keyframes in the app's blocks and stylesheet files a generated name, used only in the block or file that defines it (including keyframes from prepended files), like styled-components' `keyframes`. Libraries use their own setting.",
93
+ "type": "boolean"
94
+ },
87
95
  "libraries": {
88
96
  "description": "App only. Component libraries to compile, by package name, in addition to dependencies with a \"pre.style\" field. A config replaces the package's field, `true` uses the defaults, and `false` leaves the package out.",
89
97
  "type": "object",