@codedia/react-web-component-bridge 0.1.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.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +16 -0
  3. package/dist/configuration/global-config.d.ts +4 -0
  4. package/dist/configuration/global-config.d.ts.map +1 -0
  5. package/dist/configuration/registry.d.ts +6 -0
  6. package/dist/configuration/registry.d.ts.map +1 -0
  7. package/dist/core/create-react-element.d.ts +4 -0
  8. package/dist/core/create-react-element.d.ts.map +1 -0
  9. package/dist/core/define-react-element.d.ts +5 -0
  10. package/dist/core/define-react-element.d.ts.map +1 -0
  11. package/dist/core/event-controller.d.ts +9 -0
  12. package/dist/core/event-controller.d.ts.map +1 -0
  13. package/dist/core/form-controller.d.ts +11 -0
  14. package/dist/core/form-controller.d.ts.map +1 -0
  15. package/dist/core/lifecycle.d.ts +11 -0
  16. package/dist/core/lifecycle.d.ts.map +1 -0
  17. package/dist/core/method-controller.d.ts +11 -0
  18. package/dist/core/method-controller.d.ts.map +1 -0
  19. package/dist/core/portal-controller.d.ts +12 -0
  20. package/dist/core/portal-controller.d.ts.map +1 -0
  21. package/dist/core/property-controller.d.ts +25 -0
  22. package/dist/core/property-controller.d.ts.map +1 -0
  23. package/dist/core/render-controller.d.ts +25 -0
  24. package/dist/core/render-controller.d.ts.map +1 -0
  25. package/dist/core/slot-controller.d.ts +9 -0
  26. package/dist/core/slot-controller.d.ts.map +1 -0
  27. package/dist/core/style-controller.d.ts +10 -0
  28. package/dist/core/style-controller.d.ts.map +1 -0
  29. package/dist/index.cjs +848 -0
  30. package/dist/index.cjs.map +1 -0
  31. package/dist/index.d.ts +9 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +831 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/metadata/create-metadata.d.ts +3 -0
  36. package/dist/metadata/create-metadata.d.ts.map +1 -0
  37. package/dist/metadata/index.cjs +84 -0
  38. package/dist/metadata/index.cjs.map +1 -0
  39. package/dist/metadata/index.d.ts +3 -0
  40. package/dist/metadata/index.d.ts.map +1 -0
  41. package/dist/metadata/index.js +57 -0
  42. package/dist/metadata/index.js.map +1 -0
  43. package/dist/metadata/types.d.ts +2 -0
  44. package/dist/metadata/types.d.ts.map +1 -0
  45. package/dist/react.cjs +912 -0
  46. package/dist/react.cjs.map +1 -0
  47. package/dist/react.d.ts +20 -0
  48. package/dist/react.d.ts.map +1 -0
  49. package/dist/react.js +866 -0
  50. package/dist/react.js.map +1 -0
  51. package/dist/types/public.d.ts +125 -0
  52. package/dist/types/public.d.ts.map +1 -0
  53. package/dist/utilities/casing.d.ts +4 -0
  54. package/dist/utilities/casing.d.ts.map +1 -0
  55. package/dist/utilities/errors.d.ts +3 -0
  56. package/dist/utilities/errors.d.ts.map +1 -0
  57. package/dist/utilities/parsing.d.ts +3 -0
  58. package/dist/utilities/parsing.d.ts.map +1 -0
  59. package/dist/utilities/scheduling.d.ts +3 -0
  60. package/dist/utilities/scheduling.d.ts.map +1 -0
  61. package/dist/utilities/serialization.d.ts +3 -0
  62. package/dist/utilities/serialization.d.ts.map +1 -0
  63. package/package.json +57 -0
package/dist/react.js ADDED
@@ -0,0 +1,866 @@
1
+ // src/react.ts
2
+ import React2, {
3
+ Children,
4
+ Component,
5
+ Fragment,
6
+ Profiler,
7
+ PureComponent,
8
+ StrictMode as StrictMode2,
9
+ Suspense as Suspense2,
10
+ cloneElement,
11
+ createContext,
12
+ createElement as createElement3,
13
+ createRef,
14
+ forwardRef,
15
+ isValidElement,
16
+ lazy,
17
+ memo,
18
+ startTransition,
19
+ useCallback,
20
+ useContext,
21
+ useDebugValue,
22
+ useDeferredValue,
23
+ useEffect,
24
+ useId,
25
+ useImperativeHandle,
26
+ useInsertionEffect,
27
+ useLayoutEffect,
28
+ useMemo,
29
+ useReducer,
30
+ useRef,
31
+ useState,
32
+ useSyncExternalStore,
33
+ useTransition,
34
+ version
35
+ } from "react";
36
+
37
+ // src/configuration/global-config.ts
38
+ var globalConfig = {
39
+ development: readNodeEnv() !== "production"
40
+ };
41
+ function configureReactElements(config) {
42
+ globalConfig = { ...globalConfig, ...config };
43
+ return getReactElementGlobalConfig();
44
+ }
45
+ function getReactElementGlobalConfig() {
46
+ return { ...globalConfig };
47
+ }
48
+ function readNodeEnv() {
49
+ const global = globalThis;
50
+ return global.process?.env?.NODE_ENV;
51
+ }
52
+
53
+ // src/configuration/registry.ts
54
+ var definitions = /* @__PURE__ */ new Map();
55
+ function registerDefinition(definition) {
56
+ definitions.set(definition.tagName, definition);
57
+ }
58
+ function getReactElementDefinition(tagName) {
59
+ return definitions.get(tagName.toLowerCase());
60
+ }
61
+ function isReactElementDefined(tagName) {
62
+ const normalized = tagName.toLowerCase();
63
+ if (typeof customElements !== "undefined" && customElements.get(normalized)) {
64
+ return true;
65
+ }
66
+ return definitions.has(normalized);
67
+ }
68
+ function listReactElementDefinitions() {
69
+ return [...definitions.values()];
70
+ }
71
+
72
+ // src/utilities/casing.ts
73
+ function camelToKebab(value) {
74
+ return value.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[_\s]+/g, "-").toLowerCase();
75
+ }
76
+ function normalizeCustomElementName(tagName) {
77
+ const normalized = tagName.trim().toLowerCase();
78
+ if (!/^[a-z][.0-9_a-z]*-[-.0-9_a-z]*$/.test(normalized)) {
79
+ throw new Error(`Custom element names must be valid kebab-case names: "${tagName}".`);
80
+ }
81
+ return normalized;
82
+ }
83
+
84
+ // src/metadata/create-metadata.ts
85
+ function createMetadata(tagName, options) {
86
+ const props = options.props ?? {};
87
+ const events = options.events ?? {};
88
+ const slots = options.slots ?? {};
89
+ const methods = options.methods ?? {};
90
+ return {
91
+ tagName,
92
+ properties: Object.entries(props).map(
93
+ ([name, rawDefinition]) => {
94
+ const definition = rawDefinition;
95
+ const property = { name };
96
+ if (definition?.attribute !== false)
97
+ property.attribute = definition?.attribute ?? camelToKebab(name);
98
+ if (definition?.type) property.type = definition.type;
99
+ if (definition?.required !== void 0) property.required = definition.required;
100
+ return property;
101
+ }
102
+ ),
103
+ attributes: Object.entries(props).filter(
104
+ ([, definition]) => definition?.attribute !== false
105
+ ).map(([name, rawDefinition]) => {
106
+ const definition = rawDefinition;
107
+ const attribute = {
108
+ name: definition?.attribute ?? camelToKebab(name),
109
+ property: name
110
+ };
111
+ if (definition?.reflect !== void 0) attribute.reflect = definition.reflect;
112
+ return attribute;
113
+ }),
114
+ events: Object.entries(events).map(([prop, rawDefinition]) => {
115
+ const definition = rawDefinition;
116
+ return {
117
+ name: definition?.name ?? camelToKebab(prop.replace(/^on/, "")),
118
+ prop,
119
+ bubbles: definition?.bubbles ?? true,
120
+ composed: definition?.composed ?? true
121
+ };
122
+ }),
123
+ slots: Object.entries(slots).map(([prop, definition]) => ({
124
+ prop,
125
+ name: definition === true ? null : typeof definition === "string" ? definition : definition?.name ?? null
126
+ })),
127
+ methods: Object.keys(methods).map((name) => ({ name })),
128
+ formAssociated: Boolean(options.form),
129
+ shadow: options.shadow !== false
130
+ };
131
+ }
132
+
133
+ // src/utilities/scheduling.ts
134
+ function scheduleMicrotask(task) {
135
+ if (typeof queueMicrotask === "function") {
136
+ queueMicrotask(task);
137
+ return;
138
+ }
139
+ Promise.resolve().then(task);
140
+ }
141
+
142
+ // src/core/event-controller.ts
143
+ var EventController = class {
144
+ constructor(host, options) {
145
+ this.host = host;
146
+ this.options = options;
147
+ }
148
+ host;
149
+ options;
150
+ createEventProps() {
151
+ const eventProps = {};
152
+ for (const [propName, definition] of Object.entries(this.options.events ?? {})) {
153
+ eventProps[propName] = (...args) => this.dispatch(propName, definition, args);
154
+ }
155
+ return eventProps;
156
+ }
157
+ dispatch(propName, definition, args) {
158
+ const eventName = definition?.name ?? camelToKebab(propName.replace(/^on/, ""));
159
+ const detail = definition?.detail ? definition.detail(...args) : args.length <= 1 ? args[0] : [...args];
160
+ const event = new CustomEvent(eventName, {
161
+ detail,
162
+ bubbles: definition?.bubbles ?? true,
163
+ composed: definition?.composed ?? true,
164
+ cancelable: definition?.cancelable ?? false
165
+ });
166
+ const accepted = this.host.dispatchEvent(event);
167
+ return definition?.cancelable ? accepted : void 0;
168
+ }
169
+ };
170
+
171
+ // src/core/form-controller.ts
172
+ var FormController = class {
173
+ constructor(host, options) {
174
+ this.host = host;
175
+ this.options = options;
176
+ }
177
+ host;
178
+ options;
179
+ internals;
180
+ connect() {
181
+ if (!this.options.form || this.internals) {
182
+ return;
183
+ }
184
+ const attach = this.host.attachInternals;
185
+ if (attach) {
186
+ this.internals = attach.call(this.host);
187
+ }
188
+ }
189
+ update(name, value) {
190
+ if (!this.options.form || name !== this.options.form.valueProp) {
191
+ return;
192
+ }
193
+ const serialized = this.options.form.serializeValue ? this.options.form.serializeValue(value) : defaultSerializeValue(value);
194
+ this.internals?.setFormValue(serialized);
195
+ const validation = this.options.form.validate?.(value, this.host);
196
+ if (validation && validation !== true) {
197
+ this.internals?.setValidity({ customError: true }, validation);
198
+ } else {
199
+ this.internals?.setValidity({});
200
+ }
201
+ }
202
+ emitStandardChangeEvents() {
203
+ if (!this.options.form) {
204
+ return;
205
+ }
206
+ this.host.dispatchEvent(new Event("input", { bubbles: true, composed: true }));
207
+ this.host.dispatchEvent(new Event("change", { bubbles: true, composed: true }));
208
+ }
209
+ };
210
+ function defaultSerializeValue(value) {
211
+ if (value === void 0 || value === null) return null;
212
+ if (value instanceof File) return value;
213
+ if (typeof value === "object") return JSON.stringify(value);
214
+ return String(value);
215
+ }
216
+
217
+ // src/core/lifecycle.ts
218
+ var LifecycleController = class {
219
+ constructor(render, requestRender, cleanup) {
220
+ this.render = render;
221
+ this.requestRender = requestRender;
222
+ this.cleanup = cleanup;
223
+ }
224
+ render;
225
+ requestRender;
226
+ cleanup;
227
+ disconnectToken = 0;
228
+ connected() {
229
+ this.disconnectToken++;
230
+ this.render.reconnect();
231
+ this.requestRender();
232
+ }
233
+ disconnected(host) {
234
+ const token = ++this.disconnectToken;
235
+ queueMicrotask(() => {
236
+ if (token !== this.disconnectToken || host.isConnected) {
237
+ return;
238
+ }
239
+ this.cleanup();
240
+ this.render.unmount();
241
+ });
242
+ }
243
+ };
244
+
245
+ // src/core/method-controller.ts
246
+ var MethodController = class {
247
+ constructor(options) {
248
+ this.options = options;
249
+ }
250
+ options;
251
+ ref;
252
+ queue = /* @__PURE__ */ new Map();
253
+ setRef(value) {
254
+ this.ref = value;
255
+ for (const [name, calls] of this.queue) {
256
+ for (const args of calls) {
257
+ this.call(name, args);
258
+ }
259
+ }
260
+ this.queue.clear();
261
+ }
262
+ createRefSetter() {
263
+ return (value) => this.setRef(value);
264
+ }
265
+ call(name, args, host) {
266
+ const definition = this.options.methods?.[name];
267
+ if (!definition) {
268
+ throw new Error(`Unknown public method "${name}".`);
269
+ }
270
+ if (!this.ref) {
271
+ if (definition.queue) {
272
+ const calls = this.queue.get(name) ?? [];
273
+ calls.push([...args]);
274
+ this.queue.set(name, calls);
275
+ return void 0;
276
+ }
277
+ throw new Error(`Cannot call "${name}" before the React component ref is mounted.`);
278
+ }
279
+ return definition.call(this.ref, host ?? void 0, ...args);
280
+ }
281
+ };
282
+
283
+ // src/core/portal-controller.ts
284
+ var PortalController = class {
285
+ constructor(host, renderRoot, options) {
286
+ this.host = host;
287
+ this.renderRoot = renderRoot;
288
+ this.options = options;
289
+ }
290
+ host;
291
+ renderRoot;
292
+ options;
293
+ container;
294
+ getPortalProps() {
295
+ const portal = this.options.portal;
296
+ if (!portal?.enabled || !portal.prop) {
297
+ return {};
298
+ }
299
+ return { [portal.prop]: this.getContainer() };
300
+ }
301
+ cleanup() {
302
+ this.container?.remove();
303
+ this.container = void 0;
304
+ }
305
+ getContainer() {
306
+ if (this.container) {
307
+ return this.container;
308
+ }
309
+ const portal = this.options.portal;
310
+ const target = portal?.target;
311
+ if (target instanceof HTMLElement) {
312
+ this.container = target;
313
+ return target;
314
+ }
315
+ if (typeof target === "function") {
316
+ this.container = target(this.host);
317
+ return this.container;
318
+ }
319
+ const container = document.createElement("div");
320
+ container.setAttribute("part", portal?.part ?? "overlay-root");
321
+ container.setAttribute("data-rwcb-portal", "");
322
+ if (target === "body") {
323
+ document.body.append(container);
324
+ } else if (target === "host") {
325
+ this.host.append(container);
326
+ } else {
327
+ this.renderRoot.append(container);
328
+ }
329
+ this.container = container;
330
+ return container;
331
+ }
332
+ };
333
+
334
+ // src/utilities/errors.ts
335
+ function warnDevelopment(enabled, message) {
336
+ if (enabled && typeof console !== "undefined") {
337
+ console.warn(`[react-web-component-bridge] ${message}`);
338
+ }
339
+ }
340
+ function assertBrowserApi(apiName, value) {
341
+ if (!value) {
342
+ throw new Error(
343
+ `${apiName} is unavailable. Custom element registration must run in a browser.`
344
+ );
345
+ }
346
+ }
347
+
348
+ // src/utilities/parsing.ts
349
+ function parseAttributeValue(value, definition, host) {
350
+ if (definition.parseAttribute) {
351
+ return definition.parseAttribute(value, host);
352
+ }
353
+ switch (definition.type ?? "string") {
354
+ case "boolean":
355
+ return value !== null;
356
+ case "number": {
357
+ if (value === null || value.trim() === "") return void 0;
358
+ const parsed = Number(value);
359
+ return Number.isFinite(parsed) ? parsed : void 0;
360
+ }
361
+ case "json": {
362
+ if (value === null || value.trim() === "") return void 0;
363
+ try {
364
+ return JSON.parse(value);
365
+ } catch {
366
+ return void 0;
367
+ }
368
+ }
369
+ case "date": {
370
+ if (value === null || value.trim() === "") return void 0;
371
+ const date = new Date(value);
372
+ return Number.isNaN(date.getTime()) ? void 0 : date;
373
+ }
374
+ case "string":
375
+ return value;
376
+ default:
377
+ return value;
378
+ }
379
+ }
380
+
381
+ // src/utilities/serialization.ts
382
+ function serializeAttributeValue(value, definition, host) {
383
+ if (definition.serializeAttribute) {
384
+ return definition.serializeAttribute(value, host);
385
+ }
386
+ if (value === void 0 || value === null || value === false) {
387
+ return null;
388
+ }
389
+ switch (definition.type ?? "string") {
390
+ case "boolean":
391
+ return value ? "" : null;
392
+ case "json":
393
+ try {
394
+ return JSON.stringify(value);
395
+ } catch {
396
+ return null;
397
+ }
398
+ case "date":
399
+ return value instanceof Date && !Number.isNaN(value.getTime()) ? value.toISOString() : null;
400
+ case "number":
401
+ return typeof value === "number" && Number.isFinite(value) ? String(value) : null;
402
+ case "string":
403
+ return String(value);
404
+ default:
405
+ return String(value);
406
+ }
407
+ }
408
+
409
+ // src/core/property-controller.ts
410
+ var PropertyController = class {
411
+ constructor(context) {
412
+ this.context = context;
413
+ for (const [prop, definition] of Object.entries(this.context.options.props ?? {})) {
414
+ const attribute = this.attributeName(prop, definition);
415
+ if (attribute) {
416
+ this.attributeToProp.set(attribute, prop);
417
+ }
418
+ if (definition?.default !== void 0) {
419
+ this.values.set(prop, definition.default);
420
+ }
421
+ }
422
+ }
423
+ context;
424
+ values = /* @__PURE__ */ new Map();
425
+ reflectingAttributes = /* @__PURE__ */ new Set();
426
+ attributeToProp = /* @__PURE__ */ new Map();
427
+ static observedAttributes(options) {
428
+ return Object.entries(options.props ?? {}).map(
429
+ ([prop, definition]) => definition?.attribute === false ? void 0 : definition?.attribute ?? camelToKebab(prop)
430
+ ).filter((value) => Boolean(value));
431
+ }
432
+ initializePreUpgradeProperties() {
433
+ for (const prop of Object.keys(this.context.options.props ?? {})) {
434
+ if (Object.prototype.hasOwnProperty.call(this.context.host, prop)) {
435
+ const value = this.context.host[prop];
436
+ delete this.context.host[prop];
437
+ this.setProperty(prop, value);
438
+ }
439
+ }
440
+ }
441
+ getProperty(name) {
442
+ return this.values.get(name);
443
+ }
444
+ getProps() {
445
+ return Object.fromEntries(this.values);
446
+ }
447
+ setProperty(name, rawValue) {
448
+ const definition = this.context.options.props?.[name];
449
+ const nextValue = this.normalizeValue(name, rawValue, definition);
450
+ if (Object.is(this.values.get(name), nextValue)) {
451
+ return;
452
+ }
453
+ this.values.set(name, nextValue);
454
+ this.reflectProperty(name, nextValue, definition);
455
+ this.context.formValueChanged(name, nextValue);
456
+ this.context.requestRender();
457
+ }
458
+ attributeChanged(attributeName, value) {
459
+ if (this.reflectingAttributes.has(attributeName)) {
460
+ return;
461
+ }
462
+ const prop = this.attributeToProp.get(attributeName);
463
+ if (!prop) {
464
+ return;
465
+ }
466
+ const definition = this.context.options.props?.[prop];
467
+ const parsed = parseAttributeValue(value, definition ?? {}, this.context.host);
468
+ this.setProperty(prop, parsed);
469
+ }
470
+ normalizeValue(name, rawValue, definition) {
471
+ let value = definition?.transform ? definition.transform(rawValue, this.context.host) : rawValue;
472
+ if (definition?.validate) {
473
+ const result = definition.validate(value, this.context.host);
474
+ if (result !== true) {
475
+ warnDevelopment(
476
+ this.context.development,
477
+ typeof result === "string" ? result : `Invalid value for property "${name}".`
478
+ );
479
+ }
480
+ }
481
+ if (definition?.required && (value === void 0 || value === null || value === "")) {
482
+ warnDevelopment(this.context.development, `Required property "${name}" is missing.`);
483
+ }
484
+ return value;
485
+ }
486
+ reflectProperty(name, value, definition) {
487
+ if (!definition?.reflect) {
488
+ return;
489
+ }
490
+ const attribute = this.attributeName(name, definition);
491
+ if (!attribute) {
492
+ return;
493
+ }
494
+ const serialized = serializeAttributeValue(value, definition, this.context.host);
495
+ this.reflectingAttributes.add(attribute);
496
+ try {
497
+ if (serialized === null) {
498
+ this.context.host.removeAttribute(attribute);
499
+ } else {
500
+ this.context.host.setAttribute(attribute, serialized);
501
+ }
502
+ } finally {
503
+ this.reflectingAttributes.delete(attribute);
504
+ }
505
+ }
506
+ attributeName(name, definition) {
507
+ if (definition?.attribute === false) {
508
+ return null;
509
+ }
510
+ return definition?.attribute ?? camelToKebab(name);
511
+ }
512
+ };
513
+
514
+ // src/core/render-controller.tsx
515
+ import { createElement, StrictMode, Suspense } from "react";
516
+ import { createRoot } from "react-dom/client";
517
+ var RenderController = class {
518
+ constructor(context) {
519
+ this.context = context;
520
+ }
521
+ context;
522
+ root;
523
+ unmounted = false;
524
+ render() {
525
+ if (this.unmounted) {
526
+ return;
527
+ }
528
+ this.root ??= createRoot(this.context.mount);
529
+ try {
530
+ this.root.render(this.createTree());
531
+ } catch (error) {
532
+ this.context.config.renderError?.(error, this.context.host);
533
+ throw error;
534
+ }
535
+ }
536
+ unmount() {
537
+ this.unmounted = true;
538
+ this.root?.unmount();
539
+ this.root = void 0;
540
+ }
541
+ reconnect() {
542
+ this.unmounted = false;
543
+ }
544
+ createTree() {
545
+ const Component2 = this.context.component;
546
+ const props = {
547
+ ...this.context.getProps(),
548
+ ...this.context.getSlotProps(),
549
+ ...this.context.getPortalProps(),
550
+ ...this.context.getEventProps(),
551
+ ref: this.context.refSetter
552
+ };
553
+ let element = createElement(Component2, props);
554
+ const Boundary = this.context.options.errorBoundary;
555
+ if (Boundary) {
556
+ element = createElement(Boundary, { error: void 0 }, element);
557
+ }
558
+ if (this.context.options.fallback !== void 0) {
559
+ element = createElement(Suspense, { fallback: this.context.options.fallback }, element);
560
+ }
561
+ if (this.context.options.wrap) {
562
+ element = this.context.options.wrap(element, this.context.host);
563
+ }
564
+ if (this.context.config.wrap) {
565
+ element = this.context.config.wrap(element, this.context.host);
566
+ }
567
+ if (this.context.options.strictMode ?? this.context.config.strictMode) {
568
+ element = createElement(StrictMode, void 0, element);
569
+ }
570
+ return element;
571
+ }
572
+ };
573
+
574
+ // src/core/slot-controller.tsx
575
+ import React, { createElement as createElement2 } from "react";
576
+ var SlotController = class {
577
+ constructor(options) {
578
+ this.options = options;
579
+ }
580
+ options;
581
+ createSlotProps() {
582
+ const props = {};
583
+ for (const [propName, definition] of Object.entries(this.options.slots ?? {})) {
584
+ props[propName] = this.createSlot(definition);
585
+ }
586
+ return props;
587
+ }
588
+ createSlot(definition) {
589
+ if (definition === true || definition === void 0) {
590
+ return createElement2("slot");
591
+ }
592
+ if (typeof definition === "string") {
593
+ return createElement2("slot", { name: definition });
594
+ }
595
+ const children = definition.fallback ? React.Children.toArray(definition.fallback) : void 0;
596
+ return createElement2("slot", definition.name ? { name: definition.name } : void 0, children);
597
+ }
598
+ };
599
+
600
+ // src/core/style-controller.ts
601
+ var StyleController = class {
602
+ constructor(root, host, styles) {
603
+ this.root = root;
604
+ this.host = host;
605
+ this.styles = styles;
606
+ }
607
+ root;
608
+ host;
609
+ styles;
610
+ apply() {
611
+ if (!this.styles) {
612
+ return;
613
+ }
614
+ const inputs = this.resolveInputs(this.styles);
615
+ const sheets = inputs.filter((style) => typeof style !== "string");
616
+ const text = inputs.filter((style) => typeof style === "string");
617
+ if ("adoptedStyleSheets" in this.root && sheets.length > 0) {
618
+ const current = this.root.adoptedStyleSheets ?? [];
619
+ this.root.adoptedStyleSheets = [...current, ...sheets];
620
+ }
621
+ for (const styleText of text) {
622
+ const style = document.createElement("style");
623
+ style.textContent = styleText;
624
+ this.root.prepend(style);
625
+ }
626
+ }
627
+ resolveInputs(input) {
628
+ const resolved = typeof input === "function" ? input(this.host) : input;
629
+ if (Array.isArray(resolved)) {
630
+ return resolved.flatMap((item) => Array.isArray(item) ? [...item] : [item]);
631
+ }
632
+ return [resolved];
633
+ }
634
+ };
635
+
636
+ // src/core/create-react-element.ts
637
+ function createReactElement(tagName, component, options = {}) {
638
+ const normalizedTagName = normalizeCustomElementName(tagName);
639
+ const runtimeOptions = options;
640
+ if (typeof HTMLElement === "undefined") {
641
+ return {
642
+ tagName: normalizedTagName,
643
+ component,
644
+ options,
645
+ elementClass: class {
646
+ },
647
+ metadata: createMetadata(normalizedTagName, runtimeOptions)
648
+ };
649
+ }
650
+ const observedAttributes = PropertyController.observedAttributes(runtimeOptions);
651
+ const formAssociated = Boolean(options.form);
652
+ class ReactBridgeElement extends HTMLElement {
653
+ static observedAttributes = observedAttributes;
654
+ static formAssociated = formAssociated;
655
+ config = getReactElementGlobalConfig();
656
+ mount;
657
+ renderRoot;
658
+ propertyController;
659
+ eventController = new EventController(this, runtimeOptions);
660
+ slotController = new SlotController(runtimeOptions);
661
+ methodController = new MethodController(runtimeOptions);
662
+ formController = new FormController(this, runtimeOptions);
663
+ portalController;
664
+ renderController;
665
+ lifecycleController;
666
+ renderScheduled = false;
667
+ constructor() {
668
+ super();
669
+ this.renderRoot = options.shadow === false ? this : this.attachShadow({
670
+ mode: options.shadow?.mode ?? "open",
671
+ ...options.shadow?.delegatesFocus === void 0 ? {} : { delegatesFocus: options.shadow.delegatesFocus }
672
+ });
673
+ this.mount = document.createElement("span");
674
+ this.mount.setAttribute("part", "react-mount");
675
+ this.mount.setAttribute("data-rwcb-mount", "");
676
+ this.renderRoot.append(this.mount);
677
+ new StyleController(this.renderRoot, this, runtimeOptions.styles).apply();
678
+ this.portalController = new PortalController(this, this.renderRoot, runtimeOptions);
679
+ this.propertyController = new PropertyController({
680
+ host: this,
681
+ options: runtimeOptions,
682
+ development: this.config.development ?? false,
683
+ requestRender: () => this.requestRender(),
684
+ formValueChanged: (name, value) => {
685
+ this.formController.update(name, value);
686
+ if (name === runtimeOptions.form?.valueProp) {
687
+ this.formController.emitStandardChangeEvents();
688
+ }
689
+ }
690
+ });
691
+ this.renderController = new RenderController({
692
+ host: this,
693
+ component,
694
+ options: runtimeOptions,
695
+ config: this.config,
696
+ mount: this.mount,
697
+ getProps: () => this.propertyController.getProps(),
698
+ getEventProps: () => this.eventController.createEventProps(),
699
+ getSlotProps: () => this.slotController.createSlotProps(),
700
+ getPortalProps: () => this.portalController.getPortalProps(),
701
+ refSetter: this.methodController.createRefSetter()
702
+ });
703
+ this.lifecycleController = new LifecycleController(
704
+ this.renderController,
705
+ () => this.requestRender(),
706
+ () => this.portalController.cleanup()
707
+ );
708
+ this.propertyController.initializePreUpgradeProperties();
709
+ }
710
+ connectedCallback() {
711
+ this.formController.connect();
712
+ this.lifecycleController.connected();
713
+ }
714
+ disconnectedCallback() {
715
+ this.lifecycleController.disconnected(this);
716
+ }
717
+ attributeChangedCallback(name, _oldValue, newValue) {
718
+ this.propertyController.attributeChanged(name, newValue);
719
+ }
720
+ formResetCallback() {
721
+ const valueProp = runtimeOptions.form?.valueProp;
722
+ const defaultValue = valueProp ? runtimeOptions.props?.[valueProp]?.default : void 0;
723
+ if (valueProp) {
724
+ this.propertyController.setProperty(valueProp, defaultValue);
725
+ }
726
+ }
727
+ callReactMethod(name, ...args) {
728
+ return this.methodController.call(name, args, this);
729
+ }
730
+ requestRender() {
731
+ if (this.renderScheduled || !this.isConnected) {
732
+ return;
733
+ }
734
+ this.renderScheduled = true;
735
+ scheduleMicrotask(() => {
736
+ this.renderScheduled = false;
737
+ if (this.isConnected) {
738
+ this.renderController.render();
739
+ }
740
+ });
741
+ }
742
+ }
743
+ for (const prop of Object.keys(options.props ?? {})) {
744
+ Object.defineProperty(ReactBridgeElement.prototype, prop, {
745
+ get() {
746
+ return this.propertyController.getProperty(prop);
747
+ },
748
+ set(value) {
749
+ this.propertyController.setProperty(prop, value);
750
+ }
751
+ });
752
+ }
753
+ for (const methodName of Object.keys(options.methods ?? {})) {
754
+ if (methodName in ReactBridgeElement.prototype) {
755
+ throw new Error(`Cannot expose public method "${methodName}" because it already exists.`);
756
+ }
757
+ Object.defineProperty(ReactBridgeElement.prototype, methodName, {
758
+ value(...args) {
759
+ return this.callReactMethod(methodName, ...args);
760
+ }
761
+ });
762
+ }
763
+ return {
764
+ tagName: normalizedTagName,
765
+ component,
766
+ options,
767
+ elementClass: ReactBridgeElement,
768
+ metadata: createMetadata(normalizedTagName, runtimeOptions)
769
+ };
770
+ }
771
+
772
+ // src/core/define-react-element.ts
773
+ function defineReactElement(tagName, component, options = {}) {
774
+ assertBrowserApi(
775
+ "customElements",
776
+ typeof customElements === "undefined" ? void 0 : customElements
777
+ );
778
+ const definition = createReactElement(tagName, component, options);
779
+ if (!customElements.get(definition.tagName)) {
780
+ customElements.define(definition.tagName, definition.elementClass);
781
+ }
782
+ registerDefinition(definition);
783
+ return definition;
784
+ }
785
+ function defineReactElements(definitions2) {
786
+ assertBrowserApi(
787
+ "customElements",
788
+ typeof customElements === "undefined" ? void 0 : customElements
789
+ );
790
+ for (const definition of definitions2) {
791
+ if (!customElements.get(definition.tagName)) {
792
+ customElements.define(definition.tagName, definition.elementClass);
793
+ }
794
+ registerDefinition(definition);
795
+ }
796
+ return [...definitions2];
797
+ }
798
+
799
+ // src/react.ts
800
+ var react_default = React2;
801
+ function createComponentTag(tagName, component, options = {}) {
802
+ const definition = createReactElement(tagName, component, options);
803
+ return Object.assign(definition, {
804
+ define: () => defineReactElement(tagName, component, options)
805
+ });
806
+ }
807
+ function defineComponentTag(tagName, component, options = {}) {
808
+ const definition = defineReactElement(tagName, component, options);
809
+ return Object.assign(definition, {
810
+ define: () => definition
811
+ });
812
+ }
813
+ var createWebComponent = createComponentTag;
814
+ var defineWebComponent = defineComponentTag;
815
+ function configureReactApi(config) {
816
+ return configureReactElements(config);
817
+ }
818
+ export {
819
+ Children,
820
+ Component,
821
+ Fragment,
822
+ Profiler,
823
+ PureComponent,
824
+ StrictMode2 as StrictMode,
825
+ Suspense2 as Suspense,
826
+ cloneElement,
827
+ configureReactApi,
828
+ configureReactElements,
829
+ createComponentTag,
830
+ createContext,
831
+ createElement3 as createElement,
832
+ createReactElement,
833
+ createRef,
834
+ createWebComponent,
835
+ react_default as default,
836
+ defineComponentTag,
837
+ defineReactElement,
838
+ defineReactElements,
839
+ defineWebComponent,
840
+ forwardRef,
841
+ getReactElementDefinition,
842
+ getReactElementGlobalConfig,
843
+ isReactElementDefined,
844
+ isValidElement,
845
+ lazy,
846
+ listReactElementDefinitions,
847
+ memo,
848
+ startTransition,
849
+ useCallback,
850
+ useContext,
851
+ useDebugValue,
852
+ useDeferredValue,
853
+ useEffect,
854
+ useId,
855
+ useImperativeHandle,
856
+ useInsertionEffect,
857
+ useLayoutEffect,
858
+ useMemo,
859
+ useReducer,
860
+ useRef,
861
+ useState,
862
+ useSyncExternalStore,
863
+ useTransition,
864
+ version
865
+ };
866
+ //# sourceMappingURL=react.js.map