@qontinui/ui-bridge-native 0.6.1 → 0.6.3
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/core/index.js +45 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +45 -0
- package/dist/core/index.mjs.map +1 -1
- package/dist/core/registry.d.ts +19 -0
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/index.js +333 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +333 -1
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.js +328 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +328 -1
- package/dist/react/index.mjs.map +1 -1
- package/dist/react/useUIElement.d.ts +19 -0
- package/dist/react/useUIElement.d.ts.map +1 -1
- package/dist/server/handlers.d.ts.map +1 -1
- package/dist/server/http-server.d.ts.map +1 -1
- package/dist/server/index.js +268 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +268 -0
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/page-health.d.ts +72 -0
- package/dist/server/page-health.d.ts.map +1 -0
- package/dist/server/types.d.ts +1 -0
- package/dist/server/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/react/index.mjs
CHANGED
|
@@ -349,6 +349,51 @@ var NativeUIBridgeRegistry = class {
|
|
|
349
349
|
this.emit("element:stateChanged", { id, state: newState });
|
|
350
350
|
}
|
|
351
351
|
}
|
|
352
|
+
/**
|
|
353
|
+
* Update an element's descriptive metadata (label / accessibilityLabel /
|
|
354
|
+
* testId). Sister to {@link updateElementState} (which carries layout +
|
|
355
|
+
* visibility) and {@link updateElementProps} (which carries event handlers).
|
|
356
|
+
*
|
|
357
|
+
* Idempotent — if every passed field equals the existing value, the call
|
|
358
|
+
* returns without mutating the entry or emitting an event. This keeps
|
|
359
|
+
* `useUIElement().updateLabel(...)` cheap when consumers re-publish from a
|
|
360
|
+
* render path that produces the same string on every tick.
|
|
361
|
+
*
|
|
362
|
+
* Returns `true` when the entry was mutated, `false` otherwise. Callers
|
|
363
|
+
* that want to gate a `console.warn` on no-op invocations can use the
|
|
364
|
+
* return value instead of recomputing equality.
|
|
365
|
+
*/
|
|
366
|
+
updateElementMeta(id, meta) {
|
|
367
|
+
const element = this.elements.get(id);
|
|
368
|
+
if (!element) return false;
|
|
369
|
+
const currentIdentifier = element.getIdentifier();
|
|
370
|
+
const nextLabel = meta.label !== void 0 ? meta.label : element.label;
|
|
371
|
+
const nextAccessibilityLabel = meta.accessibilityLabel !== void 0 ? meta.accessibilityLabel : currentIdentifier.accessibilityLabel;
|
|
372
|
+
const nextTestId = meta.testId !== void 0 ? meta.testId : currentIdentifier.testId;
|
|
373
|
+
const labelChanged = nextLabel !== element.label;
|
|
374
|
+
const accessibilityLabelChanged = nextAccessibilityLabel !== currentIdentifier.accessibilityLabel;
|
|
375
|
+
const testIdChanged = nextTestId !== currentIdentifier.testId;
|
|
376
|
+
if (!labelChanged && !accessibilityLabelChanged && !testIdChanged) {
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
const updated = {
|
|
380
|
+
...element,
|
|
381
|
+
label: nextLabel,
|
|
382
|
+
getIdentifier: () => ({
|
|
383
|
+
uiId: id,
|
|
384
|
+
testId: nextTestId,
|
|
385
|
+
accessibilityLabel: nextAccessibilityLabel,
|
|
386
|
+
treePath: currentIdentifier.treePath
|
|
387
|
+
})
|
|
388
|
+
};
|
|
389
|
+
this.elements.set(id, updated);
|
|
390
|
+
this.emit("element:registered", {
|
|
391
|
+
id,
|
|
392
|
+
type: element.type,
|
|
393
|
+
label: nextLabel
|
|
394
|
+
});
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
352
397
|
/**
|
|
353
398
|
* Update element props (for action execution)
|
|
354
399
|
*/
|
|
@@ -1729,6 +1774,245 @@ function createDesignHandlers(registry) {
|
|
|
1729
1774
|
};
|
|
1730
1775
|
}
|
|
1731
1776
|
|
|
1777
|
+
// src/server/page-health.ts
|
|
1778
|
+
var GRID_SIZE = 20;
|
|
1779
|
+
var NAV_TYPES = /* @__PURE__ */ new Set(["button", "heading", "badge", "status-message"]);
|
|
1780
|
+
var SKIP_TEXT_TYPES = /* @__PURE__ */ new Set(["button", "link", "tab", "menuitem"]);
|
|
1781
|
+
var INTERACTIVE_TYPES = /* @__PURE__ */ new Set([
|
|
1782
|
+
"button",
|
|
1783
|
+
"input",
|
|
1784
|
+
"switch",
|
|
1785
|
+
"checkbox",
|
|
1786
|
+
"radio",
|
|
1787
|
+
"touchable",
|
|
1788
|
+
"listItem"
|
|
1789
|
+
]);
|
|
1790
|
+
var ERROR_PHRASES = [
|
|
1791
|
+
"error occurred",
|
|
1792
|
+
"failed to",
|
|
1793
|
+
"exception",
|
|
1794
|
+
"crash",
|
|
1795
|
+
"unavailable",
|
|
1796
|
+
"something went wrong",
|
|
1797
|
+
"could not"
|
|
1798
|
+
];
|
|
1799
|
+
var LOADING_PHRASES = [
|
|
1800
|
+
"loading",
|
|
1801
|
+
"starting",
|
|
1802
|
+
"connecting",
|
|
1803
|
+
"please wait",
|
|
1804
|
+
"initializing",
|
|
1805
|
+
"fetching"
|
|
1806
|
+
];
|
|
1807
|
+
var EMPTY_PHRASES = [
|
|
1808
|
+
"no data",
|
|
1809
|
+
"no results",
|
|
1810
|
+
"nothing here",
|
|
1811
|
+
"empty",
|
|
1812
|
+
"no items",
|
|
1813
|
+
"get started"
|
|
1814
|
+
];
|
|
1815
|
+
function severityRank(s) {
|
|
1816
|
+
if (s === "CRITICAL") return 3;
|
|
1817
|
+
if (s === "WARNING") return 2;
|
|
1818
|
+
return 1;
|
|
1819
|
+
}
|
|
1820
|
+
function worstSeverity(findings) {
|
|
1821
|
+
let worst = "OK";
|
|
1822
|
+
for (const f of findings) {
|
|
1823
|
+
if (severityRank(f.severity) > severityRank(worst)) {
|
|
1824
|
+
worst = f.severity;
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
return worst;
|
|
1828
|
+
}
|
|
1829
|
+
function truncate(s, n) {
|
|
1830
|
+
if (s.length <= n) return s;
|
|
1831
|
+
return [...s].slice(0, n).join("");
|
|
1832
|
+
}
|
|
1833
|
+
function normalizeRect(state, viewport) {
|
|
1834
|
+
const layout = state.layout;
|
|
1835
|
+
if (!layout) return null;
|
|
1836
|
+
if (viewport.width <= 0 || viewport.height <= 0) return null;
|
|
1837
|
+
const px = layout.pageX ?? layout.x;
|
|
1838
|
+
const py = layout.pageY ?? layout.y;
|
|
1839
|
+
return {
|
|
1840
|
+
x: px / viewport.width,
|
|
1841
|
+
y: py / viewport.height,
|
|
1842
|
+
width: layout.width / viewport.width,
|
|
1843
|
+
height: layout.height / viewport.height
|
|
1844
|
+
};
|
|
1845
|
+
}
|
|
1846
|
+
function diagnosePageHealth(elements, viewport) {
|
|
1847
|
+
const findings = [];
|
|
1848
|
+
const projected = elements.map((el) => ({
|
|
1849
|
+
el,
|
|
1850
|
+
rect: el.state.visible ? normalizeRect(el.state, viewport) : null
|
|
1851
|
+
}));
|
|
1852
|
+
const visible = projected.filter((p) => p.rect !== null);
|
|
1853
|
+
const grid = Array.from(
|
|
1854
|
+
{ length: GRID_SIZE },
|
|
1855
|
+
() => Array.from({ length: GRID_SIZE }, () => false)
|
|
1856
|
+
);
|
|
1857
|
+
for (const { rect } of visible) {
|
|
1858
|
+
const colStart = Math.max(0, Math.floor(rect.x * GRID_SIZE));
|
|
1859
|
+
const colEnd = Math.min(GRID_SIZE, Math.ceil((rect.x + rect.width) * GRID_SIZE));
|
|
1860
|
+
const rowStart = Math.max(0, Math.floor(rect.y * GRID_SIZE));
|
|
1861
|
+
const rowEnd = Math.min(GRID_SIZE, Math.ceil((rect.y + rect.height) * GRID_SIZE));
|
|
1862
|
+
for (let r = rowStart; r < rowEnd; r++) {
|
|
1863
|
+
for (let c = colStart; c < colEnd; c++) {
|
|
1864
|
+
grid[r][c] = true;
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
const totalCells = GRID_SIZE * GRID_SIZE;
|
|
1869
|
+
const halfCells = totalCells / 2;
|
|
1870
|
+
let filled = 0;
|
|
1871
|
+
let leftFilled = 0;
|
|
1872
|
+
let rightFilled = 0;
|
|
1873
|
+
const half = GRID_SIZE / 2;
|
|
1874
|
+
for (let r = 0; r < GRID_SIZE; r++) {
|
|
1875
|
+
for (let c = 0; c < GRID_SIZE; c++) {
|
|
1876
|
+
if (grid[r][c]) {
|
|
1877
|
+
filled++;
|
|
1878
|
+
if (c < half) leftFilled++;
|
|
1879
|
+
else rightFilled++;
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
const coveragePct = Math.round(filled / totalCells * 100);
|
|
1884
|
+
const leftHalfPct = Math.round(leftFilled / halfCells * 100);
|
|
1885
|
+
const rightHalfPct = Math.round(rightFilled / halfCells * 100);
|
|
1886
|
+
let spatialSeverity = "OK";
|
|
1887
|
+
if (coveragePct < 15) spatialSeverity = "CRITICAL";
|
|
1888
|
+
else if (coveragePct < 30) spatialSeverity = "WARNING";
|
|
1889
|
+
if (rightHalfPct < 5 && leftHalfPct > 20) spatialSeverity = "CRITICAL";
|
|
1890
|
+
findings.push({
|
|
1891
|
+
check: "spatial_coverage",
|
|
1892
|
+
severity: spatialSeverity,
|
|
1893
|
+
detail: `Elements cover ${coveragePct}% of viewport. Left=${leftHalfPct}%, Right=${rightHalfPct}%`,
|
|
1894
|
+
data: {
|
|
1895
|
+
coverage_pct: coveragePct,
|
|
1896
|
+
left_half_pct: leftHalfPct,
|
|
1897
|
+
right_half_pct: rightHalfPct
|
|
1898
|
+
}
|
|
1899
|
+
});
|
|
1900
|
+
let sidebar = 0;
|
|
1901
|
+
let header = 0;
|
|
1902
|
+
let content = 0;
|
|
1903
|
+
for (const { rect } of visible) {
|
|
1904
|
+
const cx = rect.x + rect.width / 2;
|
|
1905
|
+
const cy = rect.y + rect.height / 2;
|
|
1906
|
+
if (cx < 0.2) sidebar++;
|
|
1907
|
+
else if (cy < 0.08) header++;
|
|
1908
|
+
else content++;
|
|
1909
|
+
}
|
|
1910
|
+
let layoutSeverity = "OK";
|
|
1911
|
+
if (content === 0) layoutSeverity = "CRITICAL";
|
|
1912
|
+
else if (content < 3) layoutSeverity = "WARNING";
|
|
1913
|
+
findings.push({
|
|
1914
|
+
check: "layout_regions",
|
|
1915
|
+
severity: layoutSeverity,
|
|
1916
|
+
detail: `sidebar=${sidebar}, header=${header}, content=${content}`,
|
|
1917
|
+
data: { sidebar, header, content }
|
|
1918
|
+
});
|
|
1919
|
+
const typeCounts = {};
|
|
1920
|
+
for (const el of elements) {
|
|
1921
|
+
const t = el.type || "unknown";
|
|
1922
|
+
typeCounts[t] = (typeCounts[t] ?? 0) + 1;
|
|
1923
|
+
}
|
|
1924
|
+
const allNav = elements.length > 5 && Object.keys(typeCounts).every((k) => NAV_TYPES.has(k));
|
|
1925
|
+
const diversitySeverity = allNav ? "WARNING" : "OK";
|
|
1926
|
+
findings.push({
|
|
1927
|
+
check: "element_diversity",
|
|
1928
|
+
severity: diversitySeverity,
|
|
1929
|
+
detail: `${Object.keys(typeCounts).length} type(s) across ${elements.length} elements${allNav ? " (navigation-only)" : ""}`,
|
|
1930
|
+
data: { types: typeCounts }
|
|
1931
|
+
});
|
|
1932
|
+
const detectedErrors = [];
|
|
1933
|
+
const detectedLoading = [];
|
|
1934
|
+
const detectedEmpty = [];
|
|
1935
|
+
const detectedCss = [];
|
|
1936
|
+
for (const el of elements) {
|
|
1937
|
+
const elType = el.type ?? "";
|
|
1938
|
+
if (SKIP_TEXT_TYPES.has(elType)) continue;
|
|
1939
|
+
const text = (el.state.textContent ?? "").toString();
|
|
1940
|
+
if (!text) continue;
|
|
1941
|
+
const textLower = text.toLowerCase();
|
|
1942
|
+
for (const p of ERROR_PHRASES) {
|
|
1943
|
+
if (textLower.includes(p)) {
|
|
1944
|
+
detectedErrors.push(truncate(text, 120));
|
|
1945
|
+
break;
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
for (const p of LOADING_PHRASES) {
|
|
1949
|
+
if (textLower.includes(p)) {
|
|
1950
|
+
detectedLoading.push(truncate(text, 120));
|
|
1951
|
+
break;
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
for (const p of EMPTY_PHRASES) {
|
|
1955
|
+
if (textLower.includes(p)) {
|
|
1956
|
+
detectedEmpty.push(truncate(text, 120));
|
|
1957
|
+
break;
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
let textSeverity = "OK";
|
|
1962
|
+
if (detectedErrors.length > 0) textSeverity = "CRITICAL";
|
|
1963
|
+
else if (detectedLoading.length > 0 || detectedEmpty.length > 0) textSeverity = "WARNING";
|
|
1964
|
+
findings.push({
|
|
1965
|
+
check: "text_signals",
|
|
1966
|
+
severity: textSeverity,
|
|
1967
|
+
detail: `errors=${detectedErrors.length}, loading=${detectedLoading.length}, empty=${detectedEmpty.length}, css_signals=${detectedCss.length}`,
|
|
1968
|
+
data: {
|
|
1969
|
+
errors: detectedErrors,
|
|
1970
|
+
loading: detectedLoading,
|
|
1971
|
+
empty: detectedEmpty,
|
|
1972
|
+
css_signals: detectedCss
|
|
1973
|
+
}
|
|
1974
|
+
});
|
|
1975
|
+
let interactiveTotal = 0;
|
|
1976
|
+
let interactiveDisabled = 0;
|
|
1977
|
+
for (const el of elements) {
|
|
1978
|
+
if (!INTERACTIVE_TYPES.has(el.type)) continue;
|
|
1979
|
+
interactiveTotal++;
|
|
1980
|
+
if (el.state.enabled === false) interactiveDisabled++;
|
|
1981
|
+
}
|
|
1982
|
+
const interactiveSeverity = interactiveTotal > 0 && interactiveDisabled / interactiveTotal > 0.5 ? "WARNING" : "OK";
|
|
1983
|
+
findings.push({
|
|
1984
|
+
check: "interactive_readiness",
|
|
1985
|
+
severity: interactiveSeverity,
|
|
1986
|
+
detail: `${interactiveTotal} interactive elements, ${interactiveDisabled} disabled`,
|
|
1987
|
+
data: { total: interactiveTotal, disabled: interactiveDisabled }
|
|
1988
|
+
});
|
|
1989
|
+
let zeroSize = 0;
|
|
1990
|
+
let outsideViewport = 0;
|
|
1991
|
+
for (const { rect } of visible) {
|
|
1992
|
+
if (rect.width === 0 || rect.height === 0) zeroSize++;
|
|
1993
|
+
if (rect.x + rect.width < 0 || rect.y + rect.height < 0 || rect.x > 1 || rect.y > 1) {
|
|
1994
|
+
outsideViewport++;
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
const anomalySeverity = zeroSize > 0 || outsideViewport > 0 ? "WARNING" : "OK";
|
|
1998
|
+
findings.push({
|
|
1999
|
+
check: "visual_anomalies",
|
|
2000
|
+
severity: anomalySeverity,
|
|
2001
|
+
detail: `zero_size=${zeroSize}, outside_viewport=${outsideViewport}`,
|
|
2002
|
+
data: { zero_size: zeroSize, outside_viewport: outsideViewport }
|
|
2003
|
+
});
|
|
2004
|
+
const heatmap = grid.map(
|
|
2005
|
+
(row) => row.map((cell) => cell ? "#" : ".").join("")
|
|
2006
|
+
);
|
|
2007
|
+
return {
|
|
2008
|
+
summary: worstSeverity(findings),
|
|
2009
|
+
findings,
|
|
2010
|
+
heatmap,
|
|
2011
|
+
element_count: elements.length,
|
|
2012
|
+
visible_count: visible.length
|
|
2013
|
+
};
|
|
2014
|
+
}
|
|
2015
|
+
|
|
1732
2016
|
// src/server/handlers.ts
|
|
1733
2017
|
async function executeWorkflowStep(step, registry, executor) {
|
|
1734
2018
|
const startTime = Date.now();
|
|
@@ -2113,6 +2397,25 @@ function createServerHandlers(registry, executor, config) {
|
|
|
2113
2397
|
const snapshot = registry.createSnapshot(void 0, { visibleOnly, currentRouteOnly });
|
|
2114
2398
|
return success2(snapshot);
|
|
2115
2399
|
},
|
|
2400
|
+
getPageHealth: async (ctx) => {
|
|
2401
|
+
const bodyViewport = ctx.body?.viewport;
|
|
2402
|
+
let viewport = bodyViewport;
|
|
2403
|
+
if (!viewport) {
|
|
2404
|
+
try {
|
|
2405
|
+
const { Dimensions } = __require("react-native");
|
|
2406
|
+
const win = Dimensions.get("window");
|
|
2407
|
+
viewport = { width: win.width, height: win.height };
|
|
2408
|
+
} catch {
|
|
2409
|
+
viewport = { width: 0, height: 0 };
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
const elements = registry.getAllElements().map((e) => ({
|
|
2413
|
+
type: e.type,
|
|
2414
|
+
state: e.getState()
|
|
2415
|
+
}));
|
|
2416
|
+
const report = diagnosePageHealth(elements, viewport);
|
|
2417
|
+
return success2(report);
|
|
2418
|
+
},
|
|
2116
2419
|
// Workflows
|
|
2117
2420
|
getWorkflows: async () => {
|
|
2118
2421
|
const workflows = registry.getAllWorkflows().map((w) => ({
|
|
@@ -2861,6 +3164,10 @@ var WS_ROUTES = [
|
|
|
2861
3164
|
{ pattern: "ai/find", handler: "find", httpMethods: ["POST"] },
|
|
2862
3165
|
{ pattern: "control/snapshot", handler: "getSnapshot", httpMethods: ["GET"] },
|
|
2863
3166
|
{ pattern: "control/discover", handler: "getSnapshot" },
|
|
3167
|
+
// Page health — accepts both GET and POST so the canonical skill invocation
|
|
3168
|
+
// (`POST .../control/page-health` with an empty body) and ad-hoc curls both
|
|
3169
|
+
// work without a body-shape gotcha.
|
|
3170
|
+
{ pattern: "control/page-health", handler: "getPageHealth", httpMethods: ["GET", "POST"] },
|
|
2864
3171
|
// Workflows
|
|
2865
3172
|
{ pattern: "control/workflows", handler: "getWorkflows", httpMethods: ["GET"] },
|
|
2866
3173
|
{ pattern: "control/workflow/:id/run", handler: "runWorkflow", httpMethods: ["POST"] },
|
|
@@ -2965,6 +3272,7 @@ var HANDLER_DESCRIPTIONS = {
|
|
|
2965
3272
|
executeComponentAction: "Invoke a component action directly (preferred over button clicks)",
|
|
2966
3273
|
find: "AI-powered element search by natural-language query",
|
|
2967
3274
|
getSnapshot: "Full snapshot: elements + route + state. Supports ?visibleOnly=true and ?currentRouteOnly=true",
|
|
3275
|
+
getPageHealth: 'Holistic page health diagnostic over current snapshot elements (spatial coverage, layout regions, text/anomaly signals, heatmap). Optional body: { viewport?: { width, height } } to override Dimensions.get("window").',
|
|
2968
3276
|
getWorkflows: "List registered workflows",
|
|
2969
3277
|
runWorkflow: "Trigger a workflow by id",
|
|
2970
3278
|
pageRefresh: "Reload the current route",
|
|
@@ -5112,6 +5420,7 @@ function flattenStateStyles(stateStyles) {
|
|
|
5112
5420
|
return Object.keys(result).length > 0 ? result : void 0;
|
|
5113
5421
|
}
|
|
5114
5422
|
var warnedDeadButtonIds = /* @__PURE__ */ new Set();
|
|
5423
|
+
var warnedRedundantUpdateLabelIds = /* @__PURE__ */ new Set();
|
|
5115
5424
|
function scheduleDeadButtonWarning(bridge, id, type) {
|
|
5116
5425
|
if (type !== "button" && type !== "pressable") return;
|
|
5117
5426
|
if (warnedDeadButtonIds.has(id)) return;
|
|
@@ -5340,6 +5649,23 @@ function useUIElement(options) {
|
|
|
5340
5649
|
},
|
|
5341
5650
|
[bridge, id]
|
|
5342
5651
|
);
|
|
5652
|
+
const updateLabel = useCallback(
|
|
5653
|
+
(newLabel) => {
|
|
5654
|
+
if (!bridge || !registered) return;
|
|
5655
|
+
const changed = bridge.registry.updateElementMeta(id, {
|
|
5656
|
+
label: newLabel,
|
|
5657
|
+
accessibilityLabel: newLabel,
|
|
5658
|
+
testId: id
|
|
5659
|
+
});
|
|
5660
|
+
if (!changed && !warnedRedundantUpdateLabelIds.has(id)) {
|
|
5661
|
+
warnedRedundantUpdateLabelIds.add(id);
|
|
5662
|
+
console.warn(
|
|
5663
|
+
`[UI Bridge] updateLabel("${newLabel}") on element "${id}" was a no-op (label unchanged). Gate the call behind a useEffect with [label] deps to avoid redundant publishes.`
|
|
5664
|
+
);
|
|
5665
|
+
}
|
|
5666
|
+
},
|
|
5667
|
+
[bridge, registered, id]
|
|
5668
|
+
);
|
|
5343
5669
|
const updateStyle = useCallback(
|
|
5344
5670
|
(newStyle, newStateStyles) => {
|
|
5345
5671
|
if (!bridge || !registered) return;
|
|
@@ -5365,7 +5691,8 @@ function useUIElement(options) {
|
|
|
5365
5691
|
register,
|
|
5366
5692
|
unregister,
|
|
5367
5693
|
registeredElement,
|
|
5368
|
-
updateStyle
|
|
5694
|
+
updateStyle,
|
|
5695
|
+
updateLabel
|
|
5369
5696
|
};
|
|
5370
5697
|
}
|
|
5371
5698
|
function useUIElementWithProps(options) {
|