@symbo.ls/brender 3.8.9 → 3.14.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/README.md CHANGED
@@ -113,14 +113,14 @@ const result = await render(data, { route: '/about' })
113
113
 
114
114
  // result.html -> full page HTML with data-br keys
115
115
  // result.metadata -> { title, description, og:image, ... }
116
- // result.emotionCSS -> array of CSS rule strings from emotion
116
+ // result.css -> array of CSS rule strings from the atomic CSS engine
117
117
  // result.registry -> { br-key: domqlElement }
118
118
  // result.element -> root DOMQL element
119
119
  ```
120
120
 
121
121
  ### `renderPage(data, route, options?)`
122
122
 
123
- Renders a complete, ready-to-serve HTML page. Combines `render()` output with metadata, CSS (emotion + global), fonts, and optional ISR client bundle.
123
+ Renders a complete, ready-to-serve HTML page. Combines `render()` output with metadata, CSS (atomic + global), fonts, and optional ISR client bundle.
124
124
 
125
125
  ```js
126
126
  import { renderPage, loadProject } from '@symbo.ls/brender'
@@ -345,11 +345,11 @@ This means the server and client don't need to exchange the registry — as long
345
345
 
346
346
  - `renderElement()` uses `@domql/element` create directly — lightweight, no smbls bootstrap. Good for individual components
347
347
  - `render()` uses the full `smbls/src/createDomql.js` pipeline — handles routing, designSystem initialization, uikit defaults, the works. Needed for complete apps
348
- - The smbls source is bundled with esbuild (cached after first call) because the monorepo uses extensionless/directory imports that Node.js ESM can't resolve natively. The esbuild plugin patches SSR-incompatible code (window references, createRequire, circular imports) and stubs out browser-only packages (@symbo.ls/sync)
348
+ - The smbls source is bundled with esbuild (cached after first call) because the monorepo uses extensionless/directory imports that Node.js ESM can't resolve natively. The esbuild plugin patches SSR-incompatible code (window references, createRequire, circular imports) and stubs out browser-only packages
349
349
  - `render()` sets `globalThis.document` and `globalThis.location` before each render to match the linkedom virtual env, then restores them after. This allows the bundled smbls code (which reads `window = globalThis`) to work in SSR
350
350
  - `hydrate.js` is browser-only code (no linkedom dependency) — it's exported separately via `@symbo.ls/brender/hydrate`
351
351
  - `createEnv()` sets `globalThis.window/document/Node/HTMLElement` because `@domql/utils` `isDOMNode` uses `instanceof` checks against global constructors
352
- - Emotion CSS is extracted from the CSSOM sheet rules (emotion uses `insertRule()` which doesn't populate `textContent` in linkedom)
352
+ - CSS is extracted from the atomic CSS engine's generated rules
353
353
  - `onRender` callbacks that do network requests or call `s.update()` will error during SSR — this is expected and harmless since the HTML is already produced before those callbacks fire
354
354
  - Data prefetching (`prefetch.js`) walks page definitions to find `fetch` declarations, then executes them against the DB adapter before rendering. Fetched data is injected into page state so components render with real content
355
355
 
package/dist/esm/env.js CHANGED
@@ -1,75 +1 @@
1
- import { parseHTML } from "linkedom";
2
- const createEnv = (html = "<!DOCTYPE html><html><head></head><body></body></html>") => {
3
- const { window, document } = parseHTML(html);
4
- if (!window.requestAnimationFrame) {
5
- window.requestAnimationFrame = (fn) => setTimeout(fn, 0);
6
- }
7
- if (!window.cancelAnimationFrame) {
8
- window.cancelAnimationFrame = (id) => clearTimeout(id);
9
- }
10
- if (!window.history) {
11
- window.history = {
12
- pushState: () => {
13
- },
14
- replaceState: () => {
15
- },
16
- state: null
17
- };
18
- }
19
- if (!window.location) {
20
- window.location = { pathname: "/", search: "", hash: "", origin: "http://localhost" };
21
- }
22
- if (!window.URL) {
23
- window.URL = URL;
24
- }
25
- if (!window.scrollTo) {
26
- window.scrollTo = () => {
27
- };
28
- }
29
- const createStorage = () => {
30
- const store = {};
31
- return {
32
- getItem: (k) => store[k] ?? null,
33
- setItem: (k, v) => {
34
- store[k] = String(v);
35
- },
36
- removeItem: (k) => {
37
- delete store[k];
38
- },
39
- clear: () => {
40
- for (const k in store) delete store[k];
41
- },
42
- get length() {
43
- return Object.keys(store).length;
44
- },
45
- key: (i) => Object.keys(store)[i] ?? null
46
- };
47
- };
48
- if (!window.localStorage) window.localStorage = createStorage();
49
- if (!window.sessionStorage) window.sessionStorage = createStorage();
50
- if (!globalThis.localStorage) globalThis.localStorage = window.localStorage;
51
- if (!globalThis.sessionStorage) globalThis.sessionStorage = window.sessionStorage;
52
- if (!window.MutationObserver) {
53
- window.MutationObserver = class MutationObserver {
54
- constructor() {
55
- }
56
- observe() {
57
- }
58
- disconnect() {
59
- }
60
- takeRecords() {
61
- return [];
62
- }
63
- };
64
- }
65
- globalThis.window = window;
66
- globalThis.document = document;
67
- globalThis.Node = window.Node || globalThis.Node;
68
- globalThis.HTMLElement = window.HTMLElement || globalThis.HTMLElement;
69
- globalThis.MutationObserver = window.MutationObserver;
70
- globalThis.Window = window.constructor;
71
- return { window, document };
72
- };
73
- export {
74
- createEnv
75
- };
1
+ import{parseHTML as i}from"linkedom";const c=(r="<!DOCTYPE html><html><head></head><body></body></html>")=>{const{window:e,document:l}=i(r);e.requestAnimationFrame||(e.requestAnimationFrame=o=>{const t=setTimeout(o,0);return t?.unref&&t.unref(),t}),e.cancelAnimationFrame||(e.cancelAnimationFrame=o=>clearTimeout(o)),e.history||(e.history={pushState:()=>{},replaceState:()=>{},state:null}),e.location||(e.location={pathname:"/",search:"",hash:"",origin:"http://localhost"}),e.URL||(e.URL=URL),e.scrollTo||(e.scrollTo=()=>{});const a=()=>{const o={};return{getItem:t=>o[t]??null,setItem:(t,s)=>{o[t]=String(s)},removeItem:t=>{delete o[t]},clear:()=>{for(const t in o)delete o[t]},get length(){return Object.keys(o).length},key:t=>Object.keys(o)[t]??null}};return e.localStorage||(e.localStorage=a()),e.sessionStorage||(e.sessionStorage=a()),globalThis.localStorage||(globalThis.localStorage=e.localStorage),globalThis.sessionStorage||(globalThis.sessionStorage=e.sessionStorage),e.MutationObserver||(e.MutationObserver=class{constructor(){}observe(){}disconnect(){}takeRecords(){return[]}}),globalThis.window=e,globalThis.document=l,globalThis.Node=e.Node||globalThis.Node,globalThis.Element=e.Element||globalThis.Element,globalThis.HTMLElement=e.HTMLElement||globalThis.HTMLElement,globalThis.MutationObserver=e.MutationObserver,globalThis.Window=e.constructor,{window:e,document:l}};export{c as createEnv};
@@ -1,546 +1 @@
1
- const collectBrNodes = (root) => {
2
- const container = root || document;
3
- const nodes = container.querySelectorAll("[data-br]");
4
- const map = {};
5
- nodes.forEach((node) => {
6
- map[node.getAttribute("data-br")] = node;
7
- });
8
- return map;
9
- };
10
- const hydrate = (element, options = {}) => {
11
- const {
12
- root,
13
- events: attachEvents = true,
14
- renderEvents: fireRenderEvents = true,
15
- emotion,
16
- designSystem
17
- } = options;
18
- const brNodes = collectBrNodes(root);
19
- const colorMap = designSystem?.color || {};
20
- const mediaMap = designSystem?.media || {};
21
- let linked = 0;
22
- let unlinked = 0;
23
- const walk = (el) => {
24
- if (!el || !el.__ref) return;
25
- const brKey = el.__ref.__brKey;
26
- if (brKey) {
27
- const node = brNodes[brKey];
28
- if (node) {
29
- el.node = node;
30
- node.ref = el;
31
- if (emotion) {
32
- renderCSS(el, emotion, colorMap, mediaMap);
33
- }
34
- if (attachEvents) {
35
- bindEvents(el);
36
- }
37
- linked++;
38
- } else {
39
- unlinked++;
40
- }
41
- }
42
- if (el.__ref.__children) {
43
- for (const childKey of el.__ref.__children) {
44
- const child = el[childKey];
45
- if (child && child.__ref) walk(child);
46
- }
47
- }
48
- };
49
- walk(element);
50
- if (fireRenderEvents) {
51
- fireLifecycle(element);
52
- }
53
- return { element, linked, unlinked };
54
- };
55
- const renderCSS = (el, emotion, colorMap, mediaMap) => {
56
- const { node, props } = el;
57
- if (!node || !props) return;
58
- const css = {};
59
- let hasCss = false;
60
- for (const key in props) {
61
- const val = props[key];
62
- if (key.charCodeAt(0) === 64) {
63
- const breakpoint = mediaMap[key.slice(1)];
64
- if (breakpoint && typeof val === "object") {
65
- const mediaCss = resolvePropsToCSS(val, colorMap);
66
- if (Object.keys(mediaCss).length) {
67
- css[breakpoint] = mediaCss;
68
- hasCss = true;
69
- }
70
- }
71
- continue;
72
- }
73
- if (key.charCodeAt(0) === 58) {
74
- if (typeof val === "object") {
75
- const pseudoCss = resolvePropsToCSS(val, colorMap);
76
- if (Object.keys(pseudoCss).length) {
77
- css["&" + key] = pseudoCss;
78
- hasCss = true;
79
- }
80
- }
81
- continue;
82
- }
83
- const expanded = resolveShorthand(key, val);
84
- if (expanded) {
85
- for (const ek in expanded) {
86
- css[ek] = resolveValue(ek, expanded[ek], colorMap);
87
- }
88
- hasCss = true;
89
- continue;
90
- }
91
- if (!isCSS(key)) continue;
92
- css[key] = resolveValue(key, val, colorMap);
93
- hasCss = true;
94
- }
95
- const extsCss = getExtendsCSS(el);
96
- if (extsCss) {
97
- for (const [k, v] of Object.entries(extsCss)) {
98
- if (!css[k]) {
99
- css[k] = v;
100
- hasCss = true;
101
- }
102
- }
103
- }
104
- if (el.style && typeof el.style === "object") {
105
- Object.assign(css, el.style);
106
- hasCss = true;
107
- }
108
- if (!hasCss) return;
109
- const emotionClass = emotion.css(css);
110
- const classes = [];
111
- if (emotionClass) classes.push(emotionClass);
112
- if (typeof el.key === "string" && el.key.charCodeAt(0) === 95 && el.key.charCodeAt(1) !== 95) {
113
- classes.push(el.key.slice(1));
114
- }
115
- if (props.class) classes.push(props.class);
116
- if (el.attr?.class) classes.push(el.attr.class);
117
- const classlist = el.classlist;
118
- if (classlist) {
119
- if (typeof classlist === "string") classes.push(classlist);
120
- else if (typeof classlist === "object") {
121
- for (const k in classlist) {
122
- const v = classlist[k];
123
- if (typeof v === "boolean" && v) classes.push(k);
124
- else if (typeof v === "string") classes.push(v);
125
- else if (typeof v === "object" && v) classes.push(emotion.css(v));
126
- }
127
- }
128
- }
129
- if (classes.length) {
130
- node.setAttribute("class", classes.join(" "));
131
- }
132
- for (const key in props) {
133
- if (isCSS(key) && node.hasAttribute(key)) {
134
- node.removeAttribute(key);
135
- }
136
- }
137
- };
138
- const resolvePropsToCSS = (propsObj, colorMap) => {
139
- const css = {};
140
- for (const key in propsObj) {
141
- const expanded = resolveShorthand(key, propsObj[key]);
142
- if (expanded) {
143
- for (const ek in expanded) css[ek] = resolveValue(ek, expanded[ek], colorMap);
144
- continue;
145
- }
146
- if (!isCSS(key)) continue;
147
- css[key] = resolveValue(key, propsObj[key], colorMap);
148
- }
149
- return css;
150
- };
151
- const COLOR_PROPS = /* @__PURE__ */ new Set([
152
- "color",
153
- "background",
154
- "backgroundColor",
155
- "borderColor",
156
- "borderTopColor",
157
- "borderRightColor",
158
- "borderBottomColor",
159
- "borderLeftColor",
160
- "outlineColor",
161
- "fill",
162
- "stroke",
163
- "caretColor",
164
- "columnRuleColor",
165
- "textDecorationColor",
166
- "boxShadow",
167
- "textShadow"
168
- ]);
169
- const resolveValue = (key, val, colorMap) => {
170
- if (typeof val !== "string") return val;
171
- if (COLOR_PROPS.has(key) && colorMap[val]) return colorMap[val];
172
- return val;
173
- };
174
- const NON_CSS_PROPS = /* @__PURE__ */ new Set([
175
- "href",
176
- "src",
177
- "alt",
178
- "title",
179
- "id",
180
- "name",
181
- "type",
182
- "value",
183
- "placeholder",
184
- "target",
185
- "rel",
186
- "loading",
187
- "srcset",
188
- "sizes",
189
- "media",
190
- "role",
191
- "tabindex",
192
- "for",
193
- "action",
194
- "method",
195
- "enctype",
196
- "autocomplete",
197
- "autofocus",
198
- "theme",
199
- "__element",
200
- "update"
201
- ]);
202
- const EXTENDS_CSS = {
203
- Flex: { display: "flex" },
204
- InlineFlex: { display: "inline-flex" },
205
- Grid: { display: "grid" },
206
- InlineGrid: { display: "inline-grid" },
207
- Block: { display: "block" },
208
- Inline: { display: "inline" }
209
- };
210
- const getExtendsCSS = (el) => {
211
- const exts = el.__ref?.__extends;
212
- if (!exts || !Array.isArray(exts)) return null;
213
- for (const ext of exts) {
214
- if (EXTENDS_CSS[ext]) return EXTENDS_CSS[ext];
215
- }
216
- return null;
217
- };
218
- const resolveShorthand = (key, val) => {
219
- if (typeof val === "undefined" || val === null) return null;
220
- if (key === "flow" && typeof val === "string") {
221
- let [direction, wrap] = (val || "row").split(" ");
222
- if (val.startsWith("x") || val === "row") direction = "row";
223
- if (val.startsWith("y") || val === "column") direction = "column";
224
- return { display: "flex", flexFlow: (direction || "") + " " + (wrap || "") };
225
- }
226
- if (key === "wrap") {
227
- return { display: "flex", flexWrap: val };
228
- }
229
- if ((key === "align" || key === "flexAlign") && typeof val === "string") {
230
- const [alignItems, justifyContent] = val.split(" ");
231
- return { display: "flex", alignItems, justifyContent };
232
- }
233
- if (key === "gridAlign" && typeof val === "string") {
234
- const [alignItems, justifyContent] = val.split(" ");
235
- return { display: "grid", alignItems, justifyContent };
236
- }
237
- if (key === "flexFlow" && typeof val === "string") {
238
- let [direction, wrap] = (val || "row").split(" ");
239
- if (val.startsWith("x") || val === "row") direction = "row";
240
- if (val.startsWith("y") || val === "column") direction = "column";
241
- return { display: "flex", flexFlow: (direction || "") + " " + (wrap || "") };
242
- }
243
- if (key === "flexWrap") {
244
- return { display: "flex", flexWrap: val };
245
- }
246
- if (key === "round" || key === "borderRadius" && val) {
247
- return { borderRadius: typeof val === "number" ? val + "px" : val };
248
- }
249
- if (key === "boxSize" && typeof val === "string") {
250
- const [height, width] = val.split(" ");
251
- return { height, width: width || height };
252
- }
253
- if (key === "widthRange" && typeof val === "string") {
254
- const [minWidth, maxWidth] = val.split(" ");
255
- return { minWidth, maxWidth: maxWidth || minWidth };
256
- }
257
- if (key === "heightRange" && typeof val === "string") {
258
- const [minHeight, maxHeight] = val.split(" ");
259
- return { minHeight, maxHeight: maxHeight || minHeight };
260
- }
261
- if (key === "column") return { gridColumn: val };
262
- if (key === "columns") return { gridTemplateColumns: val };
263
- if (key === "templateColumns") return { gridTemplateColumns: val };
264
- if (key === "row") return { gridRow: val };
265
- if (key === "rows") return { gridTemplateRows: val };
266
- if (key === "templateRows") return { gridTemplateRows: val };
267
- if (key === "area") return { gridArea: val };
268
- if (key === "template") return { gridTemplate: val };
269
- if (key === "templateAreas") return { gridTemplateAreas: val };
270
- if (key === "autoColumns") return { gridAutoColumns: val };
271
- if (key === "autoRows") return { gridAutoRows: val };
272
- if (key === "autoFlow") return { gridAutoFlow: val };
273
- if (key === "columnStart") return { gridColumnStart: val };
274
- if (key === "rowStart") return { gridRowStart: val };
275
- return null;
276
- };
277
- const isCSS = (key) => {
278
- const ch = key.charCodeAt(0);
279
- if (ch === 95 || ch === 64 || ch === 58) return false;
280
- if (ch >= 65 && ch <= 90) return false;
281
- if (NON_CSS_PROPS.has(key)) return false;
282
- return CSS_PROPERTIES.has(key);
283
- };
284
- const CSS_PROPERTIES = /* @__PURE__ */ new Set([
285
- "display",
286
- "position",
287
- "top",
288
- "right",
289
- "bottom",
290
- "left",
291
- "width",
292
- "height",
293
- "minWidth",
294
- "maxWidth",
295
- "minHeight",
296
- "maxHeight",
297
- "margin",
298
- "marginTop",
299
- "marginRight",
300
- "marginBottom",
301
- "marginLeft",
302
- "marginBlock",
303
- "marginInline",
304
- "padding",
305
- "paddingTop",
306
- "paddingRight",
307
- "paddingBottom",
308
- "paddingLeft",
309
- "paddingBlock",
310
- "paddingInline",
311
- "border",
312
- "borderTop",
313
- "borderRight",
314
- "borderBottom",
315
- "borderLeft",
316
- "borderRadius",
317
- "borderColor",
318
- "borderWidth",
319
- "borderStyle",
320
- "borderTopWidth",
321
- "borderRightWidth",
322
- "borderBottomWidth",
323
- "borderLeftWidth",
324
- "borderTopStyle",
325
- "borderRightStyle",
326
- "borderBottomStyle",
327
- "borderLeftStyle",
328
- "borderTopColor",
329
- "borderRightColor",
330
- "borderBottomColor",
331
- "borderLeftColor",
332
- "borderTopLeftRadius",
333
- "borderTopRightRadius",
334
- "borderBottomLeftRadius",
335
- "borderBottomRightRadius",
336
- "background",
337
- "backgroundColor",
338
- "backgroundImage",
339
- "backgroundSize",
340
- "backgroundPosition",
341
- "backgroundRepeat",
342
- "backgroundAttachment",
343
- "color",
344
- "fontSize",
345
- "fontWeight",
346
- "fontFamily",
347
- "fontStyle",
348
- "lineHeight",
349
- "letterSpacing",
350
- "textAlign",
351
- "textDecoration",
352
- "textTransform",
353
- "textIndent",
354
- "textOverflow",
355
- "textShadow",
356
- "opacity",
357
- "overflow",
358
- "overflowX",
359
- "overflowY",
360
- "zIndex",
361
- "cursor",
362
- "pointerEvents",
363
- "userSelect",
364
- "flex",
365
- "flexDirection",
366
- "flexWrap",
367
- "flexFlow",
368
- "flexGrow",
369
- "flexShrink",
370
- "flexBasis",
371
- "alignItems",
372
- "alignContent",
373
- "alignSelf",
374
- "justifyContent",
375
- "justifyItems",
376
- "justifySelf",
377
- "gap",
378
- "rowGap",
379
- "columnGap",
380
- "gridTemplateColumns",
381
- "gridTemplateRows",
382
- "gridColumn",
383
- "gridRow",
384
- "gridArea",
385
- "gridAutoFlow",
386
- "gridAutoColumns",
387
- "gridAutoRows",
388
- "inset",
389
- "inlineSize",
390
- "blockSize",
391
- "minInlineSize",
392
- "maxInlineSize",
393
- "minBlockSize",
394
- "maxBlockSize",
395
- "paddingBlockStart",
396
- "paddingBlockEnd",
397
- "paddingInlineStart",
398
- "paddingInlineEnd",
399
- "marginBlockStart",
400
- "marginBlockEnd",
401
- "marginInlineStart",
402
- "marginInlineEnd",
403
- "transform",
404
- "transformOrigin",
405
- "transition",
406
- "animation",
407
- "animationName",
408
- "animationDuration",
409
- "animationDelay",
410
- "animationTimingFunction",
411
- "animationFillMode",
412
- "animationIterationCount",
413
- "animationPlayState",
414
- "animationDirection",
415
- "gridTemplate",
416
- "gridTemplateAreas",
417
- "gridColumnStart",
418
- "gridRowStart",
419
- "boxShadow",
420
- "outline",
421
- "outlineColor",
422
- "outlineWidth",
423
- "outlineStyle",
424
- "outlineOffset",
425
- "whiteSpace",
426
- "wordBreak",
427
- "wordWrap",
428
- "overflowWrap",
429
- "visibility",
430
- "boxSizing",
431
- "objectFit",
432
- "objectPosition",
433
- "filter",
434
- "backdropFilter",
435
- "mixBlendMode",
436
- "fill",
437
- "stroke",
438
- "strokeWidth",
439
- "listStyle",
440
- "listStyleType",
441
- "listStylePosition",
442
- "counterReset",
443
- "counterIncrement",
444
- "content",
445
- "aspectRatio",
446
- "resize",
447
- "appearance",
448
- "scrollBehavior",
449
- "scrollMargin",
450
- "scrollPadding",
451
- "willChange",
452
- "contain",
453
- "isolation",
454
- "caretColor",
455
- "accentColor",
456
- "columnCount",
457
- "columnGap",
458
- "columnRuleColor",
459
- "columnRuleStyle",
460
- "columnRuleWidth",
461
- "textDecorationColor",
462
- "textDecorationStyle",
463
- "textDecorationThickness",
464
- "clipPath",
465
- "shapeOutside"
466
- ]);
467
- const DOMQL_LIFECYCLE = /* @__PURE__ */ new Set([
468
- "render",
469
- "create",
470
- "init",
471
- "start",
472
- "complete",
473
- "done",
474
- "beforeClassAssign",
475
- "attachNode",
476
- "stateInit",
477
- "stateCreated",
478
- "renderRouter",
479
- "lazyLoad",
480
- "error"
481
- ]);
482
- const bindEvents = (el) => {
483
- const { node, on, props } = el;
484
- if (!node) return;
485
- const handled = /* @__PURE__ */ new Set();
486
- if (on) {
487
- for (const param in on) {
488
- if (DOMQL_LIFECYCLE.has(param)) continue;
489
- if (typeof on[param] !== "function") continue;
490
- handled.add(param);
491
- addListener(node, param, on[param], el);
492
- }
493
- }
494
- if (props) {
495
- for (const key in props) {
496
- if (key.length <= 2 || key[0] !== "o" || key[1] !== "n") continue;
497
- if (typeof props[key] !== "function") continue;
498
- const third = key[2];
499
- if (third !== third.toUpperCase()) continue;
500
- const eventName = third.toLowerCase() + key.slice(3);
501
- if (handled.has(eventName) || DOMQL_LIFECYCLE.has(eventName)) continue;
502
- addListener(node, eventName, props[key], el);
503
- }
504
- }
505
- };
506
- const addListener = (node, eventName, handler, el) => {
507
- node.addEventListener(eventName, (event) => {
508
- const result = handler.call(el, event, el, el.state, el.context);
509
- if (result && typeof result.then === "function") {
510
- result.catch(() => {
511
- });
512
- }
513
- });
514
- };
515
- const fireLifecycle = (el) => {
516
- if (!el || !el.__ref || !el.node) return;
517
- const on = el.on;
518
- if (on) {
519
- fireEvent(on.render, el);
520
- fireEvent(on.renderRouter, el);
521
- fireEvent(on.done, el);
522
- fireEvent(on.create, el);
523
- }
524
- if (el.__ref.__children) {
525
- for (const childKey of el.__ref.__children) {
526
- const child = el[childKey];
527
- if (child && child.__ref) fireLifecycle(child);
528
- }
529
- }
530
- };
531
- const fireEvent = (fn, el) => {
532
- if (typeof fn !== "function") return;
533
- try {
534
- const result = fn.call(el, el, el.state, el.context);
535
- if (result && typeof result.then === "function") {
536
- result.catch(() => {
537
- });
538
- }
539
- } catch (e) {
540
- console.warn("[brender hydrate]", el.key, e.message);
541
- }
542
- };
543
- export {
544
- collectBrNodes,
545
- hydrate
546
- };
1
+ const R=t=>{const o=(t||document).querySelectorAll("[data-br]"),r={};return o.forEach(i=>{r[i.getAttribute("data-br")]=i}),r},j=(t,e={})=>{const{root:o,events:r=!0,renderEvents:i=!0,emotion:a,designSystem:c}=e,p=R(o),m=c?.color||{},f=c?.media||{};let u=0,n=0;const s=d=>{if(!d||!d.__ref)return;const l=d.__ref.__brKey;if(l){const g=p[l];g?(d.node=g,g.ref=d,a&&A(d,a,m,f),r&&k(d),u++):n++}if(d.__ref.__children)for(const g of d.__ref.__children){const S=d[g];S&&S.__ref&&s(S)}};return s(t),i&&_(t),{element:t,linked:u,unlinked:n}},A=(t,e,o,r)=>{const{node:i}=t;if(!i)return;const a={};let c=!1;for(const n in t){const s=t[n];if(n.charCodeAt(0)===64){const l=r[n.slice(1)];if(l&&typeof s=="object"){const g=y(s,o);Object.keys(g).length&&(a[l]=g,c=!0)}continue}if(n.charCodeAt(0)===58){if(typeof s=="object"){const l=y(s,o);Object.keys(l).length&&(a["&"+n]=l,c=!0)}continue}const d=w(n,s);if(d){for(const l in d)a[l]=h(l,d[l],o);c=!0;continue}C(n)&&(a[n]=h(n,s,o),c=!0)}const p=B(t);if(p)for(const[n,s]of Object.entries(p))a[n]||(a[n]=s,c=!0);if(t.style&&typeof t.style=="object"&&(Object.assign(a,t.style),c=!0),!c)return;const m=e.css(a),f=[];m&&f.push(m),typeof t.key=="string"&&t.key.charCodeAt(0)===95&&t.key.charCodeAt(1)!==95&&f.push(t.key.slice(1)),t.class&&f.push(t.class),t.attr?.class&&f.push(t.attr.class);const u=t.classlist;if(u){if(typeof u=="string")f.push(u);else if(typeof u=="object")for(const n in u){const s=u[n];typeof s=="boolean"&&s?f.push(n):typeof s=="string"?f.push(s):typeof s=="object"&&s&&f.push(e.css(s))}}f.length&&i.setAttribute("class",f.join(" "));for(const n in t)C(n)&&i.hasAttribute(n)&&i.removeAttribute(n)},y=(t,e)=>{const o={};for(const r in t){const i=w(r,t[r]);if(i){for(const a in i)o[a]=h(a,i[a],e);continue}C(r)&&(o[r]=h(r,t[r],e))}return o},T=new Set(["color","background","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor","fill","stroke","caretColor","columnRuleColor","textDecorationColor","boxShadow","textShadow"]),h=(t,e,o)=>typeof e!="string"?e:T.has(t)&&o[e]?o[e]:e,W=new Set(["href","src","alt","title","id","name","type","value","placeholder","target","rel","loading","srcset","sizes","media","role","tabindex","for","action","method","enctype","autocomplete","autofocus","theme","__element","update"]),x={Flex:{display:"flex"},InlineFlex:{display:"inline-flex"},Grid:{display:"grid"},InlineGrid:{display:"inline-grid"},Block:{display:"block"},Inline:{display:"inline"}},B=t=>{const e=t.__ref?.__extends;if(!e||!Array.isArray(e))return null;for(const o of e)if(x[o])return x[o];return null},w=(t,e)=>{if(typeof e>"u"||e===null)return null;if(t==="flow"&&typeof e=="string"){let[o,r]=(e||"row").split(" ");return(e.startsWith("x")||e==="row")&&(o="row"),(e.startsWith("y")||e==="column")&&(o="column"),{display:"flex",flexFlow:(o||"")+" "+(r||"")}}if(t==="wrap")return{display:"flex",flexWrap:e};if((t==="align"||t==="flexAlign")&&typeof e=="string"){const[o,r]=e.split(" ");return{display:"flex",alignItems:o,justifyContent:r}}if(t==="gridAlign"&&typeof e=="string"){const[o,r]=e.split(" ");return{display:"grid",alignItems:o,justifyContent:r}}if(t==="flexFlow"&&typeof e=="string"){let[o,r]=(e||"row").split(" ");return(e.startsWith("x")||e==="row")&&(o="row"),(e.startsWith("y")||e==="column")&&(o="column"),{display:"flex",flexFlow:(o||"")+" "+(r||"")}}if(t==="flexWrap")return{display:"flex",flexWrap:e};if(t==="round"||t==="borderRadius"&&e)return{borderRadius:typeof e=="number"?e+"px":e};if(t==="boxSize"&&typeof e=="string"){const[o,r]=e.split(" ");return{height:o,width:r||o}}if(t==="widthRange"&&typeof e=="string"){const[o,r]=e.split(" ");return{minWidth:o,maxWidth:r||o}}if(t==="heightRange"&&typeof e=="string"){const[o,r]=e.split(" ");return{minHeight:o,maxHeight:r||o}}return t==="column"?{gridColumn:e}:t==="columns"?{gridTemplateColumns:e}:t==="templateColumns"?{gridTemplateColumns:e}:t==="row"?{gridRow:e}:t==="rows"?{gridTemplateRows:e}:t==="templateRows"?{gridTemplateRows:e}:t==="area"?{gridArea:e}:t==="template"?{gridTemplate:e}:t==="templateAreas"?{gridTemplateAreas:e}:t==="autoColumns"?{gridAutoColumns:e}:t==="autoRows"?{gridAutoRows:e}:t==="autoFlow"?{gridAutoFlow:e}:t==="columnStart"?{gridColumnStart:e}:t==="rowStart"?{gridRowStart:e}:null},C=t=>{const e=t.charCodeAt(0);return e===95||e===64||e===58||e>=65&&e<=90||W.has(t)?!1:I.has(t)},I=new Set(["display","position","top","right","bottom","left","width","height","minWidth","maxWidth","minHeight","maxHeight","margin","marginTop","marginRight","marginBottom","marginLeft","marginBlock","marginInline","padding","paddingTop","paddingRight","paddingBottom","paddingLeft","paddingBlock","paddingInline","border","borderTop","borderRight","borderBottom","borderLeft","borderRadius","borderColor","borderWidth","borderStyle","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","borderTopStyle","borderRightStyle","borderBottomStyle","borderLeftStyle","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius","background","backgroundColor","backgroundImage","backgroundSize","backgroundPosition","backgroundRepeat","backgroundAttachment","color","fontSize","fontWeight","fontFamily","fontStyle","lineHeight","letterSpacing","textAlign","textDecoration","textTransform","textIndent","textOverflow","textShadow","opacity","overflow","overflowX","overflowY","zIndex","cursor","pointerEvents","userSelect","flex","flexDirection","flexWrap","flexFlow","flexGrow","flexShrink","flexBasis","alignItems","alignContent","alignSelf","justifyContent","justifyItems","justifySelf","gap","rowGap","columnGap","gridTemplateColumns","gridTemplateRows","gridColumn","gridRow","gridArea","gridAutoFlow","gridAutoColumns","gridAutoRows","inset","inlineSize","blockSize","minInlineSize","maxInlineSize","minBlockSize","maxBlockSize","paddingBlockStart","paddingBlockEnd","paddingInlineStart","paddingInlineEnd","marginBlockStart","marginBlockEnd","marginInlineStart","marginInlineEnd","transform","transformOrigin","transition","animation","animationName","animationDuration","animationDelay","animationTimingFunction","animationFillMode","animationIterationCount","animationPlayState","animationDirection","gridTemplate","gridTemplateAreas","gridColumnStart","gridRowStart","boxShadow","outline","outlineColor","outlineWidth","outlineStyle","outlineOffset","whiteSpace","wordBreak","wordWrap","overflowWrap","visibility","boxSizing","objectFit","objectPosition","filter","backdropFilter","mixBlendMode","fill","stroke","strokeWidth","listStyle","listStyleType","listStylePosition","counterReset","counterIncrement","content","aspectRatio","resize","appearance","scrollBehavior","scrollMargin","scrollPadding","willChange","contain","isolation","caretColor","accentColor","columnCount","columnGap","columnRuleColor","columnRuleStyle","columnRuleWidth","textDecorationColor","textDecorationStyle","textDecorationThickness","clipPath","shapeOutside"]),E=new Set(["render","create","init","start","complete","done","beforeClassAssign","attachNode","stateInit","stateCreated","renderRouter","lazyLoad","error"]),k=t=>{const{node:e}=t;if(e){t.__ref.__eventCleanup||(t.__ref.__eventCleanup=[]);for(const o in t){if(o.length<=2||o[0]!=="o"||o[1]!=="n"||typeof t[o]!="function")continue;const r=o[2];if(r!==r.toUpperCase())continue;const i=r.toLowerCase()+o.slice(3);E.has(i)||L(e,i,t[o],t)}}},L=(t,e,o,r)=>{const i=a=>{try{o.call(r,a,r,r.state,r.context)}catch(c){console.warn("[brender hydrate]",e,c.message)}};t.addEventListener(e,i),r.__ref.__eventCleanup.push(()=>t.removeEventListener(e,i))},_=t=>{if(!(!t||!t.__ref||!t.node)&&(b(t.onRender,t),b(t.onRenderRouter,t),b(t.onDone,t),b(t.onCreate,t),t.__ref.__children))for(const e of t.__ref.__children){const o=t[e];o&&o.__ref&&_(o)}},b=(t,e)=>{if(typeof t=="function")try{const o=t.call(e,e,e.state,e.context);o&&typeof o.then=="function"&&o.catch(()=>{})}catch(o){console.warn("[brender hydrate]",e.key,o.message)}};export{R as collectBrNodes,j as hydrate};