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