@qontinui/ui-bridge-native 0.6.5 → 0.6.6

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.
@@ -16,6 +16,10 @@ function extractHandlerNames(props) {
16
16
  if (!props) return [];
17
17
  return Object.keys(props).filter((k) => typeof props[k] === "function");
18
18
  }
19
+ function matchesCurrentRoute(registrationRoute, currentRoute) {
20
+ if (registrationRoute == null || registrationRoute === "") return true;
21
+ return registrationRoute === currentRoute;
22
+ }
19
23
  function inferActions(type) {
20
24
  const baseActions = ["focus", "blur"];
21
25
  switch (type) {
@@ -221,13 +225,20 @@ var NativeUIBridgeRegistry = class {
221
225
  if (this.config.verbose) {
222
226
  console.log(`[ui-bridge-native] Registered element: ${id} (${type})`);
223
227
  }
224
- this.updateElementState(id, {
228
+ const seededState = {
225
229
  mounted: true,
226
230
  visible: true,
227
231
  enabled: true,
228
232
  focused: false,
229
233
  layout: null
230
- });
234
+ };
235
+ if (type === "input" && typeof props?.value === "string") {
236
+ seededState.value = props.value;
237
+ }
238
+ if (type === "text" && typeof label === "string") {
239
+ seededState.value = label;
240
+ }
241
+ this.updateElementState(id, seededState);
231
242
  return registered;
232
243
  }
233
244
  /**
@@ -389,6 +400,9 @@ var NativeUIBridgeRegistry = class {
389
400
  })
390
401
  };
391
402
  this.elements.set(id, updated);
403
+ if (element.type === "text" && labelChanged && typeof nextLabel === "string") {
404
+ this.updateElementState(id, { value: nextLabel });
405
+ }
392
406
  this.emit("element:registered", {
393
407
  id,
394
408
  type: element.type,
@@ -397,7 +411,22 @@ var NativeUIBridgeRegistry = class {
397
411
  return true;
398
412
  }
399
413
  /**
400
- * Update element props (for action execution)
414
+ * Update element props (for action execution).
415
+ *
416
+ * Side effect for `type: 'input'` elements: when `props.value` is a string,
417
+ * mirror it into `state.value` so AI drivers reading the registry don't see
418
+ * `state.value === undefined` until the user types. Before this mirror,
419
+ * controlled-input consumers (`<TextInput value={x} onChangeText={setX} />`
420
+ * with `captureProps({ value: x, onChangeText: setX })`) registered an
421
+ * input whose `state.value` only became defined after the FIRST
422
+ * `onChangeText` call — bridge consumers couldn't read the default value
423
+ * (e.g. a pre-populated API-URL input) until someone typed into it.
424
+ *
425
+ * Re-runs on every `updateElementProps` so a parent passing a fresh
426
+ * `value` prop (controlled re-render) keeps the registry in sync. The
427
+ * mirror is gated on `type === 'input'` to avoid touching non-input
428
+ * elements that may carry an unrelated `value` prop (e.g. a Switch's
429
+ * boolean value, which lives on `state.checked`).
401
430
  */
402
431
  updateElementProps(id, props) {
403
432
  const element = this.elements.get(id);
@@ -407,6 +436,12 @@ var NativeUIBridgeRegistry = class {
407
436
  props: { ...element.props, ...props }
408
437
  };
409
438
  this.elements.set(id, updated);
439
+ if (element.type === "input" && Object.prototype.hasOwnProperty.call(props, "value") && typeof props.value === "string") {
440
+ const currentState = updated.getState();
441
+ if (currentState.value !== props.value) {
442
+ this.updateElementState(id, { value: props.value });
443
+ }
444
+ }
410
445
  }
411
446
  }
412
447
  /**
@@ -617,7 +652,7 @@ var NativeUIBridgeRegistry = class {
617
652
  let elements = options?.visibleOnly ? this.getMountedVisibleElements() : this.getAllElements();
618
653
  if (options?.currentRouteOnly && resolvedRoute.currentRoute) {
619
654
  const currentRoute = resolvedRoute.currentRoute;
620
- elements = elements.filter((e) => e.registrationRoute === currentRoute);
655
+ elements = elements.filter((e) => matchesCurrentRoute(e.registrationRoute, currentRoute));
621
656
  }
622
657
  const snapshot = {
623
658
  timestamp: Date.now(),
@@ -1556,15 +1591,9 @@ function success(data) {
1556
1591
  function error(message, code) {
1557
1592
  return { success: false, error: message, code, timestamp: Date.now() };
1558
1593
  }
1559
- function createDesignHandlers(registry) {
1594
+ function createDesignHandlers(registry, viewportProvider) {
1560
1595
  function getScreenDimensions() {
1561
- try {
1562
- const { Dimensions: Dimensions2 } = __require("react-native");
1563
- const screen = Dimensions2.get("screen");
1564
- return { width: screen.width, height: screen.height };
1565
- } catch {
1566
- return { width: 0, height: 0 };
1567
- }
1596
+ return viewportProvider?.() ?? { width: 0, height: 0 };
1568
1597
  }
1569
1598
  return {
1570
1599
  // 1. GET /design/element/:id/styles
@@ -2210,7 +2239,7 @@ function error2(message, code) {
2210
2239
  };
2211
2240
  }
2212
2241
  function createServerHandlers(registry, executor, config) {
2213
- const designHandlers = createDesignHandlers(registry);
2242
+ const designHandlers = createDesignHandlers(registry, config?.viewportProvider);
2214
2243
  return {
2215
2244
  // Elements
2216
2245
  getElements: async (ctx) => {
@@ -2218,7 +2247,7 @@ function createServerHandlers(registry, executor, config) {
2218
2247
  const forRoute = ctx.query?.route || ctx.body?.route;
2219
2248
  let allElements = visibleOnly ? registry.getMountedVisibleElements() : registry.getAllElements();
2220
2249
  if (forRoute) {
2221
- allElements = allElements.filter((e) => e.registrationRoute === forRoute);
2250
+ allElements = allElements.filter((e) => matchesCurrentRoute(e.registrationRoute, forRoute));
2222
2251
  }
2223
2252
  const elements = allElements.map((e) => {
2224
2253
  const handlers = extractHandlerNames(e.props);