@wix/himalaya-cli 0.1028.0 → 0.1030.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 (89) hide show
  1. package/dist/cli.mjs +146 -36
  2. package/dist/preview-assets.generated.bin +0 -0
  3. package/guides/component-reference.json +0 -7
  4. package/guides/component-reference.md +0 -2
  5. package/package.json +2 -2
  6. package/templates/beauty-salon/dev/index.ts +590 -217
  7. package/templates/beauty-salon/tier5-src/_shared/collection-contract.ts +4 -1
  8. package/templates/beauty-salon/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
  9. package/templates/beauty-salon/tier5-src/himi-store-product/index.ts +36 -5
  10. package/templates/beauty-salon/tier5-src/wix-spaces-app-language/index.ts +4 -2
  11. package/templates/beauty-salon-owner/dev/index.ts +22 -27
  12. package/templates/beauty-salon-owner/tier5-src/_shared/aria-chat.ts +23 -3
  13. package/templates/beauty-salon-owner/tier5-src/_shared/collection-contract.ts +4 -1
  14. package/templates/branded-lite/dev/index.ts +731 -232
  15. package/templates/branded-lite/tier5-src/_shared/collection-contract.ts +4 -1
  16. package/templates/branded-lite/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
  17. package/templates/branded-lite/tier5-src/himi-branded-lite-notifsettings/index.ts +11 -6
  18. package/templates/branded-lite/tier5-src/himi-branded-lite-reviews/index.ts +11 -6
  19. package/templates/branded-lite/tier5-src/himi-store-product/index.ts +36 -5
  20. package/templates/branded-lite/tier5-src/wix-spaces-app-language/index.ts +4 -2
  21. package/templates/community-club/dev/index.ts +451 -204
  22. package/templates/community-club/tier5-src/_shared/collection-contract.ts +4 -1
  23. package/templates/community-club/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
  24. package/templates/community-club/tier5-src/wix-spaces-app-language/index.ts +4 -2
  25. package/templates/community-club-owner/dev/index.ts +22 -27
  26. package/templates/community-club-owner/tier5-src/_shared/aria-chat.ts +23 -3
  27. package/templates/community-club-owner/tier5-src/_shared/collection-contract.ts +4 -1
  28. package/templates/events-meetups/dev/index.ts +451 -204
  29. package/templates/events-meetups/tier5-src/_shared/collection-contract.ts +4 -1
  30. package/templates/events-meetups/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
  31. package/templates/events-meetups/tier5-src/wix-spaces-app-language/index.ts +4 -2
  32. package/templates/events-meetups-owner/dev/index.ts +22 -27
  33. package/templates/events-meetups-owner/tier5-src/_shared/aria-chat.ts +23 -3
  34. package/templates/events-meetups-owner/tier5-src/_shared/collection-contract.ts +4 -1
  35. package/templates/gym-fitness/dev/index.ts +590 -217
  36. package/templates/gym-fitness/tier5-src/_shared/collection-contract.ts +4 -1
  37. package/templates/gym-fitness/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
  38. package/templates/gym-fitness/tier5-src/himi-store-product/index.ts +36 -5
  39. package/templates/gym-fitness/tier5-src/wix-spaces-app-language/index.ts +4 -2
  40. package/templates/gym-fitness-owner/dev/index.ts +22 -27
  41. package/templates/gym-fitness-owner/tier5-src/_shared/aria-chat.ts +23 -3
  42. package/templates/gym-fitness-owner/tier5-src/_shared/collection-contract.ts +4 -1
  43. package/templates/nonprofit-cause/dev/index.ts +451 -204
  44. package/templates/nonprofit-cause/tier5-src/_shared/collection-contract.ts +4 -1
  45. package/templates/nonprofit-cause/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
  46. package/templates/nonprofit-cause/tier5-src/wix-spaces-app-language/index.ts +4 -2
  47. package/templates/nonprofit-cause-owner/dev/index.ts +22 -27
  48. package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-chat.ts +23 -3
  49. package/templates/nonprofit-cause-owner/tier5-src/_shared/collection-contract.ts +4 -1
  50. package/templates/owner-lite/dev/index.ts +22 -27
  51. package/templates/owner-lite/tier5-src/_shared/aria-chat.ts +23 -3
  52. package/templates/owner-lite/tier5-src/_shared/collection-contract.ts +4 -1
  53. package/templates/podcast-creator/dev/index.ts +451 -204
  54. package/templates/podcast-creator/tier5-src/_shared/collection-contract.ts +4 -1
  55. package/templates/podcast-creator/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
  56. package/templates/podcast-creator/tier5-src/wix-spaces-app-language/index.ts +4 -2
  57. package/templates/podcast-creator-owner/dev/index.ts +22 -27
  58. package/templates/podcast-creator-owner/tier5-src/_shared/aria-chat.ts +23 -3
  59. package/templates/podcast-creator-owner/tier5-src/_shared/collection-contract.ts +4 -1
  60. package/templates/portfolio-creative/dev/index.ts +575 -214
  61. package/templates/portfolio-creative/tier5-src/_shared/collection-contract.ts +4 -1
  62. package/templates/portfolio-creative/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
  63. package/templates/portfolio-creative/tier5-src/himi-store-product/index.ts +36 -5
  64. package/templates/portfolio-creative/tier5-src/wix-spaces-app-language/index.ts +4 -2
  65. package/templates/portfolio-creative-owner/dev/index.ts +22 -27
  66. package/templates/portfolio-creative-owner/tier5-src/_shared/aria-chat.ts +23 -3
  67. package/templates/portfolio-creative-owner/tier5-src/_shared/collection-contract.ts +4 -1
  68. package/templates/restaurant/dev/index.ts +451 -204
  69. package/templates/restaurant/tier5-src/_shared/collection-contract.ts +4 -1
  70. package/templates/restaurant/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
  71. package/templates/restaurant/tier5-src/wix-spaces-app-language/index.ts +4 -2
  72. package/templates/restaurant-owner/dev/index.ts +22 -27
  73. package/templates/restaurant-owner/tier5-src/_shared/aria-chat.ts +23 -3
  74. package/templates/restaurant-owner/tier5-src/_shared/collection-contract.ts +4 -1
  75. package/templates/retail-store/dev/index.ts +575 -214
  76. package/templates/retail-store/tier5-src/_shared/collection-contract.ts +4 -1
  77. package/templates/retail-store/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
  78. package/templates/retail-store/tier5-src/himi-store-product/index.ts +36 -5
  79. package/templates/retail-store/tier5-src/wix-spaces-app-language/index.ts +4 -2
  80. package/templates/retail-store-owner/dev/index.ts +22 -27
  81. package/templates/retail-store-owner/tier5-src/_shared/aria-chat.ts +23 -3
  82. package/templates/retail-store-owner/tier5-src/_shared/collection-contract.ts +4 -1
  83. package/templates/yoga-studio/dev/index.ts +466 -205
  84. package/templates/yoga-studio/tier5-src/_shared/collection-contract.ts +4 -1
  85. package/templates/yoga-studio/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
  86. package/templates/yoga-studio/tier5-src/wix-spaces-app-language/index.ts +4 -2
  87. package/templates/yoga-studio-owner/dev/index.ts +22 -27
  88. package/templates/yoga-studio-owner/tier5-src/_shared/aria-chat.ts +23 -3
  89. package/templates/yoga-studio-owner/tier5-src/_shared/collection-contract.ts +4 -1
@@ -14,6 +14,9 @@ export interface CollectionConfig {
14
14
  searchPlaceholder?: string;
15
15
  sortLabels?: { default: string; az: string; za: string };
16
16
  metadata?: string[];
17
+ /** Numeric 0–5 row field rendered as a Rating (accessible "N out of 5") instead of
18
+ * folding a "★★★★☆" glyph string into the metadata line, so screen readers get a value. */
19
+ rating?: string;
17
20
  sectioned?: boolean;
18
21
  view: 'list' | 'grid';
19
22
  backendQuery?: boolean;
@@ -58,7 +61,7 @@ export const COLLECTIONS: Record<string, CollectionConfig> = {
58
61
  himiBrandedCoupons: { rows: 'coupons', title: 'name', subtitle: 'subtitle', view: 'list', primaryVerb: { label: 'Get code' } },
59
62
  himiBrandedNotifications: { rows: 'items', title: 'name', subtitle: 'subtitle', image: 'photo', metadata: ['unreadDot'], view: 'list' },
60
63
  himiBrandedLoyalty: { rows: 'rewards', title: 'name', subtitle: 'description', view: 'grid', primaryVerb: { label: 'Redeem' } },
61
- himiBrandedReviews: { rows: 'reviews', title: 'title', subtitle: 'body', metadata: ['author', 'stars'], view: 'list' },
64
+ himiBrandedReviews: { rows: 'reviews', title: 'title', subtitle: 'body', metadata: ['author'], rating: 'rating', view: 'list' },
62
65
  himiBrandedPortfolio: { rows: 'projects', title: 'title', subtitle: 'subtitle', image: 'image', view: 'grid', gridImageHeight: 180 },
63
66
  himiBrandedInvoices: { rows: 'invoices', title: 'title', subtitle: 'subtitle', view: 'list' },
64
67
  himiBrandedBadges: { rows: 'badges', title: 'name', subtitle: 'description', view: 'grid' },
@@ -1,5 +1,6 @@
1
1
  import { defineService } from "@himalaya/state";
2
2
  import {
3
+ ACCENT_IDS,
3
4
  ACCENT_KEY,
4
5
  ACCENT_META,
5
6
  DEFAULT_ACCENT,
@@ -29,6 +30,10 @@ interface State {
29
30
  accentHex_sage: string;
30
31
  accentHex_plum: string;
31
32
  accentHex_ocean: string;
33
+ // Per-accent selection flags for the radio group (`selected_<id>`) and the
34
+ // check mark on the swatch (`notSelected_<id>`, hiddenWhen hides on TRUE). Flat
35
+ // fields for the same reason as the hex ones: the swatches are static nodes.
36
+ [flag: `selected_${string}` | `notSelected_${string}`]: boolean | string;
32
37
  }
33
38
 
34
39
  interface StorageLike {
@@ -50,7 +55,13 @@ function paramValue(arg: unknown, key: string): string {
50
55
  }
51
56
 
52
57
  function build(pendingAccent: string, brandAccent: string): State {
58
+ const flags: Record<string, boolean> = {};
59
+ for (const id of ACCENT_IDS) {
60
+ flags[`selected_${id}`] = id === pendingAccent;
61
+ flags[`notSelected_${id}`] = id !== pendingAccent;
62
+ }
53
63
  return {
64
+ ...flags,
54
65
  pendingAccent,
55
66
  brandAccent,
56
67
  accentHex_brand: brandAccent || ACCENT_META.amber.hex,
@@ -85,7 +96,7 @@ const svc = defineService<State, {
85
96
  selectAccent: (state, arg) => {
86
97
  const id = paramValue(arg, "id");
87
98
  if (!isAccentId(id)) return state;
88
- return { ...state, pendingAccent: id };
99
+ return build(id, state.brandAccent);
89
100
  },
90
101
  // Apply: persist the accent; the home worker re-reads it on launch.
91
102
  apply: (state) => {
@@ -5,11 +5,12 @@
5
5
  import { defineService } from "@himalaya/state";
6
6
  import { dispatch } from "@himalaya/dispatch";
7
7
 
8
- interface Row { id: string; name: string; subtitle: string }
8
+ /** `selected` drives the row's radio; `subtitle` stays for older descriptors. */
9
+ interface Row { id: string; name: string; subtitle: string; selected: boolean }
9
10
  interface S { status: "ready"; options: Row[] }
10
11
 
11
12
  /** Locales with catalogs (`tools/l10n/catalog.<tag>.json`) + LocaleStore support. */
12
- const LOCALE_OPTIONS: Omit<Row, "subtitle">[] = [
13
+ const LOCALE_OPTIONS: Omit<Row, "subtitle" | "selected">[] = [
13
14
  { id: "en", name: "English" },
14
15
  { id: "es", name: "Español" },
15
16
  { id: "he", name: "עברית" },
@@ -19,6 +20,7 @@ function withSelected(selected: string): Row[] {
19
20
  return LOCALE_OPTIONS.map((o) => ({
20
21
  ...o,
21
22
  subtitle: o.id === selected ? "Selected" : "",
23
+ selected: o.id === selected,
22
24
  }));
23
25
  }
24
26
 
@@ -54823,7 +54823,7 @@ const SCREENS = runtimeSetting({
54823
54823
  "spacing": 3,
54824
54824
  "children": [
54825
54825
  {
54826
- "id": "himi_owner_lite_aria.msg_$item.id.who",
54826
+ "id": "himi_owner_lite_aria.msg_$item.id.content",
54827
54827
  "body": {
54828
54828
  "package": "himalaya",
54829
54829
  "type": "HStack",
@@ -54842,43 +54842,34 @@ const SCREENS = runtimeSetting({
54842
54842
  }
54843
54843
  },
54844
54844
  {
54845
- "id": "",
54845
+ "id": "himi_owner_lite_aria.msg_$item.id.bubble",
54846
54846
  "body": {
54847
54847
  "package": "himalaya",
54848
54848
  "type": "Text",
54849
54849
  "props": {
54850
- "text": "$item.who",
54851
- "style": "footnote",
54852
- "color": "textSecondary",
54853
- "maxLines": 1
54850
+ "text": "$item.content",
54851
+ "style": "body",
54852
+ "maxLines": 50
54854
54853
  }
54855
- }
54856
- }
54857
- ]
54858
- }
54859
- }
54860
- },
54861
- {
54862
- "id": "himi_owner_lite_aria.msg_$item.id.content",
54863
- "body": {
54864
- "package": "himalaya",
54865
- "type": "HStack",
54866
- "props": {
54867
- "spacing": 0,
54868
- "children": [
54869
- {
54870
- "id": "",
54871
- "body": {
54872
- "package": "himalaya",
54873
- "type": "Spacer",
54874
- "props": {}
54875
54854
  },
54876
54855
  "modifiers": {
54856
+ "accessibilityLabel": "$item.spoken",
54857
+ "padding": {
54858
+ "leading": 16,
54859
+ "trailing": 16,
54860
+ "top": 8,
54861
+ "bottom": 8
54862
+ },
54863
+ "background": {
54864
+ "token": "surfaceSecondary"
54865
+ },
54866
+ "cornerRadius": 20,
54867
+ "maxWidth": 300,
54877
54868
  "hiddenPath": "$item.notUser"
54878
54869
  }
54879
54870
  },
54880
54871
  {
54881
- "id": "",
54872
+ "id": "himi_owner_lite_aria.msg_$item.id.text",
54882
54873
  "body": {
54883
54874
  "package": "himalaya",
54884
54875
  "type": "Text",
@@ -54887,6 +54878,10 @@ const SCREENS = runtimeSetting({
54887
54878
  "style": "body",
54888
54879
  "maxLines": 50
54889
54880
  }
54881
+ },
54882
+ "modifiers": {
54883
+ "accessibilityLabel": "$item.spoken",
54884
+ "hiddenPath": "$item.notAria"
54890
54885
  }
54891
54886
  }
54892
54887
  ]
@@ -83,6 +83,11 @@ export interface AriaBubble {
83
83
  * that right-aligns the owner renders two templates and collapses one. */
84
84
  notUser: boolean;
85
85
  notAria: boolean;
86
+ /** What a screen reader says for the row: the author, then the words. A
87
+ * screen that draws the speaker only as a bubble and a side of the screen
88
+ * (`messageStyle: 'userBubble'`) has no visible author line to read, and
89
+ * without this the owner's question and Aria's reply sound the same. */
90
+ spoken: string;
86
91
  link1Label: string; link1Url: string; link1Hidden: boolean;
87
92
  link2Label: string; link2Url: string; link2Hidden: boolean;
88
93
  link3Label: string; link3Url: string; link3Hidden: boolean;
@@ -561,9 +566,23 @@ export function disclosedLabel(link: { label: string; url: string }): string {
561
566
  * machinery dies. (Measured: 20 tests, every one of them about polling.) */
562
567
  export { stripMarkdown };
563
568
 
569
+ /** The screen-reader line for a bubble — see `AriaBubble.spoken`. */
570
+ export function spokenOf(who: string, content: string): string {
571
+ return who ? `${who}: ${content}` : content;
572
+ }
573
+
574
+ /** A persisted transcript from before `spoken` existed, made whole. A `$item.`
575
+ * path missing on a row does not substitute, so a row without the field would
576
+ * announce the literal binding until the next rebuild replaced it. */
577
+ export function withSpoken(bubbles: AriaBubble[]): AriaBubble[] {
578
+ return bubbles.every((b) => typeof b.spoken === "string")
579
+ ? bubbles
580
+ : bubbles.map((b) => (typeof b.spoken === "string" ? b : { ...b, spoken: spokenOf(b.who, b.content) }));
581
+ }
582
+
564
583
  /** A greeting or optimistic bubble: no links, all slots defaulted. */
565
584
  export function plainBubble(id: string, role: string, who: string, content: string): AriaBubble {
566
- return { id, role, who, content, notUser: role !== "USER", notAria: role === "USER", ...linkFieldsOf("", role) };
585
+ return { id, role, who, content, notUser: role !== "USER", notAria: role === "USER", spoken: spokenOf(who, content), ...linkFieldsOf("", role) };
567
586
  }
568
587
 
569
588
  /** Server transcript → bubbles. USER text is literal; ASSISTANT replies are
@@ -644,6 +663,7 @@ function bubbleOf(id: string, role: string, who: string, raw: string, writing: b
644
663
  content,
645
664
  notUser: role !== "USER",
646
665
  notAria: role === "USER",
666
+ spoken: spokenOf(who, content),
647
667
  ...linkFieldsOf(prose, role),
648
668
  };
649
669
  }
@@ -2004,7 +2024,7 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
2004
2024
  // a rehydrated turn there was no ladder at all, leaving "Aria is
2005
2025
  // typing…" on screen with nothing ever fetching the answer.
2006
2026
  if (s._pending || s.status === "sending") {
2007
- const held: AriaChatState = { ...s, status: "sending", prompts: [] };
2027
+ const held: AriaChatState = { ...s, status: "sending", prompts: [], messages: withSpoken(s.messages) };
2008
2028
  return cadence(held, o.poll ? o.poll.fastMs : null, null);
2009
2029
  }
2010
2030
  // …but the self-kick pass runs BEFORE the pack is stashed, so the
@@ -2013,7 +2033,7 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
2013
2033
  // still the only thing on screen — `prompts` is already recomputed
2014
2034
  // here, and a chip pack that localizes beside a greeting that does not
2015
2035
  // is the visible half of the same bug.
2016
- const messages = isGreetingOnly(s.messages) ? greetingOnly() : s.messages;
2036
+ const messages = isGreetingOnly(s.messages) ? greetingOnly() : withSpoken(s.messages);
2017
2037
  return { ...s, status: "ready", messages, prompts: promptsFor(messages, promptList()) };
2018
2038
  }
2019
2039
  try {
@@ -14,6 +14,9 @@ export interface CollectionConfig {
14
14
  searchPlaceholder?: string;
15
15
  sortLabels?: { default: string; az: string; za: string };
16
16
  metadata?: string[];
17
+ /** Numeric 0–5 row field rendered as a Rating (accessible "N out of 5") instead of
18
+ * folding a "★★★★☆" glyph string into the metadata line, so screen readers get a value. */
19
+ rating?: string;
17
20
  sectioned?: boolean;
18
21
  view: 'list' | 'grid';
19
22
  backendQuery?: boolean;
@@ -58,7 +61,7 @@ export const COLLECTIONS: Record<string, CollectionConfig> = {
58
61
  himiBrandedCoupons: { rows: 'coupons', title: 'name', subtitle: 'subtitle', view: 'list', primaryVerb: { label: 'Get code' } },
59
62
  himiBrandedNotifications: { rows: 'items', title: 'name', subtitle: 'subtitle', image: 'photo', metadata: ['unreadDot'], view: 'list' },
60
63
  himiBrandedLoyalty: { rows: 'rewards', title: 'name', subtitle: 'description', view: 'grid', primaryVerb: { label: 'Redeem' } },
61
- himiBrandedReviews: { rows: 'reviews', title: 'title', subtitle: 'body', metadata: ['author', 'stars'], view: 'list' },
64
+ himiBrandedReviews: { rows: 'reviews', title: 'title', subtitle: 'body', metadata: ['author'], rating: 'rating', view: 'list' },
62
65
  himiBrandedPortfolio: { rows: 'projects', title: 'title', subtitle: 'subtitle', image: 'image', view: 'grid', gridImageHeight: 180 },
63
66
  himiBrandedInvoices: { rows: 'invoices', title: 'title', subtitle: 'subtitle', view: 'list' },
64
67
  himiBrandedBadges: { rows: 'badges', title: 'name', subtitle: 'description', view: 'grid' },