@wix/himalaya-cli 0.1473.0 → 0.1475.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.
Binary file
@@ -2,7 +2,7 @@
2
2
  "_comment": "GENERATED by core/web-embed/authoring/gen-reference.mjs from core/ts/src/schema.ts — do not hand-edit. The schema is the source of truth; regenerate on schema changes.",
3
3
  "schemaSource": "core/ts/src/schema.ts",
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
- "componentCount": 86,
5
+ "componentCount": 87,
6
6
  "notImplementedComponents": [
7
7
  "Text",
8
8
  "Icon",
@@ -14,8 +14,6 @@
14
14
  "SelectionControl",
15
15
  "ActivityIndicator",
16
16
  "Menu",
17
- "Tooltip",
18
- "Popover",
19
17
  "ChipsInput",
20
18
  "OtpInput",
21
19
  "Video",
@@ -805,21 +803,7 @@
805
803
  "category": "Overlays & menus",
806
804
  "propsType": "TooltipProps",
807
805
  "bindings": [],
808
- "notImplemented": {
809
- "props": [
810
- "edge",
811
- "trigger",
812
- "onDismiss"
813
- ],
814
- "platforms": [
815
- "ios",
816
- "android",
817
- "web"
818
- ],
819
- "severity": "category",
820
- "note": "Not an overlay — renders always-expanded inline; `edge`, `trigger` and dismissal are inert."
821
- },
822
- "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}"
806
+ "propsSource": "export interface TooltipProps {\n anchor?: Component;\n text?: string;\n /** Present → rich tooltip. */\n title?: string;\n /** The side of the anchor the bubble floats on; `auto` / absent → `top`. Flips to the opposite\n * side when there is no room, as every renderer does. */\n edge?: \"top\" | \"bottom\" | \"leading\" | \"trailing\" | \"auto\";\n /** What opens the (otherwise hidden) bubble. `auto` / absent → a long-press on touch, hover and\n * keyboard focus on the web. */\n trigger?: \"tap\" | \"long_press\" | \"auto\";\n /** Fired once each time an open tooltip closes (outside tap, Escape, timeout). */\n onDismiss?: Action;\n}"
823
807
  },
824
808
  {
825
809
  "name": "Popover",
@@ -828,16 +812,6 @@
828
812
  "bindings": [
829
813
  "presentedPath"
830
814
  ],
831
- "notImplemented": {
832
- "props": [
833
- "edge"
834
- ],
835
- "platforms": [
836
- "ios"
837
- ],
838
- "severity": "category",
839
- "note": "The bubble is drawn in flow under its anchor; `edge` placement is not implemented."
840
- },
841
815
  "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}"
842
816
  },
843
817
  {
@@ -1027,6 +1001,13 @@
1027
1001
  ],
1028
1002
  "propsSource": "export interface DataTableProps {\n columns?: DataTableColumn[];\n rows?: DataTableRow[];\n /**\n * `$service:` ONLY → an array of OBJECTS keyed by `column.key`. An array of\n * arrays (positional, like the literal `rows`) is also accepted.\n */\n rowsPath?: string;\n /**\n * `hideHeader`, not `showHeader`: the proto field is a bool that defaults to\n * false, so the affirmative spelling would default a table to headerless.\n */\n hideHeader?: boolean;\n totals?: DataTableRow;\n /** `$service:` ONLY → one row object. */\n totalsPath?: string;\n /** 0 / absent ⇒ unbounded */\n maxRows?: number;\n zebra?: boolean;\n}"
1029
1003
  },
1004
+ {
1005
+ "name": "Shape",
1006
+ "category": "Shape",
1007
+ "propsType": "ShapeProps",
1008
+ "bindings": [],
1009
+ "propsSource": "export interface ShapeProps {\n /** \"rectangle\" (default) | \"roundedRectangle\" | \"capsule\" | \"circle\" | \"ellipse\" */\n kind?: string;\n cornerRadius?: number;\n cornerRadii?: CornerRadii;\n fill?: TokenRef;\n fillGradient?: Gradient;\n stroke?: ShapeStroke;\n}"
1010
+ },
1030
1011
  {
1031
1012
  "name": "RichContent",
1032
1013
  "category": "Rich content",
@@ -1416,7 +1397,7 @@
1416
1397
  "ScreenDescriptor": "export interface ScreenDescriptor {\n screenId: string;\n renderer: RendererKind;\n title?: string;\n /** Present when `renderer` is `sdui_intent` or `sdui_layout`. */\n payload?: Component;\n /** A component pinned ABOVE the scrolling payload (sticky tab-header / toolbar).\n * Rendered by the host outside the screen scroll, so it stays put as content\n * scrolls. Optional; absent = no sticky header. */\n stickyHeader?: Component;\n /** A component pinned BELOW the scrolling payload (sticky footer — price/confirm\n * bar, peeking bottom-sheet). Rendered outside the screen scroll by the host. */\n stickyFooter?: Component;\n /** When true, the host wraps the screen in a scroll that starts pinned to the\n * bottom and shows a floating \"jump to latest\" button whenever the user scrolls\n * up (a chat transcript). Tapping it animates back to the bottom. Absent/false =\n * a normal top-anchored scroll. Honored by the app host (Router). */\n scrollToBottom?: boolean;\n /** The chat transcript scroll policy. On a send the host pins the\n * named component near the top and reserves the space the reply grows into;\n * when the reply outgrows it the host follows the tail. A drag pauses\n * following, and only then is a jump-to-latest control shown. */\n transcriptScroll?: TranscriptScroll;\n /** Present when `renderer` is `webview_native_bridge` or `webview_ds`. */\n url?: string;\n capabilitiesRequired?: string[];\n schemaVersion: number;\n togglesApplied?: string[];\n /** Per-session flag/experiment assignments baked in for this request. */\n assignments?: import(\"./flags.js\").Assignment[];\n /** Per-screen top bar (trailing actions +\n * leading/style override). Fully replaces `NavigationConfig.topBarDefault`. */\n topBar?: TopBarConfig;\n etag?: string;\n cacheControl?: CacheControl;\n telemetryScreenName?: string;\n bundleSri?: string;\n manifestVersion?: number;\n /**\n * Present on Tier-5 screens. The presence of this field is the tier-5\n * signal — there is no separate `tier: 5` flag.\n */\n logicBundle?: LogicBundleRef;\n /**\n * Static per-screen input injected as `globalThis.himalaya.input` before the\n * Tier-5 worker bundle evaluates — the worker reads it synchronously in `load()`\n * (e.g. `himalaya.input.id` for a detail screen, or a baked catalog like\n * `himalaya.input.cmsCollections`).\n *\n * A push merges its navigation parameters into this object on web, iOS, and Android.\n * For example, `himi.open({ screenId: \"event\", id: \"$item.id\" })` makes the id\n * available as `himalaya.input.id` in the pushed worker; static `input` remains the\n * fallback for values baked into a descriptor or a templated route. The host also\n * supplies `screenId`. See docs/tier-5-add-a-screen.md → \"Navigate to a detail screen\".\n *\n * Arbitrary JSON object; consumed by the web host (ScreenController) and the\n * native JSWorker.\n */\n input?: Record<string, unknown>;\n /**\n * Tier 3 / Tier 4 — behavior of the hosted WebView. Ignored by SDUI tiers.\n * Authored in the descriptor builder (git); served OTA verbatim.\n */\n webViewConfig?: WebViewConfig;\n}",
1417
1398
  "Component": "export interface Component {\n id: string;\n body: ComponentBody;\n modifiers?: Modifiers;\n minVersion?: number;\n}",
1418
1399
  "LogicBundleRef": "export interface LogicBundleRef {\n url: string;\n /** \"sha256-...\" SRI string. */\n integrity: string;\n contentType?: string;\n /** SDK capability ids the bundle is permitted to import / invoke. */\n declaredCapabilities: string[];\n /** Bundle refuses to load on a binary older than this (semver). */\n minBinaryVersion?: string;\n /** Bundle's own semver. */\n bundleVersion?: string;\n /** Base64 detached publisher signature over the bundle bytes\n * (authenticity beyond SRI). Verified by a host-injected verifier when present;\n * unsigned bundles load as today. */\n signature?: string;\n /** The publisher key id a host pins, paired with `signature`. */\n keyId?: string;\n /** Ambient refresh (gap G2): the host invokes `action` (a `tier5.<svc>.<action>`\n * path) every `intervalMs` while the screen is visible — workers have no timer\n * of their own, so the host owns the cadence. */\n refresh?: { intervalMs: number; action: string };\n}",
1419
- "Modifiers": "export interface Modifiers {\n padding?: EdgeInsets;\n background?: TokenRef;\n cornerRadius?: number;\n /** Fixed intrinsic width (pt/dp/px). Honored by iOS (`FrameIfPresent`), Android\n * (frame) and web (`modifiers.ts`). With no `ScrollView` in the vocabulary and\n * regions clipped at `maxHeight`, `width`/`height`/`fillMaxWidth` are the main\n * sizing tools for embed/host content. */\n width?: number;\n /** Fixed intrinsic height (pt/dp/px). See `width`. */\n height?: number;\n /** Fill the available cross-axis width (keeps any fixed `height`). Mirrors\n * Compose `fillMaxWidth` / SwiftUI `.frame(maxWidth: .infinity)`. See `width`. */\n fillMaxWidth?: boolean;\n /** CAP the node's laid-out width at this many points. It CONSTRAINS, it\n * does not SET: a node narrower than the cap keeps its intrinsic width, so a\n * short chat bubble stays short while a long one stops at the cap — the\n * asymmetry `width` cannot express and `weight` cannot either (weights divide\n * the *available* space, so every child lands on the same fraction).\n * The cap covers the node's TOTAL width, padding + border included (CSS\n * `max-width` under `box-sizing: border-box`). `fillMaxWidth` grabs the axis but\n * THE CAP WINS — fill + cap is exactly `maxWidth` wide; a literal `width` larger\n * than the cap is clamped to it too. POINTS, not a fraction: a modifier is\n * resolved with no portable notion of \"the row\" on any renderer — compose a\n * percentage from a weighted sibling gap instead. `0`/absent = no cap. */\n maxWidth?: number;\n /** Flex weight along the parent stack's MAIN axis (HStack = width, VStack =\n * height). The stack measures its intrinsic (unweighted) children first, then\n * divides what is LEFT among the weighted ones in proportion to their weights:\n * two children at `1` split the leftover equally, `2` and `1` split it 2:1.\n * Absent (or <= 0) keeps the node at its intrinsic size. Use this — not\n * `fillMaxWidth` — when a node should claim the remaining space *beside* its\n * siblings; a full-bleed fill grabs the whole axis and starves them. Ignored\n * outside an HStack/VStack.\n * CAVEAT — row-sharing controls have NO intrinsic width to measure first: in an\n * HStack a `Button` and a `Toggle` are implicitly weighted, so they DIVIDE the\n * row with your weighted child instead of taking a width ahead of it —\n * `[VStack(weight:1), Button, Button]` is a three-way split, not \"the VStack gets\n * the remainder\". To opt a Button out on EVERY renderer set `fullWidth: false`\n * (an explicit flag wins in both directions; absent falls back to the style\n * default, which is \"share\" for every style but `tertiary`/`link`), or use\n * `iconOnly`. Otherwise give the actions their own row.\n * See `himi docs designing-himi-screens` §4. */\n weight?: number;\n /** RTL — pin the subtree's writing direction: `\"ltr\"` | `\"rtl\"` | `\"locale\"`\n * (inherit). The common RTL pattern is the inverse of `Text.textDirection`: pin a\n * container `ltr` (a logotype, an attachment-tile row, a composer button row)\n * inside an otherwise-RTL screen. Absent = inherit the ambient direction. #1060. */\n layoutDirection?: \"ltr\" | \"rtl\" | \"locale\";\n /** Absolute visual translation (pt/dp/px). Applied as the OUTERMOST transform so\n * it shifts the fully-styled node WITHOUT changing its layout footprint — lets a\n * ZStack place polar/absolute children (e.g. AgentOrbit). Negative allowed. */\n offsetX?: number;\n offsetY?: number;\n onTap?: Action;\n /** Double-tap gesture (e.g. Instagram double-tap-to-like). Distinct from onTap. */\n onDoubleTap?: Action;\n accessibilityLabel?: string;\n hidden?: boolean;\n /** Data-bound conditional visibility: a `\"$service:<svc>.<field>\"`\n * or `\"$item.<field>\"` sentinel resolving to a bool at render; when true the\n * subtree fully COLLAPSES (zero layout, like `hidden`), overriding the\n * literal `hidden`. */\n hiddenPath?: string;\n /** Long-press gesture modifier. */\n onLongPress?: Action;\n /** Fires once when the component first appears on screen. */\n onAppear?: Action;\n /** Scoped token overrides for the subtree. */\n theme?: ThemeOverrides;\n /** Names a token from the app's `shadows` registry. */\n shadow?: TokenRef;\n /** Names a token from the app's `gradients` registry (background fill). */\n backgroundGradient?: TokenRef;\n /** Value-driven gradient: a `$service:`/`$item.` path resolving to a gradient\n * TOKEN NAME used as the live background (e.g. weather sky day→night). */\n backgroundGradientPath?: string;\n /** Value-driven background COLOR: a `$service:`/`$item.` path resolving to a\n * color TOKEN NAME used as the live background. Honored on iOS + Android\n * (`BoundBackgroundIfPresent`); web render support is tracked in #1057. */\n backgroundColorPath?: string;\n /** Value-driven background IMAGE: a `$service:`/`$item.` path resolving to an\n * image URL used as the live background. Honored on iOS + Android; web render\n * support is tracked in #1057. */\n backgroundImagePath?: string;\n /** #1051 — MEASURE (publish): report this node's laid-out size into the renderer's\n * self-contained (worker-free) measure store under the named keys, so a SIBLING can\n * feed the number back into its own layout via a `$measure:<key>` binding. The SDUI\n * equivalent of SwiftUI `.onGeometryChange` / Compose `onGloballyPositioned`; the\n * canonical use is a pinned bottom bar whose measured height becomes a scroll view's\n * bottom inset (sticky-footer + scroll-inset, unrepresentable before — #1051). */\n onMeasure?: Measure;\n /** #1051 — bound height: a `\"$measure:<key>\"` (measure store) or\n * `\"$service:<svc>.<field>\"` / `\"$item.<field>\"` (worker/row state) sentinel resolving\n * to a NUMBER at render. Wins over the literal `height`. String path only, so a\n * binding can never blank the node (never overload the numeric `height`). */\n heightPath?: string;\n /** #1051 — bound width. See `heightPath`. Wins over the literal `width`. */\n widthPath?: string;\n /** #1051 — bound TOP inset (the header-height → top-inset idiom). A `$measure:`/\n * `$service:`/`$item.` sentinel resolving to a number; added as top padding. */\n paddingTopPath?: string;\n /** #1051 — bound BOTTOM inset (the sticky-footer-height → bottom-inset idiom). A\n * `$measure:`/`$service:`/`$item.` sentinel resolving to a number; added as bottom\n * padding so the last scroll row clears a pinned bottom bar. */\n paddingBottomPath?: string;\n /** #1053 — INLINE gradient background paint. Distinct from `backgroundGradient`\n * (which names a `gradients` registry token an embed host can't register): this\n * carries its stops/colours in the descriptor, so it works anywhere. Painted as\n * a surface (behind children), below `material`/`backgroundGradient` if those are\n * also set. */\n gradient?: Gradient;\n /** #1053 — gradient ALPHA MASK: the node shows through where the gradient is\n * opaque and fades where it's transparent (a transparent-token stop = fully\n * clear). The material-under-gradient-scrim / scroll-fade-out idiom. Mirrors iOS\n * `.mask()`, Android `BlendMode.DstIn`, web `mask-image`. */\n mask?: Gradient;\n /** Inline border/stroke. */\n border?: Border;\n /** Subtree alpha 0.0–1.0; absent = opaque. */\n opacity?: number;\n /** #433 — constrain the subtree to a width:height ratio (e.g. `1` = square,\n * `1.777` = 16:9). Width-driven: the height derives from the resolved width.\n * Lets a data-bound Grid cell / photo tile hold its shape at any width. */\n aspectRatio?: number;\n /** Names a token from the app's `motions` registry; the subtree\n * fades + slides up on first appearance. */\n appear?: TokenRef;\n /** Surface material token (flat/glass/frosted). */\n material?: TokenRef;\n /** Per-node construction-language override. */\n variant?: string;\n /** Per-node density / motion override. */\n density?: string;\n motion?: string;\n /** Motion grammar (Batch 1) — press/tap feedback style\n * (auto|none|scale|highlight|scaleHighlight|lift); timing comes from `motion`.\n * Applied only when the node is interactive. Unknown degrades to `auto`. */\n pressFeedback?: string;\n /** Motion grammar (Batch 1) — press-coupled haptic\n * (none|selection|light|medium|heavy|success|warning|error); fires with onTap.\n * Default none (opt-in). Web is a no-op. */\n haptic?: string;\n /** Motion grammar (Batch 1) — animate this container's size changes instead of\n * snapping (iOS `.animation(value:)`, Android `animateContentSize`, web height\n * transition). Curve from the active `motion` personality. */\n animateContentSize?: boolean;\n /** Motion grammar (Batch 1) — enter/exit transition; supersedes `appear` when\n * both are present. */\n transition?: Transition;\n /** Motion grammar (Batch 2, scroll-driven) — defer the `transition` enter until\n * the node first crosses into the scroll viewport (reveal-on-scroll). Gated by\n * reduced motion (shown immediately when reduced). */\n revealOnScroll?: boolean;\n /** Motion grammar (Batch 2, scroll-driven) — parallax factor: the node drifts\n * vertically at this fraction of the scroll delta as it moves through the\n * viewport. Gated by reduced motion. Generalizes CollapsingHeader parallaxFactor. */\n parallax?: number;\n /** Motion grammar (Batch 4, rich visual) — when a backgroundGradient is present,\n * continuously drift/rotate it (animated gradient). Gated by reduced motion. */\n animatedGradient?: boolean;\n /** Motion grammar (Batch 3, hero/nav) — shared-element key: a matching\n * transitionId on the source + destination screen morphs that element across\n * navigation (web View Transitions / iOS matchedTransitionSource / Android\n * SharedTransitionLayout). Gated by reduced motion. */\n transitionId?: string;\n /** Motion grammar (Batch 4, rich visual) — render the backgroundGradient as a\n * mesh (overlapping multi-point blend) rather than a linear sweep; combine with\n * animatedGradient to drift it. */\n meshGradient?: boolean;\n /** Motion grammar (Batch 4, celebration) — burst a one-shot confetti overlay\n * within the node on appear. Gated by reduced motion. */\n confetti?: boolean;\n /** Motion grammar (Batch 2, scroll-driven) — pin this node to the top of its\n * scroll container (sticky section header). Functional positioning; not gated\n * by reduced motion. */\n sticky?: boolean;\n /** Motion grammar (Batch 2, scroll-driven) — turn this thin node into a\n * reading-progress bar that fills left→right with scroll (scaleX). web reads\n * window scroll; native reads the host scroll fraction. Functional. */\n scrollProgress?: boolean;\n /** Motion grammar (Batch 4, rich vector) — a named built-in vector animation\n * (\"loader\" | \"success\" | \"pulse\"), dependency-free. Gated by reduced motion.\n * Arbitrary Lottie/Rive JSON is the lib-backed superset follow-up. */\n vectorAnim?: string;\n /** Motion grammar (Batch 1, choreography) — delay this node's ENTER transition\n * by N ms so a screen can SEQUENCE its entrance beyond list stagger (\"title\n * fades, subtitle slides in 100ms later\"). Adds to any list `staggerMs`. Gated\n * by reduced motion. 0/absent = no extra delay. */\n enterDelayMs?: number;\n /** Motion grammar (Phase-3, per-node MotionSpec) — overrides the PRESS-feedback\n * curve with a `motions`-registry token, mirroring `Transition.motion` for the\n * enter curve. Absent → press uses the global `motion` personality. */\n pressMotion?: TokenRef;\n /** Motion grammar (Phase-3, gesture-driven) — finger-tracked drag-to-dismiss; past\n * threshold along `direction` it animates off and fires `action`, else springs back. */\n swipeDismiss?: SwipeDismiss;\n /** Motion grammar (Phase-4, reduced-motion) — per-node escape from the reduced-motion\n * gate. Default true (respect). false = \"must move anyway\" (transition/press animate\n * even when reduced motion is on). */\n respectReducedMotion?: boolean;\n /** #1052 — uniform scale (1 = no change). */\n scale?: number;\n /** #1052 — rotation in DEGREES. */\n rotation?: number;\n /** #1052 — stacking order within a ZStack/overlay. */\n zIndex?: number;\n /** #1052 — gaussian blur radius (pt/dp/px). */\n blur?: number;\n /** #1052 — `false` = decorative (ignores taps, unlike `hidden` which stays hit-testable);\n * `true` = force hit-testable (a clear tap target). */\n hitTestable?: boolean;\n /** #1052 — explicit drop shadow (colour + radius + offset), for upward / multi-layer\n * shadows the `shadow` token can't express. */\n boxShadow?: Shadow;\n /** The role assistive technology should announce. Absent = the\n * renderer INFERS it from the component type, so an author never restates the\n * obvious. `\"decorative\"` is node-local: the node itself stops being an\n * accessibility element (no role, not a stop) while its children stay\n * traversable — the ARIA `role=\"presentation\"` semantic. To remove the subtree\n * too, use `accessibilityHidden`. */\n accessibilityRole?: AccessibilityRole;\n /** The supplementary \"what happens if I act\" phrase\n * (iOS `accessibilityHint`, Android `onClickLabel`, ARIA `aria-describedby`).\n * Never a substitute for `accessibilityLabel`: AT may not speak a hint at all. */\n accessibilityHint?: string;\n /** Remove this node AND its subtree from the accessibility tree.\n * Distinct from `hidden` (which removes it visually too) and from the\n * `\"decorative\"` role (node-local; children stay reachable). */\n accessibilityHidden?: boolean;\n /** Mark the node as a heading at level 1–6, for rotor / heading\n * navigation. Implies the `\"heading\"` role when `accessibilityRole` is absent.\n * The LEVEL reaches iOS and web only: Android (Compose `heading()`) and React Native\n * (`accessibilityRole: \"header\"`) have no level primitive and mark a plain heading. */\n headingLevel?: number;\n /** An explicit SPOKEN value where the visual and spoken values\n * differ (a rating \"3 of 5\", a gauge \"72 percent\"). Where the value is derivable\n * from a prop the renderer computes it and this override is unnecessary. */\n accessibilityValue?: string;\n /** Additive state that a single role cannot carry. A node may\n * hold several. */\n accessibilityTraits?: AccessibilityTrait[];\n /** Explicit traversal index within the nearest focus group. Absent ⇒\n * the arm's visual / DOM order. The lower index is reached FIRST, which is why iOS\n * (whose `accessibilitySortPriority` is descending) negates it. */\n focusOrder?: number;\n /** This node's subtree is ONE traversal scope: children are ordered\n * relative to each other, then the group takes its parent's slot (iOS\n * `shouldGroupAccessibilityChildren`, Android `isTraversalGroup`, ARIA grouping). */\n focusGroup?: boolean;\n /** AT / keyboard focus lands here when the screen or a newly presented\n * modal appears. At most one per focus scope. */\n initialFocus?: boolean;\n /** A general live-region announcement, on any node and any transition.\n * The generalization of `FragmentSlotCase.accessibilityAnnouncement`, which only ever\n * fired on a fragment-slot case swap. */\n announce?: LiveRegion;\n /** A recurring, finite, transform-only motion on a decorative node: a\n * living character's idle `hop`, a `blink`, a working `breathe`. Never changes the\n * node's layout footprint. Stopped by reduced motion unless `respectReducedMotion`\n * is false. */\n ambientMotion?: AmbientMotion;\n}",
1400
+ "Modifiers": "export interface Modifiers {\n padding?: EdgeInsets;\n background?: TokenRef;\n cornerRadius?: number;\n /** Fixed intrinsic width (pt/dp/px). Honored by iOS (`FrameIfPresent`), Android\n * (frame) and web (`modifiers.ts`). With no `ScrollView` in the vocabulary and\n * regions clipped at `maxHeight`, `width`/`height`/`fillMaxWidth` are the main\n * sizing tools for embed/host content. */\n width?: number;\n /** Fixed intrinsic height (pt/dp/px). See `width`. */\n height?: number;\n /** Fill the available cross-axis width (keeps any fixed `height`). Mirrors\n * Compose `fillMaxWidth` / SwiftUI `.frame(maxWidth: .infinity)`. See `width`. */\n fillMaxWidth?: boolean;\n /** CAP the node's laid-out width at this many points. It CONSTRAINS, it\n * does not SET: a node narrower than the cap keeps its intrinsic width, so a\n * short chat bubble stays short while a long one stops at the cap — the\n * asymmetry `width` cannot express and `weight` cannot either (weights divide\n * the *available* space, so every child lands on the same fraction).\n * The cap covers the node's TOTAL width, padding + border included (CSS\n * `max-width` under `box-sizing: border-box`). `fillMaxWidth` grabs the axis but\n * THE CAP WINS — fill + cap is exactly `maxWidth` wide; a literal `width` larger\n * than the cap is clamped to it too. POINTS, not a fraction: a modifier is\n * resolved with no portable notion of \"the row\" on any renderer — compose a\n * percentage from a weighted sibling gap instead. `0`/absent = no cap. */\n maxWidth?: number;\n /** Flex weight along the parent stack's MAIN axis (HStack = width, VStack =\n * height). The stack measures its intrinsic (unweighted) children first, then\n * divides what is LEFT among the weighted ones in proportion to their weights:\n * two children at `1` split the leftover equally, `2` and `1` split it 2:1.\n * Absent (or <= 0) keeps the node at its intrinsic size. Use this — not\n * `fillMaxWidth` — when a node should claim the remaining space *beside* its\n * siblings; a full-bleed fill grabs the whole axis and starves them. Ignored\n * outside an HStack/VStack.\n * CAVEAT — row-sharing controls have NO intrinsic width to measure first: in an\n * HStack a `Button` and a `Toggle` are implicitly weighted, so they DIVIDE the\n * row with your weighted child instead of taking a width ahead of it —\n * `[VStack(weight:1), Button, Button]` is a three-way split, not \"the VStack gets\n * the remainder\". To opt a Button out on EVERY renderer set `fullWidth: false`\n * (an explicit flag wins in both directions; absent falls back to the style\n * default, which is \"share\" for every style but `tertiary`/`link`), or use\n * `iconOnly`. Otherwise give the actions their own row.\n * See `himi docs designing-himi-screens` §4. */\n weight?: number;\n /** RTL — pin the subtree's writing direction: `\"ltr\"` | `\"rtl\"` | `\"locale\"`\n * (inherit). The common RTL pattern is the inverse of `Text.textDirection`: pin a\n * container `ltr` (a logotype, an attachment-tile row, a composer button row)\n * inside an otherwise-RTL screen. Absent = inherit the ambient direction. #1060. */\n layoutDirection?: \"ltr\" | \"rtl\" | \"locale\";\n /** Absolute visual translation (pt/dp/px). Applied as the OUTERMOST transform so\n * it shifts the fully-styled node WITHOUT changing its layout footprint — lets a\n * ZStack place polar/absolute children (e.g. AgentOrbit). Negative allowed. */\n offsetX?: number;\n offsetY?: number;\n onTap?: Action;\n /** Double-tap gesture (e.g. Instagram double-tap-to-like). Distinct from onTap. */\n onDoubleTap?: Action;\n accessibilityLabel?: string;\n hidden?: boolean;\n /** Data-bound conditional visibility: a `\"$service:<svc>.<field>\"`\n * or `\"$item.<field>\"` sentinel resolving to a bool at render; when true the\n * subtree fully COLLAPSES (zero layout, like `hidden`), overriding the\n * literal `hidden`. */\n hiddenPath?: string;\n /** Long-press gesture modifier. */\n onLongPress?: Action;\n /** Fires once when the component first appears on screen. */\n onAppear?: Action;\n /** Scoped token overrides for the subtree. */\n theme?: ThemeOverrides;\n /** Names a token from the app's `shadows` registry. */\n shadow?: TokenRef;\n /** Names a token from the app's `gradients` registry (background fill). */\n backgroundGradient?: TokenRef;\n /** Value-driven gradient: a `$service:`/`$item.` path resolving to a gradient\n * TOKEN NAME used as the live background (e.g. weather sky day→night). */\n backgroundGradientPath?: string;\n /** Value-driven background COLOR: a `$service:`/`$item.` path resolving to a\n * color TOKEN NAME used as the live background. Honored on iOS + Android\n * (`BoundBackgroundIfPresent`); web render support is tracked in #1057. */\n backgroundColorPath?: string;\n /** Value-driven background IMAGE: a `$service:`/`$item.` path resolving to an\n * image URL used as the live background. Honored on iOS + Android; web render\n * support is tracked in #1057. */\n backgroundImagePath?: string;\n /** #1051 — MEASURE (publish): report this node's laid-out size into the renderer's\n * self-contained (worker-free) measure store under the named keys, so a SIBLING can\n * feed the number back into its own layout via a `$measure:<key>` binding. The SDUI\n * equivalent of SwiftUI `.onGeometryChange` / Compose `onGloballyPositioned`; the\n * canonical use is a pinned bottom bar whose measured height becomes a scroll view's\n * bottom inset (sticky-footer + scroll-inset, unrepresentable before — #1051). */\n onMeasure?: Measure;\n /** #1051 — bound height: a `\"$measure:<key>\"` (measure store) or\n * `\"$service:<svc>.<field>\"` / `\"$item.<field>\"` (worker/row state) sentinel resolving\n * to a NUMBER at render. Wins over the literal `height`. String path only, so a\n * binding can never blank the node (never overload the numeric `height`). */\n heightPath?: string;\n /** #1051 — bound width. See `heightPath`. Wins over the literal `width`. */\n widthPath?: string;\n /** #1051 — bound TOP inset (the header-height → top-inset idiom). A `$measure:`/\n * `$service:`/`$item.` sentinel resolving to a number; added as top padding. */\n paddingTopPath?: string;\n /** #1051 — bound BOTTOM inset (the sticky-footer-height → bottom-inset idiom). A\n * `$measure:`/`$service:`/`$item.` sentinel resolving to a number; added as bottom\n * padding so the last scroll row clears a pinned bottom bar. */\n paddingBottomPath?: string;\n /** #1053 — INLINE gradient background paint. Distinct from `backgroundGradient`\n * (which names a `gradients` registry token an embed host can't register): this\n * carries its stops/colours in the descriptor, so it works anywhere. Painted as\n * a surface (behind children), below `material`/`backgroundGradient` if those are\n * also set. */\n gradient?: Gradient;\n /** #1053 — gradient ALPHA MASK: the node shows through where the gradient is\n * opaque and fades where it's transparent (a transparent-token stop = fully\n * clear). The material-under-gradient-scrim / scroll-fade-out idiom. Mirrors iOS\n * `.mask()`, Android `BlendMode.DstIn`, web `mask-image`. */\n mask?: Gradient;\n /** Inline border/stroke. */\n border?: Border;\n /** Subtree alpha 0.0–1.0; absent = opaque. */\n opacity?: number;\n /** #433 — constrain the subtree to a width:height ratio (e.g. `1` = square,\n * `1.777` = 16:9). Width-driven: the height derives from the resolved width.\n * Lets a data-bound Grid cell / photo tile hold its shape at any width. */\n aspectRatio?: number;\n /** Names a token from the app's `motions` registry; the subtree\n * fades + slides up on first appearance. */\n appear?: TokenRef;\n /** Surface material token (flat/glass/frosted). */\n material?: TokenRef;\n /** Per-node construction-language override. */\n variant?: string;\n /** Per-node density / motion override. */\n density?: string;\n motion?: string;\n /** Motion grammar (Batch 1) — press/tap feedback style\n * (auto|none|scale|highlight|scaleHighlight|lift); timing comes from `motion`.\n * Applied only when the node is interactive. Unknown degrades to `auto`. */\n pressFeedback?: string;\n /** Motion grammar (Batch 1) — press-coupled haptic\n * (none|selection|light|medium|heavy|success|warning|error); fires with onTap.\n * Default none (opt-in). Web is a no-op. */\n haptic?: string;\n /** Motion grammar (Batch 1) — animate this container's size changes instead of\n * snapping (iOS `.animation(value:)`, Android `animateContentSize`, web height\n * transition). Curve from the active `motion` personality. */\n animateContentSize?: boolean;\n /** Motion grammar (Batch 1) — enter/exit transition; supersedes `appear` when\n * both are present. */\n transition?: Transition;\n /** Motion grammar (Batch 2, scroll-driven) — defer the `transition` enter until\n * the node first crosses into the scroll viewport (reveal-on-scroll). Gated by\n * reduced motion (shown immediately when reduced). */\n revealOnScroll?: boolean;\n /** Motion grammar (Batch 2, scroll-driven) — parallax factor: the node drifts\n * vertically at this fraction of the scroll delta as it moves through the\n * viewport. Gated by reduced motion. Generalizes CollapsingHeader parallaxFactor. */\n parallax?: number;\n /** Motion grammar (Batch 4, rich visual) — when a backgroundGradient is present,\n * continuously drift/rotate it (animated gradient). Gated by reduced motion. */\n animatedGradient?: boolean;\n /** Motion grammar (Batch 3, hero/nav) — shared-element key: a matching\n * transitionId on the source + destination screen morphs that element across\n * navigation (web View Transitions / iOS matchedTransitionSource / Android\n * SharedTransitionLayout). Gated by reduced motion. */\n transitionId?: string;\n /** Motion grammar (Batch 4, rich visual) — render the backgroundGradient as a\n * mesh (overlapping multi-point blend) rather than a linear sweep; combine with\n * animatedGradient to drift it. */\n meshGradient?: boolean;\n /** Motion grammar (Batch 4, celebration) — burst a one-shot confetti overlay\n * within the node on appear. Gated by reduced motion. */\n confetti?: boolean;\n /** Motion grammar (Batch 2, scroll-driven) — pin this node to the top of its\n * scroll container (sticky section header). Functional positioning; not gated\n * by reduced motion. */\n sticky?: boolean;\n /** Motion grammar (Batch 2, scroll-driven) — turn this thin node into a\n * reading-progress bar that fills left→right with scroll (scaleX). web reads\n * window scroll; native reads the host scroll fraction. Functional. */\n scrollProgress?: boolean;\n /** Motion grammar (Batch 4, rich vector) — a named built-in vector animation\n * (\"loader\" | \"success\" | \"pulse\"), dependency-free. Gated by reduced motion.\n * Arbitrary Lottie/Rive JSON is the lib-backed superset follow-up. */\n vectorAnim?: string;\n /** Motion grammar (Batch 1, choreography) — delay this node's ENTER transition\n * by N ms so a screen can SEQUENCE its entrance beyond list stagger (\"title\n * fades, subtitle slides in 100ms later\"). Adds to any list `staggerMs`. Gated\n * by reduced motion. 0/absent = no extra delay. */\n enterDelayMs?: number;\n /** Motion grammar (Phase-3, per-node MotionSpec) — overrides the PRESS-feedback\n * curve with a `motions`-registry token, mirroring `Transition.motion` for the\n * enter curve. Absent → press uses the global `motion` personality. */\n pressMotion?: TokenRef;\n /** Motion grammar (Phase-3, gesture-driven) — finger-tracked drag-to-dismiss; past\n * threshold along `direction` it animates off and fires `action`, else springs back. */\n swipeDismiss?: SwipeDismiss;\n /** Motion grammar (Phase-4, reduced-motion) — per-node escape from the reduced-motion\n * gate. Default true (respect). false = \"must move anyway\" (transition/press animate\n * even when reduced motion is on). */\n respectReducedMotion?: boolean;\n /** #1052 — uniform scale (1 = no change). */\n scale?: number;\n /** #1052 — rotation in DEGREES. */\n rotation?: number;\n /** #1052 — stacking order within a ZStack/overlay. */\n zIndex?: number;\n /** #1052 — gaussian blur radius (pt/dp/px). */\n blur?: number;\n /** #1052 — `false` = decorative (ignores taps, unlike `hidden` which stays hit-testable);\n * `true` = force hit-testable (a clear tap target). */\n hitTestable?: boolean;\n /** #1052 — explicit drop shadow (colour + radius + offset), for upward / multi-layer\n * shadows the `shadow` token can't express. */\n boxShadow?: Shadow;\n /** The role assistive technology should announce. Absent = the\n * renderer INFERS it from the component type, so an author never restates the\n * obvious. `\"decorative\"` is node-local: the node itself stops being an\n * accessibility element (no role, not a stop) while its children stay\n * traversable — the ARIA `role=\"presentation\"` semantic. To remove the subtree\n * too, use `accessibilityHidden`. */\n accessibilityRole?: AccessibilityRole;\n /** The supplementary \"what happens if I act\" phrase\n * (iOS `accessibilityHint`, Android `onClickLabel`, ARIA `aria-describedby`).\n * Never a substitute for `accessibilityLabel`: AT may not speak a hint at all. */\n accessibilityHint?: string;\n /** Remove this node AND its subtree from the accessibility tree.\n * Distinct from `hidden` (which removes it visually too) and from the\n * `\"decorative\"` role (node-local; children stay reachable). */\n accessibilityHidden?: boolean;\n /** Mark the node as a heading at level 1–6, for rotor / heading\n * navigation. Implies the `\"heading\"` role when `accessibilityRole` is absent.\n * The LEVEL reaches iOS and web only: Android (Compose `heading()`) and React Native\n * (`accessibilityRole: \"header\"`) have no level primitive and mark a plain heading. */\n headingLevel?: number;\n /** An explicit SPOKEN value where the visual and spoken values\n * differ (a rating \"3 of 5\", a gauge \"72 percent\"). Where the value is derivable\n * from a prop the renderer computes it and this override is unnecessary. */\n accessibilityValue?: string;\n /** Additive state that a single role cannot carry. A node may\n * hold several. */\n accessibilityTraits?: AccessibilityTrait[];\n /** Explicit traversal index within the nearest focus group. Absent ⇒\n * the arm's visual / DOM order. The lower index is reached FIRST, which is why iOS\n * (whose `accessibilitySortPriority` is descending) negates it. */\n focusOrder?: number;\n /** This node's subtree is ONE traversal scope: children are ordered\n * relative to each other, then the group takes its parent's slot (iOS\n * `shouldGroupAccessibilityChildren`, Android `isTraversalGroup`, ARIA grouping). */\n focusGroup?: boolean;\n /** AT / keyboard focus lands here when the screen or a newly presented\n * modal appears. At most one per focus scope. */\n initialFocus?: boolean;\n /** A general live-region announcement, on any node and any transition.\n * The generalization of `FragmentSlotCase.accessibilityAnnouncement`, which only ever\n * fired on a fragment-slot case swap. */\n announce?: LiveRegion;\n /** Clip ANY node (content + surface) to a shape:\n * \"rectangle\" | \"roundedRectangle\" | \"capsule\" | \"circle\" | \"ellipse\". Unknown/empty =\n * no shape clip (`cornerRadius` keeps its meaning). When set it replaces the\n * corner-radius-only clip; a \"roundedRectangle\" uses `clipCornerRadii`, else `cornerRadius`. */\n clipShape?: string;\n /** Uneven corner radii for `clipShape: \"roundedRectangle\"`. */\n clipCornerRadii?: CornerRadii;\n /** A recurring, finite, transform-only motion on a decorative node: a\n * living character's idle `hop`, a `blink`, a working `breathe`. Never changes the\n * node's layout footprint. Stopped by reduced motion unless `respectReducedMotion`\n * is false. */\n ambientMotion?: AmbientMotion;\n}",
1420
1401
  "TokenRef": "export interface TokenRef {\n token: TokenName;\n}",
1421
1402
  "Action": "export interface Action {\n actionId: string;\n /** Backwards-compatible string-only params. Prefer `args` for typed payloads. */\n params?: Record<string, string>;\n /** Typed action args; nested objects/arrays preserved end-to-end. With `presentation: \"sheet\"`,\n * `args.detents` (fractions of the height in (0, 1], e.g. `[0.5, 1]`) sizes the presented\n * sheet; absent ⇒ the default sheet. Applies on iOS, Android and web; a macOS (and tvOS)\n * screen sheet is a window-modal panel sized to its content, so there it is accepted and\n * ignored, as for the BottomSheet component. */\n args?: Record<string, Value>;\n /** Navigation hint for the router; ignored for non-nav actions. */\n presentation?: Presentation;\n}",
1422
1403
  "Presentation": "export type Presentation =\n | \"push\"\n | \"sheet\"\n | \"replace\"\n | \"dismiss\"\n | \"back\"\n | \"full_screen\"\n | \"alert\"\n | \"snackbar\";",
@@ -1426,6 +1407,9 @@
1426
1407
  "PickerFieldStyle": "export interface PickerFieldStyle {\n borderColor?: string;\n borderWidth?: number;\n cornerRadius?: number;\n minHeight?: number;\n padding?: number;\n chevronIcon?: string;\n placeholderColor?: string;\n}",
1427
1408
  "GaugeRing": "export interface GaugeRing {\n /** Fraction 0..1 for this ring. */\n value?: number;\n /** `$service:`/`$item.` binding → a live number (overrides `value`). */\n valuePath?: string;\n tint?: TokenName;\n}",
1428
1409
  "WidgetTimeRef": "export interface WidgetTimeRef {\n /** Epoch seconds the style counts from/to. */\n at: number;\n /** SwiftUI `Text.DateStyle` / Android time style (default \"timer\"). */\n style?: \"timer\" | \"relative\" | \"date\" | \"time\" | \"offset\";\n}",
1410
+ "CornerRadii": "export interface CornerRadii {\n topLeading?: number;\n topTrailing?: number;\n bottomLeading?: number;\n bottomTrailing?: number;\n}",
1411
+ "Gradient": "export interface Gradient {\n kind?: \"linear\" | \"radial\";\n stops: GradientStop[];\n start?: string;\n end?: string;\n}",
1412
+ "ShapeStroke": "export interface ShapeStroke {\n color?: TokenRef;\n /** pt/dp; absent/0 ⇒ 1 */\n width?: number;\n /** on/off dash lengths in pt/dp; empty ⇒ solid. RN draws any dash as its fixed `dashed` style. */\n dash?: number[];\n}",
1429
1413
  "RichContentEditorTool": "export type RichContentEditorTool = \"bold\" | \"italic\" | \"underline\" | \"heading\" | \"bullet\" | \"ordered\" | \"quote\" | \"link\" | \"image\" | \"divider\" | \"undo\" | \"redo\";",
1430
1414
  "Border": "export interface Border {\n width: number;\n color: TokenRef;\n}"
1431
1415
  }
@@ -3,7 +3,7 @@
3
3
  > GENERATED from `core/ts/src/schema.ts` by `core/web-embed/authoring/gen-reference.mjs`.
4
4
  > The schema is the source of truth — regenerate on schema changes; do not hand-edit.
5
5
 
6
- **86 core component types.** Every component body is `{ "package": "himalaya", "type": "<Type>", "props": { … } }`.
6
+ **87 core component types.** Every component body is `{ "package": "himalaya", "type": "<Type>", "props": { … } }`.
7
7
  Binding grammar: `$service:<service>.<path>` (worker state) · `$item.<field>` (list row template) · `$flag:<key>` (feature flag) · `$env:<key>` (client environment — #1056).
8
8
  Bindings resolve in the text/value props marked **binding-aware** below — **including two `Modifiers` token refs**, `background` and `border.color`, which are the only two whose token a binding actually fills: a worker can drive per-item **theming** (e.g. a game board's per-square color, `background: { token: "$item.bg" }`), not just text content. `shadow` and `backgroundGradient` are `TokenRef`s but are **not** binding-aware on any renderer — `shadow: { token: "$item.x" }` keeps the sentinel as a literal token name and silently loses the per-item styling, and a gradient is driven by its own `backgroundGradientPath` prop resolving to a gradient token NAME, not by a binding inside a token ref.
9
9
  `$env:` is **client-resolved** (no worker) and valid in `modifiers.hiddenPath` and `FragmentSlot.casePath` **only** — keys `reduceMotion` / `colorScheme` / `sizeClass` / `isRTL`, with an optional `==`/`!=` comparison (e.g. `hiddenPath: "$env:reduceMotion"`, `hiddenPath: "$env:colorScheme==light"`, `casePath: "$env:colorScheme"`). An unknown key fails open (shown / `defaultCase`).
@@ -92,6 +92,7 @@ See also **[Modifiers](#modifiers)** (the `modifiers` block) and **[Actions](#ac
92
92
  | `DonutChart` | Analytics data-viz | `slicesPath` |
93
93
  | `Legend` | Analytics data-viz | `itemsPath` |
94
94
  | `DataTable` | Analytics data-viz | `rowsPath`, `totalsPath` |
95
+ | `Shape` | Shape | — |
95
96
  | `RichContent` | Rich content | `documentJsonPath` |
96
97
  | `RichContentEditor` | Rich content editor | `documentPath` |
97
98
  | `MediaField` | Image well + Wix Media upload | `valuePath`, `fallbackTextPath` |
@@ -118,9 +119,9 @@ See also **[Modifiers](#modifiers)** (the `modifiers` block) and **[Actions](#ac
118
119
 
119
120
  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.
120
121
 
121
- **Scope: 18 of 86 components, all of them android / web / ios-only** — every other component/platform pair reads every prop it decodes. The list splits in two, and the halves mean different things:
122
+ **Scope: 16 of 87 components, all of them android / web / ios-only** — every other component/platform pair reads every prop it decodes. The list splits in two, and the halves mean different things:
122
123
 
123
- - **`category` (7: `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.
124
+ - **`category` (5: `Menu`, `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.
124
125
  - **`styling` (11: `Text`, `Icon`, `Carousel`, `Pager`, `Snackbar`, `WebView`, `Slider`, `SelectionControl`, `ActivityIndicator`, `Video`, `PdfView`)** — 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.
125
126
 
126
127
  | Component | Unread props | Platform | Kind | Note |
@@ -136,8 +137,6 @@ These props are accepted by the schema and pass validation, but the named platfo
136
137
  | `ActivityIndicator` | `ring` | ios, android, web | styling | The `ring` style is never selected (determinate vs indeterminate follows `value`). |
137
138
  | `Menu` | `itemsPath` | ios | category | `itemsPath` does not bind items. |
138
139
  | `Menu` | `style`, `itemsPath` | android, web | category | `style: "action_sheet"` renders as a dropdown. (`style: "context"` is honoured: it opens on a long-press, or right-click on web, with its `preview`.) `itemsPath` does not bind items. |
139
- | `Tooltip` | `edge`, `trigger`, `onDismiss` | ios, android, web | category | Not an overlay — renders always-expanded inline; `edge`, `trigger` and dismissal are inert. |
140
- | `Popover` | `edge` | ios | category | The bubble is drawn in flow under its anchor; `edge` placement is not implemented. |
141
140
  | `ChipsInput` | `onAdd` | ios, android | category | `onAdd` never dispatches. |
142
141
  | `OtpInput` | `onComplete`, `onChange` | ios, android, web | category | Neither `onChange` nor `onComplete` dispatches. |
143
142
  | `Video` | `poster` | ios | styling | `poster` is not shown. |
@@ -1408,14 +1407,17 @@ export interface TooltipProps {
1408
1407
  text?: string;
1409
1408
  /** Present → rich tooltip. */
1410
1409
  title?: string;
1410
+ /** The side of the anchor the bubble floats on; `auto` / absent → `top`. Flips to the opposite
1411
+ * side when there is no room, as every renderer does. */
1411
1412
  edge?: "top" | "bottom" | "leading" | "trailing" | "auto";
1413
+ /** What opens the (otherwise hidden) bubble. `auto` / absent → a long-press on touch, hover and
1414
+ * keyboard focus on the web. */
1412
1415
  trigger?: "tap" | "long_press" | "auto";
1416
+ /** Fired once each time an open tooltip closes (outside tap, Escape, timeout). */
1413
1417
  onDismiss?: Action;
1414
1418
  }
1415
1419
  ```
1416
1420
 
1417
- > ⚠️ **Not implemented on ios, android, web:** `edge`, `trigger`, `onDismiss` — Not an overlay — renders always-expanded inline; `edge`, `trigger` and dismissal are inert.
1418
-
1419
1421
  #### Popover
1420
1422
 
1421
1423
  ```ts
@@ -1436,8 +1438,6 @@ export interface PopoverProps {
1436
1438
  }
1437
1439
  ```
1438
1440
 
1439
- > ⚠️ **Not implemented on ios:** `edge` — The bubble is drawn in flow under its anchor; `edge` placement is not implemented.
1440
-
1441
1441
  ### Chips & selection
1442
1442
 
1443
1443
  #### Chip
@@ -1688,6 +1688,22 @@ export interface DataTableProps {
1688
1688
  }
1689
1689
  ```
1690
1690
 
1691
+ ### Shape
1692
+
1693
+ #### Shape
1694
+
1695
+ ```ts
1696
+ export interface ShapeProps {
1697
+ /** "rectangle" (default) | "roundedRectangle" | "capsule" | "circle" | "ellipse" */
1698
+ kind?: string;
1699
+ cornerRadius?: number;
1700
+ cornerRadii?: CornerRadii;
1701
+ fill?: TokenRef;
1702
+ fillGradient?: Gradient;
1703
+ stroke?: ShapeStroke;
1704
+ }
1705
+ ```
1706
+
1691
1707
  ### Rich content
1692
1708
 
1693
1709
  #### RichContent
@@ -2395,6 +2411,9 @@ A few props take a typed **object** rather than nested components. Some are arra
2395
2411
  `Picker.field` is a single `PickerFieldStyle`, the drawn field's look), and
2396
2412
  `Gauge.rings` is a `GaugeRing[]` (concentric rings, drawn outer→inner), and
2397
2413
  `RichContentEditor.tools` is a `RichContentEditorTool[]` (a fixed list of toolbar buttons).
2414
+ `Shape` takes three objects: `cornerRadii` is a `CornerRadii` (layout-direction corners,
2415
+ also `modifiers.clipCornerRadii`), `fillGradient` is a `Gradient` and `stroke` is a
2416
+ `ShapeStroke` (its `dash` is on/off lengths; empty is solid).
2398
2417
  One is a single object: `Text.timeRef` is a `WidgetTimeRef`, the widget-safe live clock —
2399
2418
  note its `at` is REQUIRED and is in epoch SECONDS. The prop blocks above name these types;
2400
2419
  here are the interfaces themselves (for the arrays, each item's own fields — `id` is what an
@@ -2453,6 +2472,28 @@ export interface WidgetTimeRef {
2453
2472
  }
2454
2473
 
2455
2474
  export type RichContentEditorTool = "bold" | "italic" | "underline" | "heading" | "bullet" | "ordered" | "quote" | "link" | "image" | "divider" | "undo" | "redo";
2475
+
2476
+ export interface CornerRadii {
2477
+ topLeading?: number;
2478
+ topTrailing?: number;
2479
+ bottomLeading?: number;
2480
+ bottomTrailing?: number;
2481
+ }
2482
+
2483
+ export interface Gradient {
2484
+ kind?: "linear" | "radial";
2485
+ stops: GradientStop[];
2486
+ start?: string;
2487
+ end?: string;
2488
+ }
2489
+
2490
+ export interface ShapeStroke {
2491
+ color?: TokenRef;
2492
+ /** pt/dp; absent/0 ⇒ 1 */
2493
+ width?: number;
2494
+ /** on/off dash lengths in pt/dp; empty ⇒ solid. RN draws any dash as its fixed `dashed` style. */
2495
+ dash?: number[];
2496
+ }
2456
2497
  ```
2457
2498
 
2458
2499
  ## Modifiers
@@ -2720,6 +2761,13 @@ export interface Modifiers {
2720
2761
  * The generalization of `FragmentSlotCase.accessibilityAnnouncement`, which only ever
2721
2762
  * fired on a fragment-slot case swap. */
2722
2763
  announce?: LiveRegion;
2764
+ /** Clip ANY node (content + surface) to a shape:
2765
+ * "rectangle" | "roundedRectangle" | "capsule" | "circle" | "ellipse". Unknown/empty =
2766
+ * no shape clip (`cornerRadius` keeps its meaning). When set it replaces the
2767
+ * corner-radius-only clip; a "roundedRectangle" uses `clipCornerRadii`, else `cornerRadius`. */
2768
+ clipShape?: string;
2769
+ /** Uneven corner radii for `clipShape: "roundedRectangle"`. */
2770
+ clipCornerRadii?: CornerRadii;
2723
2771
  /** A recurring, finite, transform-only motion on a decorative node: a
2724
2772
  * living character's idle `hop`, a `blink`, a working `breathe`. Never changes the
2725
2773
  * node's layout footprint. Stopped by reduced motion unless `respectReducedMotion`
package/guides/index.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "_comment": "AUTO-GENERATED by tools/authoring-kit/bundle.mjs — DO NOT EDIT. Regenerate with: npm run authoring:gen",
3
3
  "schemaStamp": {
4
- "componentCount": 86,
4
+ "componentCount": 87,
5
5
  "schemaSource": "core/ts/src/schema.ts"
6
6
  },
7
7
  "portalUrl": "https://apps.wix.com/_api/himi-serve/docs",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/himalaya-cli",
3
- "version": "0.1473.0",
3
+ "version": "0.1475.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": [
@@ -71,5 +71,5 @@
71
71
  "artifactId": "himalaya-cli"
72
72
  }
73
73
  },
74
- "falconPackageHash": "f58b0d57918c163a9918dbe6f1170839ea6c6d6cf0d2b9c38b7a7004"
74
+ "falconPackageHash": "224e56d2071ce0050cf65a861313895b2147862685f52d1f6b8abd95"
75
75
  }