@wix/himalaya-cli 0.1188.0 → 0.1190.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.
- package/dist/cli.mjs +61 -25
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/component-reference.json +326 -93
- package/guides/component-reference.md +92 -40
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -25225,6 +25225,7 @@ function shouldRevealError(args) {
|
|
|
25225
25225
|
var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
|
|
25226
25226
|
var init_validation = __esm({
|
|
25227
25227
|
"../../core/ts/src/validation.ts"() {
|
|
25228
|
+
"use strict";
|
|
25228
25229
|
EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
|
|
25229
25230
|
URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
|
|
25230
25231
|
INTEGER_RE = /^[+-]?[0-9]+$/;
|
|
@@ -25884,6 +25885,7 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
|
|
|
25884
25885
|
var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
|
|
25885
25886
|
var init_worker_subtree = __esm({
|
|
25886
25887
|
"../../core/ts/src/worker-subtree.ts"() {
|
|
25888
|
+
"use strict";
|
|
25887
25889
|
init_worker_subtree_safe_types_generated();
|
|
25888
25890
|
WORKER_SUBTREE_CEILINGS = Object.freeze({
|
|
25889
25891
|
maxEncodedBytes: 65536,
|
|
@@ -31656,6 +31658,26 @@ function encodeDateFieldValue(raw) {
|
|
|
31656
31658
|
const ms = Date.parse(raw);
|
|
31657
31659
|
return Number.isFinite(ms) ? String(Math.trunc(ms / 1e3)) : "";
|
|
31658
31660
|
}
|
|
31661
|
+
function clampDateFieldValue(encoded2, minUnix, maxUnix, mode) {
|
|
31662
|
+
if (!/^-?\d+$/.test(encoded2)) return encoded2;
|
|
31663
|
+
return String(clampDateUnix(Number(encoded2), minUnix, maxUnix, mode));
|
|
31664
|
+
}
|
|
31665
|
+
function clampDateUnix(unix, minUnix, maxUnix, mode) {
|
|
31666
|
+
const onDay = (bound) => {
|
|
31667
|
+
if (typeof bound !== "number") return null;
|
|
31668
|
+
if (mode !== "time") return bound;
|
|
31669
|
+
const b = new Date(bound * 1e3);
|
|
31670
|
+
const d = new Date(unix * 1e3);
|
|
31671
|
+
d.setHours(b.getHours(), b.getMinutes(), b.getSeconds(), 0);
|
|
31672
|
+
return Math.floor(d.getTime() / 1e3);
|
|
31673
|
+
};
|
|
31674
|
+
const lo = onDay(minUnix);
|
|
31675
|
+
const hi = onDay(maxUnix);
|
|
31676
|
+
let held = unix;
|
|
31677
|
+
if (hi != null && held > hi) held = hi;
|
|
31678
|
+
if (lo != null && held < lo) held = lo;
|
|
31679
|
+
return held;
|
|
31680
|
+
}
|
|
31659
31681
|
var ISO_INTERNET_DATE_TIME;
|
|
31660
31682
|
var init_form_bag = __esm({
|
|
31661
31683
|
"../../core/ts/src/form-bag.ts"() {
|
|
@@ -37484,6 +37506,10 @@ var init_renderNode = __esm({
|
|
|
37484
37506
|
InteractiveDatePicker = withExtras("InteractiveDatePicker", ({ props, ctx, wrap }) => {
|
|
37485
37507
|
const C = ctx.color;
|
|
37486
37508
|
const timeMode = props.mode === "time";
|
|
37509
|
+
const dateTimeMode = props.mode === "datetime";
|
|
37510
|
+
const minUnix = typeof props.minUnix === "number" ? props.minUnix : null;
|
|
37511
|
+
const maxUnix = typeof props.maxUnix === "number" ? props.maxUnix : null;
|
|
37512
|
+
const clampUnix = (unix) => clampDateUnix(unix, minUnix, maxUnix, props.mode);
|
|
37487
37513
|
const boundRaw = useBoundValue(ctx, typeof props.valuePath === "string" && isBinding(props.valuePath) ? props.valuePath : "");
|
|
37488
37514
|
const seedUnix = () => {
|
|
37489
37515
|
if (typeof boundRaw === "number") return boundRaw;
|
|
@@ -37497,16 +37523,22 @@ var init_renderNode = __esm({
|
|
|
37497
37523
|
if (unix == null) return "";
|
|
37498
37524
|
const d = new Date(unix * 1e3);
|
|
37499
37525
|
const p = (n) => String(n).padStart(2, "0");
|
|
37500
|
-
|
|
37526
|
+
const day = `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
|
|
37527
|
+
const time = `${p(d.getHours())}:${p(d.getMinutes())}`;
|
|
37528
|
+
return timeMode ? time : dateTimeMode ? `${day}T${time}` : day;
|
|
37529
|
+
};
|
|
37530
|
+
const shownSeed = () => {
|
|
37531
|
+
const s = seedUnix();
|
|
37532
|
+
return s == null ? null : clampUnix(s);
|
|
37501
37533
|
};
|
|
37502
|
-
const [val, setVal] = React7.useState(ctx.empty ? "" : toInput(
|
|
37534
|
+
const [val, setVal] = React7.useState(ctx.empty ? "" : toInput(shownSeed()));
|
|
37503
37535
|
const dateServiceBound = typeof props.valuePath === "string" && props.valuePath.startsWith("$service:");
|
|
37504
37536
|
const bagSource = () => dateServiceBound ? boundRaw : boundRaw !== void 0 && boundRaw !== null && boundRaw !== "" ? boundRaw : props.valueUnix;
|
|
37505
|
-
const [dateBagVal, setDateBagVal] = React7.useState(ctx.empty ? "" : encodeDateFieldValue(bagSource()));
|
|
37537
|
+
const [dateBagVal, setDateBagVal] = React7.useState(ctx.empty ? "" : clampDateFieldValue(encodeDateFieldValue(bagSource()), props.minUnix, props.maxUnix, props.mode));
|
|
37506
37538
|
React7.useEffect(() => {
|
|
37507
37539
|
if (ctx.empty) return;
|
|
37508
|
-
setVal(toInput(
|
|
37509
|
-
setDateBagVal(encodeDateFieldValue(bagSource()));
|
|
37540
|
+
setVal(toInput(shownSeed()));
|
|
37541
|
+
setDateBagVal(clampDateFieldValue(encodeDateFieldValue(bagSource()), props.minUnix, props.maxUnix, props.mode));
|
|
37510
37542
|
}, [boundRaw, props.valueUnix, props.valuePath, ctx.empty]);
|
|
37511
37543
|
const dateBag = React7.useContext(FormValuesContext);
|
|
37512
37544
|
const dateFieldId = props.__formFieldId;
|
|
@@ -37523,7 +37555,7 @@ var init_renderNode = __esm({
|
|
|
37523
37555
|
let label2 = "Select date";
|
|
37524
37556
|
if (!ctx.empty && props.valueUnix) {
|
|
37525
37557
|
const d = new Date(props.valueUnix * 1e3);
|
|
37526
|
-
label2 = timeMode ? d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) : d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
37558
|
+
label2 = timeMode ? d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) : dateTimeMode ? d.toLocaleString(void 0, { year: "numeric", month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }) : d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
37527
37559
|
}
|
|
37528
37560
|
return /* @__PURE__ */ jsxs5("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%", background: C("surfacePrimary", "#fff"), border: `1px solid ${C("border", "#e3e3e3")}`, borderRadius: ctx.radius("md", 8), padding: "12px 14px", boxSizing: "border-box", fontFamily: bodyFont(ctx), fontSize: pxToRem(15), color: C("textPrimary", "#111"), ...wrap }, children: [
|
|
37529
37561
|
/* @__PURE__ */ jsx8("span", { children: label2 }),
|
|
@@ -37537,12 +37569,14 @@ var init_renderNode = __esm({
|
|
|
37537
37569
|
setDateBagVal("");
|
|
37538
37570
|
return;
|
|
37539
37571
|
}
|
|
37540
|
-
const
|
|
37572
|
+
const picked = timeMode ? (() => {
|
|
37541
37573
|
const [h, m] = raw.split(":").map(Number);
|
|
37542
37574
|
const d = /* @__PURE__ */ new Date();
|
|
37543
37575
|
d.setHours(h || 0, m || 0, 0, 0);
|
|
37544
37576
|
return Math.floor(d.getTime() / 1e3);
|
|
37545
|
-
})() : Math.floor(Date.parse(`${raw}T00:00:00`) / 1e3);
|
|
37577
|
+
})() : dateTimeMode ? Math.floor(Date.parse(raw) / 1e3) : Math.floor(Date.parse(`${raw}T00:00:00`) / 1e3);
|
|
37578
|
+
const unix = Number.isFinite(picked) ? clampUnix(picked) : NaN;
|
|
37579
|
+
if (Number.isFinite(unix) && unix !== picked) setVal(toInput(unix));
|
|
37546
37580
|
const value = Number.isFinite(unix) ? String(unix) : "";
|
|
37547
37581
|
setDateBagVal(value);
|
|
37548
37582
|
if (!onChange || !ctx.onAction) return;
|
|
@@ -37551,10 +37585,12 @@ var init_renderNode = __esm({
|
|
|
37551
37585
|
return /* @__PURE__ */ jsx8(
|
|
37552
37586
|
"input",
|
|
37553
37587
|
{
|
|
37554
|
-
type: timeMode ? "time" : "date",
|
|
37588
|
+
type: timeMode ? "time" : dateTimeMode ? "datetime-local" : "date",
|
|
37555
37589
|
value: val,
|
|
37556
37590
|
onChange: (e) => emit(e.currentTarget.value),
|
|
37557
|
-
|
|
37591
|
+
min: minUnix != null ? toInput(minUnix) : void 0,
|
|
37592
|
+
max: maxUnix != null ? toInput(maxUnix) : void 0,
|
|
37593
|
+
"aria-label": timeMode ? "Select time" : dateTimeMode ? "Select date and time" : "Select date",
|
|
37558
37594
|
style: { width: "100%", boxSizing: "border-box", background: C("surfacePrimary", "#fff"), border: `1px solid ${C("border", "#e3e3e3")}`, borderRadius: ctx.radius("md", 8), padding: "12px 14px", fontFamily: bodyFont(ctx), fontSize: pxToRem(15), color: C("textPrimary", "#111"), ...wrap }
|
|
37559
37595
|
}
|
|
37560
37596
|
);
|
|
@@ -61120,21 +61156,21 @@ var init_preview_assets_generated = __esm({
|
|
|
61120
61156
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
61121
61157
|
init_preview_assets_format();
|
|
61122
61158
|
PREVIEW_ASSET_MANIFEST = [
|
|
61123
|
-
{ key: "assets/index-
|
|
61124
|
-
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset:
|
|
61125
|
-
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset:
|
|
61126
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
61127
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
61128
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
61129
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
61130
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
61131
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
61132
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
61133
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
61134
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
61135
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
61136
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
61137
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
61159
|
+
{ key: "assets/index-C_AIgKp4.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1135680, sha256: "dec95bd7419620a5edfb4e9cdcf7a027a81cce9009bc214cf03578d384fc1724" },
|
|
61160
|
+
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 1135688, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
|
|
61161
|
+
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 1140298, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
|
|
61162
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1628882, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
61163
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1719806, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
61164
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1810790, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
61165
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1901770, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
61166
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1992642, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
61167
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 2083622, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
61168
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 2192258, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
61169
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 2301342, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
61170
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 2410390, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
61171
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 2518090, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
61172
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 2606198, length: 4947, sha256: "c3f476b436d5ba5d2c7e928ba8da0472201b6353f25d6f73fb6cce9f5326c965" },
|
|
61173
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 2611145, length: 17344, sha256: "d057298d75e7373e5e2c4d11b7d1bcbea88e03af555ba63d97641c78509c58e4" }
|
|
61138
61174
|
];
|
|
61139
61175
|
}
|
|
61140
61176
|
});
|
|
Binary file
|
|
@@ -4,12 +4,16 @@
|
|
|
4
4
|
"bindingGrammar": "$service:<service>.<path> (worker state) · $item.<field> (list row) · $flag:<key> (feature flag) · $env:<key> (client environment — #1056). Bindings resolve in the text/value props marked 'binding-aware' below — INCLUDING Modifiers token refs — but only `background` and `border.color`, which are the two whose token a binding actually fills: a worker can drive per-item theming (e.g. a game board's per-square color), not just text. `shadow` is NOT binding-aware on any renderer, and a gradient is driven by its own `backgroundGradientPath` prop resolving to a gradient token NAME, not by a binding inside a token ref — so `shadow: { token: \"$item.x\" }` and `backgroundGradient: { token: \"$item.x\" }` keep the sentinel and silently lose the per-item styling. Colour slots split by LEVEL, not by component: inside modifiers a colour is a TokenRef OBJECT ({ token: \"…\" }), inside props it is a bare TokenName STRING — there is no modifiers.color or modifiers.tint (see the 'Token slots' section in component-reference.md). A few input props render the LITERAL and are NOT binding-aware — notably SearchField.placeholder and Chip.label; SearchField.value is live and binding-aware like other content props. Bindings also CANNOT target strict-enum fields (style, size, alignment, severity, presentation, contentMode, …) — those fail at render, not validation. $env: is client-resolved (no worker) and valid in modifiers.hiddenPath and FragmentSlot.casePath ONLY — keys reduceMotion/colorScheme/sizeClass/isRTL, e.g. hiddenPath:\"$env:reduceMotion\" or hiddenPath:\"$env:colorScheme==light\", casePath:\"$env:colorScheme\"; unknown key fails open (shown / defaultCase).",
|
|
5
5
|
"componentCount": 84,
|
|
6
6
|
"notImplementedComponents": [
|
|
7
|
-
"
|
|
7
|
+
"Text",
|
|
8
8
|
"Picker",
|
|
9
|
-
"DatePicker",
|
|
10
9
|
"Tabs",
|
|
10
|
+
"Carousel",
|
|
11
|
+
"CollapsingHeader",
|
|
12
|
+
"Banner",
|
|
11
13
|
"Snackbar",
|
|
14
|
+
"WebView",
|
|
12
15
|
"Slider",
|
|
16
|
+
"SelectionControl",
|
|
13
17
|
"ActivityIndicator",
|
|
14
18
|
"BottomSheet",
|
|
15
19
|
"Menu",
|
|
@@ -17,7 +21,12 @@
|
|
|
17
21
|
"Popover",
|
|
18
22
|
"ChipsInput",
|
|
19
23
|
"OtpInput",
|
|
20
|
-
"
|
|
24
|
+
"Map",
|
|
25
|
+
"Video",
|
|
26
|
+
"PdfView",
|
|
27
|
+
"MediaPlayer",
|
|
28
|
+
"TimeGrid",
|
|
29
|
+
"Agenda"
|
|
21
30
|
],
|
|
22
31
|
"components": [
|
|
23
32
|
{
|
|
@@ -101,6 +110,17 @@
|
|
|
101
110
|
"bindings": [
|
|
102
111
|
"text"
|
|
103
112
|
],
|
|
113
|
+
"notImplemented": {
|
|
114
|
+
"props": [
|
|
115
|
+
"textDirection",
|
|
116
|
+
"animateReveal"
|
|
117
|
+
],
|
|
118
|
+
"platforms": [
|
|
119
|
+
"web"
|
|
120
|
+
],
|
|
121
|
+
"severity": "styling",
|
|
122
|
+
"note": "`textDirection` sets no `dir`. `animateReveal` does not animate."
|
|
123
|
+
},
|
|
104
124
|
"propsSource": "export type TextProps = TextContent & {\n style?: TokenName;\n /** Foreground color token (default \"textPrimary\"). */\n color?: TokenName;\n /** Tail-truncate after N lines (absent = unlimited). */\n maxLines?: number;\n /** Lever D — a live time value (countdown/relative) the OS ticks with no refresh.\n * When present it OVERRIDES `text`. Widget-safe render only. */\n timeRef?: WidgetTimeRef;\n /** Render `text` as a constrained Markdown subset. */\n markdown?: boolean;\n /** Capability enrichments. */\n textAlign?: \"leading\" | \"center\" | \"trailing\" | \"justify\";\n /** Base writing direction. \"auto\" (or \"rtl\") makes a bidi paragraph resolve +\n * align by its own strong-directional content (Hebrew/Arabic → right-aligned,\n * RTL layout), matching per-message direction in chat bubbles. Absent/\"ltr\" =\n * the current left-to-right behavior. Both renderers honor it (parity). */\n textDirection?: \"auto\" | \"ltr\" | \"rtl\";\n decoration?: \"underline\" | \"strikethrough\";\n /** EXTRA SPACE BETWEEN LINES, in points/px — added ON TOP of the line height the `style`\n * token already sets. It is NOT a multiple: `lineSpacing: 6` means six points of extra\n * leading, not six times the font size, and every renderer agrees on that. To\n * change the line height as a ratio of the font size, set the typography token's `line`\n * instead; that is where a body style's 1.4/1.7 lives. Absent/0 = the token's own line\n * height, which is the right answer for almost every screen. */\n lineSpacing?: number;\n /** Per-item gate (usually an `$item.` field pre-substituted per row): when it\n * resolves empty, the text collapses to zero size instead of taking layout. */\n collapseWhenEmpty?: boolean;\n /** Motion grammar (Batch 1, item 4) — count-up tween for a numeric value on\n * change; non-numeric values render instantly. Gated by reduced motion. */\n animateValue?: boolean;\n /** Motion grammar — reveal the (post-substitution literal) text word-by-word,\n * once per distinct content, like a chat assistant \"typing\" its reply. Each\n * content animates a single time (progress is remembered), so list re-renders\n * and scrolls don't restart it. Gated by reduced motion (snaps to full).\n * Both renderers honor it (parity). Default nil/false. */\n animateReveal?: boolean;\n};"
|
|
105
125
|
},
|
|
106
126
|
{
|
|
@@ -296,16 +316,6 @@
|
|
|
296
316
|
"bindings": [
|
|
297
317
|
"textPath"
|
|
298
318
|
],
|
|
299
|
-
"notImplemented": {
|
|
300
|
-
"props": [
|
|
301
|
-
"severity"
|
|
302
|
-
],
|
|
303
|
-
"platforms": [
|
|
304
|
-
"ios"
|
|
305
|
-
],
|
|
306
|
-
"severity": "styling",
|
|
307
|
-
"note": "`severity: \"warning\"` still paints `danger` red."
|
|
308
|
-
},
|
|
309
319
|
"propsSource": "export interface FieldErrorProps {\n /** LITERAL - every renderer paints this verbatim. Bind `textPath` instead. */\n text: string;\n severity?: \"error\" | \"warning\";\n /** `$service:`/`$item.` binding -> the error text. Overrides `text`; resolving\n * to empty COLLAPSES the node, so one `FieldError` can sit permanently in the\n * tree and appear only when it has something to say (the same contract as\n * `TextProps.collapseWhenEmpty`). Before this, `FieldError` could not show\n * worker state at all, so apps hand-rolled a danger-colored `Text` instead. */\n textPath?: string;\n /** Explicit visibility override; `false` collapses the node. */\n visible?: boolean;\n}"
|
|
310
320
|
},
|
|
311
321
|
{
|
|
@@ -340,7 +350,7 @@
|
|
|
340
350
|
"ios"
|
|
341
351
|
],
|
|
342
352
|
"severity": "styling",
|
|
343
|
-
"note": "`optionsPath` does not bind
|
|
353
|
+
"note": "Standalone Picker: `optionsPath` does not bind (it does inside a FormField); `placeholder` is only the accessible name, never shown."
|
|
344
354
|
},
|
|
345
355
|
"propsSource": "export interface PickerProps {\n options: PickerOption[];\n selectedId?: string;\n onChange?: Action;\n placeholder?: string;\n /** \"$service:\" sentinel → worker array of {id,label}; `options` is the fallback. */\n optionsPath?: string;\n}"
|
|
346
356
|
},
|
|
@@ -348,22 +358,16 @@
|
|
|
348
358
|
"name": "DatePicker",
|
|
349
359
|
"category": "Form primitives",
|
|
350
360
|
"propsType": "DatePickerProps",
|
|
351
|
-
"bindings": [
|
|
361
|
+
"bindings": [
|
|
362
|
+
"valuePath"
|
|
363
|
+
],
|
|
352
364
|
"dispatches": [
|
|
353
365
|
{
|
|
354
366
|
"callback": "onChange",
|
|
355
367
|
"key": "value",
|
|
356
368
|
"encoding": "unix-seconds-string",
|
|
357
|
-
"note": "Unix SECONDS, string-encoded so the params mirror stays legal. iOS
|
|
369
|
+
"note": "Unix SECONDS, string-encoded so the params mirror stays legal, clamped into [minUnix, maxUnix]. iOS, Android and web conform (iOS shipped `valueUnix` as an int until the SwiftUI-parity DatePicker fix); RN ships nothing. The normative key is `value` because that is what the arms use for every other scalar control.",
|
|
358
370
|
"divergences": [
|
|
359
|
-
{
|
|
360
|
-
"arms": [
|
|
361
|
-
"ios"
|
|
362
|
-
],
|
|
363
|
-
"kind": "wrong-key",
|
|
364
|
-
"actual": "sends `valueUnix` as an int instead of the contract's `value`.",
|
|
365
|
-
"reason": "Only web conforms. This is the widest split in the vocabulary and the clearest argument for the file."
|
|
366
|
-
},
|
|
367
371
|
{
|
|
368
372
|
"arms": [
|
|
369
373
|
"rn"
|
|
@@ -382,19 +386,6 @@
|
|
|
382
386
|
]
|
|
383
387
|
}
|
|
384
388
|
],
|
|
385
|
-
"notImplemented": {
|
|
386
|
-
"props": [
|
|
387
|
-
"mode",
|
|
388
|
-
"minUnix",
|
|
389
|
-
"maxUnix",
|
|
390
|
-
"valuePath"
|
|
391
|
-
],
|
|
392
|
-
"platforms": [
|
|
393
|
-
"ios"
|
|
394
|
-
],
|
|
395
|
-
"severity": "styling",
|
|
396
|
-
"note": "The picker itself renders as a native date wheel — these four props are inert: `mode: \"time\"` still renders a date wheel; `minUnix`/`maxUnix` do not clamp; `valuePath` does not bind."
|
|
397
|
-
},
|
|
398
389
|
"propsSource": "export interface DatePickerProps {\n valueUnix?: number;\n minUnix?: number;\n maxUnix?: number;\n mode?: \"date\" | \"time\" | \"datetime\";\n onChange?: Action;\n /** \"$service:\" sentinel → ISO-8601 string (or unix seconds); prefills + tracks. */\n valuePath?: string;\n}"
|
|
399
390
|
},
|
|
400
391
|
{
|
|
@@ -484,7 +475,6 @@
|
|
|
484
475
|
"propsType": "TabsProps",
|
|
485
476
|
"bindings": [
|
|
486
477
|
"optionsPath",
|
|
487
|
-
"activeColorPath",
|
|
488
478
|
"selectedId"
|
|
489
479
|
],
|
|
490
480
|
"dispatches": [
|
|
@@ -494,16 +484,39 @@
|
|
|
494
484
|
"encoding": "string"
|
|
495
485
|
}
|
|
496
486
|
],
|
|
497
|
-
"notImplemented":
|
|
498
|
-
|
|
499
|
-
"
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
"
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
487
|
+
"notImplemented": [
|
|
488
|
+
{
|
|
489
|
+
"props": [
|
|
490
|
+
"style"
|
|
491
|
+
],
|
|
492
|
+
"platforms": [
|
|
493
|
+
"ios"
|
|
494
|
+
],
|
|
495
|
+
"severity": "styling",
|
|
496
|
+
"note": "`style: \"swipe\"` renders as plain top tabs."
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
"props": [
|
|
500
|
+
"activeColorPath"
|
|
501
|
+
],
|
|
502
|
+
"platforms": [
|
|
503
|
+
"android"
|
|
504
|
+
],
|
|
505
|
+
"severity": "styling",
|
|
506
|
+
"note": "`activeColorPath` does not tint the active tab."
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
"props": [
|
|
510
|
+
"activeColorPath",
|
|
511
|
+
"style"
|
|
512
|
+
],
|
|
513
|
+
"platforms": [
|
|
514
|
+
"web"
|
|
515
|
+
],
|
|
516
|
+
"severity": "styling",
|
|
517
|
+
"note": "`activeColorPath` does not tint the active tab. `style: \"swipe\"` renders as plain top tabs."
|
|
518
|
+
}
|
|
519
|
+
],
|
|
507
520
|
"propsSource": "export interface TabsProps {\n tabs: TabItem[];\n /** Literal id, or a binding-aware `$service:`/`$item.` live selection. */\n selectedId: string;\n onChange?: Action;\n style?: \"top\" | \"swipe\";\n /** `$service:` binding → a live tabs array (overrides `tabs`). */\n optionsPath?: string;\n /** `$service:` binding → a token name for the active-tab color. */\n activeColorPath?: string;\n}"
|
|
508
521
|
},
|
|
509
522
|
{
|
|
@@ -530,6 +543,17 @@
|
|
|
530
543
|
"bindings": [
|
|
531
544
|
"itemsPath"
|
|
532
545
|
],
|
|
546
|
+
"notImplemented": {
|
|
547
|
+
"props": [
|
|
548
|
+
"autoplayIntervalMs"
|
|
549
|
+
],
|
|
550
|
+
"platforms": [
|
|
551
|
+
"android",
|
|
552
|
+
"web"
|
|
553
|
+
],
|
|
554
|
+
"severity": "styling",
|
|
555
|
+
"note": "No autoplay."
|
|
556
|
+
},
|
|
533
557
|
"propsSource": "export interface CarouselProps {\n items: Component[];\n currentIndex?: number;\n onChange?: Action;\n autoplayIntervalMs?: number;\n /** `$service:` binding → a live array to render as slides (overrides `items`). */\n itemsPath?: string;\n}"
|
|
534
558
|
},
|
|
535
559
|
{
|
|
@@ -551,6 +575,30 @@
|
|
|
551
575
|
"category": "Navigation primitives",
|
|
552
576
|
"propsType": "CollapsingHeaderProps",
|
|
553
577
|
"bindings": [],
|
|
578
|
+
"notImplemented": [
|
|
579
|
+
{
|
|
580
|
+
"props": [
|
|
581
|
+
"imageAsset",
|
|
582
|
+
"collapsedHeight",
|
|
583
|
+
"parallaxFactor"
|
|
584
|
+
],
|
|
585
|
+
"platforms": [
|
|
586
|
+
"web"
|
|
587
|
+
],
|
|
588
|
+
"severity": "styling",
|
|
589
|
+
"note": "A static hero: `imageAsset`, `collapsedHeight` and `parallaxFactor` are inert (only `imageUrl` is read)."
|
|
590
|
+
},
|
|
591
|
+
{
|
|
592
|
+
"props": [
|
|
593
|
+
"imageAsset"
|
|
594
|
+
],
|
|
595
|
+
"platforms": [
|
|
596
|
+
"android"
|
|
597
|
+
],
|
|
598
|
+
"severity": "styling",
|
|
599
|
+
"note": "`imageAsset` (a baked asset name) is not resolved — only `imageUrl` paints the hero."
|
|
600
|
+
}
|
|
601
|
+
],
|
|
554
602
|
"propsSource": "export interface CollapsingHeaderProps {\n /** Hero image URL (`$service:`-resolvable upstream). */\n imageUrl?: string;\n /** Bundle asset fallback. */\n imageAsset?: string;\n /** Required; scales & fades with collapse. */\n title: string;\n subtitle?: string;\n /** Initial height in points (default 280). */\n expandedHeight?: number;\n /** Final height when fully scrolled (default 64). */\n collapsedHeight?: number;\n /** Body content that scrolls under the header. */\n children?: Component[];\n /** 0.0 = static, 1.0 = full parallax (default 0.5). */\n parallaxFactor?: number;\n}"
|
|
555
603
|
},
|
|
556
604
|
{
|
|
@@ -570,6 +618,16 @@
|
|
|
570
618
|
"title",
|
|
571
619
|
"message"
|
|
572
620
|
],
|
|
621
|
+
"notImplemented": {
|
|
622
|
+
"props": [
|
|
623
|
+
"dismissible"
|
|
624
|
+
],
|
|
625
|
+
"platforms": [
|
|
626
|
+
"web"
|
|
627
|
+
],
|
|
628
|
+
"severity": "styling",
|
|
629
|
+
"note": "No dismiss control."
|
|
630
|
+
},
|
|
573
631
|
"propsSource": "export interface BannerProps {\n severity: Severity;\n /** Banner headline — binding-aware (\"$item.\"/\"$service:\") on web, iOS and Android. */\n title: string;\n /** Banner body — binding-aware (\"$item.\"/\"$service:\") on web, iOS and Android. */\n message?: string;\n action?: Action;\n dismissible?: boolean;\n /** #1059 — action label; overridable for localized hosts. Default \"Take action\". */\n actionLabel?: string;\n}"
|
|
574
632
|
},
|
|
575
633
|
{
|
|
@@ -582,10 +640,12 @@
|
|
|
582
640
|
"durationMs"
|
|
583
641
|
],
|
|
584
642
|
"platforms": [
|
|
585
|
-
"ios"
|
|
643
|
+
"ios",
|
|
644
|
+
"android",
|
|
645
|
+
"web"
|
|
586
646
|
],
|
|
587
647
|
"severity": "styling",
|
|
588
|
-
"note": "`durationMs` does
|
|
648
|
+
"note": "The Snackbar component renders inline, so `durationMs` does nothing (the `snackbar` presentation verb is the working toast)."
|
|
589
649
|
},
|
|
590
650
|
"propsSource": "export interface SnackbarProps {\n message: string;\n action?: Action;\n durationMs?: number;\n severity?: Severity;\n /** #1059 — action label; overridable for localized hosts. Default \"Take action\". */\n actionLabel?: string;\n}"
|
|
591
651
|
},
|
|
@@ -608,6 +668,17 @@
|
|
|
608
668
|
"category": "Embeddable WebView (web-in-SDUI)",
|
|
609
669
|
"propsType": "WebViewProps",
|
|
610
670
|
"bindings": [],
|
|
671
|
+
"notImplemented": {
|
|
672
|
+
"props": [
|
|
673
|
+
"scrollEnabled",
|
|
674
|
+
"config"
|
|
675
|
+
],
|
|
676
|
+
"platforms": [
|
|
677
|
+
"web"
|
|
678
|
+
],
|
|
679
|
+
"severity": "styling",
|
|
680
|
+
"note": "The iframe always scrolls. `config` (the native WebView options: cookies, bridge, zoom…) is not applied to the iframe."
|
|
681
|
+
},
|
|
611
682
|
"propsSource": "export interface WebViewProps {\n url?: string;\n /** Inline HTML to load instead of `url` (mutually exclusive). */\n inlineHtml?: string;\n /** Fixed height in points/dp; set this OR `aspectRatio`. */\n height?: number;\n /** width:height ratio; used when `height` is unset. */\n aspectRatio?: number;\n /** Keep the WebView's own scrolling (default false). */\n scrollEnabled?: boolean;\n config?: WebViewConfig;\n capabilitiesRequired?: string[];\n}"
|
|
612
683
|
},
|
|
613
684
|
{
|
|
@@ -661,10 +732,11 @@
|
|
|
661
732
|
"debounceMs"
|
|
662
733
|
],
|
|
663
734
|
"platforms": [
|
|
664
|
-
"ios"
|
|
735
|
+
"ios",
|
|
736
|
+
"web"
|
|
665
737
|
],
|
|
666
738
|
"severity": "styling",
|
|
667
|
-
"note": "`debounceMs` does not throttle
|
|
739
|
+
"note": "`debounceMs` does not throttle onChange."
|
|
668
740
|
},
|
|
669
741
|
"propsSource": "export interface SliderProps {\n value?: number;\n min?: number;\n max?: number;\n /** 0 = continuous; >0 snaps. */\n step?: number;\n onChange?: Action;\n /** Two-thumb range mode. */\n range?: boolean;\n upperValue?: number;\n /** \"$service:\"/\"$item.\" binding → number (overrides `value`). */\n valuePath?: string;\n tint?: TokenName;\n debounceMs?: number;\n disabled?: boolean;\n}"
|
|
670
742
|
},
|
|
@@ -700,6 +772,17 @@
|
|
|
700
772
|
]
|
|
701
773
|
}
|
|
702
774
|
],
|
|
775
|
+
"notImplemented": {
|
|
776
|
+
"props": [
|
|
777
|
+
"groupId"
|
|
778
|
+
],
|
|
779
|
+
"platforms": [
|
|
780
|
+
"android",
|
|
781
|
+
"web"
|
|
782
|
+
],
|
|
783
|
+
"severity": "styling",
|
|
784
|
+
"note": "Radios sharing a `groupId` are not mutually exclusive."
|
|
785
|
+
},
|
|
703
786
|
"propsSource": "export interface SelectionControlProps {\n label?: string;\n value?: boolean;\n kind?: \"checkbox\" | \"radio\";\n /** Radios sharing a `groupId` are mutually exclusive. */\n groupId?: string;\n onChange?: Action;\n /** \"$service:\"/\"$item.\" binding → bool (overrides `value`). */\n valuePath?: string;\n disabled?: boolean;\n /** Checkbox tri-state (renders a dash); ignored for radio. */\n indeterminate?: boolean;\n}"
|
|
704
787
|
},
|
|
705
788
|
{
|
|
@@ -714,10 +797,12 @@
|
|
|
714
797
|
"ring"
|
|
715
798
|
],
|
|
716
799
|
"platforms": [
|
|
717
|
-
"ios"
|
|
800
|
+
"ios",
|
|
801
|
+
"android",
|
|
802
|
+
"web"
|
|
718
803
|
],
|
|
719
804
|
"severity": "styling",
|
|
720
|
-
"note": "The `ring` style is
|
|
805
|
+
"note": "The `ring` style is never selected (determinate vs indeterminate follows `value`)."
|
|
721
806
|
},
|
|
722
807
|
"propsSource": "export interface ActivityIndicatorProps {\n /** 0..1 (determinate); ignored when `indeterminate`. */\n value?: number;\n /** `$service:`/`$item.` binding → a live 0..1 fraction (overrides `value`). */\n valuePath?: string;\n indeterminate?: boolean;\n size?: number;\n tint?: TokenName;\n /** Determinate ring vs. arc spinner. */\n ring?: boolean;\n}"
|
|
723
808
|
},
|
|
@@ -725,22 +810,45 @@
|
|
|
725
810
|
"name": "BottomSheet",
|
|
726
811
|
"category": "Overlays & menus",
|
|
727
812
|
"propsType": "BottomSheetProps",
|
|
728
|
-
"bindings": [
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
"
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
"
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
"
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
813
|
+
"bindings": [
|
|
814
|
+
"presentedPath"
|
|
815
|
+
],
|
|
816
|
+
"notImplemented": [
|
|
817
|
+
{
|
|
818
|
+
"props": [
|
|
819
|
+
"edge"
|
|
820
|
+
],
|
|
821
|
+
"platforms": [
|
|
822
|
+
"ios"
|
|
823
|
+
],
|
|
824
|
+
"severity": "category",
|
|
825
|
+
"note": "`edge` (side sheet) is ignored — it always opens from the bottom."
|
|
826
|
+
},
|
|
827
|
+
{
|
|
828
|
+
"props": [
|
|
829
|
+
"detents",
|
|
830
|
+
"edge"
|
|
831
|
+
],
|
|
832
|
+
"platforms": [
|
|
833
|
+
"android"
|
|
834
|
+
],
|
|
835
|
+
"severity": "category",
|
|
836
|
+
"note": "`detents` are ignored (opens full height). `edge` (side sheet) is ignored — it always opens from the bottom."
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
"props": [
|
|
840
|
+
"detents",
|
|
841
|
+
"dismissible",
|
|
842
|
+
"onDismiss",
|
|
843
|
+
"edge"
|
|
844
|
+
],
|
|
845
|
+
"platforms": [
|
|
846
|
+
"web"
|
|
847
|
+
],
|
|
848
|
+
"severity": "category",
|
|
849
|
+
"note": "`detents` are ignored (opens full height). No scrim tap / Escape to close, so `onDismiss` never fires — for a dismissible sheet here, present the content as its own screen with `presentation: \"sheet\"` on the navigating `Action`. `edge` (side sheet) is ignored — it always opens from the bottom."
|
|
850
|
+
}
|
|
851
|
+
],
|
|
744
852
|
"propsSource": "export interface BottomSheetProps {\n /** Place the sheet as a root-payload sibling (normally the final child), not\n * inside the trigger row, so its presented overlay can cover the whole screen. */\n content?: Component;\n /** Fractional heights, e.g. [0.3, 0.9]. */\n detents?: number[];\n dismissible?: boolean;\n showGrabber?: boolean;\n onDismiss?: Action;\n presented?: boolean;\n /** \"$service:\" binding → bool (overrides `presented`). */\n presentedPath?: string;\n edge?: \"bottom\" | \"leading\" | \"trailing\";\n /** The overlay traps focus and hides the rest of the tree from AT while\n * presented (iOS `accessibilityViewIsModal`, Android `isTraversalGroup`, ARIA\n * `aria-modal`). TRI-STATE: absent takes this component's default (**true**), an\n * explicit `false` opts it out. */\n modal?: boolean;\n}"
|
|
745
853
|
},
|
|
746
854
|
{
|
|
@@ -748,17 +856,30 @@
|
|
|
748
856
|
"category": "Overlays & menus",
|
|
749
857
|
"propsType": "MenuProps",
|
|
750
858
|
"bindings": [],
|
|
751
|
-
"notImplemented":
|
|
752
|
-
|
|
753
|
-
"
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
859
|
+
"notImplemented": [
|
|
860
|
+
{
|
|
861
|
+
"props": [
|
|
862
|
+
"itemsPath"
|
|
863
|
+
],
|
|
864
|
+
"platforms": [
|
|
865
|
+
"ios"
|
|
866
|
+
],
|
|
867
|
+
"severity": "category",
|
|
868
|
+
"note": "`itemsPath` does not bind items."
|
|
869
|
+
},
|
|
870
|
+
{
|
|
871
|
+
"props": [
|
|
872
|
+
"style",
|
|
873
|
+
"itemsPath"
|
|
874
|
+
],
|
|
875
|
+
"platforms": [
|
|
876
|
+
"android",
|
|
877
|
+
"web"
|
|
878
|
+
],
|
|
879
|
+
"severity": "category",
|
|
880
|
+
"note": "`style` is ignored — `context`/`action_sheet` render as a dropdown. `itemsPath` does not bind items."
|
|
881
|
+
}
|
|
882
|
+
],
|
|
762
883
|
"propsSource": "export interface MenuProps {\n anchor?: Component;\n items?: MenuItem[];\n style?: \"dropdown\" | \"context\" | \"action_sheet\";\n /** \"$service:\" binding → MenuItem[]. */\n itemsPath?: string;\n /** The overlay traps focus and hides the rest of the tree from AT while\n * presented (iOS `accessibilityViewIsModal`, Android `isTraversalGroup`, ARIA\n * `aria-modal`). TRI-STATE: absent takes the Menu's default — MODAL,\n * from the one shared overlay default table — and an explicit `false` opts out. */\n modal?: boolean;\n}"
|
|
763
884
|
},
|
|
764
885
|
{
|
|
@@ -773,10 +894,12 @@
|
|
|
773
894
|
"onDismiss"
|
|
774
895
|
],
|
|
775
896
|
"platforms": [
|
|
776
|
-
"ios"
|
|
897
|
+
"ios",
|
|
898
|
+
"android",
|
|
899
|
+
"web"
|
|
777
900
|
],
|
|
778
901
|
"severity": "category",
|
|
779
|
-
"note": "Not an overlay — renders always-expanded inline; `trigger` and dismissal are inert."
|
|
902
|
+
"note": "Not an overlay — renders always-expanded inline; `edge`, `trigger` and dismissal are inert."
|
|
780
903
|
},
|
|
781
904
|
"propsSource": "export interface TooltipProps {\n anchor?: Component;\n text?: string;\n /** Present → rich tooltip. */\n title?: string;\n edge?: \"top\" | \"bottom\" | \"leading\" | \"trailing\" | \"auto\";\n trigger?: \"tap\" | \"long_press\" | \"auto\";\n onDismiss?: Action;\n}"
|
|
782
905
|
},
|
|
@@ -795,7 +918,7 @@
|
|
|
795
918
|
"ios"
|
|
796
919
|
],
|
|
797
920
|
"severity": "category",
|
|
798
|
-
"note": "
|
|
921
|
+
"note": "The bubble is drawn in flow under its anchor; `edge` placement is not implemented."
|
|
799
922
|
},
|
|
800
923
|
"propsSource": "export interface PopoverProps {\n anchor?: Component;\n content?: Component;\n edge?: \"top\" | \"bottom\" | \"leading\" | \"trailing\" | \"auto\";\n presented?: boolean;\n presentedPath?: string;\n onDismiss?: Action;\n /** The overlay traps focus and hides the rest of the tree from AT while\n * presented (iOS `accessibilityViewIsModal`, Android `isTraversalGroup`, ARIA\n * `aria-modal`). TRI-STATE: absent takes the Popover's default — MODAL,\n * from the one shared overlay default table — and an explicit `false` opts out. Applies to a\n * popover presented through `presented` / `presentedPath`; one with neither is an\n * inline callout, and never modal. */\n modal?: boolean;\n}"
|
|
801
924
|
},
|
|
@@ -838,9 +961,11 @@
|
|
|
838
961
|
"onAdd"
|
|
839
962
|
],
|
|
840
963
|
"platforms": [
|
|
841
|
-
"ios"
|
|
964
|
+
"ios",
|
|
965
|
+
"android",
|
|
966
|
+
"web"
|
|
842
967
|
],
|
|
843
|
-
"severity": "
|
|
968
|
+
"severity": "category",
|
|
844
969
|
"note": "`onAdd` never dispatches."
|
|
845
970
|
},
|
|
846
971
|
"propsSource": "export interface ChipsInputProps {\n values?: string[];\n /** \"$service:\" binding → string[]. */\n valuesPath?: string;\n placeholder?: string;\n onAdd?: Action;\n onRemove?: Action;\n disabled?: boolean;\n}"
|
|
@@ -1159,14 +1284,16 @@
|
|
|
1159
1284
|
],
|
|
1160
1285
|
"notImplemented": {
|
|
1161
1286
|
"props": [
|
|
1162
|
-
"
|
|
1163
|
-
"
|
|
1287
|
+
"onComplete",
|
|
1288
|
+
"onChange"
|
|
1164
1289
|
],
|
|
1165
1290
|
"platforms": [
|
|
1166
|
-
"ios"
|
|
1291
|
+
"ios",
|
|
1292
|
+
"android",
|
|
1293
|
+
"web"
|
|
1167
1294
|
],
|
|
1168
|
-
"severity": "
|
|
1169
|
-
"note": "Neither
|
|
1295
|
+
"severity": "category",
|
|
1296
|
+
"note": "Neither `onChange` nor `onComplete` dispatches."
|
|
1170
1297
|
},
|
|
1171
1298
|
"propsSource": "export interface OtpInputProps {\n length?: number;\n /** LITERAL code. A `$service:` sentinel here paints the raw token into the\n * boxes — bind `valuePath` instead. */\n value?: string;\n /** `$service:`/`$item.` binding → the live code (overrides `value`), so a\n * worker that clears it after submit empties the boxes. */\n valuePath?: string;\n onChange?: Action;\n onComplete?: Action;\n secure?: boolean;\n}"
|
|
1172
1299
|
},
|
|
@@ -1187,6 +1314,17 @@
|
|
|
1187
1314
|
"cameraPath",
|
|
1188
1315
|
"shapesPath"
|
|
1189
1316
|
],
|
|
1317
|
+
"notImplemented": {
|
|
1318
|
+
"props": [
|
|
1319
|
+
"followUserLocation"
|
|
1320
|
+
],
|
|
1321
|
+
"platforms": [
|
|
1322
|
+
"android",
|
|
1323
|
+
"web"
|
|
1324
|
+
],
|
|
1325
|
+
"severity": "styling",
|
|
1326
|
+
"note": "`followUserLocation` does not track."
|
|
1327
|
+
},
|
|
1190
1328
|
"propsSource": "export interface MapProps {\n latitude?: number;\n longitude?: number;\n zoom?: number;\n markers?: MapMarker[];\n /** `$service:` binding → a live markers array (overrides `markers`). */\n markersPath?: string;\n height?: number;\n interactive?: boolean;\n /**\n * Polyline waypoints — a recorded GPS track, or a delivery route. Drawn in order, so\n * pass the fixes chronologically (`@himalaya/location`'s `watch()` yields them that way).\n */\n route?: MapMarker[];\n /**\n * How a `route` is drawn. Default `\"tile\"` — the polyline over REAL map tiles, which is\n * what a track/navigation screen wants. `\"schematic\"` keeps the normalized,\n * projection-free mini-map (no tile fetch, so no flicker) that suits a small\n * delivery/route CARD. Strict enum: a `$service:` binding here fails at render time,\n * not validation.\n */\n routeMode?: \"tile\" | \"schematic\";\n /** Draw the live device-position dot. Silently inert without location permission. */\n showUserLocation?: boolean;\n /** Keep the camera following the user. Implies `showUserLocation`. */\n followUserLocation?: boolean;\n /** Frame the viewport to `markers` ∪ `route` instead of `latitude`/`longitude` + `zoom`. */\n fitToContent?: boolean;\n /**\n * Imagery style: `\"standard\"` (default) | `\"satellite\"` | `\"hybrid\"` (satellite + labels).\n * Strict enum — a `$service:` binding here fails at render, not validation.\n *\n * HONORED ON THE MAPKIT SURFACES (iOS + macOS). MapKit ships first-party satellite/hybrid\n * imagery (MKMapType), and the tile-route arm has a macOS representable, so a Mac gets it too. The Android + web tile arms draw OSM raster tiles, and OSM has no satellite\n * layer — serving one would mean bundling a third-party imagery provider with its own\n * attribution terms and usage limits, which is an app's licensing decision rather than the\n * platform's. Those arms normalize the value and keep drawing standard tiles.\n *\n * For satellite/topo on EVERY surface, use the app-scoped `TrailMap` component\n * and point its `styleUrl` at a vector style you have rights to.\n */\n mapStyle?: \"standard\" | \"satellite\" | \"hybrid\";\n /**\n * Tap on the map surface. The event payload is merged into the Action's `args` — exactly\n * like Slider/SelectionControl merge `value` — so a Tier-5 reducer reads\n * `{latitude, longitude}` with no new dispatch contract.\n *\n * Honored on the TILE arms, which have real geography. The schematic mini-map draws a\n * normalized, projection-free polyline with no meaningful coordinate to report, so it\n * fires `onMarkerTap` only. `interactive` governs pan/zoom, not taps: a deliberately\n * non-interactive map still reports them.\n */\n onMapTap?: Action;\n /**\n * Tap on a marker. `args`: `{index, label?, latitude, longitude}`, where `index` is into\n * the RESOLVED marker array (`markersPath` when bound, else `markers`) so the worker can\n * look the item back up in its own state. `label` is OMITTED for an unlabeled pin rather\n * than sent as `\"\"`. A tap that landed on a pin is a marker tap only — never also a map tap.\n */\n onMarkerTap?: Action;\n /**\n * Camera settled after a pan/zoom — fired on gesture END, never per frame.\n * `args`: `{latitude, longitude, zoom, north, south, east, west}`, so a worker can fetch\n * \"trails in view\" without re-deriving the viewport. Programmatic camera moves\n * (e.g. a `fitToContent` re-frame) do NOT fire it, or a worker that refetches on region\n * change would loop against its own camera.\n */\n onRegionChange?: Action;\n /**\n * `$service:` binding → a live route array (overrides `route`), mirroring `markersPath`.\n * Without it a growing recorded track had to re-push the whole descriptor for every fix;\n * with it the polyline follows worker state. Defaults to the TILE arm, not the schematic\n * one — a bound route is a recorded track, which is why the binding exists.\n */\n routePath?: string;\n /**\n * `$service:` binding → `{latitude, longitude, zoom}`: the camera, driven by the WORKER.\n *\n * `latitude`/`longitude`/`zoom` are numbers, so a `$service:` sentinel cannot go in them —\n * which meant a worker could not move the camera at all (\"fly to this search result\" was\n * inexpressible without re-pushing the descriptor).\n *\n * Precedence: a resolved `cameraPath` wins, then `fitToContent`, then the static\n * `latitude`/`longitude`/`zoom`. A NEW value also overrides the user's own pan; an unchanged\n * one leaves it alone. Applying it is programmatic, so it never echoes back through\n * `onRegionChange`. Partial objects are honored — `{zoom}` re-zooms in place.\n */\n cameraPath?: string;\n /** Overlays beyond the single `route`: lines, polygons, circles. */\n shapes?: MapShape[];\n /** `$service:` binding → a live shapes array (overrides `shapes`). */\n shapesPath?: string;\n /**\n * Tap on a drawn shape. `args`: `{id?, index, kind}`. Hit-tested before the surface and after\n * markers — a pin on top of a polygon belongs to the pin.\n */\n onShapeTap?: Action;\n /** App-supplied basemap tiles. Absent ⇒ each arm's default (OSM raster, or Apple's imagery). */\n tileSource?: MapTileSource;\n}"
|
|
1191
1329
|
},
|
|
1192
1330
|
{
|
|
@@ -1202,7 +1340,7 @@
|
|
|
1202
1340
|
"ios"
|
|
1203
1341
|
],
|
|
1204
1342
|
"severity": "styling",
|
|
1205
|
-
"note": "`poster`
|
|
1343
|
+
"note": "`poster` is not shown."
|
|
1206
1344
|
},
|
|
1207
1345
|
"propsSource": "export interface VideoProps {\n url?: string;\n poster?: string;\n autoplay?: boolean;\n controls?: boolean;\n loop?: boolean;\n muted?: boolean;\n height?: number;\n aspectRatio?: number;\n}"
|
|
1208
1346
|
},
|
|
@@ -1211,6 +1349,31 @@
|
|
|
1211
1349
|
"category": "Cross-cutting & media",
|
|
1212
1350
|
"propsType": "PdfViewProps",
|
|
1213
1351
|
"bindings": [],
|
|
1352
|
+
"notImplemented": [
|
|
1353
|
+
{
|
|
1354
|
+
"props": [
|
|
1355
|
+
"showPageControls",
|
|
1356
|
+
"startPage"
|
|
1357
|
+
],
|
|
1358
|
+
"platforms": [
|
|
1359
|
+
"android"
|
|
1360
|
+
],
|
|
1361
|
+
"severity": "styling",
|
|
1362
|
+
"note": "No page controls. `startPage` is ignored."
|
|
1363
|
+
},
|
|
1364
|
+
{
|
|
1365
|
+
"props": [
|
|
1366
|
+
"showPageControls",
|
|
1367
|
+
"zoomable",
|
|
1368
|
+
"allowShare"
|
|
1369
|
+
],
|
|
1370
|
+
"platforms": [
|
|
1371
|
+
"web"
|
|
1372
|
+
],
|
|
1373
|
+
"severity": "styling",
|
|
1374
|
+
"note": "No page controls. The browser PDF viewer ignores `zoomable` and `allowShare`."
|
|
1375
|
+
}
|
|
1376
|
+
],
|
|
1214
1377
|
"propsSource": "export interface PdfViewProps {\n url?: string;\n height?: number;\n showPageControls?: boolean;\n /** 1-based; 0/absent ⇒ page 1. */\n startPage?: number;\n zoomable?: boolean;\n allowShare?: boolean;\n}"
|
|
1215
1378
|
},
|
|
1216
1379
|
{
|
|
@@ -1220,6 +1383,56 @@
|
|
|
1220
1383
|
"bindings": [
|
|
1221
1384
|
"itemsPath"
|
|
1222
1385
|
],
|
|
1386
|
+
"notImplemented": [
|
|
1387
|
+
{
|
|
1388
|
+
"props": [
|
|
1389
|
+
"autoplayVisibilityThreshold",
|
|
1390
|
+
"preload",
|
|
1391
|
+
"playbackRates",
|
|
1392
|
+
"showQueue",
|
|
1393
|
+
"showChapters",
|
|
1394
|
+
"showTranscript"
|
|
1395
|
+
],
|
|
1396
|
+
"platforms": [
|
|
1397
|
+
"ios"
|
|
1398
|
+
],
|
|
1399
|
+
"severity": "category",
|
|
1400
|
+
"note": "`autoplayVisibilityThreshold` is ignored (whenVisible = once on appear). `preload` is ignored. `playbackRates` is ignored, and the queue/chapters/transcript panels never render."
|
|
1401
|
+
},
|
|
1402
|
+
{
|
|
1403
|
+
"props": [
|
|
1404
|
+
"externalPlayback",
|
|
1405
|
+
"appearance",
|
|
1406
|
+
"allowCellular",
|
|
1407
|
+
"preload",
|
|
1408
|
+
"playbackRates",
|
|
1409
|
+
"showQueue",
|
|
1410
|
+
"showChapters",
|
|
1411
|
+
"showTranscript"
|
|
1412
|
+
],
|
|
1413
|
+
"platforms": [
|
|
1414
|
+
"android"
|
|
1415
|
+
],
|
|
1416
|
+
"severity": "category",
|
|
1417
|
+
"note": "`externalPlayback` is forced off. `appearance` is ignored. `allowCellular` is ignored. `preload` is ignored. `playbackRates` is ignored, and the queue/chapters/transcript panels never render."
|
|
1418
|
+
},
|
|
1419
|
+
{
|
|
1420
|
+
"props": [
|
|
1421
|
+
"allowCellular",
|
|
1422
|
+
"forwardSkipSeconds",
|
|
1423
|
+
"backwardSkipSeconds",
|
|
1424
|
+
"playbackRates",
|
|
1425
|
+
"showQueue",
|
|
1426
|
+
"showChapters",
|
|
1427
|
+
"showTranscript"
|
|
1428
|
+
],
|
|
1429
|
+
"platforms": [
|
|
1430
|
+
"web"
|
|
1431
|
+
],
|
|
1432
|
+
"severity": "category",
|
|
1433
|
+
"note": "`allowCellular` is ignored. Skip buttons ignore `forwardSkipSeconds`/`backwardSkipSeconds`. `playbackRates` is ignored, and the queue/chapters/transcript panels never render."
|
|
1434
|
+
}
|
|
1435
|
+
],
|
|
1223
1436
|
"propsSource": "export interface MediaPlayerProps {\n sessionId?: string;\n items?: MediaItem[];\n startIndex?: number;\n startPositionSeconds?: number;\n presentation?: MediaPresentation;\n controls?: MediaControls;\n autoplay?: MediaAutoplay;\n autoplayVisibilityThreshold?: number;\n muted?: boolean;\n loop?: MediaLoop;\n fullscreen?: Exclude<MediaPolicy, \"automatic\" | \"audioOnly\">;\n pictureInPicture?: Extract<MediaPolicy, \"disabled\" | \"allowed\" | \"automatic\">;\n backgroundPlayback?: Extract<MediaPolicy, \"disabled\" | \"allowed\" | \"audioOnly\">;\n externalPlayback?: Exclude<MediaPolicy, \"automatic\" | \"audioOnly\">;\n playbackRates?: number[];\n forwardSkipSeconds?: number;\n backwardSkipSeconds?: number;\n showQueue?: boolean;\n showChapters?: boolean;\n showTranscript?: boolean;\n height?: number;\n aspectRatio?: number;\n contentMode?: \"fit\" | \"fill\";\n posterUrl?: string;\n appearance?: MediaPlayerAppearance;\n slots?: MediaPlayerSlots;\n onReady?: Action;\n onPlay?: Action;\n onPause?: Action;\n onEnd?: Action;\n onError?: Action;\n onProgress?: Action;\n onFullscreenChange?: Action;\n onItemChange?: Action;\n allowCellular?: boolean;\n preload?: boolean;\n /**\n * `$service:` binding → a live `MediaItem[]`: the worker-driven QUEUE, resolved\n * through the same list-binding seam as `LazyList.itemsPath` / `Map.markersPath`.\n * `items` is `MediaItem[]`, so a value binding there is a type mismatch — this\n * companion string carries the binding and OVERRIDES the literal `items` when set.\n * Each resolved item's own scalar fields (url/title/artist/artworkUrl) still resolve\n * per-field through the media-source seam.\n */\n itemsPath?: string;\n}"
|
|
1224
1437
|
},
|
|
1225
1438
|
{
|
|
@@ -1255,10 +1468,20 @@
|
|
|
1255
1468
|
"category": "Rich vector & celebration (motion grammar Batch 4)",
|
|
1256
1469
|
"propsType": "TimeGridProps",
|
|
1257
1470
|
"bindings": [
|
|
1258
|
-
"anchorDatePath",
|
|
1259
1471
|
"eventsPath",
|
|
1260
1472
|
"resourcesPath"
|
|
1261
1473
|
],
|
|
1474
|
+
"notImplemented": {
|
|
1475
|
+
"props": [
|
|
1476
|
+
"anchorDatePath",
|
|
1477
|
+
"onRangeChange"
|
|
1478
|
+
],
|
|
1479
|
+
"platforms": [
|
|
1480
|
+
"android"
|
|
1481
|
+
],
|
|
1482
|
+
"severity": "category",
|
|
1483
|
+
"note": "`anchorDatePath` does not bind and `onRangeChange` never fires."
|
|
1484
|
+
},
|
|
1262
1485
|
"propsSource": "export interface TimeGridProps {\n mode?: \"day\" | \"3day\" | \"week\";\n anchorDate?: string;\n anchorDatePath?: string;\n events?: CalendarEvent[];\n eventsPath?: string;\n startHour?: number;\n endHour?: number;\n firstWeekday?: number;\n showNowLine?: boolean;\n onSelectEvent?: Action;\n onRangeChange?: Action;\n /** Per-event body, `$item.*`-substituted per event. Absent ⇒ the built-in block. */\n eventTemplate?: Component;\n /** RESOURCE lanes: staff, rooms, chairs, courts. Overlap packing already splits\n * concurrent events into ANONYMOUS sub-columns; lanes make a column MEAN\n * something. Single-day modes only — a week of resource columns is a 2-D grid\n * that does not fit a phone, so `mode: \"week\"` ignores them. */\n resources?: TimeGridResource[];\n resourcesPath?: string;\n /** EDITING. Opt-in, default off, so no existing read-only\n * grid can regress into one that moves bookings when a user meant to scroll. */\n editable?: boolean;\n /** Snap grid in minutes (default 15). A drag landing on 10:07 is almost never\n * what anyone meant, and no scheduling system accepts it. */\n snapMinutes?: number;\n /** Moved or resized → args{id, start, end}. The component REPORTS; the worker\n * decides. An edit that must be rejected has to be able to fail. */\n onEventChange?: Action;\n /** Empty space long-pressed → args{start, end} for one `snapMinutes` slot. */\n onCreate?: Action;\n /** Labels for the non-drag equivalents. Drag is unreachable by VoiceOver,\n * TalkBack and keyboard, so these are how editing stays operable at all. */\n moveActionLabel?: string;\n resizeActionLabel?: string;\n}"
|
|
1263
1486
|
},
|
|
1264
1487
|
{
|
|
@@ -1269,6 +1492,16 @@
|
|
|
1269
1492
|
"eventsPath",
|
|
1270
1493
|
"scrollToDatePath"
|
|
1271
1494
|
],
|
|
1495
|
+
"notImplemented": {
|
|
1496
|
+
"props": [
|
|
1497
|
+
"stickyHeaders"
|
|
1498
|
+
],
|
|
1499
|
+
"platforms": [
|
|
1500
|
+
"android"
|
|
1501
|
+
],
|
|
1502
|
+
"severity": "styling",
|
|
1503
|
+
"note": "Day headers do not pin."
|
|
1504
|
+
},
|
|
1272
1505
|
"propsSource": "export interface AgendaProps {\n events?: CalendarEvent[];\n eventsPath?: string;\n scrollToDate?: string;\n /** Worker-driven jump target (a literal `scrollToDate` is frozen in the descriptor). */\n scrollToDatePath?: string;\n stickyHeaders?: boolean;\n emptyText?: string;\n onSelectEvent?: Action;\n /** Per-event row body, `$item.*`-substituted per event. Closes the gap that made\n * `agendaList()` (the LazyList-backed PRESET, which takes a `rowTemplate`) more\n * expressive than this component. Absent ⇒ the built-in row. */\n eventTemplate?: Component;\n /** Newest-first. Absent/false ⇒ ascending. Applies to the day GROUPS and to the\n * events within each group. Without it a list whose default sort is \"Newest\"\n * (an owner's orders, recent activity) could not become an Agenda without\n * silently inverting itself — every arm sorted ascending unconditionally. */\n descending?: boolean;\n}"
|
|
1273
1506
|
}
|
|
1274
1507
|
],
|
|
@@ -52,14 +52,14 @@ See also **[Modifiers](#modifiers)** (the `modifiers` block) and **[Actions](#ac
|
|
|
52
52
|
| `FormField` | Form primitives | — |
|
|
53
53
|
| `FieldError` | Form primitives | `textPath` |
|
|
54
54
|
| `Picker` | Form primitives | — |
|
|
55
|
-
| `DatePicker` | Form primitives |
|
|
55
|
+
| `DatePicker` | Form primitives | `valuePath` |
|
|
56
56
|
| `StatefulSection` | State envelopes | — |
|
|
57
57
|
| `Skeleton` | State envelopes | — |
|
|
58
58
|
| `FragmentSlot` | Descriptor-shipped dynamic structure | `casePath` |
|
|
59
59
|
| `WorkerSubtree` | Bounded worker-authored component tree | `treeJsonPath` |
|
|
60
60
|
| `SearchField` | Search & filter | — |
|
|
61
61
|
| `FilterChips` | Search & filter | `optionsPath`, `selectedIds` |
|
|
62
|
-
| `Tabs` | Navigation primitives | `optionsPath`, `
|
|
62
|
+
| `Tabs` | Navigation primitives | `optionsPath`, `selectedId` |
|
|
63
63
|
| `SegmentedControl` | Navigation primitives | `optionsPath`, `selectedId` |
|
|
64
64
|
| `Carousel` | Navigation primitives | `itemsPath` |
|
|
65
65
|
| `Pager` | Navigation primitives | — |
|
|
@@ -75,7 +75,7 @@ See also **[Modifiers](#modifiers)** (the `modifiers` block) and **[Actions](#ac
|
|
|
75
75
|
| `Slider` | Controls & cells | `valuePath` |
|
|
76
76
|
| `SelectionControl` | Controls & cells | `valuePath` |
|
|
77
77
|
| `ActivityIndicator` | Controls & cells | `valuePath` |
|
|
78
|
-
| `BottomSheet` | Overlays & menus |
|
|
78
|
+
| `BottomSheet` | Overlays & menus | `presentedPath` |
|
|
79
79
|
| `Menu` | Overlays & menus | — |
|
|
80
80
|
| `Tooltip` | Overlays & menus | — |
|
|
81
81
|
| `Popover` | Overlays & menus | `presentedPath` |
|
|
@@ -109,34 +109,52 @@ See also **[Modifiers](#modifiers)** (the `modifiers` block) and **[Actions](#ac
|
|
|
109
109
|
| `Lottie` | Rich vector & celebration (motion grammar Batch 4) | — |
|
|
110
110
|
| `Rive` | Rich vector & celebration (motion grammar Batch 4) | — |
|
|
111
111
|
| `MonthCalendar` | Rich vector & celebration (motion grammar Batch 4) | `selectedDatePath`, `decorationsPath`, `yearPath`, `monthPath`, `selectedStartDatePath`, `selectedEndDatePath` |
|
|
112
|
-
| `TimeGrid` | Rich vector & celebration (motion grammar Batch 4) | `
|
|
112
|
+
| `TimeGrid` | Rich vector & celebration (motion grammar Batch 4) | `eventsPath`, `resourcesPath` |
|
|
113
113
|
| `Agenda` | Rich vector & celebration (motion grammar Batch 4) | `eventsPath`, `scrollToDatePath` |
|
|
114
114
|
|
|
115
115
|
## Not implemented (decoded but never read)
|
|
116
116
|
|
|
117
117
|
These props are accepted by the schema and pass validation, but the named platform's renderer never reads them — they silently do nothing (no warning, no log). Prefer a prop NOT listed here, or drive the behaviour from a worker.
|
|
118
118
|
|
|
119
|
-
**Scope:
|
|
119
|
+
**Scope: 23 of 84 components, all of them web / ios / android-only** — every other component/platform pair reads every prop it decodes. The list splits in two, and the halves mean different things:
|
|
120
120
|
|
|
121
|
-
- **`category` (
|
|
122
|
-
- **`styling` (
|
|
121
|
+
- **`category` (8: `BottomSheet`, `Menu`, `Tooltip`, `Popover`, `ChipsInput`, `OtpInput`, `MediaPlayer`, `TimeGrid`)** — the prop changes the component's *kind*. These genuinely are **not implemented**: an overlay renders always-visible inline, so the component does not do the job its name implies. Check the row's note for a working alternative — for a dismissible sheet it is `presentation: "sheet"` on the navigating `Action`, not `BottomSheet`.
|
|
122
|
+
- **`styling` (15: `Text`, `Picker`, `Tabs`, `Carousel`, `CollapsingHeader`, `Banner`, `Snackbar`, `WebView`, `Slider`, `SelectionControl`, `ActivityIndicator`, `Map`, `Video`, `PdfView`, `Agenda`)** — the component itself **works**; only the listed prop is inert. `Slider` on iOS is a working slider whose `debounceMs` does not throttle — not a broken `Slider`. Use the component; just do not depend on that one prop.
|
|
123
123
|
|
|
124
124
|
| Component | Unread props | Platform | Kind | Note |
|
|
125
125
|
|---|---|---|---|---|
|
|
126
|
-
| `
|
|
127
|
-
| `Picker` | `optionsPath`, `placeholder` | ios | styling | `optionsPath` does not bind
|
|
128
|
-
| `
|
|
129
|
-
| `Tabs` | `
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
| `
|
|
133
|
-
| `
|
|
134
|
-
| `
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
126
|
+
| `Text` | `textDirection`, `animateReveal` | web | styling | `textDirection` sets no `dir`. `animateReveal` does not animate. |
|
|
127
|
+
| `Picker` | `optionsPath`, `placeholder` | ios | styling | Standalone Picker: `optionsPath` does not bind (it does inside a FormField); `placeholder` is only the accessible name, never shown. |
|
|
128
|
+
| `Tabs` | `style` | ios | styling | `style: "swipe"` renders as plain top tabs. |
|
|
129
|
+
| `Tabs` | `activeColorPath` | android | styling | `activeColorPath` does not tint the active tab. |
|
|
130
|
+
| `Tabs` | `activeColorPath`, `style` | web | styling | `activeColorPath` does not tint the active tab. `style: "swipe"` renders as plain top tabs. |
|
|
131
|
+
| `Carousel` | `autoplayIntervalMs` | android, web | styling | No autoplay. |
|
|
132
|
+
| `CollapsingHeader` | `imageAsset`, `collapsedHeight`, `parallaxFactor` | web | styling | A static hero: `imageAsset`, `collapsedHeight` and `parallaxFactor` are inert (only `imageUrl` is read). |
|
|
133
|
+
| `CollapsingHeader` | `imageAsset` | android | styling | `imageAsset` (a baked asset name) is not resolved — only `imageUrl` paints the hero. |
|
|
134
|
+
| `Banner` | `dismissible` | web | styling | No dismiss control. |
|
|
135
|
+
| `Snackbar` | `durationMs` | ios, android, web | styling | The Snackbar component renders inline, so `durationMs` does nothing (the `snackbar` presentation verb is the working toast). |
|
|
136
|
+
| `WebView` | `scrollEnabled`, `config` | web | styling | The iframe always scrolls. `config` (the native WebView options: cookies, bridge, zoom…) is not applied to the iframe. |
|
|
137
|
+
| `Slider` | `debounceMs` | ios, web | styling | `debounceMs` does not throttle onChange. |
|
|
138
|
+
| `SelectionControl` | `groupId` | android, web | styling | Radios sharing a `groupId` are not mutually exclusive. |
|
|
139
|
+
| `ActivityIndicator` | `ring` | ios, android, web | styling | The `ring` style is never selected (determinate vs indeterminate follows `value`). |
|
|
140
|
+
| `BottomSheet` | `edge` | ios | category | `edge` (side sheet) is ignored — it always opens from the bottom. |
|
|
141
|
+
| `BottomSheet` | `detents`, `edge` | android | category | `detents` are ignored (opens full height). `edge` (side sheet) is ignored — it always opens from the bottom. |
|
|
142
|
+
| `BottomSheet` | `detents`, `dismissible`, `onDismiss`, `edge` | web | category | `detents` are ignored (opens full height). No scrim tap / Escape to close, so `onDismiss` never fires — for a dismissible sheet here, present the content as its own screen with `presentation: "sheet"` on the navigating `Action`. `edge` (side sheet) is ignored — it always opens from the bottom. |
|
|
143
|
+
| `Menu` | `itemsPath` | ios | category | `itemsPath` does not bind items. |
|
|
144
|
+
| `Menu` | `style`, `itemsPath` | android, web | category | `style` is ignored — `context`/`action_sheet` render as a dropdown. `itemsPath` does not bind items. |
|
|
145
|
+
| `Tooltip` | `edge`, `trigger`, `onDismiss` | ios, android, web | category | Not an overlay — renders always-expanded inline; `edge`, `trigger` and dismissal are inert. |
|
|
146
|
+
| `Popover` | `edge` | ios | category | The bubble is drawn in flow under its anchor; `edge` placement is not implemented. |
|
|
147
|
+
| `ChipsInput` | `onAdd` | ios, android, web | category | `onAdd` never dispatches. |
|
|
148
|
+
| `OtpInput` | `onComplete`, `onChange` | ios, android, web | category | Neither `onChange` nor `onComplete` dispatches. |
|
|
149
|
+
| `Map` | `followUserLocation` | android, web | styling | `followUserLocation` does not track. |
|
|
150
|
+
| `Video` | `poster` | ios | styling | `poster` is not shown. |
|
|
151
|
+
| `PdfView` | `showPageControls`, `startPage` | android | styling | No page controls. `startPage` is ignored. |
|
|
152
|
+
| `PdfView` | `showPageControls`, `zoomable`, `allowShare` | web | styling | No page controls. The browser PDF viewer ignores `zoomable` and `allowShare`. |
|
|
153
|
+
| `MediaPlayer` | `autoplayVisibilityThreshold`, `preload`, `playbackRates`, `showQueue`, `showChapters`, `showTranscript` | ios | category | `autoplayVisibilityThreshold` is ignored (whenVisible = once on appear). `preload` is ignored. `playbackRates` is ignored, and the queue/chapters/transcript panels never render. |
|
|
154
|
+
| `MediaPlayer` | `externalPlayback`, `appearance`, `allowCellular`, `preload`, `playbackRates`, `showQueue`, `showChapters`, `showTranscript` | android | category | `externalPlayback` is forced off. `appearance` is ignored. `allowCellular` is ignored. `preload` is ignored. `playbackRates` is ignored, and the queue/chapters/transcript panels never render. |
|
|
155
|
+
| `MediaPlayer` | `allowCellular`, `forwardSkipSeconds`, `backwardSkipSeconds`, `playbackRates`, `showQueue`, `showChapters`, `showTranscript` | web | category | `allowCellular` is ignored. Skip buttons ignore `forwardSkipSeconds`/`backwardSkipSeconds`. `playbackRates` is ignored, and the queue/chapters/transcript panels never render. |
|
|
156
|
+
| `TimeGrid` | `anchorDatePath`, `onRangeChange` | android | category | `anchorDatePath` does not bind and `onRangeChange` never fires. |
|
|
157
|
+
| `Agenda` | `stickyHeaders` | android | styling | Day headers do not pin. |
|
|
140
158
|
|
|
141
159
|
## Token slots: `TokenRef` object vs bare `TokenName` string
|
|
142
160
|
|
|
@@ -433,6 +451,8 @@ export type TextProps = TextContent & {
|
|
|
433
451
|
};
|
|
434
452
|
```
|
|
435
453
|
|
|
454
|
+
> ⚠️ **Implemented, but these props are inert on web:** `textDirection`, `animateReveal` — `textDirection` sets no `dir`. `animateReveal` does not animate.
|
|
455
|
+
|
|
436
456
|
#### Image
|
|
437
457
|
|
|
438
458
|
```ts
|
|
@@ -780,8 +800,6 @@ export interface FieldErrorProps {
|
|
|
780
800
|
}
|
|
781
801
|
```
|
|
782
802
|
|
|
783
|
-
> ⚠️ **Implemented, but these props are inert on ios:** `severity` — `severity: "warning"` still paints `danger` red.
|
|
784
|
-
|
|
785
803
|
#### Picker
|
|
786
804
|
|
|
787
805
|
```ts
|
|
@@ -795,7 +813,7 @@ export interface PickerProps {
|
|
|
795
813
|
}
|
|
796
814
|
```
|
|
797
815
|
|
|
798
|
-
> ⚠️ **Implemented, but these props are inert on ios:** `optionsPath`, `placeholder` — `optionsPath` does not bind
|
|
816
|
+
> ⚠️ **Implemented, but these props are inert on ios:** `optionsPath`, `placeholder` — Standalone Picker: `optionsPath` does not bind (it does inside a FormField); `placeholder` is only the accessible name, never shown.
|
|
799
817
|
|
|
800
818
|
**Dispatches** — see [What a control sends](#what-a-control-sends-action-payloads):
|
|
801
819
|
|
|
@@ -821,17 +839,13 @@ export interface DatePickerProps {
|
|
|
821
839
|
}
|
|
822
840
|
```
|
|
823
841
|
|
|
824
|
-
> ⚠️ **Implemented, but these props are inert on ios:** `mode`, `minUnix`, `maxUnix`, `valuePath` — The picker itself renders as a native date wheel — these four props are inert: `mode: "time"` still renders a date wheel; `minUnix`/`maxUnix` do not clamp; `valuePath` does not bind.
|
|
825
|
-
|
|
826
842
|
**Dispatches** — see [What a control sends](#what-a-control-sends-action-payloads):
|
|
827
843
|
|
|
828
844
|
| callback | key | type |
|
|
829
845
|
|---|---|---|
|
|
830
846
|
| `onChange` | `value` | unix-seconds-string |
|
|
831
847
|
|
|
832
|
-
> `onChange` — Unix SECONDS, string-encoded so the params mirror stays legal. iOS
|
|
833
|
-
|
|
834
|
-
> ⚠️ **`onChange` on ios — DIVERGES:** sends `valueUnix` as an int instead of the contract's `value`. Only web conforms. This is the widest split in the vocabulary and the clearest argument for the file.
|
|
848
|
+
> `onChange` — Unix SECONDS, string-encoded so the params mirror stays legal, clamped into [minUnix, maxUnix]. iOS, Android and web conform (iOS shipped `valueUnix` as an int until the SwiftUI-parity DatePicker fix); RN ships nothing. The normative key is `value` because that is what the arms use for every other scalar control.
|
|
835
849
|
|
|
836
850
|
> ⚠️ **`onChange` on rn — DIVERGES:** dispatches the bare action with no date at all.
|
|
837
851
|
|
|
@@ -957,7 +971,11 @@ export interface TabsProps {
|
|
|
957
971
|
}
|
|
958
972
|
```
|
|
959
973
|
|
|
960
|
-
> ⚠️ **Implemented, but these props are inert on ios:** `style` —
|
|
974
|
+
> ⚠️ **Implemented, but these props are inert on ios:** `style` — `style: "swipe"` renders as plain top tabs.
|
|
975
|
+
|
|
976
|
+
> ⚠️ **Implemented, but these props are inert on android:** `activeColorPath` — `activeColorPath` does not tint the active tab.
|
|
977
|
+
|
|
978
|
+
> ⚠️ **Implemented, but these props are inert on web:** `activeColorPath`, `style` — `activeColorPath` does not tint the active tab. `style: "swipe"` renders as plain top tabs.
|
|
961
979
|
|
|
962
980
|
**Dispatches** — see [What a control sends](#what-a-control-sends-action-payloads):
|
|
963
981
|
|
|
@@ -997,6 +1015,8 @@ export interface CarouselProps {
|
|
|
997
1015
|
}
|
|
998
1016
|
```
|
|
999
1017
|
|
|
1018
|
+
> ⚠️ **Implemented, but these props are inert on android, web:** `autoplayIntervalMs` — No autoplay.
|
|
1019
|
+
|
|
1000
1020
|
#### Pager
|
|
1001
1021
|
|
|
1002
1022
|
```ts
|
|
@@ -1040,6 +1060,10 @@ export interface CollapsingHeaderProps {
|
|
|
1040
1060
|
}
|
|
1041
1061
|
```
|
|
1042
1062
|
|
|
1063
|
+
> ⚠️ **Implemented, but these props are inert on web:** `imageAsset`, `collapsedHeight`, `parallaxFactor` — A static hero: `imageAsset`, `collapsedHeight` and `parallaxFactor` are inert (only `imageUrl` is read).
|
|
1064
|
+
|
|
1065
|
+
> ⚠️ **Implemented, but these props are inert on android:** `imageAsset` — `imageAsset` (a baked asset name) is not resolved — only `imageUrl` paints the hero.
|
|
1066
|
+
|
|
1043
1067
|
#### AvatarStrip
|
|
1044
1068
|
|
|
1045
1069
|
```ts
|
|
@@ -1086,6 +1110,8 @@ export interface BannerProps {
|
|
|
1086
1110
|
}
|
|
1087
1111
|
```
|
|
1088
1112
|
|
|
1113
|
+
> ⚠️ **Implemented, but these props are inert on web:** `dismissible` — No dismiss control.
|
|
1114
|
+
|
|
1089
1115
|
#### Snackbar
|
|
1090
1116
|
|
|
1091
1117
|
```ts
|
|
@@ -1099,7 +1125,7 @@ export interface SnackbarProps {
|
|
|
1099
1125
|
}
|
|
1100
1126
|
```
|
|
1101
1127
|
|
|
1102
|
-
> ⚠️ **Implemented, but these props are inert on ios:** `durationMs` — `durationMs` does
|
|
1128
|
+
> ⚠️ **Implemented, but these props are inert on ios, android, web:** `durationMs` — The Snackbar component renders inline, so `durationMs` does nothing (the `snackbar` presentation verb is the working toast).
|
|
1103
1129
|
|
|
1104
1130
|
#### AlertDialog
|
|
1105
1131
|
|
|
@@ -1153,6 +1179,8 @@ export interface WebViewProps {
|
|
|
1153
1179
|
}
|
|
1154
1180
|
```
|
|
1155
1181
|
|
|
1182
|
+
> ⚠️ **Implemented, but these props are inert on web:** `scrollEnabled`, `config` — The iframe always scrolls. `config` (the native WebView options: cookies, bridge, zoom…) is not applied to the iframe.
|
|
1183
|
+
|
|
1156
1184
|
### Controls & cells
|
|
1157
1185
|
|
|
1158
1186
|
#### ListItem
|
|
@@ -1203,7 +1231,7 @@ export interface SliderProps {
|
|
|
1203
1231
|
}
|
|
1204
1232
|
```
|
|
1205
1233
|
|
|
1206
|
-
> ⚠️ **Implemented, but these props are inert on ios:** `debounceMs` — `debounceMs` does not throttle
|
|
1234
|
+
> ⚠️ **Implemented, but these props are inert on ios, web:** `debounceMs` — `debounceMs` does not throttle onChange.
|
|
1207
1235
|
|
|
1208
1236
|
**Dispatches** — see [What a control sends](#what-a-control-sends-action-payloads):
|
|
1209
1237
|
|
|
@@ -1235,6 +1263,8 @@ export interface SelectionControlProps {
|
|
|
1235
1263
|
}
|
|
1236
1264
|
```
|
|
1237
1265
|
|
|
1266
|
+
> ⚠️ **Implemented, but these props are inert on android, web:** `groupId` — Radios sharing a `groupId` are not mutually exclusive.
|
|
1267
|
+
|
|
1238
1268
|
**Dispatches** — see [What a control sends](#what-a-control-sends-action-payloads):
|
|
1239
1269
|
|
|
1240
1270
|
| callback | key | type |
|
|
@@ -1263,7 +1293,7 @@ export interface ActivityIndicatorProps {
|
|
|
1263
1293
|
}
|
|
1264
1294
|
```
|
|
1265
1295
|
|
|
1266
|
-
> ⚠️ **Implemented, but these props are inert on ios:** `ring` — The `ring` style is
|
|
1296
|
+
> ⚠️ **Implemented, but these props are inert on ios, android, web:** `ring` — The `ring` style is never selected (determinate vs indeterminate follows `value`).
|
|
1267
1297
|
|
|
1268
1298
|
### Overlays & menus
|
|
1269
1299
|
|
|
@@ -1291,7 +1321,11 @@ export interface BottomSheetProps {
|
|
|
1291
1321
|
}
|
|
1292
1322
|
```
|
|
1293
1323
|
|
|
1294
|
-
> ⚠️ **Not implemented on ios:** `
|
|
1324
|
+
> ⚠️ **Not implemented on ios:** `edge` — `edge` (side sheet) is ignored — it always opens from the bottom.
|
|
1325
|
+
|
|
1326
|
+
> ⚠️ **Not implemented on android:** `detents`, `edge` — `detents` are ignored (opens full height). `edge` (side sheet) is ignored — it always opens from the bottom.
|
|
1327
|
+
|
|
1328
|
+
> ⚠️ **Not implemented on web:** `detents`, `dismissible`, `onDismiss`, `edge` — `detents` are ignored (opens full height). No scrim tap / Escape to close, so `onDismiss` never fires — for a dismissible sheet here, present the content as its own screen with `presentation: "sheet"` on the navigating `Action`. `edge` (side sheet) is ignored — it always opens from the bottom.
|
|
1295
1329
|
|
|
1296
1330
|
#### Menu
|
|
1297
1331
|
|
|
@@ -1310,7 +1344,9 @@ export interface MenuProps {
|
|
|
1310
1344
|
}
|
|
1311
1345
|
```
|
|
1312
1346
|
|
|
1313
|
-
> ⚠️ **Not implemented on ios:** `
|
|
1347
|
+
> ⚠️ **Not implemented on ios:** `itemsPath` — `itemsPath` does not bind items.
|
|
1348
|
+
|
|
1349
|
+
> ⚠️ **Not implemented on android, web:** `style`, `itemsPath` — `style` is ignored — `context`/`action_sheet` render as a dropdown. `itemsPath` does not bind items.
|
|
1314
1350
|
|
|
1315
1351
|
#### Tooltip
|
|
1316
1352
|
|
|
@@ -1326,7 +1362,7 @@ export interface TooltipProps {
|
|
|
1326
1362
|
}
|
|
1327
1363
|
```
|
|
1328
1364
|
|
|
1329
|
-
> ⚠️ **Not implemented on ios:** `edge`, `trigger`, `onDismiss` — Not an overlay — renders always-expanded inline; `trigger` and dismissal are inert.
|
|
1365
|
+
> ⚠️ **Not implemented on ios, android, web:** `edge`, `trigger`, `onDismiss` — Not an overlay — renders always-expanded inline; `edge`, `trigger` and dismissal are inert.
|
|
1330
1366
|
|
|
1331
1367
|
#### Popover
|
|
1332
1368
|
|
|
@@ -1348,7 +1384,7 @@ export interface PopoverProps {
|
|
|
1348
1384
|
}
|
|
1349
1385
|
```
|
|
1350
1386
|
|
|
1351
|
-
> ⚠️ **Not implemented on ios:** `edge` —
|
|
1387
|
+
> ⚠️ **Not implemented on ios:** `edge` — The bubble is drawn in flow under its anchor; `edge` placement is not implemented.
|
|
1352
1388
|
|
|
1353
1389
|
### Chips & selection
|
|
1354
1390
|
|
|
@@ -1388,7 +1424,7 @@ export interface ChipsInputProps {
|
|
|
1388
1424
|
}
|
|
1389
1425
|
```
|
|
1390
1426
|
|
|
1391
|
-
> ⚠️ **
|
|
1427
|
+
> ⚠️ **Not implemented on ios, android, web:** `onAdd` — `onAdd` never dispatches.
|
|
1392
1428
|
|
|
1393
1429
|
**Dispatches** — see [What a control sends](#what-a-control-sends-action-payloads):
|
|
1394
1430
|
|
|
@@ -1788,7 +1824,7 @@ export interface OtpInputProps {
|
|
|
1788
1824
|
}
|
|
1789
1825
|
```
|
|
1790
1826
|
|
|
1791
|
-
> ⚠️ **
|
|
1827
|
+
> ⚠️ **Not implemented on ios, android, web:** `onComplete`, `onChange` — Neither `onChange` nor `onComplete` dispatches.
|
|
1792
1828
|
|
|
1793
1829
|
**Dispatches** — see [What a control sends](#what-a-control-sends-action-payloads):
|
|
1794
1830
|
|
|
@@ -1924,6 +1960,8 @@ export interface MapProps {
|
|
|
1924
1960
|
}
|
|
1925
1961
|
```
|
|
1926
1962
|
|
|
1963
|
+
> ⚠️ **Implemented, but these props are inert on android, web:** `followUserLocation` — `followUserLocation` does not track.
|
|
1964
|
+
|
|
1927
1965
|
#### Video
|
|
1928
1966
|
|
|
1929
1967
|
```ts
|
|
@@ -1939,7 +1977,7 @@ export interface VideoProps {
|
|
|
1939
1977
|
}
|
|
1940
1978
|
```
|
|
1941
1979
|
|
|
1942
|
-
> ⚠️ **Implemented, but these props are inert on ios:** `poster` — `poster`
|
|
1980
|
+
> ⚠️ **Implemented, but these props are inert on ios:** `poster` — `poster` is not shown.
|
|
1943
1981
|
|
|
1944
1982
|
#### PdfView
|
|
1945
1983
|
|
|
@@ -1955,6 +1993,10 @@ export interface PdfViewProps {
|
|
|
1955
1993
|
}
|
|
1956
1994
|
```
|
|
1957
1995
|
|
|
1996
|
+
> ⚠️ **Implemented, but these props are inert on android:** `showPageControls`, `startPage` — No page controls. `startPage` is ignored.
|
|
1997
|
+
|
|
1998
|
+
> ⚠️ **Implemented, but these props are inert on web:** `showPageControls`, `zoomable`, `allowShare` — No page controls. The browser PDF viewer ignores `zoomable` and `allowShare`.
|
|
1999
|
+
|
|
1958
2000
|
#### MediaPlayer
|
|
1959
2001
|
|
|
1960
2002
|
```ts
|
|
@@ -2007,6 +2049,12 @@ export interface MediaPlayerProps {
|
|
|
2007
2049
|
}
|
|
2008
2050
|
```
|
|
2009
2051
|
|
|
2052
|
+
> ⚠️ **Not implemented on ios:** `autoplayVisibilityThreshold`, `preload`, `playbackRates`, `showQueue`, `showChapters`, `showTranscript` — `autoplayVisibilityThreshold` is ignored (whenVisible = once on appear). `preload` is ignored. `playbackRates` is ignored, and the queue/chapters/transcript panels never render.
|
|
2053
|
+
|
|
2054
|
+
> ⚠️ **Not implemented on android:** `externalPlayback`, `appearance`, `allowCellular`, `preload`, `playbackRates`, `showQueue`, `showChapters`, `showTranscript` — `externalPlayback` is forced off. `appearance` is ignored. `allowCellular` is ignored. `preload` is ignored. `playbackRates` is ignored, and the queue/chapters/transcript panels never render.
|
|
2055
|
+
|
|
2056
|
+
> ⚠️ **Not implemented on web:** `allowCellular`, `forwardSkipSeconds`, `backwardSkipSeconds`, `playbackRates`, `showQueue`, `showChapters`, `showTranscript` — `allowCellular` is ignored. Skip buttons ignore `forwardSkipSeconds`/`backwardSkipSeconds`. `playbackRates` is ignored, and the queue/chapters/transcript panels never render.
|
|
2057
|
+
|
|
2010
2058
|
### Rich vector & celebration (motion grammar Batch 4)
|
|
2011
2059
|
|
|
2012
2060
|
#### Lottie
|
|
@@ -2114,6 +2162,8 @@ export interface TimeGridProps {
|
|
|
2114
2162
|
}
|
|
2115
2163
|
```
|
|
2116
2164
|
|
|
2165
|
+
> ⚠️ **Not implemented on android:** `anchorDatePath`, `onRangeChange` — `anchorDatePath` does not bind and `onRangeChange` never fires.
|
|
2166
|
+
|
|
2117
2167
|
#### Agenda
|
|
2118
2168
|
|
|
2119
2169
|
```ts
|
|
@@ -2138,6 +2188,8 @@ export interface AgendaProps {
|
|
|
2138
2188
|
}
|
|
2139
2189
|
```
|
|
2140
2190
|
|
|
2191
|
+
> ⚠️ **Implemented, but these props are inert on android:** `stickyHeaders` — Day headers do not pin.
|
|
2192
|
+
|
|
2141
2193
|
## Screen descriptor shape
|
|
2142
2194
|
|
|
2143
2195
|
```ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1190.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
|
|
6
6
|
"keywords": [
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"artifactId": "himalaya-cli"
|
|
68
68
|
}
|
|
69
69
|
},
|
|
70
|
-
"falconPackageHash": "
|
|
70
|
+
"falconPackageHash": "9372e1bc93fb23ce8d6d5db9c0d7574d95632af38bcce8830a656813"
|
|
71
71
|
}
|