@barocss/browser 0.4.0 → 0.5.0

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.
package/dist/index.d.ts CHANGED
@@ -16,9 +16,12 @@ export declare class BrowserRuntime {
16
16
  private context;
17
17
  private options;
18
18
  private isDestroyed;
19
+ private existing;
20
+ private existingSheetCount;
19
21
  private incrementalParser;
20
22
  private changeDetector;
21
23
  private stylePartitionManager;
24
+ private getCategory;
22
25
  constructor(options?: BrowserRuntimeOptions);
23
26
  /**
24
27
  * Add debug logs (by level)
@@ -46,6 +49,8 @@ export declare class BrowserRuntime {
46
49
  applyParseResults(results: Array<GenerateCssRulesResult>, _opts?: {
47
50
  isBrowser?: boolean;
48
51
  }): void;
52
+ /** Class names defined by the page's own stylesheets (BaroCSS's sheets and cross-origin sheets excluded). */
53
+ getExistingClasses(): Set<string>;
49
54
  /**
50
55
  * MutationObserver instance method to automatically call addClass when class attributes change in DOM
51
56
  */
@@ -128,6 +133,15 @@ export declare interface BrowserRuntimeOptions {
128
133
  styleId?: string;
129
134
  insertionPoint?: 'head' | 'body' | HTMLElement;
130
135
  maxRulesPerPartition?: number;
136
+ /**
137
+ * #210: skip classes the page's existing (non-BaroCSS, same-origin) stylesheets already define,
138
+ * so a built app plus the runtime injects only what the build is missing. Opt-in. A class counts
139
+ * as covered only when a rule's selector starts with it (e.g. `.p-4`, `.md\:p-4` inside @media,
140
+ * `.hover\:x:hover`), so a class seen only as a descendant (`.group:hover .x`) is not skipped.
141
+ * The index is rebuilt when `document.styleSheets.length` changes. A page class that leads a selector
142
+ * with the same name is treated as covered, and rules added later to an already-indexed sheet aren't seen.
143
+ */
144
+ skipExisting?: boolean;
131
145
  }
132
146
 
133
147
  /**
@@ -152,13 +166,14 @@ export declare class ChangeDetector {
152
166
  private incrementalParser;
153
167
  /** Reference to BrowserRuntime for CSS injection (optional) */
154
168
  private BrowserRuntime?;
169
+ private getCategory;
155
170
  /**
156
171
  * Create a new ChangeDetector instance
157
172
  *
158
173
  * @param incrementalParser - IncrementalParser instance for class processing
159
174
  * @param BrowserRuntime - Optional BrowserRuntime instance for CSS injection
160
175
  */
161
- constructor(incrementalParser: IncrementalParser, BrowserRuntime?: BrowserRuntime);
176
+ constructor(incrementalParser: IncrementalParser, BrowserRuntime?: BrowserRuntime, getCategory?: (cls: string) => string | undefined);
162
177
  setParser(parser: IncrementalParser): void;
163
178
  /**
164
179
  * Starts observing DOM changes for new CSS classes
@@ -206,19 +221,65 @@ export declare class ChangeDetector {
206
221
  disconnect(): void;
207
222
  }
208
223
 
209
- export declare function getRuntime(options: BrowserRuntimeOptions): BrowserRuntime;
224
+ /** Collect literal className tokens from a json-render Spec's flat elements map. */
225
+ export declare function collectJsonRenderClassNames(spec: unknown): string[];
226
+
227
+ /**
228
+ * Returns the shared runtime, creating it on first use. If a live runtime
229
+ * already exists and `options.config` is a different config object, it is
230
+ * applied via `updateConfig` (which replaces the whole config), so an early
231
+ * `getRuntime()` never makes a later `baroStart({ config })` lose its config.
232
+ */
233
+ export declare function getRuntime(options?: BrowserRuntimeOptions): BrowserRuntime;
234
+
235
+ /** Tailwind 4 layer order, declared by BaroCSS's first <style> in <head>. */
236
+ export declare const LAYER_ORDER = "@layer theme, base, components, utilities;";
210
237
 
211
238
  export declare function normalizeClassName(className: any): string;
212
239
 
213
240
  export declare function normalizeClassNameList(className: any): string[];
214
241
 
242
+ /** Submit literal classes synchronously before UI mount; the caller validates class support. */
243
+ export declare function preloadJsonRenderClasses(spec: unknown, runtime: Pick<BrowserRuntime, 'addClass'>): void;
244
+
245
+ /**
246
+ * Tailwind-compatible cascade order for runtime-inserted rules (#254).
247
+ *
248
+ * The runtime discovers classes in DOM order, so without sorting `lg:px-8`
249
+ * seen before `sm:px-6` would land earlier and lose at >= 1024px. Each rule
250
+ * gets a sort key derived from its leading `@media` / `@container` preludes:
251
+ *
252
+ * 0 base, state media (hover), motion/contrast, unknown
253
+ * 1 max-* breakpoints (larger width first)
254
+ * 2 min-* breakpoints (smaller width first)
255
+ * 3 @max-* container queries (larger width first)
256
+ * 4 @min-* container queries (smaller width first)
257
+ * 5 orientation, dark (prefers-color-scheme), print, forced-colors
258
+ *
259
+ * Nested at-rules (e.g. `sm:dark:`) contribute one key pair per level, so
260
+ * `sm:` < `sm:dark:` < `md:`. Equal keys keep discovery order.
261
+ */
262
+ declare type RuleKey = number[];
263
+
264
+ export declare const shadcnTheme: {
265
+ colors: Record<string, string>;
266
+ borderRadius: Record<string, string>;
267
+ };
268
+
215
269
  export declare interface StylePartition {
216
270
  id: string;
217
271
  styles: string[];
218
272
  styleElement: HTMLStyleElement;
273
+ /** Sort keys parallel to `styles` / the sheet's cssRules (#254). */
274
+ keys?: RuleKey[];
219
275
  }
220
276
 
221
277
  export declare class StylePartitionManager {
278
+ /**
279
+ * Insert `rule` at its Tailwind variant position within `partition` (#254):
280
+ * one insertRule at a binary-searched index, no sheet rewrite.
281
+ */
282
+ private insertSorted;
222
283
  private partitions;
223
284
  private categoryPartitions;
224
285
  private partitionCounter;
@@ -227,7 +288,8 @@ export declare class StylePartitionManager {
227
288
  private classToPartitionMap;
228
289
  private classToCategoryPartitionMap;
229
290
  private styleIdPrefix;
230
- constructor(insertionPoint: HTMLElement, maxRulesPerPartition?: number, styleIdPrefix?: string);
291
+ private getCategory;
292
+ constructor(insertionPoint: HTMLElement, maxRulesPerPartition?: number, styleIdPrefix?: string, getCategory?: (cls: string) => string | undefined);
231
293
  private initializeDefaultPartition;
232
294
  private createNewCategoryPartition;
233
295
  private createNewPartition;
@@ -258,7 +320,7 @@ export declare class StylePartitionManager {
258
320
  * 특정 규칙이 어느 파티션에 있는지 찾기
259
321
  */
260
322
  findRulePartition(rule: string): StylePartition | null;
261
- updateRuleContent(category: string, ruleContent: string): void;
323
+ updateRuleContent(category: string, ruleContent: string, atDocumentStart?: boolean): void;
262
324
  /**
263
325
  * 모든 파티션 정리
264
326
  */
package/dist/index.es.js CHANGED
@@ -1,18 +1,64 @@
1
- import { parseResultCache as y, createContext as f, IncrementalParser as g, clearAstCache as P } from "@barocss/kit";
2
- class u {
3
- constructor(t, e = 50, s = "barocss-style-partition-") {
4
- this.partitions = [], this.categoryPartitions = /* @__PURE__ */ new Map(), this.partitionCounter = 0, this.maxRulesPerPartition = 50, this.classToPartitionMap = /* @__PURE__ */ new Map(), this.classToCategoryPartitionMap = /* @__PURE__ */ new Map(), this.styleIdPrefix = "barocss-style-partition-", this.insertionPoint = t, this.maxRulesPerPartition = e, this.styleIdPrefix = s, this.initializeDefaultPartition();
1
+ import { parseClassName as y, createContext as g, IncrementalParser as p, clearAstCache as x } from "@barocss/kit";
2
+ const w = /^\s*@(media|container)\s+([^{]*)\{/, E = /prefers-color-scheme|\bprint\b|forced-colors|orientation/, S = /(?:min-width\s*:\s*|width\s*>=?\s*)([\d.]+)(px|rem|em)?/, A = /(?:max-width\s*:\s*|width\s*<=?\s*)([\d.]+)(px|rem|em)?/;
3
+ function m(n, t) {
4
+ const e = parseFloat(n);
5
+ return t === "rem" || t === "em" ? e * 16 : e;
6
+ }
7
+ function M(n, t) {
8
+ const e = n === "container", s = S.exec(t);
9
+ if (s) return [e ? 4 : 2, m(s[1], s[2])];
10
+ const i = A.exec(t);
11
+ return i ? [e ? 3 : 1, -m(i[1], i[2])] : !e && E.test(t) ? [5, 0] : [0, 0];
12
+ }
13
+ function C(n) {
14
+ const t = [];
15
+ let e = n, s;
16
+ for (; s = w.exec(e); ) {
17
+ const [i, r] = M(s[1], s[2]);
18
+ t.push(i, r), e = e.slice(s[0].length);
19
+ }
20
+ return t;
21
+ }
22
+ function P(n, t) {
23
+ const e = Math.min(n.length, t.length);
24
+ for (let s = 0; s < e; s++)
25
+ if (n[s] !== t[s]) return n[s] - t[s];
26
+ return n.length - t.length;
27
+ }
28
+ function v(n, t) {
29
+ let e = 0, s = n.length;
30
+ for (; e < s; ) {
31
+ const i = e + s >> 1;
32
+ P(n[i], t) <= 0 ? e = i + 1 : s = i;
33
+ }
34
+ return e;
35
+ }
36
+ class d {
37
+ constructor(t, e = 50, s = "barocss-style-partition-", i = (r) => y(r).utility?.category) {
38
+ this.partitions = [], this.categoryPartitions = /* @__PURE__ */ new Map(), this.partitionCounter = 0, this.maxRulesPerPartition = 50, this.classToPartitionMap = /* @__PURE__ */ new Map(), this.classToCategoryPartitionMap = /* @__PURE__ */ new Map(), this.styleIdPrefix = "barocss-style-partition-", this.insertionPoint = t, this.maxRulesPerPartition = e, this.styleIdPrefix = s, this.getCategory = i, this.initializeDefaultPartition();
39
+ }
40
+ /**
41
+ * Insert `rule` at its Tailwind variant position within `partition` (#254):
42
+ * one insertRule at a binary-searched index, no sheet rewrite.
43
+ */
44
+ insertSorted(t, e, s) {
45
+ const i = t.keys ??= [], r = v(i, s), o = t.styleElement.sheet;
46
+ o && o.cssRules.length === i.length ? (o.insertRule(this.escapeCssRule(e), r), t.styles.splice(r, 0, e)) : (t.styles.splice(r, 0, e), t.styleElement.textContent = t.styles.join(`
47
+ `) + `
48
+ `), i.splice(r, 0, s);
5
49
  }
6
50
  initializeDefaultPartition() {
7
51
  this.createNewPartition();
8
52
  }
9
- createNewCategoryPartition(t) {
10
- const e = {
53
+ createNewCategoryPartition(t, e = !1) {
54
+ const s = {
11
55
  id: this.styleIdPrefix + `-${t}`,
12
56
  styles: [],
13
57
  styleElement: document.createElement("style")
14
58
  };
15
- return e.styleElement.id = e.id, e.styleElement.setAttribute("data-barocss", "partition"), e.styleElement.setAttribute("data-category", t), this.insertionPoint.appendChild(e.styleElement), this.categoryPartitions.set(t, e), e;
59
+ s.styleElement.id = s.id, s.styleElement.setAttribute("data-barocss", "partition"), s.styleElement.setAttribute("data-category", t);
60
+ const i = this.insertionPoint.ownerDocument?.head;
61
+ return e && i ? i.insertBefore(s.styleElement, i.firstChild) : this.insertionPoint.appendChild(s.styleElement), this.categoryPartitions.set(t, s), s;
16
62
  }
17
63
  createNewPartition() {
18
64
  const t = {
@@ -57,16 +103,19 @@ class u {
57
103
  addRule(t) {
58
104
  if (this.hasRule(t))
59
105
  return !1;
60
- this.currentPartition.styles.length >= this.maxRulesPerPartition && this.createNewPartition();
61
- const e = this.currentPartition, s = this.partitions.length - 1;
106
+ const e = C(t);
107
+ let s = this.partitions.findIndex((r) => {
108
+ const o = r.keys;
109
+ return !!o && o.length > 0 && P(o[o.length - 1], e) > 0;
110
+ });
111
+ s === -1 && (this.currentPartition.styles.length >= this.maxRulesPerPartition && this.createNewPartition(), s = this.partitions.length - 1);
112
+ const i = this.partitions[s];
62
113
  try {
63
- const i = e.styleElement.sheet;
64
- return i ? i.insertRule(this.escapeCssRule(t), i.cssRules.length) : e.styleElement.textContent += t + `
65
- `, this.setRuleCache(t, s), e.styles.push(t), !0;
66
- } catch (i) {
114
+ return this.insertSorted(i, t, e), this.setRuleCache(t, s), !0;
115
+ } catch (r) {
67
116
  return console.warn(
68
117
  `[StylePartitionManager] Failed to insert rule: ${t}`,
69
- i
118
+ r
70
119
  ), !1;
71
120
  }
72
121
  }
@@ -76,16 +125,14 @@ class u {
76
125
  let s = this.getCategoryPartition(e);
77
126
  s || (s = this.createNewCategoryPartition(e));
78
127
  try {
79
- const i = s.styleElement.sheet;
80
- i ? i.insertRule(this.escapeCssRule(t), i.cssRules.length) : s.styleElement.textContent += t + `
81
- `;
128
+ this.insertSorted(s, t, C(t));
82
129
  } catch (i) {
83
130
  return console.warn(
84
131
  `[StylePartitionManager] Failed to insert rule in category: ${e} ${t}`,
85
132
  i
86
133
  ), !1;
87
134
  }
88
- return this.setCategoryRuleCache(t, e), s.styles.push(t), !0;
135
+ return this.setCategoryRuleCache(t, e), !0;
89
136
  }
90
137
  addRootRules(t) {
91
138
  let e = this.getCategoryPartition("root");
@@ -107,10 +154,10 @@ class u {
107
154
  addRules(t) {
108
155
  let e = 0, s = 0;
109
156
  for (const i of t) {
110
- const n = y.get(i.cls)?.utility?.category;
111
- if (n)
157
+ const r = this.getCategory(i.cls);
158
+ if (r)
112
159
  for (const o of i.cssList)
113
- this.addCategoryRule(o, n);
160
+ this.addCategoryRule(o, r);
114
161
  else
115
162
  for (const o of i.cssList)
116
163
  this.addRule(o) ? e++ : s++;
@@ -127,13 +174,13 @@ class u {
127
174
  const s = this.classToCategoryPartitionMap.get(t);
128
175
  return s !== void 0 && this.categoryPartitions.get(s) || null;
129
176
  }
130
- updateRuleContent(t, e) {
131
- const s = this.getCategoryPartition(t);
132
- if (s)
133
- s.styleElement.textContent = e;
177
+ updateRuleContent(t, e, s = !1) {
178
+ const i = this.getCategoryPartition(t);
179
+ if (i)
180
+ i.styleElement.textContent = e;
134
181
  else {
135
- const i = this.createNewCategoryPartition(t);
136
- console.log(`[StylePartitionManager] Created new partition for category: ${t}`), i.styleElement.textContent = e;
182
+ const r = this.createNewCategoryPartition(t, s);
183
+ console.log(`[StylePartitionManager] Created new partition for category: ${t}`), r.styleElement.textContent = e;
137
184
  }
138
185
  }
139
186
  /**
@@ -147,21 +194,21 @@ class u {
147
194
  }), this.partitions = [], this.categoryPartitions.clear(), this.partitionCounter = 0, this.classToPartitionMap.clear(), this.classToCategoryPartitionMap.clear();
148
195
  }
149
196
  }
150
- function p(a) {
151
- return a ? a instanceof SVGAnimatedString ? a.baseVal.toString() : a.toString() : "";
197
+ function N(n) {
198
+ return n ? typeof n == "object" && typeof n.baseVal == "string" ? n.baseVal : n.toString() : "";
152
199
  }
153
- function c(a) {
154
- return a ? p(a).split(/\s+/).filter(Boolean) : [];
200
+ function h(n) {
201
+ return n ? N(n).split(/\s+/).filter(Boolean) : [];
155
202
  }
156
- class m {
203
+ class D {
157
204
  /**
158
205
  * Create a new ChangeDetector instance
159
206
  *
160
207
  * @param incrementalParser - IncrementalParser instance for class processing
161
208
  * @param BrowserRuntime - Optional BrowserRuntime instance for CSS injection
162
209
  */
163
- constructor(t, e) {
164
- this.observer = null, this.incrementalParser = t, this.BrowserRuntime = e;
210
+ constructor(t, e, s = (i) => y(i).utility?.category) {
211
+ this.observer = null, this.incrementalParser = t, this.BrowserRuntime = e, this.getCategory = s;
165
212
  }
166
213
  setParser(t) {
167
214
  this.incrementalParser = t;
@@ -186,21 +233,25 @@ class m {
186
233
  }) : (this.observer && this.observer.disconnect(), this.observer = new MutationObserver((s) => {
187
234
  const i = /* @__PURE__ */ new Set();
188
235
  if (s.forEach((r) => {
189
- if (r.type === "attributes" && r.attributeName === "class") {
190
- const n = r.target;
191
- n.className && c(n.className).forEach((l) => {
192
- this.incrementalParser.isProcessed(l) || i.add(l);
236
+ if (r.type === "attributes" && r.attributeName === "class" && t.contains(r.target)) {
237
+ const o = r.target;
238
+ o.className && h(o.className).forEach((c) => {
239
+ this.incrementalParser.isProcessed(c) || i.add(c);
193
240
  });
194
241
  }
195
- r.type === "childList" && r.addedNodes.forEach((n) => {
196
- n instanceof Element && (this.processElement(n, i), n.querySelectorAll("[class]").forEach((o) => {
197
- this.processElement(o, i);
198
- }));
242
+ r.type === "childList" && r.addedNodes.forEach((o) => {
243
+ if (o.nodeType === Node.ELEMENT_NODE && t.contains(o)) {
244
+ const a = o;
245
+ this.processElement(a, i), a.querySelectorAll("[class]").forEach((c) => {
246
+ this.processElement(c, i);
247
+ });
248
+ }
199
249
  });
200
250
  }), i.size > 0) {
201
- const r = Array.from(i), n = this.incrementalParser.processClasses(r);
202
- this.BrowserRuntime?.applyParseResults(n);
203
- }
251
+ const r = Array.from(i), o = this.incrementalParser.processClasses(r);
252
+ this.BrowserRuntime?.applyParseResults(o);
253
+ } else
254
+ this.BrowserRuntime?.applyParseResults([]);
204
255
  }), this.observer.observe(t, {
205
256
  attributes: !0,
206
257
  subtree: !0,
@@ -213,20 +264,21 @@ class m {
213
264
  */
214
265
  scanExistingClasses(t, e) {
215
266
  const s = /* @__PURE__ */ new Set();
216
- t.className && c(t.className).forEach((n) => {
217
- this.incrementalParser.isProcessed(n) || s.add(n);
267
+ t.className && h(t.className).forEach((o) => {
268
+ this.incrementalParser.isProcessed(o) || s.add(o);
218
269
  });
219
270
  const i = t.querySelectorAll("[class]");
220
271
  for (const r of i)
221
272
  if (r.className) {
222
- const n = c(r.className);
223
- for (const o of n)
224
- this.incrementalParser.isProcessed(o) || s.add(o);
273
+ const o = h(r.className);
274
+ for (const a of o)
275
+ this.incrementalParser.isProcessed(a) || s.add(a);
225
276
  }
226
277
  if (s.size > 0) {
227
- const r = Array.from(s), n = this.incrementalParser.processClasses(r), o = n.filter((h) => y.get(h.cls)?.utility?.category === "layout"), l = n.filter((h) => y.get(h.cls)?.utility?.category !== "layout");
228
- this.BrowserRuntime?.applyParseResults(o), e?.onReady?.(), this.BrowserRuntime?.applyParseResults(l);
229
- }
278
+ const r = Array.from(s), o = this.incrementalParser.processClasses(r), a = o.filter((u) => this.getCategory(u.cls) === "layout"), c = o.filter((u) => this.getCategory(u.cls) !== "layout");
279
+ this.BrowserRuntime?.applyParseResults(a), e?.onReady?.(), this.BrowserRuntime?.applyParseResults(c);
280
+ } else
281
+ e?.onReady?.();
230
282
  }
231
283
  /**
232
284
  * Processes an individual element and extracts new classes
@@ -241,7 +293,7 @@ class m {
241
293
  * @param newClasses - Set to collect newly discovered class names
242
294
  */
243
295
  processElement(t, e) {
244
- t.className && c(t.className).forEach((i) => {
296
+ t.className && h(t.className).forEach((i) => {
245
297
  this.incrementalParser.isProcessed(i) || e.add(i);
246
298
  });
247
299
  }
@@ -256,16 +308,44 @@ class m {
256
308
  this.observer && (this.observer.disconnect(), this.observer = null);
257
309
  }
258
310
  }
259
- class C {
311
+ function I(n) {
312
+ return n.replace(/\\([0-9a-fA-F]{1,6})\s?|\\(.)/g, (t, e, s) => e ? String.fromCodePoint(parseInt(e, 16)) : s);
313
+ }
314
+ const L = /^\s*\.((?:\\[0-9a-fA-F]{1,6}\s?|\\.|[\w-]|[^\x00-\x7F])+)/;
315
+ function T(n) {
316
+ const t = [];
317
+ let e = 0, s = 0;
318
+ for (let i = 0; i < n.length; i++) {
319
+ const r = n[i];
320
+ r === "\\" ? i++ : r === "(" || r === "[" ? e++ : r === ")" || r === "]" ? e-- : r === "," && e === 0 && (t.push(n.slice(s, i)), s = i + 1);
321
+ }
322
+ return t.push(n.slice(s)), t;
323
+ }
324
+ function b(n, t = /* @__PURE__ */ new Set()) {
325
+ for (const e of Array.from(n)) {
326
+ const s = e.selectorText;
327
+ if (typeof s == "string")
328
+ for (const r of T(s)) {
329
+ const o = L.exec(r);
330
+ o && t.add(I(o[1]));
331
+ }
332
+ const i = e.cssRules;
333
+ i && i.length && b(i, t);
334
+ }
335
+ return t;
336
+ }
337
+ const $ = "@layer theme, base, components, utilities;";
338
+ class k {
260
339
  constructor(t = {}) {
261
- this.cache = /* @__PURE__ */ new Map(), this.rootCache = /* @__PURE__ */ new Set(), this.isDestroyed = !1;
340
+ this.cache = /* @__PURE__ */ new Map(), this.rootCache = /* @__PURE__ */ new Set(), this.isDestroyed = !1, this.existing = null, this.existingSheetCount = -1, this.getCategory = (s) => y(s, this.context).utility?.category;
262
341
  const e = {};
263
342
  this.options = {
264
343
  config: t.config || e,
265
344
  styleId: t.styleId || "barocss-runtime",
266
345
  insertionPoint: t.insertionPoint || "head",
267
- maxRulesPerPartition: t.maxRulesPerPartition || 50
268
- }, this.context = f(this.options.config), this.incrementalParser = new g(this.context), this.changeDetector = new m(this.incrementalParser, this), this.stylePartitionManager = new u(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`), this.init();
346
+ maxRulesPerPartition: t.maxRulesPerPartition || 50,
347
+ skipExisting: t.skipExisting ?? !1
348
+ }, this.context = g(this.options.config), this.incrementalParser = new p(this.context), this.changeDetector = new D(this.incrementalParser, this, this.getCategory), this.stylePartitionManager = new d(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`, this.getCategory), this.init();
269
349
  }
270
350
  // Debugging and logging helpers
271
351
  /**
@@ -278,9 +358,17 @@ class C {
278
358
  console.log("[BrowserRuntime] init"), this.injectPreflightCSS(), this.ensureCssVars();
279
359
  }
280
360
  injectPreflightCSS() {
281
- if (this.options.config.preflight) {
282
- const t = this.context.getPreflightCSS(this.options.config.preflight);
283
- this.stylePartitionManager.updateRuleContent("preflight", t);
361
+ const t = this.options.config.preflight ?? !0;
362
+ if (t) {
363
+ const e = this.context.getPreflightCSS(t);
364
+ this.stylePartitionManager.updateRuleContent(
365
+ "preflight",
366
+ `${$}
367
+ @layer base {
368
+ ${e}
369
+ }`,
370
+ !0
371
+ );
284
372
  }
285
373
  }
286
374
  ensureCssVars() {
@@ -289,7 +377,7 @@ class C {
289
377
  this.stylePartitionManager.updateRuleContent("css-vars", t);
290
378
  }
291
379
  getInsertionPoint() {
292
- if (this.options.insertionPoint instanceof HTMLElement)
380
+ if (typeof this.options.insertionPoint != "string")
293
381
  return this.options.insertionPoint;
294
382
  switch (this.options.insertionPoint) {
295
383
  case "body":
@@ -327,18 +415,42 @@ class C {
327
415
  if (this.isDestroyed) return;
328
416
  if (this.getInsertionPoint().isConnected && this.stylePartitionManager.hasDetachedPartitions()) {
329
417
  const r = Array.from(this.cache.values());
330
- this.reset(), t = [...r, ...t], t.forEach((n) => this.incrementalParser.markProcessed(n.cls));
418
+ this.reset(), t = [...r, ...t], t.forEach((o) => this.incrementalParser.markProcessed(o.cls));
419
+ }
420
+ if (this.options.skipExisting && t.length > 0 && typeof document < "u") {
421
+ const r = this.getExistingClasses();
422
+ t = t.filter((o) => !r.has(o.cls));
331
423
  }
424
+ if (t.length === 0) return;
332
425
  const s = [], i = [];
333
426
  for (const r of t)
334
427
  if (r.css && Array.isArray(r.cssList) && (s.push(r), this.cache.set(r.cls, r)), r.rootCss && Array.isArray(r.rootCssList))
335
- for (const n of r.rootCssList)
336
- this.rootCache.has(n) || (this.rootCache.add(n), i.push(n));
428
+ for (const o of r.rootCssList)
429
+ this.rootCache.has(o) || (this.rootCache.add(o), i.push(o));
337
430
  i.length > 0 && this.stylePartitionManager.addRootRules(i.filter(Boolean)), s.length > 0 && this.stylePartitionManager.addRules(s), this.debugLog("info", `Applied ${t.length} parser results`, {
338
431
  cssRuleCount: s.length,
339
432
  rootCssCount: i.length
340
433
  });
341
434
  }
435
+ /** Class names defined by the page's own stylesheets (BaroCSS's sheets and cross-origin sheets excluded). */
436
+ getExistingClasses() {
437
+ const t = Array.from(document.styleSheets).filter((s) => {
438
+ const i = s.ownerNode;
439
+ return !(i && typeof i.hasAttribute == "function" && (i.hasAttribute("data-barocss") || (i.id || "").startsWith(this.options.styleId)));
440
+ });
441
+ if (this.existing && t.length === this.existingSheetCount) return this.existing;
442
+ const e = /* @__PURE__ */ new Set();
443
+ for (const s of t) {
444
+ let i;
445
+ try {
446
+ i = s.cssRules;
447
+ } catch {
448
+ continue;
449
+ }
450
+ b(i, e);
451
+ }
452
+ return this.existing = e, this.existingSheetCount = t.length, e;
453
+ }
342
454
  /**
343
455
  * MutationObserver instance method to automatically call addClass when class attributes change in DOM
344
456
  */
@@ -356,7 +468,7 @@ class C {
356
468
  `);
357
469
  }
358
470
  getAllCss() {
359
- return Array.from(this.cache.values()).flatMap((e) => e.cssList).join(`
471
+ return [...this.rootCache, ...Array.from(this.cache.values()).flatMap((e) => e.cssList)].join(`
360
472
  `);
361
473
  }
362
474
  getClasses() {
@@ -380,15 +492,15 @@ class C {
380
492
  * Clear all caches (useful for debugging or memory management)
381
493
  */
382
494
  clearCaches() {
383
- this.isDestroyed || (this.cache.clear(), this.rootCache.clear(), P(this.context), this.incrementalParser.clearProcessed(), this.stylePartitionManager.cleanup(), this.stylePartitionManager = new u(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`), this.injectPreflightCSS(), this.ensureCssVars());
495
+ this.isDestroyed || (this.cache.clear(), this.rootCache.clear(), x(this.context), this.incrementalParser.clearProcessed(), this.stylePartitionManager.cleanup(), this.stylePartitionManager = new d(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`, this.getCategory), this.injectPreflightCSS(), this.ensureCssVars());
384
496
  }
385
497
  reset() {
386
- this.isDestroyed || (this.cache.clear(), this.rootCache.clear(), this.incrementalParser.clearProcessed(), this.stylePartitionManager.cleanup(), this.stylePartitionManager = new u(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`), this.injectPreflightCSS(), this.ensureCssVars());
498
+ this.isDestroyed || (this.cache.clear(), this.rootCache.clear(), this.incrementalParser.clearProcessed(), this.stylePartitionManager.cleanup(), this.stylePartitionManager = new d(this.getInsertionPoint(), this.options.maxRulesPerPartition, `${this.options.styleId}-partition`, this.getCategory), this.injectPreflightCSS(), this.ensureCssVars());
387
499
  }
388
500
  updateConfig(t) {
389
501
  if (this.isDestroyed) return;
390
502
  const e = Array.from(this.cache.keys());
391
- this.options.config = t, this.context = f(t), this.incrementalParser = new g(this.context), this.changeDetector.setParser(this.incrementalParser), this.reset(), e.length > 0 && this.addClass(e);
503
+ this.options.config = t, this.context = g(t), this.incrementalParser = new p(this.context), this.changeDetector.setParser(this.incrementalParser), this.reset(), e.length > 0 && this.addClass(e);
392
504
  }
393
505
  removeClass(t) {
394
506
  if (this.isDestroyed) return;
@@ -408,28 +520,98 @@ class C {
408
520
  };
409
521
  }
410
522
  }
411
- let d = null;
412
- function R(a) {
413
- return d || (d = new C(a)), d;
523
+ let l = null, f;
524
+ function B(n = {}) {
525
+ return !l || l.getStats().isDestroyed ? (l = new k(n), f = n.config) : n.config && n.config !== f && (l.updateConfig(n.config), f = n.config), l;
414
526
  }
415
- function b({ loadingClassName: a = "baro-boot", ...t } = {}) {
416
- const e = `${a}-doing`, s = `${a}-done`;
527
+ function R({ loadingClassName: n = "baro-boot", ...t } = {}) {
528
+ if (!document.body) {
529
+ document.addEventListener("DOMContentLoaded", () => R({ loadingClassName: n, ...t }), { once: !0 });
530
+ return;
531
+ }
532
+ const e = `${n}-doing`, s = `${n}-done`;
417
533
  try {
418
- document.body.classList.add(e), R(t).observe(document.body, { scan: !0, onReady: () => {
534
+ document.body.classList.add(e), B(t).observe(document.body, { scan: !0, onReady: () => {
419
535
  document.body.classList.remove(e), document.body.classList.add(s);
420
536
  } });
421
537
  } catch (i) {
422
- console.error("BaroCSS boot failed:", i);
538
+ document.body?.classList.remove(e), console.error("BaroCSS boot failed:", i);
423
539
  }
424
540
  }
425
- const E = b;
541
+ const V = R;
542
+ function j(n) {
543
+ if (!n || typeof n != "object" || Array.isArray(n)) return [];
544
+ const t = n.elements;
545
+ if (!t || typeof t != "object" || Array.isArray(t)) return [];
546
+ const e = /* @__PURE__ */ new Set();
547
+ for (const s of Object.keys(t)) {
548
+ const i = t[s];
549
+ if (!i || typeof i != "object" || Array.isArray(i)) continue;
550
+ const r = i.props;
551
+ if (!r || typeof r != "object" || Array.isArray(r)) continue;
552
+ const o = r.className;
553
+ if (typeof o == "string")
554
+ for (const a of o.split(/\s+/))
555
+ a && e.add(a);
556
+ }
557
+ return Array.from(e);
558
+ }
559
+ function O(n, t) {
560
+ const e = j(n);
561
+ e.length > 0 && t.addClass(e);
562
+ }
563
+ const z = [
564
+ "background",
565
+ "foreground",
566
+ "card",
567
+ "card-foreground",
568
+ "popover",
569
+ "popover-foreground",
570
+ "primary",
571
+ "primary-foreground",
572
+ "secondary",
573
+ "secondary-foreground",
574
+ "muted",
575
+ "muted-foreground",
576
+ "accent",
577
+ "accent-foreground",
578
+ "destructive",
579
+ "border",
580
+ "input",
581
+ "ring",
582
+ "chart-1",
583
+ "chart-2",
584
+ "chart-3",
585
+ "chart-4",
586
+ "chart-5",
587
+ "sidebar",
588
+ "sidebar-foreground",
589
+ "sidebar-primary",
590
+ "sidebar-primary-foreground",
591
+ "sidebar-accent",
592
+ "sidebar-accent-foreground",
593
+ "sidebar-border",
594
+ "sidebar-ring"
595
+ ], F = {
596
+ colors: Object.fromEntries(z.map((n) => [n, `var(--${n})`])),
597
+ borderRadius: {
598
+ sm: "calc(var(--radius) - 4px)",
599
+ md: "calc(var(--radius) - 2px)",
600
+ lg: "var(--radius)",
601
+ xl: "calc(var(--radius) + 4px)"
602
+ }
603
+ };
426
604
  export {
427
- C as BrowserRuntime,
428
- m as ChangeDetector,
429
- u as StylePartitionManager,
430
- b as baroBoot,
431
- E as baroStart,
432
- R as getRuntime,
433
- p as normalizeClassName,
434
- c as normalizeClassNameList
605
+ k as BrowserRuntime,
606
+ D as ChangeDetector,
607
+ $ as LAYER_ORDER,
608
+ d as StylePartitionManager,
609
+ R as baroBoot,
610
+ V as baroStart,
611
+ j as collectJsonRenderClassNames,
612
+ B as getRuntime,
613
+ N as normalizeClassName,
614
+ h as normalizeClassNameList,
615
+ O as preloadJsonRenderClasses,
616
+ F as shadcnTheme
435
617
  };