@pandacss/transformer 2.0.0-beta.9 → 2.0.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.
@@ -1,96 +1,335 @@
1
1
  // src/runtime/internal/cx.ts
2
2
  var bakedSeparator = typeof __PANDA_CX_SEPARATOR__ !== "undefined" && __PANDA_CX_SEPARATOR__ ? __PANDA_CX_SEPARATOR__ : "_";
3
+ var CHAR_OPEN_BRACKET = 91;
4
+ var CHAR_CLOSE_BRACKET = 93;
5
+ var CHAR_COLON = 58;
3
6
  function splitClassName(className) {
4
7
  const segments = [];
5
- let current = "";
8
+ let start = 0;
6
9
  let bracketDepth = 0;
7
10
  for (let i = 0; i < className.length; i++) {
8
- const ch = className[i];
9
- if (ch === "[") {
11
+ const code = className.charCodeAt(i);
12
+ if (code === CHAR_OPEN_BRACKET) {
10
13
  bracketDepth++;
11
- current += ch;
12
- } else if (ch === "]") {
14
+ } else if (code === CHAR_CLOSE_BRACKET) {
13
15
  bracketDepth--;
14
- current += ch;
15
- } else if (ch === ":" && bracketDepth === 0) {
16
- if (current) segments.push(current);
17
- current = "";
18
- } else {
19
- current += ch;
16
+ } else if (code === CHAR_COLON && bracketDepth === 0) {
17
+ if (i > start) segments.push(className.slice(start, i));
18
+ start = i + 1;
20
19
  }
21
20
  }
22
- if (current) segments.push(current);
21
+ if (start < className.length) segments.push(className.slice(start));
23
22
  return segments;
24
23
  }
25
24
  function getMergeKey(className, separator) {
26
- let cls = className;
27
- if (cls.endsWith("!")) {
28
- cls = cls.slice(0, -1);
25
+ let end = className.length;
26
+ if (end > 0 && className.charCodeAt(end - 1) === 33) {
27
+ end -= 1;
29
28
  }
30
- const segments = splitClassName(cls);
31
- if (segments.length === 0) return null;
32
- const last = segments[segments.length - 1];
33
- const sepIdx = last.indexOf(separator);
34
- if (sepIdx < 1) return null;
35
- const property = last.slice(0, sepIdx);
36
- if (segments.length === 1) {
37
- return property;
29
+ if (end === 0) return null;
30
+ let bracketDepth = 0;
31
+ let lastColon = -1;
32
+ for (let i = 0; i < end; i++) {
33
+ const code = className.charCodeAt(i);
34
+ if (code === CHAR_OPEN_BRACKET) {
35
+ bracketDepth++;
36
+ } else if (code === CHAR_CLOSE_BRACKET) {
37
+ bracketDepth--;
38
+ } else if (code === CHAR_COLON && bracketDepth === 0) {
39
+ lastColon = i;
40
+ }
38
41
  }
39
- const conditions = segments.slice(0, -1).join(":");
40
- return `${conditions}:${property}`;
41
- }
42
- function flattenParts(parts, out) {
43
- for (const part of parts) {
44
- if (!part) continue;
45
- if (Array.isArray(part)) {
46
- flattenParts(part, out);
42
+ const propStart = lastColon + 1;
43
+ const sepIdx = className.indexOf(separator, propStart);
44
+ if (sepIdx < propStart + 1 || sepIdx >= end) return null;
45
+ return className.slice(0, sepIdx);
46
+ }
47
+ var CACHE_LIMIT = 2048;
48
+ var CHAR_SPACE = 32;
49
+ var CHAR_BANG = 33;
50
+ var FIELDS = 4;
51
+ function createCache(limit = CACHE_LIMIT) {
52
+ let size = 0;
53
+ let current = /* @__PURE__ */ new Map();
54
+ let previous = /* @__PURE__ */ new Map();
55
+ const set = (key, value) => {
56
+ current.set(key, value);
57
+ if (++size > limit) {
58
+ size = 0;
59
+ previous = current;
60
+ current = /* @__PURE__ */ new Map();
61
+ }
62
+ };
63
+ return {
64
+ get(key) {
65
+ let value = current.get(key);
66
+ if (value === void 0 && (value = previous.get(key)) !== void 0) set(key, value);
67
+ return value;
68
+ },
69
+ set
70
+ };
71
+ }
72
+ function scanPart(part, separator, out, offset) {
73
+ let count = 0;
74
+ let clean = part.length > 0;
75
+ let start = 0;
76
+ for (let i = 0; i <= part.length; i++) {
77
+ const code = i === part.length ? CHAR_SPACE : part.charCodeAt(i);
78
+ if (code !== CHAR_SPACE && (code < 9 || code > 13)) continue;
79
+ if (code !== CHAR_SPACE || i === start) clean = false;
80
+ if (i === start) {
81
+ start = i + 1;
47
82
  continue;
48
83
  }
49
- if (part === "") continue;
50
- out.push(part);
84
+ const at = offset + count * FIELDS;
85
+ count++;
86
+ out[at] = start;
87
+ out[at + 1] = i;
88
+ out[at + 2] = -1;
89
+ let end = i;
90
+ if (part.charCodeAt(end - 1) === CHAR_BANG) end--;
91
+ let depth = 0;
92
+ let propStart = start;
93
+ for (let c = start; c < end; c++) {
94
+ const code2 = part.charCodeAt(c);
95
+ if (code2 === CHAR_OPEN_BRACKET) depth++;
96
+ else if (code2 === CHAR_CLOSE_BRACKET) depth--;
97
+ else if (code2 === CHAR_COLON && depth === 0) propStart = c + 1;
98
+ }
99
+ const sep = part.indexOf(separator, propStart);
100
+ if (sep > propStart && sep < end) {
101
+ let hash = 2166136261;
102
+ for (let c = start; c < sep; c++) hash = Math.imul(hash ^ part.charCodeAt(c), 16777619);
103
+ out[at + 2] = sep;
104
+ out[at + 3] = hash;
105
+ }
106
+ start = i + 1;
51
107
  }
108
+ return clean ? count : -count;
52
109
  }
53
- function mergeClassStrings(separator, classes) {
54
- const seen = /* @__PURE__ */ new Map();
55
- const order = [];
56
- let id = 0;
57
- for (const cls of classes) {
58
- for (const token of cls.split(" ")) {
59
- if (!token) continue;
60
- const key = getMergeKey(token, separator);
61
- if (key !== null) {
62
- if (!seen.has(key)) order.push(key);
63
- seen.set(key, token);
110
+ function createCx(options = {}) {
111
+ const separator = options.separator ?? bakedSeparator;
112
+ const scanned = createCache();
113
+ const seenOnce = createCache(512);
114
+ const parts = [];
115
+ let tokens = new Int32Array(64 * FIELDS);
116
+ let tokenPart = new Int32Array(64);
117
+ let winner = new Int32Array(64);
118
+ let tableSize = 128;
119
+ let table = new Int32Array(tableSize);
120
+ let stamps = new Int32Array(tableSize);
121
+ let stamp = 0;
122
+ function collect(value) {
123
+ if (!value) return;
124
+ if (typeof value === "string") parts.push(value);
125
+ else for (let i = 0; i < value.length; i++) collect(value[i]);
126
+ }
127
+ function reserve(tokenCount) {
128
+ if (tokenCount <= tokenPart.length) return;
129
+ let size = tokenPart.length;
130
+ while (size < tokenCount) size *= 2;
131
+ const grow = (from, length) => {
132
+ const next = new Int32Array(length);
133
+ next.set(from);
134
+ return next;
135
+ };
136
+ tokens = grow(tokens, size * FIELDS);
137
+ tokenPart = grow(tokenPart, size);
138
+ winner = grow(winner, size);
139
+ }
140
+ function sameKey(a, b) {
141
+ const aStart = tokens[a * FIELDS];
142
+ const bStart = tokens[b * FIELDS];
143
+ const length = tokens[a * FIELDS + 2] - aStart;
144
+ if (tokens[b * FIELDS + 2] - bStart !== length) return false;
145
+ const left = parts[tokenPart[a]];
146
+ const right = parts[tokenPart[b]];
147
+ for (let i = 0; i < length; i++) {
148
+ if (left.charCodeAt(aStart + i) !== right.charCodeAt(bStart + i)) return false;
149
+ }
150
+ return true;
151
+ }
152
+ function merge() {
153
+ let count = 0;
154
+ let clean = true;
155
+ for (let p = 0; p < parts.length; p++) {
156
+ const part = parts[p];
157
+ const cached = scanned.get(part);
158
+ let partCount;
159
+ if (cached !== void 0) {
160
+ partCount = cached[0];
161
+ reserve(count + Math.abs(partCount));
162
+ const base = count * FIELDS;
163
+ for (let i = 1; i < cached.length; i++) tokens[base + i - 1] = cached[i];
64
164
  } else {
65
- const uniqueKey = `__${id++}`;
66
- order.push(uniqueKey);
67
- seen.set(uniqueKey, token);
165
+ reserve(count + part.length);
166
+ partCount = scanPart(part, separator, tokens, count * FIELDS);
167
+ if (seenOnce.get(part) === void 0) seenOnce.set(part, true);
168
+ else {
169
+ const record = new Int32Array(1 + Math.abs(partCount) * FIELDS);
170
+ record[0] = partCount;
171
+ record.set(tokens.subarray(count * FIELDS, (count + Math.abs(partCount)) * FIELDS), 1);
172
+ scanned.set(part, record);
173
+ }
68
174
  }
175
+ if (partCount <= 0) clean = false;
176
+ const end = count + Math.abs(partCount);
177
+ for (; count < end; count++) tokenPart[count] = p;
69
178
  }
179
+ if (count * 2 > tableSize) {
180
+ while (count * 2 > tableSize) tableSize *= 2;
181
+ table = new Int32Array(tableSize);
182
+ stamps = new Int32Array(tableSize);
183
+ stamp = 0;
184
+ }
185
+ if (++stamp === 2147483647) {
186
+ stamp = 1;
187
+ stamps.fill(0);
188
+ }
189
+ const mask = tableSize - 1;
190
+ let replaced = false;
191
+ for (let t = 0; t < count; t++) {
192
+ winner[t] = t;
193
+ if (tokens[t * FIELDS + 2] < 0) continue;
194
+ const hash = tokens[t * FIELDS + 3];
195
+ let slot = hash & mask;
196
+ let owner = -1;
197
+ while (stamps[slot] === stamp) {
198
+ const candidate = table[slot];
199
+ if (tokens[candidate * FIELDS + 3] === hash && sameKey(candidate, t)) {
200
+ owner = candidate;
201
+ break;
202
+ }
203
+ slot = slot + 1 & mask;
204
+ }
205
+ if (owner === -1) {
206
+ stamps[slot] = stamp;
207
+ table[slot] = t;
208
+ } else {
209
+ winner[owner] = t;
210
+ winner[t] = -1;
211
+ replaced = true;
212
+ }
213
+ }
214
+ if (!replaced && clean) {
215
+ let joined = parts[0];
216
+ for (let p = 1; p < parts.length; p++) joined += " " + parts[p];
217
+ return joined;
218
+ }
219
+ let result = "";
220
+ for (let t = 0; t < count; t++) {
221
+ const w = winner[t];
222
+ if (w === -1) continue;
223
+ const piece = parts[tokenPart[w]].slice(tokens[w * FIELDS], tokens[w * FIELDS + 1]);
224
+ result = result ? result + " " + piece : piece;
225
+ }
226
+ return result;
70
227
  }
71
- let str = "";
72
- for (let i = 0; i < order.length; i++) {
73
- if (str) str += " ";
74
- str += seen.get(order[i]);
75
- }
76
- return str;
77
- }
78
- function createCx(options = {}) {
79
- const separator = options.separator ?? bakedSeparator;
80
- return function cx2(...parts) {
81
- const flat = [];
82
- flattenParts(parts, flat);
83
- return mergeClassStrings(separator, flat);
228
+ return function cx2(...args) {
229
+ parts.length = 0;
230
+ for (let i = 0; i < args.length; i++) collect(args[i]);
231
+ const count = parts.length;
232
+ if (count === 0) return "";
233
+ if (count === 1) return parts[0];
234
+ return merge();
84
235
  };
85
236
  }
86
- var cx = createCx();
237
+ var cx = /* @__PURE__ */ createCx();
87
238
 
88
239
  // src/runtime/internal/css.ts
89
240
  function css(...styles) {
90
241
  return cx(...styles);
91
242
  }
92
243
 
93
- // src/runtime/internal/cva.ts
244
+ // src/runtime/internal/memo.ts
245
+ var TABLE_MAX_SLOTS = 256;
246
+ var RING_ROWS = 16;
247
+ var isMutable = (value) => value !== null && (typeof value === "object" || typeof value === "function");
248
+ var KNOWN_MISSES = ["true", "false", "null"];
249
+ function tableMemo(resolve, keys, variantMap, strict) {
250
+ let slots = 1;
251
+ const radixes = [];
252
+ const trueStates = [];
253
+ const falseStates = [];
254
+ const nullStates = [];
255
+ const states = keys.map((key) => {
256
+ const state = /* @__PURE__ */ Object.create(null);
257
+ let count = 1;
258
+ for (const option of variantMap[key]) state[option] = count++;
259
+ if (strict) {
260
+ trueStates.push(count++);
261
+ falseStates.push(count++);
262
+ nullStates.push(count++);
263
+ } else {
264
+ for (const value of KNOWN_MISSES) state[value] ??= count++;
265
+ trueStates.push(state.true);
266
+ falseStates.push(state.false);
267
+ nullStates.push(state.null);
268
+ }
269
+ radixes.push(count);
270
+ slots *= count;
271
+ return state;
272
+ });
273
+ if (slots > TABLE_MAX_SLOTS) return null;
274
+ const table = new Array(slots);
275
+ let noProps;
276
+ return (props) => {
277
+ if (props == null) return noProps === void 0 ? noProps = resolve() : noProps;
278
+ let slot = 0;
279
+ for (let i = 0; i < keys.length; i++) {
280
+ const value = props[keys[i]];
281
+ let state = 0;
282
+ if (value === true) state = trueStates[i];
283
+ else if (value === false) state = falseStates[i];
284
+ else if (value === null) state = nullStates[i];
285
+ else if (typeof value === "string") state = states[i][value];
286
+ else if (value !== void 0) {
287
+ if (strict || isMutable(value)) return resolve(props);
288
+ state = states[i][String(value)];
289
+ }
290
+ if (state === void 0) return resolve(props);
291
+ slot = slot * radixes[i] + state;
292
+ }
293
+ let result = table[slot];
294
+ if (result === void 0) table[slot] = result = resolve(props);
295
+ return result;
296
+ };
297
+ }
298
+ function ringMemo(resolve, keys) {
299
+ const width = keys.length;
300
+ const values = new Array(RING_ROWS * width);
301
+ const results = new Array(RING_ROWS);
302
+ let written = 0;
303
+ let next = 0;
304
+ let noProps;
305
+ return (props) => {
306
+ if (props == null) return noProps === void 0 ? noProps = resolve() : noProps;
307
+ scan: for (let row = 0; row < written; row++) {
308
+ const start2 = row * width;
309
+ for (let i = 0; i < width; i++) {
310
+ if (props[keys[i]] !== values[start2 + i]) continue scan;
311
+ }
312
+ return results[row];
313
+ }
314
+ for (let i = 0; i < width; i++) {
315
+ if (isMutable(props[keys[i]])) return resolve(props);
316
+ }
317
+ const result = resolve(props);
318
+ const start = next * width;
319
+ for (let i = 0; i < width; i++) values[start + i] = props[keys[i]];
320
+ results[next] = result;
321
+ if (next === written) written++;
322
+ next = (next + 1) % RING_ROWS;
323
+ return result;
324
+ };
325
+ }
326
+ function memoRecipe(resolve, variantMap, hasCompounds) {
327
+ const keys = Object.keys(variantMap);
328
+ if (keys.length === 0) return resolve;
329
+ return tableMemo(resolve, keys, variantMap, !!hasCompounds) ?? ringMemo(resolve, keys);
330
+ }
331
+
332
+ // src/runtime/internal/shared.ts
94
333
  function withDefaults(defaults, props) {
95
334
  const out = { ...defaults };
96
335
  for (const key in props) {
@@ -111,142 +350,88 @@ function compoundMatches(compound, variants) {
111
350
  }
112
351
  return true;
113
352
  }
114
- function toVariantMap(variants) {
115
- const map = {};
116
- for (const key in variants) map[key] = Object.keys(variants[key] ?? {});
117
- return map;
353
+
354
+ // src/runtime/internal/recipe.ts
355
+ var isStyleObject = (value) => value != null && typeof value === "object" && !Array.isArray(value);
356
+ function mergeStyles(...styles) {
357
+ const out = {};
358
+ for (const style of styles) {
359
+ if (!isStyleObject(style)) continue;
360
+ for (const key in style) {
361
+ const value = style[key];
362
+ out[key] = isStyleObject(value) ? mergeStyles(out[key], value) : value;
363
+ }
364
+ }
365
+ return out;
118
366
  }
119
- function cva(config) {
120
- const base = config.base ?? "";
367
+ function resolveRaw(config, props, pick = (style) => style) {
368
+ const selected = withDefaults(config.defaultVariants ?? {}, props);
121
369
  const variants = config.variants ?? {};
122
- const defaultVariants = config.defaultVariants ?? {};
123
- const compoundVariants = config.compoundVariants ?? [];
124
- const variantKeys = Object.keys(variants);
125
- const resolve = (props = {}) => {
126
- const computed = withDefaults(defaultVariants, props);
127
- const parts = [];
128
- if (base) parts.push(base);
129
- for (const key of variantKeys) {
130
- const value = computed[key];
131
- if (typeof value === "string" && variants[key]?.[value]) {
132
- parts.push(variants[key][value]);
133
- }
134
- }
135
- for (const compound of compoundVariants) {
136
- if (!compoundMatches(compound, computed)) continue;
137
- const cls = compound.className ?? compound.css;
138
- if (typeof cls === "string" && cls) parts.push(cls);
139
- }
140
- return cx(...parts);
141
- };
142
- const cvaFn = (props = {}) => resolve(props);
143
- return Object.assign(cvaFn, {
144
- __cva__: true,
145
- variantKeys,
146
- variantMap: toVariantMap(variants),
147
- raw: resolve,
148
- config,
149
- getVariantProps(props) {
150
- return withDefaults(defaultVariants, props);
151
- },
152
- splitVariantProps(props) {
153
- const rest = {};
154
- const variantProps = {};
155
- for (const key in props) {
156
- if (variantKeys.includes(key)) variantProps[key] = props[key];
157
- else rest[key] = props[key];
158
- }
159
- return [rest, variantProps];
160
- }
161
- });
370
+ const styles = [pick(config.base)];
371
+ for (const key in selected) styles.push(pick(variants[key]?.[selected[key]]));
372
+ for (const compound of config.compoundVariants ?? []) {
373
+ if (compoundMatches(compound, selected)) styles.push(pick(compound.css));
374
+ }
375
+ return mergeStyles(...styles);
162
376
  }
163
-
164
- // src/runtime/internal/sva.ts
165
- function slotCompoundVariants(compoundVariants, slot) {
166
- if (!compoundVariants?.length) return void 0;
167
- return compoundVariants.map((compound) => {
168
- const next = {};
169
- for (const key in compound) {
170
- if (key === "css" || key === "className" || key === "classNames") continue;
171
- next[key] = compound[key];
172
- }
173
- const css2 = compound.css;
174
- if (typeof css2 === "string") next.css = css2;
175
- else if (css2 && typeof css2 === "object" && slot in css2) next.css = css2[slot];
176
- const className = compound.classNames?.[slot] ?? compound.className;
177
- if (className) next.className = className;
178
- return next;
179
- }).filter((compound) => compound.css || compound.className);
180
- }
181
- function getSlotRecipes(config) {
182
- const slots = config.slots ?? Object.keys(config.base ?? {});
183
- const recipes = {};
184
- for (const slot of slots) {
185
- recipes[slot] = {
186
- base: config.base?.[slot],
187
- variants: config.variants,
188
- defaultVariants: config.defaultVariants,
189
- compoundVariants: slotCompoundVariants(config.compoundVariants, slot)
190
- };
191
- if (config.className?.[slot]) {
192
- recipes[slot] = {
193
- ...recipes[slot],
194
- base: cx(recipes[slot]?.base, config.className[slot])
195
- };
196
- }
377
+ function resolveSlotRaw(config, props) {
378
+ const result = {};
379
+ for (const slot of config.slots ?? Object.keys(config.base ?? {})) {
380
+ result[slot] = resolveRaw(config, props, (style) => style?.[slot]);
197
381
  }
198
- return recipes;
199
- }
200
- function sva(config) {
201
- const slotRecipes = getSlotRecipes(config);
202
- const slots = Object.entries(slotRecipes).map(([slot, recipe]) => [slot, cva(recipe)]);
203
- const defaultVariants = config.defaultVariants ?? {};
204
- const variantKeys = Object.keys(config.variants ?? {});
205
- const svaFn = (props = {}) => {
206
- const result = {};
207
- for (const [slot, slotFn] of slots) {
208
- result[slot] = slotFn(props);
209
- }
210
- return result;
211
- };
212
- const raw = (props = {}) => {
213
- const result = {};
214
- for (const [slot, slotFn] of slots) {
215
- result[slot] = slotFn.raw(props);
216
- }
217
- return result;
382
+ return result;
383
+ }
384
+ function mergeRecipes(parent, child) {
385
+ const defaultVariants = { ...parent.config?.defaultVariants, ...child.config?.defaultVariants };
386
+ const variantKeys = [.../* @__PURE__ */ new Set([...parent.variantKeys ?? [], ...child.variantKeys ?? []])];
387
+ const resolve = (props = {}) => withDefaults(defaultVariants, props);
388
+ const merged = attachRecipe(
389
+ (props) => {
390
+ const selected = resolve(props);
391
+ return cx(parent(selected), child(selected));
392
+ },
393
+ // Compounds from either side rule out the coercing table memo.
394
+ {
395
+ defaultVariants,
396
+ compoundVariants: [...parent.config?.compoundVariants ?? [], ...child.config?.compoundVariants ?? []]
397
+ },
398
+ variantKeys,
399
+ { ...parent.variantMap, ...child.variantMap }
400
+ );
401
+ merged.raw = (props) => {
402
+ const selected = resolve(props);
403
+ return mergeStyles(parent.raw(selected), child.raw(selected));
218
404
  };
219
- return Object.assign(svaFn, {
220
- __cva__: false,
221
- raw,
222
- config,
223
- variantMap: Object.fromEntries(variantKeys.map((key) => [key, Object.keys(config.variants?.[key] ?? {})])),
405
+ return merged;
406
+ }
407
+ function attachRecipe(fn, config, variantKeys, variantMap, classNameMap) {
408
+ const recipeConfig = config;
409
+ const defaults = recipeConfig.defaultVariants ?? {};
410
+ const recipe = memoRecipe(fn, variantMap, recipeConfig.compoundVariants?.length);
411
+ return Object.assign(recipe, {
412
+ __cva__: !classNameMap,
224
413
  variantKeys,
225
- classNameMap: config.className ?? {},
226
- getVariantProps(props) {
227
- const out = { ...defaultVariants };
228
- for (const key in props) {
229
- if (props[key] !== void 0) out[key] = props[key];
230
- }
231
- return out;
232
- },
233
- splitVariantProps(props) {
234
- const rest = {};
414
+ variantMap,
415
+ ...classNameMap && { classNameMap },
416
+ config,
417
+ raw: (props = {}) => classNameMap ? resolveSlotRaw(recipeConfig, props) : resolveRaw(recipeConfig, props),
418
+ // The styled factory passes its own `cva`, so chains merge exactly like styled-system.
419
+ merge: (other, cva) => cva ? cva(config).merge(other) : mergeRecipes(recipe, other),
420
+ getVariantProps: (props = {}) => withDefaults(defaults, props),
421
+ splitVariantProps: (props) => {
235
422
  const variantProps = {};
236
- for (const key in props) {
237
- if (variantKeys.includes(key)) variantProps[key] = props[key];
238
- else rest[key] = props[key];
239
- }
240
- return [rest, variantProps];
423
+ const restProps = {};
424
+ for (const key in props) (variantKeys.includes(key) ? variantProps : restProps)[key] = props[key];
425
+ return [variantProps, restProps];
241
426
  }
242
427
  });
243
428
  }
244
429
  export {
430
+ attachRecipe,
245
431
  createCx,
246
432
  css,
247
- cva,
248
433
  cx,
249
434
  getMergeKey,
250
- splitClassName,
251
- sva
435
+ memoRecipe,
436
+ splitClassName
252
437
  };