@wix/himalaya-cli 0.1000.0 → 0.1002.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.
Files changed (42) hide show
  1. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/schema.d.ts +39 -1
  2. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/validator.d.ts +50 -0
  3. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core.mjs +46 -0
  4. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/sdui.mjs +46 -0
  5. package/dist/cli.mjs +207 -20
  6. package/dist/preview-assets.generated.bin +0 -0
  7. package/guides/component-reference.json +2 -2
  8. package/guides/component-reference.md +32 -0
  9. package/package.json +2 -2
  10. package/templates/beauty-salon-owner/tier5-src/_shared/aria-chat.ts +11 -31
  11. package/templates/beauty-salon-owner/tier5-src/_shared/aria-widget-model.ts +31 -0
  12. package/templates/beauty-salon-owner/tier5-src/_shared/aria-widget-view.ts +48 -13
  13. package/templates/community-club-owner/tier5-src/_shared/aria-chat.ts +11 -31
  14. package/templates/community-club-owner/tier5-src/_shared/aria-widget-model.ts +31 -0
  15. package/templates/community-club-owner/tier5-src/_shared/aria-widget-view.ts +48 -13
  16. package/templates/events-meetups-owner/tier5-src/_shared/aria-chat.ts +11 -31
  17. package/templates/events-meetups-owner/tier5-src/_shared/aria-widget-model.ts +31 -0
  18. package/templates/events-meetups-owner/tier5-src/_shared/aria-widget-view.ts +48 -13
  19. package/templates/gym-fitness-owner/tier5-src/_shared/aria-chat.ts +11 -31
  20. package/templates/gym-fitness-owner/tier5-src/_shared/aria-widget-model.ts +31 -0
  21. package/templates/gym-fitness-owner/tier5-src/_shared/aria-widget-view.ts +48 -13
  22. package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-chat.ts +11 -31
  23. package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-widget-model.ts +31 -0
  24. package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-widget-view.ts +48 -13
  25. package/templates/owner-lite/tier5-src/_shared/aria-chat.ts +11 -31
  26. package/templates/owner-lite/tier5-src/_shared/aria-widget-model.ts +31 -0
  27. package/templates/owner-lite/tier5-src/_shared/aria-widget-view.ts +48 -13
  28. package/templates/podcast-creator-owner/tier5-src/_shared/aria-chat.ts +11 -31
  29. package/templates/podcast-creator-owner/tier5-src/_shared/aria-widget-model.ts +31 -0
  30. package/templates/podcast-creator-owner/tier5-src/_shared/aria-widget-view.ts +48 -13
  31. package/templates/portfolio-creative-owner/tier5-src/_shared/aria-chat.ts +11 -31
  32. package/templates/portfolio-creative-owner/tier5-src/_shared/aria-widget-model.ts +31 -0
  33. package/templates/portfolio-creative-owner/tier5-src/_shared/aria-widget-view.ts +48 -13
  34. package/templates/restaurant-owner/tier5-src/_shared/aria-chat.ts +11 -31
  35. package/templates/restaurant-owner/tier5-src/_shared/aria-widget-model.ts +31 -0
  36. package/templates/restaurant-owner/tier5-src/_shared/aria-widget-view.ts +48 -13
  37. package/templates/retail-store-owner/tier5-src/_shared/aria-chat.ts +11 -31
  38. package/templates/retail-store-owner/tier5-src/_shared/aria-widget-model.ts +31 -0
  39. package/templates/retail-store-owner/tier5-src/_shared/aria-widget-view.ts +48 -13
  40. package/templates/yoga-studio-owner/tier5-src/_shared/aria-chat.ts +11 -31
  41. package/templates/yoga-studio-owner/tier5-src/_shared/aria-widget-model.ts +31 -0
  42. package/templates/yoga-studio-owner/tier5-src/_shared/aria-widget-view.ts +48 -13
@@ -322,7 +322,40 @@ export interface Modifiers {
322
322
  /** #1052 — explicit drop shadow (colour + radius + offset), for upward / multi-layer
323
323
  * shadows the `shadow` token can't express. */
324
324
  boxShadow?: Shadow;
325
- }
325
+ /** RFC 0058 §3.1 — the role assistive technology should announce. Absent = the
326
+ * renderer INFERS it from the component type, so an author never restates the
327
+ * obvious. `"decorative"` is node-local: the node itself stops being an
328
+ * accessibility element (no role, not a stop) while its children stay
329
+ * traversable — the ARIA `role="presentation"` semantic. To remove the subtree
330
+ * too, use `accessibilityHidden`. */
331
+ accessibilityRole?: AccessibilityRole;
332
+ /** RFC 0058 §3.1 — the supplementary "what happens if I act" phrase
333
+ * (iOS `accessibilityHint`, Android `onClickLabel`, ARIA `aria-describedby`).
334
+ * Never a substitute for `accessibilityLabel`: AT may not speak a hint at all. */
335
+ accessibilityHint?: string;
336
+ /** RFC 0058 §3.1 — remove this node AND its subtree from the accessibility tree.
337
+ * Distinct from `hidden` (which removes it visually too) and from the
338
+ * `"decorative"` role (node-local; children stay reachable). */
339
+ accessibilityHidden?: boolean;
340
+ /** RFC 0058 §3.1 — mark the node as a heading at level 1–6, for rotor / heading
341
+ * navigation. Implies the `"heading"` role when `accessibilityRole` is absent.
342
+ * The LEVEL reaches iOS and web only: Android (Compose `heading()`) and React Native
343
+ * (`accessibilityRole: "header"`) have no level primitive and mark a plain heading. */
344
+ headingLevel?: number;
345
+ /** RFC 0058 §3.1 — an explicit SPOKEN value where the visual and spoken values
346
+ * differ (a rating "3 of 5", a gauge "72 percent"). Where the value is derivable
347
+ * from a prop the renderer computes it and this override is unnecessary. */
348
+ accessibilityValue?: string;
349
+ /** RFC 0058 §3.1 — additive state that a single role cannot carry. A node may
350
+ * hold several. */
351
+ accessibilityTraits?: AccessibilityTrait[];
352
+ }
353
+ /** RFC 0058 §3.2 — the role AT announces for a node. The union of what iOS,
354
+ * Android, web and React Native can express; an arm that cannot express a role
355
+ * exactly falls back to the nearest one it has. */
356
+ export type AccessibilityRole = "decorative" | "text" | "heading" | "image" | "button" | "link" | "toggle" | "checkbox" | "radio" | "tab" | "tablist" | "adjustable" | "search" | "textfield" | "combobox" | "list" | "listitem" | "menu" | "menuitem" | "dialog" | "alert" | "progressbar" | "summary" | "status" | "group" | "grid" | "gridcell";
357
+ /** RFC 0058 §3.2 — additive, orthogonal state a single role cannot carry. */
358
+ export type AccessibilityTrait = "selected" | "disabled" | "updates_frequently" | "plays_sound" | "starts_media";
326
359
  /** Motion grammar (Phase-3) — drag-to-dismiss config (see `Modifiers.swipeDismiss`). */
327
360
  export interface SwipeDismiss {
328
361
  action: Action;
@@ -606,6 +639,11 @@ export interface IconProps {
606
639
  name: IconRef;
607
640
  size?: number;
608
641
  tint?: TokenName;
642
+ /** RFC 0058 §3.1 — the spoken name for a MEANINGFUL icon, mirroring
643
+ * `ImageProps.contentDescription`. Absent (and with no enclosing labelled
644
+ * control) the icon is decorative and stays OUT of the accessibility tree,
645
+ * rather than being announced by its raw glyph name. */
646
+ contentDescription?: string;
609
647
  }
610
648
  export interface ButtonProps {
611
649
  /** Button label — binding-aware ("$item."/"$service:") on web, iOS and Android. */
@@ -599,6 +599,31 @@ export declare const screenDescriptorSchema: {
599
599
  readonly hitTestable: {
600
600
  readonly type: "boolean";
601
601
  };
602
+ readonly accessibilityRole: {
603
+ readonly type: "string";
604
+ readonly enum: readonly ["decorative", "text", "heading", "image", "button", "link", "toggle", "checkbox", "radio", "tab", "tablist", "adjustable", "search", "textfield", "combobox", "list", "listitem", "menu", "menuitem", "dialog", "alert", "progressbar", "summary", "status", "group", "grid", "gridcell"];
605
+ };
606
+ readonly accessibilityHint: {
607
+ readonly type: "string";
608
+ };
609
+ readonly accessibilityHidden: {
610
+ readonly type: "boolean";
611
+ };
612
+ readonly headingLevel: {
613
+ readonly type: "integer";
614
+ readonly minimum: 1;
615
+ readonly maximum: 6;
616
+ };
617
+ readonly accessibilityValue: {
618
+ readonly type: "string";
619
+ };
620
+ readonly accessibilityTraits: {
621
+ readonly type: "array";
622
+ readonly items: {
623
+ readonly type: "string";
624
+ readonly enum: readonly ["selected", "disabled", "updates_frequently", "plays_sound", "starts_media"];
625
+ };
626
+ };
602
627
  readonly boxShadow: {
603
628
  readonly type: "object";
604
629
  readonly additionalProperties: false;
@@ -1491,6 +1516,31 @@ export declare const widgetSnapshotSchema: {
1491
1516
  readonly hitTestable: {
1492
1517
  readonly type: "boolean";
1493
1518
  };
1519
+ readonly accessibilityRole: {
1520
+ readonly type: "string";
1521
+ readonly enum: readonly ["decorative", "text", "heading", "image", "button", "link", "toggle", "checkbox", "radio", "tab", "tablist", "adjustable", "search", "textfield", "combobox", "list", "listitem", "menu", "menuitem", "dialog", "alert", "progressbar", "summary", "status", "group", "grid", "gridcell"];
1522
+ };
1523
+ readonly accessibilityHint: {
1524
+ readonly type: "string";
1525
+ };
1526
+ readonly accessibilityHidden: {
1527
+ readonly type: "boolean";
1528
+ };
1529
+ readonly headingLevel: {
1530
+ readonly type: "integer";
1531
+ readonly minimum: 1;
1532
+ readonly maximum: 6;
1533
+ };
1534
+ readonly accessibilityValue: {
1535
+ readonly type: "string";
1536
+ };
1537
+ readonly accessibilityTraits: {
1538
+ readonly type: "array";
1539
+ readonly items: {
1540
+ readonly type: "string";
1541
+ readonly enum: readonly ["selected", "disabled", "updates_frequently", "plays_sound", "starts_media"];
1542
+ };
1543
+ };
1494
1544
  readonly boxShadow: {
1495
1545
  readonly type: "object";
1496
1546
  readonly additionalProperties: false;
@@ -8251,6 +8251,52 @@ var screenDescriptorSchema = {
8251
8251
  zIndex: { type: "integer" },
8252
8252
  blur: { type: "integer", minimum: 0 },
8253
8253
  hitTestable: { type: "boolean" },
8254
+ // RFC 0058 §3.1 — the accessibility grammar (core.proto Modifiers 63–68).
8255
+ // `accessibilityLabel` (field 5, above) is the NAME; these carry role, hint,
8256
+ // tree membership, heading structure, spoken value and additive state.
8257
+ accessibilityRole: {
8258
+ type: "string",
8259
+ enum: [
8260
+ "decorative",
8261
+ "text",
8262
+ "heading",
8263
+ "image",
8264
+ "button",
8265
+ "link",
8266
+ "toggle",
8267
+ "checkbox",
8268
+ "radio",
8269
+ "tab",
8270
+ "tablist",
8271
+ "adjustable",
8272
+ "search",
8273
+ "textfield",
8274
+ "combobox",
8275
+ "list",
8276
+ "listitem",
8277
+ "menu",
8278
+ "menuitem",
8279
+ "dialog",
8280
+ "alert",
8281
+ "progressbar",
8282
+ "summary",
8283
+ "status",
8284
+ "group",
8285
+ "grid",
8286
+ "gridcell"
8287
+ ]
8288
+ },
8289
+ accessibilityHint: { type: "string" },
8290
+ accessibilityHidden: { type: "boolean" },
8291
+ headingLevel: { type: "integer", minimum: 1, maximum: 6 },
8292
+ accessibilityValue: { type: "string" },
8293
+ accessibilityTraits: {
8294
+ type: "array",
8295
+ items: {
8296
+ type: "string",
8297
+ enum: ["selected", "disabled", "updates_frequently", "plays_sound", "starts_media"]
8298
+ }
8299
+ },
8254
8300
  // #1052 — explicit drop shadow (colour token + radius + offset), alongside the `shadow` token form.
8255
8301
  boxShadow: {
8256
8302
  type: "object",
@@ -7323,6 +7323,52 @@ var screenDescriptorSchema = {
7323
7323
  zIndex: { type: "integer" },
7324
7324
  blur: { type: "integer", minimum: 0 },
7325
7325
  hitTestable: { type: "boolean" },
7326
+ // RFC 0058 §3.1 — the accessibility grammar (core.proto Modifiers 63–68).
7327
+ // `accessibilityLabel` (field 5, above) is the NAME; these carry role, hint,
7328
+ // tree membership, heading structure, spoken value and additive state.
7329
+ accessibilityRole: {
7330
+ type: "string",
7331
+ enum: [
7332
+ "decorative",
7333
+ "text",
7334
+ "heading",
7335
+ "image",
7336
+ "button",
7337
+ "link",
7338
+ "toggle",
7339
+ "checkbox",
7340
+ "radio",
7341
+ "tab",
7342
+ "tablist",
7343
+ "adjustable",
7344
+ "search",
7345
+ "textfield",
7346
+ "combobox",
7347
+ "list",
7348
+ "listitem",
7349
+ "menu",
7350
+ "menuitem",
7351
+ "dialog",
7352
+ "alert",
7353
+ "progressbar",
7354
+ "summary",
7355
+ "status",
7356
+ "group",
7357
+ "grid",
7358
+ "gridcell"
7359
+ ]
7360
+ },
7361
+ accessibilityHint: { type: "string" },
7362
+ accessibilityHidden: { type: "boolean" },
7363
+ headingLevel: { type: "integer", minimum: 1, maximum: 6 },
7364
+ accessibilityValue: { type: "string" },
7365
+ accessibilityTraits: {
7366
+ type: "array",
7367
+ items: {
7368
+ type: "string",
7369
+ enum: ["selected", "disabled", "updates_frequently", "plays_sound", "starts_media"]
7370
+ }
7371
+ },
7326
7372
  // #1052 — explicit drop shadow (colour token + radius + offset), alongside the `shadow` token form.
7327
7373
  boxShadow: {
7328
7374
  type: "object",
package/dist/cli.mjs CHANGED
@@ -5913,6 +5913,52 @@ var init_validator = __esm({
5913
5913
  zIndex: { type: "integer" },
5914
5914
  blur: { type: "integer", minimum: 0 },
5915
5915
  hitTestable: { type: "boolean" },
5916
+ // RFC 0058 §3.1 — the accessibility grammar (core.proto Modifiers 63–68).
5917
+ // `accessibilityLabel` (field 5, above) is the NAME; these carry role, hint,
5918
+ // tree membership, heading structure, spoken value and additive state.
5919
+ accessibilityRole: {
5920
+ type: "string",
5921
+ enum: [
5922
+ "decorative",
5923
+ "text",
5924
+ "heading",
5925
+ "image",
5926
+ "button",
5927
+ "link",
5928
+ "toggle",
5929
+ "checkbox",
5930
+ "radio",
5931
+ "tab",
5932
+ "tablist",
5933
+ "adjustable",
5934
+ "search",
5935
+ "textfield",
5936
+ "combobox",
5937
+ "list",
5938
+ "listitem",
5939
+ "menu",
5940
+ "menuitem",
5941
+ "dialog",
5942
+ "alert",
5943
+ "progressbar",
5944
+ "summary",
5945
+ "status",
5946
+ "group",
5947
+ "grid",
5948
+ "gridcell"
5949
+ ]
5950
+ },
5951
+ accessibilityHint: { type: "string" },
5952
+ accessibilityHidden: { type: "boolean" },
5953
+ headingLevel: { type: "integer", minimum: 1, maximum: 6 },
5954
+ accessibilityValue: { type: "string" },
5955
+ accessibilityTraits: {
5956
+ type: "array",
5957
+ items: {
5958
+ type: "string",
5959
+ enum: ["selected", "disabled", "updates_frequently", "plays_sound", "starts_media"]
5960
+ }
5961
+ },
5916
5962
  // #1052 — explicit drop shadow (colour token + radius + offset), alongside the `shadow` token form.
5917
5963
  boxShadow: {
5918
5964
  type: "object",
@@ -8683,7 +8729,9 @@ var init_validate_descriptor_core = __esm({
8683
8729
  staggerMs: "number"
8684
8730
  },
8685
8731
  HStack: { alignment: "string", children: "array", spacing: "number" },
8686
- Icon: { name: "string", size: "number", tint: "string" },
8732
+ // RFC 0058 §3.1 — `contentDescription` names a MEANINGFUL icon (mirroring Image);
8733
+ // its absence is what marks an icon decorative.
8734
+ Icon: { contentDescription: "string", name: "string", size: "number", tint: "string" },
8687
8735
  Image: {
8688
8736
  aspectRatio: "number",
8689
8737
  asset: "string",
@@ -9279,6 +9327,7 @@ var init_validate_descriptor_core = __esm({
9279
9327
  "blur",
9280
9328
  "cornerRadius",
9281
9329
  "enterDelayMs",
9330
+ "headingLevel",
9282
9331
  "height",
9283
9332
  "maxWidth",
9284
9333
  "offsetX",
@@ -19401,6 +19450,7 @@ function shouldRevealError(args) {
19401
19450
  var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
19402
19451
  var init_validation = __esm({
19403
19452
  "../../core/ts/src/validation.ts"() {
19453
+ "use strict";
19404
19454
  EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
19405
19455
  URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
19406
19456
  INTEGER_RE = /^[+-]?[0-9]+$/;
@@ -22825,6 +22875,7 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
22825
22875
  var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
22826
22876
  var init_worker_subtree = __esm({
22827
22877
  "../../core/ts/src/worker-subtree.ts"() {
22878
+ "use strict";
22828
22879
  init_worker_subtree_safe_types_generated();
22829
22880
  WORKER_SUBTREE_CEILINGS = Object.freeze({
22830
22881
  maxEncodedBytes: 65536,
@@ -23572,19 +23623,44 @@ function withExtras(name, render) {
23572
23623
  const el = render({ props, ctx, wrap, nodeId, gap });
23573
23624
  if (!React5.isValidElement(el)) return /* @__PURE__ */ jsx6(Fragment3, { children: el });
23574
23625
  const additive = addIntrinsicPadding(el.props.style, wrap ?? {});
23626
+ const inferredDecorative = el.props[INFERRED_DECORATIVE] === true;
23627
+ const iconGlyph2 = el.props[ICON_GLYPH] === true;
23575
23628
  if (!Object.keys(pass).length) {
23629
+ if (inferredDecorative || iconGlyph2) {
23630
+ return React5.cloneElement(el, { [INFERRED_DECORATIVE]: void 0, [ICON_GLYPH]: void 0, ...additive ? { style: additive } : {} });
23631
+ }
23576
23632
  return additive ? React5.cloneElement(el, { style: additive }) : /* @__PURE__ */ jsx6(Fragment3, { children: el });
23577
23633
  }
23578
23634
  const prev = el.props;
23579
23635
  const next = { ...pass };
23636
+ if (inferredDecorative) {
23637
+ next[INFERRED_DECORATIVE] = void 0;
23638
+ const passRole = typeof pass.role === "string" ? pass.role : void 0;
23639
+ const nodeSpeaksForItself = pass["aria-label"] != null || passRole != null && passRole !== "presentation" && passRole !== "none" || typeof pass.onClick === "function" || typeof pass.onDoubleClick === "function";
23640
+ if (pass["aria-hidden"] == null && nodeSpeaksForItself) next["aria-hidden"] = void 0;
23641
+ }
23642
+ if (iconGlyph2) {
23643
+ next[ICON_GLYPH] = void 0;
23644
+ if (pass.role === "presentation" && typeof pass.onClick !== "function" && typeof pass.onDoubleClick !== "function") {
23645
+ next["aria-hidden"] = "true";
23646
+ next["aria-label"] = void 0;
23647
+ next.title = void 0;
23648
+ next.role = void 0;
23649
+ }
23650
+ }
23651
+ const roleIsSynthetic = next[SYNTHETIC_TAP_ROLE] === true;
23652
+ delete next[SYNTHETIC_TAP_ROLE];
23580
23653
  if (additive) next.style = additive;
23581
23654
  const ownsInteractiveSemantics = isNativeInteractiveElement(el) || hasInteractiveReactDescendant(el);
23582
23655
  if (ownsInteractiveSemantics) {
23583
- delete next.role;
23656
+ if (roleIsSynthetic) delete next.role;
23584
23657
  delete next.tabIndex;
23585
23658
  delete next.onKeyDown;
23586
23659
  }
23587
23660
  if (pass.style) next.style = { ...additive ?? prev.style ?? {}, ...pass.style };
23661
+ if (typeof pass["aria-describedby"] === "string" && typeof prev["aria-describedby"] === "string") {
23662
+ next["aria-describedby"] = `${prev["aria-describedby"]} ${pass["aria-describedby"]}`;
23663
+ }
23588
23664
  if (typeof pass.onClick === "function" && typeof prev.onClick === "function") {
23589
23665
  next.onClick = (e) => {
23590
23666
  prev.onClick(e);
@@ -24014,6 +24090,63 @@ function calKeyActivate(enabled, activate) {
24014
24090
  activate();
24015
24091
  };
24016
24092
  }
24093
+ function applyA11ySemantics(node, ctx, extra) {
24094
+ const m = node?.modifiers;
24095
+ if (!m) return void 0;
24096
+ const str6 = (v) => {
24097
+ if (v == null) return void 0;
24098
+ const r = resolveScalarStatic(v, ctx);
24099
+ const s = r == null ? "" : String(r).trim();
24100
+ return s === "" ? void 0 : s;
24101
+ };
24102
+ if ((m.accessibilityHidden ?? m.accessibility_hidden) === true) {
24103
+ extra["aria-hidden"] = "true";
24104
+ extra.inert = "";
24105
+ return void 0;
24106
+ }
24107
+ const role = str6(m.accessibilityRole ?? m.accessibility_role);
24108
+ const headingLevel = m.headingLevel ?? m.heading_level;
24109
+ const tappable = Boolean((m.onTap ?? m.on_tap ?? m.onDoubleTap ?? m.on_double_tap) && ctx.onAction);
24110
+ if (role === "decorative" && !tappable) {
24111
+ extra.role = "presentation";
24112
+ delete extra["aria-label"];
24113
+ return void 0;
24114
+ } else if (role != null && role !== "decorative" && ARIA_ROLE[role]) {
24115
+ extra.role = ARIA_ROLE[role];
24116
+ } else if (typeof headingLevel === "number" && headingLevel >= 1 && headingLevel <= 6) {
24117
+ extra.role = "heading";
24118
+ }
24119
+ if (typeof headingLevel === "number" && headingLevel >= 1 && headingLevel <= 6) {
24120
+ extra["aria-level"] = String(headingLevel);
24121
+ }
24122
+ const hint = str6(m.accessibilityHint ?? m.accessibility_hint);
24123
+ const value = str6(m.accessibilityValue ?? m.accessibility_value);
24124
+ if (value) extra["aria-valuetext"] = value;
24125
+ const traits = m.accessibilityTraits ?? m.accessibility_traits;
24126
+ if (Array.isArray(traits)) {
24127
+ for (const t of traits) {
24128
+ switch (t) {
24129
+ case "selected":
24130
+ extra["aria-selected"] = "true";
24131
+ break;
24132
+ case "disabled":
24133
+ extra["aria-disabled"] = "true";
24134
+ break;
24135
+ // `updates_frequently` means "do not announce every tick" — on web that is an
24136
+ // explicit `aria-live="off"`, which overrides an ancestor live region.
24137
+ case "updates_frequently":
24138
+ extra["aria-live"] = "off";
24139
+ break;
24140
+ // `plays_sound` / `starts_media` are iOS speech-behaviour traits with no ARIA
24141
+ // counterpart; §3.2 says an arm falls back to the nearest thing it HAS, and ARIA
24142
+ // has nothing here, so they are ignored rather than approximated.
24143
+ default:
24144
+ break;
24145
+ }
24146
+ }
24147
+ }
24148
+ return hint;
24149
+ }
24017
24150
  function renderNodeInner(node, ctx) {
24018
24151
  if (ctx.previewSurface && node && typeof node === "object") {
24019
24152
  const { type } = normalize(node);
@@ -24088,6 +24221,8 @@ function renderNodeInner(node, ctx) {
24088
24221
  if (resolved2 != null && String(resolved2).trim()) extra["aria-label"] = String(resolved2);
24089
24222
  }
24090
24223
  }
24224
+ const a11yHint = applyA11ySemantics(node, ctx, extra);
24225
+ const a11yHidden = extra["aria-hidden"] === "true";
24091
24226
  const tap = node?.modifiers?.onTap ?? node?.modifiers?.on_tap;
24092
24227
  const tapDisabled = normalize(node).props?.disabled === true || normalize(node).props?.loading === true || node?.modifiers?.disabled === true || node?.modifiers?.hitTestable === false || node?.modifiers?.hit_testable === false;
24093
24228
  if (tap && ctx.onAction && !tapDisabled) {
@@ -24097,8 +24232,11 @@ function renderNodeInner(node, ctx) {
24097
24232
  prevOnClick?.(e);
24098
24233
  ctx.onAction(resolveItemDeep2(tap, ctx));
24099
24234
  };
24100
- if (!isNativeInteractiveElement(el) && !hasInteractiveDescendant(node)) {
24101
- extra.role = "button";
24235
+ if (!a11yHidden && !isNativeInteractiveElement(el) && !hasInteractiveDescendant(node)) {
24236
+ if (extra.role == null) {
24237
+ extra.role = "button";
24238
+ if (typeof el.type !== "string") extra[SYNTHETIC_TAP_ROLE] = true;
24239
+ }
24102
24240
  extra.tabIndex = 0;
24103
24241
  const prevOnKeyDown = el.props.onKeyDown;
24104
24242
  extra.onKeyDown = (e) => {
@@ -24145,7 +24283,10 @@ function renderNodeInner(node, ctx) {
24145
24283
  if (composed) extra.style = composed;
24146
24284
  }
24147
24285
  }
24148
- const out = Object.keys(extra).length ? React5.cloneElement(el, extra) : el;
24286
+ let out = Object.keys(extra).length ? React5.cloneElement(el, extra) : el;
24287
+ if (a11yHint) {
24288
+ out = /* @__PURE__ */ jsx6(A11yHintDescription, { hint: a11yHint, idBase: componentId, children: out });
24289
+ }
24149
24290
  const sd = node?.modifiers?.swipeDismiss ?? node?.modifiers?.swipe_dismiss;
24150
24291
  if (sd?.action && ctx.onAction) {
24151
24292
  return /* @__PURE__ */ jsx6(SwipeDismissWrap, { action: sd.action, direction: sd.direction, onAction: ctx.onAction, children: out });
@@ -24853,7 +24994,7 @@ function renderInner(node, ctx) {
24853
24994
  }
24854
24995
  }
24855
24996
  }
24856
- var useIsomorphicLayoutEffect, ResponsiveGrid, SPLIT_EXPANDED_MIN_WIDTH, SPLIT_COLUMN_GAP, ResponsiveSplitView, ABSOLUTE_URL_RE, appearKeyframesInjected, pressStylesInjected, FOCUS_RING_CSS, focusStylesInjected, HLIST_CHILD_CSS, hListStylesInjected, listAnimateRuntimeInstalled, transitionKeyframesInjected, countUpRuntimeInjected, MEASURE_PREFIX, measureRuntimeInjected, revealRuntimeInjected, vectorAnimStylesInjected, scrollProgressRuntimeInjected, confettiRuntimeInjected, lottieRuntimeInjected, riveRuntimeInjected, gradientKeyframesInjected, parallaxRuntimeInjected, spinKeyframesInjected, marqueeKeyframesInjected, alignItems, zJustifyItems, hAlignItems, bodyFont, kids, rowKids, staggeredKids, asTextL10n, asBoundText, useBoundString, InterpolatedTextView, txt, selectFragmentCase, fragmentValueHash, fragmentSlotContent, FragmentSlotNode, WorkerSubtreeNode, resolveItemDeep2, resolveSwipeActions, resolveModBindings, resolvedComponentId, directServiceBindings, ReactiveDirectScalars, HiddenGate, KEYBOARD_INPUT_MODES, AUTOCAPITALIZE_VALUES, ENTER_KEY_HINTS, AUTOGROW_CEILING, EditableField, MenuNode, LoadMoreSentinel, FieldErrorNode, FormView, MediaSlotProvider, MEDIA_ITEM_BINDABLE, MediaPlayerView, VideoNode, PdfViewNode, WebViewNode, InteractivePicker, InteractiveDatePicker, InteractiveSearchField, InteractiveStepper, INTERACTIVE_ROLES, ALWAYS_INTERACTIVE_COMPONENT_TYPES, controlNode, ToggleNode, SliderNode, SelectionControlNode, TabsNode, SegmentedControlNode, DisclosureGroupNode, GridNode, SplitViewNode, TextNode, ImageNode, AvatarNode, IconNode, ButtonNode, OtpInputNode, ProgressBarNode, ActivityIndicatorNode, BottomSheetNode, ChipsInputNode, ChipNode, TableNode, GaugeRing, GaugeNode, RatingNode, AvatarStripNode, CHART_STROKE_CYCLE, chartStrokeAt, chartBarCenter, ChartNode, donutSliceOpacity, DonutChartNode, LegendMarker, LegendNode, cellAlign, DataTableNode, voiceNoteState, voiceNoteDelivery, VOICE_NOTE_DEFAULT_BARS, clampBarCount, VoiceNoteNode, TimelineNode, WheelPickerNode, ColorPickerNode, FilterChipsNode, TILE_PX, MAX_MERCATOR_LAT, DEFAULT_TILE_MAX_ZOOM, CIRCLE_SEGMENTS, METRES_PER_DEG_LAT, MARKER_HIT_RADIUS, SHAPE_HIT_RADIUS, MapNode, CollapsingHeaderNode, UnsupportedOnSurface, CALENDAR_DATE_ONLY_RE, CAL_DEFAULT_MAX_DOTS, CAL_AGENDA_INITIAL_DAYS, CAL_AGENDA_PAGE_DAYS, CAL_DEFAULT_SNAP_MINUTES, CAL_UNASSIGNED_LANE_ID, MonthCalendarNode, TimeGridNode, AgendaNode, WebRenderer;
24997
+ var useIsomorphicLayoutEffect, ResponsiveGrid, SPLIT_EXPANDED_MIN_WIDTH, SPLIT_COLUMN_GAP, ResponsiveSplitView, ABSOLUTE_URL_RE, appearKeyframesInjected, pressStylesInjected, FOCUS_RING_CSS, focusStylesInjected, HLIST_CHILD_CSS, hListStylesInjected, listAnimateRuntimeInstalled, transitionKeyframesInjected, countUpRuntimeInjected, MEASURE_PREFIX, measureRuntimeInjected, revealRuntimeInjected, vectorAnimStylesInjected, scrollProgressRuntimeInjected, confettiRuntimeInjected, lottieRuntimeInjected, riveRuntimeInjected, gradientKeyframesInjected, parallaxRuntimeInjected, spinKeyframesInjected, marqueeKeyframesInjected, alignItems, zJustifyItems, hAlignItems, bodyFont, kids, rowKids, staggeredKids, asTextL10n, asBoundText, useBoundString, InterpolatedTextView, txt, selectFragmentCase, fragmentValueHash, fragmentSlotContent, FragmentSlotNode, WorkerSubtreeNode, resolveItemDeep2, resolveSwipeActions, resolveModBindings, resolvedComponentId, directServiceBindings, ReactiveDirectScalars, HiddenGate, KEYBOARD_INPUT_MODES, AUTOCAPITALIZE_VALUES, ENTER_KEY_HINTS, AUTOGROW_CEILING, EditableField, MenuNode, LoadMoreSentinel, FieldErrorNode, FormView, MediaSlotProvider, MEDIA_ITEM_BINDABLE, MediaPlayerView, VideoNode, PdfViewNode, WebViewNode, InteractivePicker, InteractiveDatePicker, InteractiveSearchField, InteractiveStepper, SYNTHETIC_TAP_ROLE, INFERRED_DECORATIVE, ICON_GLYPH, INTERACTIVE_ROLES, ALWAYS_INTERACTIVE_COMPONENT_TYPES, controlNode, ToggleNode, SliderNode, SelectionControlNode, TabsNode, SegmentedControlNode, DisclosureGroupNode, GridNode, SplitViewNode, TextNode, ImageNode, AvatarNode, IconNode, ButtonNode, OtpInputNode, ProgressBarNode, ActivityIndicatorNode, BottomSheetNode, ChipsInputNode, ChipNode, TableNode, GaugeRing, GaugeNode, RatingNode, AvatarStripNode, CHART_STROKE_CYCLE, chartStrokeAt, chartBarCenter, ChartNode, donutSliceOpacity, DonutChartNode, LegendMarker, LegendNode, cellAlign, DataTableNode, voiceNoteState, voiceNoteDelivery, VOICE_NOTE_DEFAULT_BARS, clampBarCount, VoiceNoteNode, TimelineNode, WheelPickerNode, ColorPickerNode, FilterChipsNode, TILE_PX, MAX_MERCATOR_LAT, DEFAULT_TILE_MAX_ZOOM, CIRCLE_SEGMENTS, METRES_PER_DEG_LAT, MARKER_HIT_RADIUS, SHAPE_HIT_RADIUS, MapNode, CollapsingHeaderNode, UnsupportedOnSurface, CALENDAR_DATE_ONLY_RE, CAL_DEFAULT_MAX_DOTS, CAL_AGENDA_INITIAL_DAYS, CAL_AGENDA_PAGE_DAYS, CAL_DEFAULT_SNAP_MINUTES, CAL_UNASSIGNED_LANE_ID, MonthCalendarNode, TimeGridNode, AgendaNode, ARIA_ROLE, A11yHintDescription, WebRenderer;
24857
24998
  var init_renderNode = __esm({
24858
24999
  "../../core/web-renderer/src/renderNode.tsx"() {
24859
25000
  "use strict";
@@ -26327,6 +26468,9 @@ var init_renderNode = __esm({
26327
26468
  /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Increase", disabled: disabled("max"), onClick: () => bump(step), style: { ...btn("max"), font: "inherit" }, children: "+" })
26328
26469
  ] });
26329
26470
  });
26471
+ SYNTHETIC_TAP_ROLE = "data-hm-synthetic-role";
26472
+ INFERRED_DECORATIVE = "data-hm-inferred-decorative";
26473
+ ICON_GLYPH = "data-hm-icon-glyph";
26330
26474
  INTERACTIVE_ROLES = /* @__PURE__ */ new Set([
26331
26475
  "button",
26332
26476
  "checkbox",
@@ -26532,7 +26676,10 @@ var init_renderNode = __esm({
26532
26676
  const size = props.size ?? 22;
26533
26677
  const bound = useResolvedScalar(isBinding(props.name) ? props.name : void 0, ctx);
26534
26678
  const iconName = isBinding(props.name) ? String(bound ?? "") : props.name;
26535
- return /* @__PURE__ */ jsx6("span", { title: iconName, style: { display: "inline-grid", placeItems: "center", width: size + 6, height: size + 6, lineHeight: 1, flex: "none", ...wrap }, children: iconSvg(iconName, { size, color: C(resolveScalarStatic(props.tint, ctx) ?? "textPrimary", "#636b78") }) });
26679
+ const contentDescription = useResolvedScalar(props.contentDescription, ctx);
26680
+ const described = contentDescription != null && String(contentDescription).trim() !== "";
26681
+ const a11y = described ? { role: "img", "aria-label": String(contentDescription), [ICON_GLYPH]: true } : { "aria-hidden": "true", [INFERRED_DECORATIVE]: true, [ICON_GLYPH]: true };
26682
+ return /* @__PURE__ */ jsx6("span", { ...a11y, style: { display: "inline-grid", placeItems: "center", width: size + 6, height: size + 6, lineHeight: 1, flex: "none", ...wrap }, children: iconSvg(iconName, { size, color: C(resolveScalarStatic(props.tint, ctx) ?? "textPrimary", "#636b78") }) });
26536
26683
  });
26537
26684
  ButtonNode = withExtras("ButtonNode", ({ props, ctx, wrap }) => {
26538
26685
  const C = ctx.color;
@@ -28185,6 +28332,46 @@ var init_renderNode = __esm({
28185
28332
  )
28186
28333
  ] });
28187
28334
  });
28335
+ ARIA_ROLE = {
28336
+ text: "",
28337
+ // no ARIA role — plain text is already exposed as text
28338
+ heading: "heading",
28339
+ image: "img",
28340
+ button: "button",
28341
+ link: "link",
28342
+ toggle: "switch",
28343
+ checkbox: "checkbox",
28344
+ radio: "radio",
28345
+ tab: "tab",
28346
+ tablist: "tablist",
28347
+ adjustable: "slider",
28348
+ search: "searchbox",
28349
+ textfield: "textbox",
28350
+ combobox: "combobox",
28351
+ list: "list",
28352
+ listitem: "listitem",
28353
+ menu: "menu",
28354
+ menuitem: "menuitem",
28355
+ dialog: "dialog",
28356
+ alert: "alert",
28357
+ progressbar: "progressbar",
28358
+ summary: "group",
28359
+ status: "status",
28360
+ group: "group",
28361
+ grid: "grid",
28362
+ gridcell: "gridcell"
28363
+ };
28364
+ A11yHintDescription = ({ hint, idBase, children, ...forwarded }) => {
28365
+ const descId = `${idBase ?? "hm"}__hint${React5.useId()}`;
28366
+ const own2 = children.props;
28367
+ const next = { ...forwarded };
28368
+ if (forwarded.style) next.style = { ...own2.style ?? {}, ...forwarded.style };
28369
+ next["aria-describedby"] = [own2["aria-describedby"], descId].filter(Boolean).join(" ");
28370
+ return /* @__PURE__ */ jsxs3(Fragment3, { children: [
28371
+ React5.cloneElement(children, next),
28372
+ /* @__PURE__ */ jsx6("span", { id: descId, hidden: true, "data-hm-a11y-hint": "", children: hint })
28373
+ ] });
28374
+ };
28188
28375
  WebRenderer = ({ node, tokens, scheme = "light", opts }) => {
28189
28376
  return /* @__PURE__ */ jsx6(Fragment3, { children: renderNode(node, makeCtx(tokens, scheme, opts)) });
28190
28377
  };
@@ -45119,19 +45306,19 @@ var init_preview_assets_generated = __esm({
45119
45306
  "../../packages/serve/src/preview-assets.generated.ts"() {
45120
45307
  init_preview_assets_format();
45121
45308
  PREVIEW_ASSET_MANIFEST = [
45122
- { key: "assets/index-DDTP2AZP.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1006262, sha256: "a58db7c122941f1b116a9f14d311e8a7215b9f2cfa89aed7c948c894613753d9" },
45123
- { key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1006270, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
45124
- { key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1097194, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
45125
- { key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1188178, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
45126
- { key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1279158, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
45127
- { key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1370030, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
45128
- { key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 1461010, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
45129
- { key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 1569646, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
45130
- { key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 1678730, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
45131
- { key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 1787778, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
45132
- { key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 1895478, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
45133
- { key: "index.html", contentType: "text/html; charset=utf-8", offset: 1983586, length: 4448, sha256: "65ea76642aa529b3a8f3826561ee9627fe9cde9d249abc1bba3e6a9b462ac25c" },
45134
- { key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 1988034, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
45309
+ { key: "assets/index-H72XVDeZ.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1009153, sha256: "494ebf398dfe5604666d1699bc6209b584a78a6a85d33a55553eca57124fe04c" },
45310
+ { key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1009161, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
45311
+ { key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1100085, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
45312
+ { key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1191069, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
45313
+ { key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1282049, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
45314
+ { key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1372921, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
45315
+ { key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 1463901, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
45316
+ { key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 1572537, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
45317
+ { key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 1681621, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
45318
+ { key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 1790669, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
45319
+ { key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 1898369, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
45320
+ { key: "index.html", contentType: "text/html; charset=utf-8", offset: 1986477, length: 4448, sha256: "375c26618baf6332437220049558fe0694b614fa92018d237a5c5c22ee5b3bde" },
45321
+ { key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 1990925, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
45135
45322
  ];
45136
45323
  }
45137
45324
  });
Binary file