@yak/solid 0.1.0 → 0.2.1

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/internal.js CHANGED
@@ -1,15 +1,17 @@
1
- import { createMemo, merge } from "solid-js";
2
- import { Dynamic, createComponent } from "@solidjs/web";
1
+ import { $PROXY, createMemo } from "solid-js";
2
+ import { ChildProperties, DOMWithState, MathMLElements, SVGElements, createComponent, escape, getNextElement, insert, isServer, runHydrationEvents, spread, ssr, ssrClassName, ssrHydrationKey, ssrStyle, template } from "@solidjs/web";
3
3
  import { YakThemeContext, YakThemeProvider, useTheme, useTheme as useTheme$1 } from "@yak/solid/context";
4
4
 
5
5
  //#region runtime/cssLiteral.ts
6
- const yakComponentSymbol = Symbol("yak");
6
+ const yakComponentSymbol = Symbol.for("@yak/solid:component");
7
7
  var Classes = class {
8
8
  value;
9
+ generated = true;
9
10
  constructor(initial) {
10
11
  this.value = initial || "";
11
12
  }
12
- add(name) {
13
+ add(name, generated = true) {
14
+ if (!generated) this.generated = false;
13
15
  if (!this.value) this.value = name;
14
16
  else if (!this.has(name)) this.value += " " + name;
15
17
  }
@@ -37,10 +39,10 @@ function css(...args) {
37
39
  }, { $dynamic: false });
38
40
  return Object.assign((props, classes, allStyles) => {
39
41
  if (staticClass) classes.add(staticClass);
40
- for (let i = 0; i < dynamicCssFunctions.length; i++) unwrapProps(props, dynamicCssFunctions[i], classes, allStyles);
42
+ for (let i = 0; i < dynamicCssFunctions.length; i++) runProcessor(props, dynamicCssFunctions[i], classes, allStyles);
41
43
  }, { $dynamic: true });
42
44
  }
43
- const unwrapProps = (props, fn, classes, style) => {
45
+ const runProcessor = (props, fn, classes, style) => {
44
46
  let result = fn(props, classes, style);
45
47
  while (result) {
46
48
  if (typeof result === "function") {
@@ -81,65 +83,223 @@ const mergeClasses = (yakClass, userClass) => {
81
83
 
82
84
  //#endregion
83
85
  //#region runtime/styled.ts
84
- const renderDynamic = (props) => createComponent(Dynamic, props);
86
+ const VOID_ELEMENTS = /^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i;
85
87
  const styledFactory = (Component) => Object.assign(yakStyled(Component), { attrs: (attrs) => yakStyled(Component, attrs) });
86
88
  const styled = styledFactory;
87
89
  const yakStyled = (Component, attrs) => {
88
- const isYakComponent = typeof Component === "function" && Component[yakComponentSymbol] !== void 0;
89
- const [, parentAttrsFn, parentRuntimeStylesFn, parentTarget] = isYakComponent ? Component[yakComponentSymbol] : [];
90
- const targetComponent = isYakComponent ? parentTarget : Component;
91
- const mergedAttrsFn = buildRuntimeAttrsProcessor(attrs, parentAttrsFn);
90
+ const [parentAttrs, parentRuntimeStylesFn, parentTarget] = typeof Component === "function" && Component[yakComponentSymbol] !== void 0 ? Component[yakComponentSymbol] : [];
91
+ const targetComponent = parentTarget ?? Component;
92
+ const mergedAttrs = composeAttrs(attrs, parentAttrs);
92
93
  return (styles, ...values) => {
93
- const runtimeStyleProcessor = buildRuntimeStylesProcessor(css(styles, ...values), parentRuntimeStylesFn);
94
+ const runtimeStylesFn = css(styles, ...values);
95
+ const runtimeStyleProcessor = composeStyles(runtimeStylesFn, parentRuntimeStylesFn);
94
96
  const isTag = typeof targetComponent === "string";
95
- const targetProps = isTag ? { component: targetComponent } : {};
96
- const renderTarget = isTag ? renderDynamic : (finalProps) => createComponent(targetComponent, finalProps);
97
- const Yak = !mergedAttrsFn && !runtimeStyleProcessor.$dynamic ? (props) => renderTarget(filterDomProps(merge(props, targetProps, { get class() {
98
- const classes = new Classes(normalizeClass(props.class));
99
- runtimeStyleProcessor(props, classes, void 0);
100
- return classes.value || void 0;
101
- } }))) : (props) => {
102
- const theme = useTheme$1();
103
- const propsWithTheme = merge({ theme }, props);
104
- const attrsProps = mergedAttrsFn ? createMemo(() => mergedAttrsFn(propsWithTheme)) : void 0;
105
- const styleInput = attrsProps ? merge(propsWithTheme, attrsProps) : propsWithTheme;
106
- const computed = createMemo(() => {
107
- const attrsResult = attrsProps?.();
108
- const classes = new Classes(normalizeClass(props.class));
109
- const attrsClass = normalizeClass(attrsResult?.class);
110
- if (attrsClass) classes.add(attrsClass);
111
- const style = runtimeStyleProcessor.$dynamic || attrsResult?.style ? {
112
- ...unwrapStyle(props.style),
113
- ...unwrapStyle(attrsResult?.style)
114
- } : unwrapStyle(props.style);
115
- runtimeStyleProcessor(styleInput, classes, style);
116
- return {
117
- class: classes.value || void 0,
118
- style: style && Object.keys(style).length > 0 ? style : void 0
119
- };
120
- });
121
- const merged = merge(props, attrsProps ?? {}, {
122
- get class() {
123
- return computed().class;
124
- },
125
- get style() {
126
- return computed().style;
127
- }
128
- });
129
- const allowTheme = () => {
130
- const attrsResult = attrsProps?.();
131
- return !!attrsResult && "theme" in attrsResult && attrsResult.theme !== theme;
132
- };
133
- return renderTarget(filterDomProps(merge(merged, targetProps), allowTheme));
134
- };
135
- return Object.assign(Yak, { [yakComponentSymbol]: [
136
- Yak,
137
- mergedAttrsFn,
97
+ const baked = isTag && mergedAttrs && typeof mergedAttrs !== "function" && bakeable(targetComponent, mergedAttrs) ? mergedAttrs : void 0;
98
+ const attrString = baked ? bakeAttributes(baked) : "";
99
+ const renderTarget = createTargetRenderer(targetComponent, attrString);
100
+ const isStatic = (!mergedAttrs || !!baked) && !runtimeStyleProcessor.$dynamic;
101
+ const skip = (key) => typeof key !== "string" || key.charCodeAt(0) === 36 || key === "class" || key === "theme" || !isStatic && key === "style" || baked !== void 0 && Object.hasOwn(baked, key);
102
+ const Yak = isStatic ? createStaticComponent(isTag ? targetComponent : void 0, renderTarget, runtimeStyleProcessor, skip, attrString) : createDynamicComponent(renderTarget, typeof mergedAttrs === "function" ? mergedAttrs : mergedAttrs && (() => mergedAttrs), runtimeStyleProcessor, skip, !!baked);
103
+ const metadata = [
104
+ mergedAttrs,
138
105
  runtimeStyleProcessor,
139
106
  targetComponent
140
- ] });
107
+ ];
108
+ return Object.assign(Yak, { [yakComponentSymbol]: metadata });
109
+ };
110
+ };
111
+ const bakeable = (tag, attrs) => {
112
+ const stateful = DOMWithState[tag.toUpperCase()];
113
+ return Object.getOwnPropertyNames(attrs).every((key) => {
114
+ const descriptor = Object.getOwnPropertyDescriptor(attrs, key);
115
+ if (!descriptor.enumerable || !("value" in descriptor)) return false;
116
+ const type = typeof descriptor.value;
117
+ return (type === "string" || type === "number" || type === "boolean" || descriptor.value == null) && ATTRIBUTE_NAME.test(key) && key.charCodeAt(0) !== 36 && key !== "class" && key !== "style" && key !== "theme" && key !== "ref" && !ChildProperties.has(key) && !key.startsWith("on") && !key.startsWith("prop:") && !(stateful && key in stateful);
118
+ });
119
+ };
120
+ const bakeAttributes = (attrs) => {
121
+ let result = "";
122
+ for (const key of Object.keys(attrs)) {
123
+ const value = attrs[key];
124
+ if (value == null || value === false) continue;
125
+ result += value === true || value === "" ? ` ${key}` : ` ${key}="${escapeAttribute(String(value))}"`;
126
+ }
127
+ return result;
128
+ };
129
+ const escapeAttribute = (value) => value.replaceAll("&", "&amp;").replaceAll("\"", "&quot;");
130
+ const ATTRIBUTE_NAME = /^[A-Za-z_:][\w:.-]*$/;
131
+ const composeAttrs = (attrs, parent) => {
132
+ if (!attrs) return parent;
133
+ if (!parent) return attrs;
134
+ if (typeof attrs !== "function" && typeof parent !== "function" && !hasGetter(attrs) && !hasGetter(parent)) return combineProps(parent, attrs);
135
+ const own = typeof attrs === "function" ? attrs : () => attrs;
136
+ const parentFn = typeof parent === "function" ? parent : () => parent;
137
+ return (props) => {
138
+ const parentProps = parentFn(props);
139
+ return combineProps(parentProps, own(combineProps(props, parentProps)));
140
+ };
141
+ };
142
+ const composeStyles = (own, parent) => {
143
+ if (!parent) return own;
144
+ return Object.assign((props, classes, style) => {
145
+ parent(props, classes, style);
146
+ own(props, classes, style);
147
+ }, { $dynamic: own.$dynamic || parent.$dynamic });
148
+ };
149
+ const combineProps = (props, newProps) => {
150
+ if (!newProps) return props;
151
+ const descriptors = {
152
+ ...Object.getOwnPropertyDescriptors(props),
153
+ ...Object.getOwnPropertyDescriptors(newProps)
154
+ };
155
+ if (newProps.class && props.class !== newProps.class) descriptors.class = valueDescriptor(mergeClasses(normalizeClass(props.class), newProps.class));
156
+ if (newProps.style && props.style !== newProps.style) descriptors.style = valueDescriptor({
157
+ ...unwrapStyle(props.style),
158
+ ...unwrapStyle(newProps.style)
159
+ });
160
+ return Object.defineProperties({}, descriptors);
161
+ };
162
+ const valueDescriptor = (value) => ({
163
+ value,
164
+ enumerable: true,
165
+ configurable: true,
166
+ writable: true
167
+ });
168
+ const hasGetter = (object) => {
169
+ for (const key of Object.getOwnPropertyNames(object)) if (!("value" in Object.getOwnPropertyDescriptor(object, key))) return true;
170
+ return false;
171
+ };
172
+ const createStaticComponent = (tag, renderTarget, processor, skip, attrString) => {
173
+ const collected = new Classes();
174
+ processor(void 0, collected);
175
+ const staticClass = collected.value || void 0;
176
+ const classOf = (props) => {
177
+ const userClass = normalizeClass(props.class);
178
+ if (!userClass) return staticClass;
179
+ const classes = new Classes(userClass);
180
+ processor(props, classes);
181
+ return classes.value || void 0;
182
+ };
183
+ const renderChildrenOnly = tag && !VOID_ELEMENTS.test(tag) ? createChildrenOnlyRenderer(tag, staticClass, attrString) : void 0;
184
+ const meta = {
185
+ skip,
186
+ compute: void 0,
187
+ classOf,
188
+ attrsAddKeys: false,
189
+ unescapedClass: collected.generated ? staticClass : void 0
190
+ };
191
+ return (props) => {
192
+ if (renderChildrenOnly && (isServer || !($PROXY in props))) {
193
+ const keys = Object.keys(props);
194
+ if (!keys.length || keys.length === 1 && keys[0] === "children") return renderChildrenOnly(props, keys.length !== 0);
195
+ }
196
+ return renderTarget(props, meta);
197
+ };
198
+ };
199
+ const createChildrenOnlyRenderer = (tag, className, attrString) => {
200
+ if (isServer) {
201
+ const head = `<${tag}${attrString}`;
202
+ const open = `${className ? ` class="${ssrClassName(className)}"` : ""}>`;
203
+ const closing = `</${tag}>`;
204
+ const parts = [
205
+ head,
206
+ open,
207
+ closing
208
+ ];
209
+ const raw = tag === "script" || tag === "style";
210
+ return (props, hasChildren) => {
211
+ const hk = ssrHydrationKey();
212
+ const children = hasChildren ? raw ? props.children : escape(props.children) : void 0;
213
+ const text = plainContent(children);
214
+ if (text !== void 0) return { t: `${head}${hk}${open}${text}${closing}` };
215
+ return ssr(parts, hk, children);
216
+ };
217
+ }
218
+ const create = createElementTemplate(tag, attrString, className);
219
+ return (props, hasChildren) => {
220
+ const el = getNextElement(create);
221
+ if (hasChildren) {
222
+ const descriptor = Object.getOwnPropertyDescriptor(props, "children");
223
+ if (descriptor && "value" in descriptor) insert(el, descriptor.value);
224
+ else insert(el, () => props.children);
225
+ }
226
+ runHydrationEvents();
227
+ return el;
141
228
  };
142
229
  };
230
+ const createDynamicComponent = (renderTarget, attrsFn, processor, skip, baked) => (props) => {
231
+ const theme = useTheme$1();
232
+ const propsWithTheme = withTheme(props, theme);
233
+ const compute = () => computeStyles(props, propsWithTheme, attrsFn, processor);
234
+ const computed = isServer ? once(compute) : createMemo(compute, { transparent: true });
235
+ const allowTheme = attrsFn && (() => {
236
+ const attrs = computed().attrs;
237
+ return !!attrs && "theme" in attrs && attrs.theme !== theme;
238
+ });
239
+ return renderTarget(props, {
240
+ skip: allowTheme ? (key) => key === "theme" ? !allowTheme() : skip(key) : skip,
241
+ compute: computed,
242
+ classOf: void 0,
243
+ attrsAddKeys: !!attrsFn && !baked,
244
+ unescapedClass: void 0
245
+ });
246
+ };
247
+ const computeStyles = (props, propsWithTheme, attrsFn, processor) => {
248
+ const attrs = attrsFn?.(propsWithTheme);
249
+ const authorClass = normalizeClass(props.class);
250
+ const classes = new Classes(authorClass);
251
+ const attrsClass = normalizeClass(attrs?.class);
252
+ if (attrsClass) classes.add(attrsClass);
253
+ const style = processor.$dynamic || attrs?.style ? {
254
+ ...unwrapStyle(props.style),
255
+ ...unwrapStyle(attrs?.style)
256
+ } : unwrapStyle(props.style);
257
+ processor(attrs ? withAttrs(propsWithTheme, attrs) : propsWithTheme, classes, style);
258
+ return {
259
+ class: classes.value || void 0,
260
+ generatedClass: !authorClass && !attrsClass && classes.generated,
261
+ style: style && hasKeys(style) ? style : void 0,
262
+ attrs
263
+ };
264
+ };
265
+ const viewTraps = {
266
+ get: ({ props, theme, attrs }, key) => {
267
+ if (key === "theme" && theme && !("theme" in props)) return theme;
268
+ if (attrs && key in attrs) return Reflect.get(attrs, key);
269
+ return Reflect.get(props, key);
270
+ },
271
+ has: ({ props, theme, attrs }, key) => key === "theme" && !!theme || !!attrs && key in attrs || Reflect.has(props, key),
272
+ ownKeys: ({ props, theme, attrs }) => {
273
+ const keys = new Set(Reflect.ownKeys(props));
274
+ if (attrs) for (const key of Reflect.ownKeys(attrs)) keys.add(key);
275
+ if (theme) keys.add("theme");
276
+ return [...keys];
277
+ },
278
+ getOwnPropertyDescriptor: ({ props, theme, attrs }, key) => {
279
+ if (key === "theme" && theme && !("theme" in props)) return {
280
+ value: theme,
281
+ enumerable: true,
282
+ configurable: true
283
+ };
284
+ const descriptor = Reflect.getOwnPropertyDescriptor(attrs && key in attrs ? attrs : props, key);
285
+ return descriptor && {
286
+ ...descriptor,
287
+ configurable: true
288
+ };
289
+ }
290
+ };
291
+ const withTheme = (props, theme) => !($PROXY in props) && "theme" in props ? props : new Proxy({
292
+ props,
293
+ theme
294
+ }, viewTraps);
295
+ const withAttrs = (props, attrs) => new Proxy({
296
+ props,
297
+ attrs
298
+ }, viewTraps);
299
+ const once = (fn) => {
300
+ let value;
301
+ return () => value ??= fn();
302
+ };
143
303
  const unwrapStyle = (style) => {
144
304
  if (typeof style !== "string") return style;
145
305
  const result = {};
@@ -152,45 +312,178 @@ const unwrapStyle = (style) => {
152
312
  }
153
313
  return result;
154
314
  };
155
- const isBlockedProp = (key, allowTheme) => typeof key === "string" && (key.startsWith("$") || key === "theme" && !(allowTheme && allowTheme()));
156
- const filterDomProps = (props, allowTheme) => new Proxy(props, {
157
- get: (target, key) => isBlockedProp(key, allowTheme) ? void 0 : Reflect.get(target, key),
158
- has: (target, key) => !isBlockedProp(key, allowTheme) && Reflect.has(target, key),
159
- ownKeys: (target) => Reflect.ownKeys(target).filter((key) => !isBlockedProp(key, allowTheme)),
160
- getOwnPropertyDescriptor: (target, key) => isBlockedProp(key, allowTheme) ? void 0 : Reflect.getOwnPropertyDescriptor(target, key)
161
- });
162
- const mergeClasses$1 = (a, b) => {
163
- if (!a && !b) return void 0;
164
- if (!a) return b;
165
- if (!b) return a;
166
- return a + " " + b;
167
- };
168
- const combineProps = (props, newProps) => newProps ? (props.class === newProps.class || !newProps.class) && (props.style === newProps.style || !newProps.style) ? {
169
- ...props,
170
- ...newProps
171
- } : {
172
- ...props,
173
- ...newProps,
174
- class: mergeClasses$1(props.class, newProps.class),
175
- style: {
176
- ...unwrapStyle(props.style),
177
- ...unwrapStyle(newProps.style)
315
+ const hasKeys = (object) => {
316
+ for (const _ in object) return true;
317
+ return false;
318
+ };
319
+ const createTargetRenderer = (target, attrString) => {
320
+ if (typeof target !== "string") return (props, meta) => createComponent(target, targetProps(props, meta));
321
+ if (isServer) {
322
+ const head = `<${target}${attrString}`;
323
+ const closing = VOID_ELEMENTS.test(target) ? void 0 : `</${target}>`;
324
+ return (props, meta) => serializeElement(target, head, closing, props, meta);
178
325
  }
179
- } : props;
180
- const buildRuntimeAttrsProcessor = (attrs, parentAttrsFn) => {
181
- const ownAttrsFn = attrs && (typeof attrs === "function" ? attrs : () => attrs);
182
- if (ownAttrsFn && parentAttrsFn) return (props) => {
183
- const parentProps = parentAttrsFn(props);
184
- return combineProps(parentProps, ownAttrsFn(combineProps(props, parentProps)));
185
- };
186
- return ownAttrsFn || parentAttrsFn;
326
+ return createElementRenderer(target, attrString);
327
+ };
328
+ const serializeElement = (tag, head, closing, props, meta) => {
329
+ const hk = ssrHydrationKey();
330
+ let computed;
331
+ let className;
332
+ if (meta.compute) {
333
+ computed = meta.compute();
334
+ className = computed.class;
335
+ } else className = meta.classOf(props);
336
+ const attrs = computed?.attrs;
337
+ const style = computed?.style;
338
+ const skip = meta.skip;
339
+ let result = head + hk;
340
+ let children;
341
+ const textarea = tag === "textarea";
342
+ for (const key of Object.keys(props)) {
343
+ if (skip(key)) continue;
344
+ const source = attrs && key in attrs ? attrs : props;
345
+ if (!isChildKey(key, textarea)) result += attribute(key, source[key]);
346
+ else if (children === void 0 && closing) children = childContent(tag, key, source[key]);
347
+ }
348
+ if (attrs) for (const key of Object.keys(attrs)) {
349
+ if (skip(key) || key in props) continue;
350
+ if (!isChildKey(key, textarea)) result += attribute(key, attrs[key]);
351
+ else if (children === void 0 && closing) children = childContent(tag, key, attrs[key]);
352
+ }
353
+ if (className !== void 0) {
354
+ const generated = computed ? computed.generatedClass : className === meta.unescapedClass;
355
+ result += ` class="${generated ? className : ssrClassName(className)}"`;
356
+ }
357
+ if (style !== void 0) result += ` style="${ssrStyle(style)}"`;
358
+ if (!closing) return { t: result + " />" };
359
+ const text = plainContent(children);
360
+ if (text !== void 0) return { t: result + ">" + text + closing };
361
+ return ssr([result + ">", closing], children);
362
+ };
363
+ const isChildKey = (key, textarea) => ChildProperties.has(key) || textarea && (key === "value" || key === "defaultValue");
364
+ const plainContent = (node) => {
365
+ if (typeof node === "string") return node;
366
+ if (typeof node === "number") return String(node);
367
+ if (node == null || typeof node === "boolean") return "";
368
+ if (typeof node !== "object" || Array.isArray(node)) return void 0;
369
+ const server = node;
370
+ if (server.h && server.h.length > 0) return void 0;
371
+ if (typeof server.t === "string") return server.t;
372
+ };
373
+ const attribute = (prop, value) => {
374
+ if (prop === "style") return ` style="${ssrStyle(value)}"`;
375
+ if (prop === "class") return ` class="${ssrClassName(value)}"`;
376
+ if (value == void 0 || prop === "ref" || prop.startsWith("on") || prop.startsWith("prop:")) return "";
377
+ if (typeof value === "boolean") return value ? ` ${escape(prop)}` : "";
378
+ return value === "" ? ` ${escape(prop)}` : ` ${escape(prop)}="${escape(value, true)}"`;
379
+ };
380
+ const childContent = (tag, prop, value) => tag === "script" || tag === "style" || prop === "innerHTML" ? value : escape(value);
381
+ const createElementTemplate = (tag, attrString, className) => {
382
+ const opening = `<${tag}${attrString}${className ? ` class="${escapeAttribute(className)}"` : ""}>`;
383
+ if (SVGElements.has(tag) && tag !== "svg") return template(`<svg>${opening}`, 2);
384
+ if (MathMLElements.has(tag) && tag !== "math") return template(`<math>${opening}`, 2);
385
+ return template(opening);
386
+ };
387
+ const createElementRenderer = (tag, attrString) => {
388
+ const create = createElementTemplate(tag, attrString);
389
+ return (props, meta) => bindElement(getNextElement(create), props, meta);
390
+ };
391
+ const bindElement = (el, props, meta) => {
392
+ const bound = targetProps(props, meta);
393
+ const skipChildren = !($PROXY in bound) && !("children" in bound);
394
+ spread(el, bound, skipChildren);
395
+ runHydrationEvents();
396
+ return el;
397
+ };
398
+ const targetProps = (props, meta) => {
399
+ if (!meta.attrsAddKeys && !($PROXY in props)) return copyProps(props, meta);
400
+ return proxyProps(props, meta);
401
+ };
402
+ const copyProps = (props, meta) => {
403
+ const { compute, classOf } = meta;
404
+ const out = {};
405
+ for (const key of Object.getOwnPropertyNames(props)) {
406
+ if (meta.skip(key)) continue;
407
+ const descriptor = Reflect.getOwnPropertyDescriptor(props, key);
408
+ if ("value" in descriptor && descriptor.enumerable) out[key] = descriptor.value;
409
+ else Object.defineProperty(out, key, descriptor);
410
+ }
411
+ if (isServer) {
412
+ if (compute) {
413
+ const computed = compute();
414
+ out.class = computed.class;
415
+ if (computed.style !== void 0) out.style = computed.style;
416
+ } else out.class = classOf(props);
417
+ return out;
418
+ }
419
+ const classFn = compute ? () => compute().class : () => classOf(props);
420
+ const styleFn = styleGetter(compute);
421
+ Object.defineProperty(out, "class", {
422
+ get: classFn,
423
+ enumerable: true,
424
+ configurable: true
425
+ });
426
+ if (styleFn) Object.defineProperty(out, "style", {
427
+ get: styleFn,
428
+ enumerable: true,
429
+ configurable: true
430
+ });
431
+ return out;
432
+ };
433
+ const styleGetter = (compute) => {
434
+ if (!compute) return void 0;
435
+ if (isServer && compute().style === void 0) return void 0;
436
+ return () => compute().style;
187
437
  };
188
- const buildRuntimeStylesProcessor = (runtimeStylesFn, parentRuntimeStylesFn) => {
189
- if (runtimeStylesFn && parentRuntimeStylesFn) return Object.assign((props, classes, style) => {
190
- parentRuntimeStylesFn(props, classes, style);
191
- runtimeStylesFn(props, classes, style);
192
- }, { $dynamic: runtimeStylesFn.$dynamic || parentRuntimeStylesFn.$dynamic });
193
- return runtimeStylesFn || parentRuntimeStylesFn;
438
+ const proxyProps = (props, meta) => {
439
+ const { skip, compute, classOf } = meta;
440
+ const attrsProps = () => meta.attrsAddKeys ? meta.compute().attrs : void 0;
441
+ const classFn = compute ? () => compute().class : () => classOf(props);
442
+ const styleFn = styleGetter(compute);
443
+ const contributed = (key) => key === "class" ? classFn : key === "style" ? styleFn : void 0;
444
+ const fromAttrs = (key) => {
445
+ const attrs = attrsProps();
446
+ return attrs && key in attrs ? attrs : void 0;
447
+ };
448
+ return new Proxy(props, {
449
+ get(target, key, receiver) {
450
+ if (key === $PROXY) return receiver;
451
+ const getter = contributed(key);
452
+ if (getter) return getter();
453
+ if (skip(key)) return void 0;
454
+ const attrs = fromAttrs(key);
455
+ return attrs ? attrs[key] : Reflect.get(target, key);
456
+ },
457
+ has(target, key) {
458
+ if (key === $PROXY) return true;
459
+ if (contributed(key)) return true;
460
+ if (skip(key)) return false;
461
+ return Reflect.has(target, key) || fromAttrs(key) !== void 0;
462
+ },
463
+ ownKeys(target) {
464
+ const keys = /* @__PURE__ */ new Set();
465
+ for (const key of Reflect.ownKeys(target)) if (!skip(key)) keys.add(key);
466
+ for (const key of Object.keys(attrsProps() ?? {})) if (!skip(key)) keys.add(key);
467
+ keys.add("class");
468
+ if (styleFn) keys.add("style");
469
+ return [...keys];
470
+ },
471
+ getOwnPropertyDescriptor(target, key) {
472
+ const getter = contributed(key);
473
+ if (getter) return {
474
+ enumerable: true,
475
+ configurable: true,
476
+ get: getter
477
+ };
478
+ if (skip(key)) return void 0;
479
+ if (fromAttrs(key)) return {
480
+ enumerable: true,
481
+ configurable: true,
482
+ get: () => attrsProps()?.[key]
483
+ };
484
+ return Reflect.getOwnPropertyDescriptor(target, key);
485
+ }
486
+ });
194
487
  };
195
488
 
196
489
  //#endregion
@@ -200,9 +493,10 @@ const atoms = (...atoms) => {
200
493
  const dynamicFunctions = [];
201
494
  for (const atom of atoms) if (typeof atom === "string") staticClasses.push(...atom.split(" "));
202
495
  else if (typeof atom === "function") dynamicFunctions.push(atom);
203
- return css(...staticClasses.length > 0 ? [(_, classes) => {
204
- staticClasses.forEach((cls) => classes.add(cls));
205
- }, ...dynamicFunctions] : dynamicFunctions);
496
+ const runtimeFunctions = staticClasses.length > 0 ? [(_, classes) => {
497
+ staticClasses.forEach((cls) => classes.add(cls, false));
498
+ }, ...dynamicFunctions] : dynamicFunctions;
499
+ return css(...runtimeFunctions);
206
500
  };
207
501
 
208
502
  //#endregion
@@ -228,17 +522,49 @@ const unitPostFix = (arg, unit) => {
228
522
 
229
523
  //#endregion
230
524
  //#region runtime/internals/mergeCssProp.ts
231
- const mergeCssProp = (relevantProps, cssProp) => {
232
- const classes = new Classes(relevantProps.class);
233
- const existingStyle = relevantProps.style;
234
- const style = existingStyle ? { ...existingStyle } : {};
235
- if (cssProp) cssProp({}, classes, style);
236
- const result = { ...relevantProps };
237
- if (Object.keys(style).length > 0) result.style = style;
238
- else delete result.style;
239
- if (classes.value) result.class = classes.value;
240
- else delete result.class;
241
- return result;
525
+ const lastWith = (sources, key) => {
526
+ for (let index = sources.length - 1; index >= 0; index--) if (key in sources[index]) return sources[index];
527
+ };
528
+ const mergeCssProp = (cssProp, ...sources) => {
529
+ const present = sources.filter((source) => source != null);
530
+ const out = {};
531
+ for (const source of present) for (const key of Reflect.ownKeys(source)) {
532
+ if (key === "class" || key === "style") continue;
533
+ const descriptor = Reflect.getOwnPropertyDescriptor(source, key);
534
+ if (descriptor.get || descriptor.set || !descriptor.enumerable) Object.defineProperty(out, key, descriptor);
535
+ else out[key] = descriptor.value;
536
+ }
537
+ const classOwner = lastWith(present, "class");
538
+ const styleOwner = lastWith(present, "style");
539
+ const mergedClass = () => {
540
+ const classes = new Classes(normalizeClass(classOwner?.class));
541
+ if (cssProp) cssProp({}, classes, {});
542
+ return classes.value || void 0;
543
+ };
544
+ const mergedStyle = () => {
545
+ const base = styleOwner?.style;
546
+ const style = base ? { ...base } : {};
547
+ if (cssProp) cssProp({}, new Classes(), style);
548
+ for (const _ in style) return style;
549
+ };
550
+ if (isServer) {
551
+ const className = mergedClass();
552
+ if (className !== void 0) out.class = className;
553
+ const style = mergedStyle();
554
+ if (style !== void 0) out.style = style;
555
+ return out;
556
+ }
557
+ if (cssProp || classOwner) Object.defineProperty(out, "class", {
558
+ get: mergedClass,
559
+ enumerable: true,
560
+ configurable: true
561
+ });
562
+ if (cssProp || styleOwner) Object.defineProperty(out, "style", {
563
+ get: mergedStyle,
564
+ enumerable: true,
565
+ configurable: true
566
+ });
567
+ return out;
242
568
  };
243
569
 
244
570
  //#endregion