@wix/himalaya-cli 0.1064.0 → 0.1066.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +175 -45
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/wix-site-to-himi-app.md +2 -2
- package/package.json +2 -2
- package/templates/beauty-salon/dev/index.ts +1 -5
- package/templates/beauty-salon/tier5-src/_shared/himi-layouts.ts +8 -6
- package/templates/beauty-salon/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
- package/templates/beauty-salon/tier5-src/himi-branded-lite-home/index.ts +5 -5
- package/templates/branded-lite/dev/index.ts +2 -6
- package/templates/branded-lite/tier5-src/_shared/himi-layouts.ts +8 -6
- package/templates/branded-lite/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
- package/templates/branded-lite/tier5-src/himi-branded-lite-home/index.ts +5 -5
- package/templates/community-club/dev/index.ts +1 -5
- package/templates/community-club/tier5-src/_shared/himi-layouts.ts +8 -6
- package/templates/community-club/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
- package/templates/community-club/tier5-src/himi-branded-lite-home/index.ts +5 -5
- package/templates/events-meetups/dev/index.ts +1 -5
- package/templates/events-meetups/tier5-src/_shared/himi-layouts.ts +8 -6
- package/templates/events-meetups/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
- package/templates/events-meetups/tier5-src/himi-branded-lite-home/index.ts +5 -5
- package/templates/gym-fitness/dev/index.ts +1 -5
- package/templates/gym-fitness/tier5-src/_shared/himi-layouts.ts +8 -6
- package/templates/gym-fitness/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
- package/templates/gym-fitness/tier5-src/himi-branded-lite-home/index.ts +5 -5
- package/templates/nonprofit-cause/dev/index.ts +1 -5
- package/templates/nonprofit-cause/tier5-src/_shared/himi-layouts.ts +8 -6
- package/templates/nonprofit-cause/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
- package/templates/nonprofit-cause/tier5-src/himi-branded-lite-home/index.ts +5 -5
- package/templates/podcast-creator/dev/index.ts +1 -5
- package/templates/podcast-creator/tier5-src/_shared/himi-layouts.ts +8 -6
- package/templates/podcast-creator/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
- package/templates/podcast-creator/tier5-src/himi-branded-lite-home/index.ts +5 -5
- package/templates/portfolio-creative/dev/index.ts +1 -5
- package/templates/portfolio-creative/tier5-src/_shared/himi-layouts.ts +8 -6
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-home/index.ts +5 -5
- package/templates/restaurant/dev/index.ts +1 -5
- package/templates/restaurant/tier5-src/_shared/himi-layouts.ts +8 -6
- package/templates/restaurant/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
- package/templates/restaurant/tier5-src/himi-branded-lite-home/index.ts +5 -5
- package/templates/retail-store/dev/index.ts +2 -6
- package/templates/retail-store/tier5-src/_shared/himi-layouts.ts +8 -6
- package/templates/retail-store/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
- package/templates/retail-store/tier5-src/himi-branded-lite-home/index.ts +5 -5
- package/templates/yoga-studio/dev/index.ts +1 -5
- package/templates/yoga-studio/tier5-src/_shared/himi-layouts.ts +8 -6
- package/templates/yoga-studio/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
- package/templates/yoga-studio/tier5-src/himi-branded-lite-home/index.ts +5 -5
|
@@ -19,11 +19,10 @@ import {
|
|
|
19
19
|
interface State {
|
|
20
20
|
/** The pending accent id (persisted on Apply, re-read by the home worker). */
|
|
21
21
|
pendingAccent: string;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
// NOT per-row `$item.` fields, so each static swatch binds its own flat field.
|
|
22
|
+
// Per-accent swatch colors. backgroundColorPath resolves `$service:` paths but NOT
|
|
23
|
+
// per-row `$item.` fields, so each static swatch binds its own flat field.
|
|
24
|
+
// `accentHex_brand` is "" on purpose: the swatch keeps its own accentPrimary token,
|
|
25
|
+
// which is the brand (see accentColor in _shared/himi-layouts.ts).
|
|
27
26
|
accentHex_brand: string;
|
|
28
27
|
accentHex_amber: string;
|
|
29
28
|
accentHex_terracotta: string;
|
|
@@ -54,7 +53,7 @@ function paramValue(arg: unknown, key: string): string {
|
|
|
54
53
|
return typeof result === "string" ? result : "";
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
function build(pendingAccent: string
|
|
56
|
+
function build(pendingAccent: string): State {
|
|
58
57
|
const flags: Record<string, boolean> = {};
|
|
59
58
|
for (const id of ACCENT_IDS) {
|
|
60
59
|
flags[`selected_${id}`] = id === pendingAccent;
|
|
@@ -63,8 +62,7 @@ function build(pendingAccent: string, brandAccent: string): State {
|
|
|
63
62
|
return {
|
|
64
63
|
...flags,
|
|
65
64
|
pendingAccent,
|
|
66
|
-
|
|
67
|
-
accentHex_brand: brandAccent || ACCENT_META.amber.hex,
|
|
65
|
+
accentHex_brand: "",
|
|
68
66
|
accentHex_amber: ACCENT_META.amber.hex,
|
|
69
67
|
accentHex_terracotta: ACCENT_META.terracotta.hex,
|
|
70
68
|
accentHex_sage: ACCENT_META.sage.hex,
|
|
@@ -84,24 +82,21 @@ const svc = defineService<State, {
|
|
|
84
82
|
apply: (state: State) => State;
|
|
85
83
|
reset: (state: State) => State;
|
|
86
84
|
}>("himiBrandedAppearance", {
|
|
87
|
-
state: build(initialAccent()
|
|
85
|
+
state: build(initialAccent()),
|
|
88
86
|
actions: {
|
|
89
|
-
// onAppear: re-read the persisted accent
|
|
90
|
-
//
|
|
91
|
-
sync: (
|
|
92
|
-
const brandAccent = paramValue(arg, "brandAccent") || state.brandAccent;
|
|
93
|
-
return build(initialAccent(), brandAccent);
|
|
94
|
-
},
|
|
87
|
+
// onAppear: re-read the persisted accent so the swatches reflect reality. An older
|
|
88
|
+
// descriptor may still pass a `brandAccent`; it is not used (the Brand swatch is the token).
|
|
89
|
+
sync: () => build(initialAccent()),
|
|
95
90
|
// Tapping an accent swatch marks it pending (persisted on Apply).
|
|
96
91
|
selectAccent: (state, arg) => {
|
|
97
92
|
const id = paramValue(arg, "id");
|
|
98
93
|
if (!isAccentId(id)) return state;
|
|
99
|
-
return build(id
|
|
94
|
+
return build(id);
|
|
100
95
|
},
|
|
101
96
|
// Apply: persist the accent; the home worker re-reads it on launch.
|
|
102
97
|
apply: (state) => {
|
|
103
98
|
try { storage()?.setItem(ACCENT_KEY, state.pendingAccent); } catch { /* best-effort */ }
|
|
104
|
-
return build(state.pendingAccent
|
|
99
|
+
return build(state.pendingAccent);
|
|
105
100
|
},
|
|
106
101
|
// Reset: clear the override, reverting to the brand accent.
|
|
107
102
|
reset: (state) => {
|
|
@@ -110,7 +105,7 @@ const svc = defineService<State, {
|
|
|
110
105
|
if (store?.removeItem) store.removeItem(ACCENT_KEY);
|
|
111
106
|
else store?.setItem(ACCENT_KEY, "");
|
|
112
107
|
} catch { /* best-effort */ }
|
|
113
|
-
return build(DEFAULT_ACCENT
|
|
108
|
+
return build(DEFAULT_ACCENT);
|
|
114
109
|
},
|
|
115
110
|
},
|
|
116
111
|
});
|
|
@@ -338,11 +338,11 @@ function storedLayout(): string | null {
|
|
|
338
338
|
function storedAccent(): string {
|
|
339
339
|
try { return storage()?.getItem(ACCENT_KEY) ?? ""; } catch { return ""; }
|
|
340
340
|
}
|
|
341
|
-
//
|
|
342
|
-
//
|
|
343
|
-
//
|
|
344
|
-
function resolveAccent(
|
|
345
|
-
return resolveAccentColor(storedAccent()
|
|
341
|
+
// The member's chosen accent (storage), else "" — the surface keeps its accentPrimary token,
|
|
342
|
+
// which is the brand. An older descriptor's `brandAccent` param is ignored: it was a copy of
|
|
343
|
+
// the brand that a hand edit of tokens.json left behind.
|
|
344
|
+
function resolveAccent(_arg?: unknown): string {
|
|
345
|
+
return resolveAccentColor(storedAccent());
|
|
346
346
|
}
|
|
347
347
|
|
|
348
348
|
// onAppear param reader (the himi-branded-lite-cms pattern): the descriptor
|
|
@@ -2016,7 +2016,6 @@ const SCREENS = runtimeSetting({
|
|
|
2016
2016
|
"verticals": "[\"plans\",\"feed\",\"events\",\"blog\",\"podcasts\"]",
|
|
2017
2017
|
"homeModules": "[{\"id\":\"saved\",\"label\":\"Saved on this device\",\"dataSource\":\"device.saved_items\",\"emptyWhen\":[\"noSavedContent\"]},{\"id\":\"section_0\",\"label\":\"Latest episode\",\"dataSource\":\"episodeFirst.section0\",\"emptyWhen\":[\"noLatestPost\"]},{\"id\":\"section_1\",\"label\":\"All episodes\",\"dataSource\":\"episodeFirst.section1\",\"emptyWhen\":[\"noPostCards\"]},{\"id\":\"section_2\",\"label\":\"Discover 3\",\"dataSource\":\"episodeFirst.section2\"},{\"id\":\"section_3\",\"label\":\"Latest activity\",\"dataSource\":\"episodeFirst.section3\"}]",
|
|
2018
2018
|
"ownerDefaultLayout": "episodeFirst",
|
|
2019
|
-
"brandAccent": "#6E4BFF",
|
|
2020
2019
|
"copy": "{\"home.allEpisodesCta\":\"Browse all episodes\",\"home.episodesTitle\":\"All episodes\",\"home.latestEpisodeCaption\":\"Latest episode\",\"home.listenCta\":\"Listen now\",\"home.listenersCaption\":\"Our listeners\",\"home.notesCta\":\"Read the show notes\",\"home.onboardingBody\":\"Catch the latest episode, read the show notes, meet other listeners and support the show — all in one place.\",\"home.supportSubtitle\":\"Join a membership and keep new episodes coming.\",\"home.supportTitle\":\"Support the show\"}"
|
|
2021
2020
|
}
|
|
2022
2021
|
}
|
|
@@ -4458,10 +4457,7 @@ const SCREENS = runtimeSetting({
|
|
|
4458
4457
|
"bottom": 28
|
|
4459
4458
|
},
|
|
4460
4459
|
"onAppear": {
|
|
4461
|
-
"actionId": "tier5.himiBrandedAppearance.sync"
|
|
4462
|
-
"params": {
|
|
4463
|
-
"brandAccent": "#6E4BFF"
|
|
4464
|
-
}
|
|
4460
|
+
"actionId": "tier5.himiBrandedAppearance.sync"
|
|
4465
4461
|
}
|
|
4466
4462
|
}
|
|
4467
4463
|
},
|
|
@@ -134,12 +134,14 @@ export function isAccentId(x: unknown): x is AccentId {
|
|
|
134
134
|
return typeof x === "string" && (ACCENT_IDS as readonly string[]).includes(x);
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
/** Resolve an accent id to
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
137
|
+
/** Resolve an accent id to its curated hex, or "" for `brand` and any unknown value.
|
|
138
|
+
* "" is deliberate: a bound `backgroundColorPath` that resolves empty keeps the surface's
|
|
139
|
+
* own `accentPrimary` token on every renderer, and that token IS the brand — after a
|
|
140
|
+
* `site analyze --apply` and after a hand edit of tokens.json alike. A brand colour copied
|
|
141
|
+
* into the descriptor instead (the old `brandAccent` param) went stale on the second path:
|
|
142
|
+
* the Home pill kept the template's blue after a rebrand. */
|
|
143
|
+
export function accentColor(id: string): string {
|
|
144
|
+
return isAccentId(id) ? ACCENT_META[id].hex : "";
|
|
143
145
|
}
|
|
144
146
|
|
|
145
147
|
/** Content-derived default: booking intent > deep catalog > editorial (blog-forward) > balanced.
|
|
@@ -19,11 +19,10 @@ import {
|
|
|
19
19
|
interface State {
|
|
20
20
|
/** The pending accent id (persisted on Apply, re-read by the home worker). */
|
|
21
21
|
pendingAccent: string;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
// NOT per-row `$item.` fields, so each static swatch binds its own flat field.
|
|
22
|
+
// Per-accent swatch colors. backgroundColorPath resolves `$service:` paths but NOT
|
|
23
|
+
// per-row `$item.` fields, so each static swatch binds its own flat field.
|
|
24
|
+
// `accentHex_brand` is "" on purpose: the swatch keeps its own accentPrimary token,
|
|
25
|
+
// which is the brand (see accentColor in _shared/himi-layouts.ts).
|
|
27
26
|
accentHex_brand: string;
|
|
28
27
|
accentHex_amber: string;
|
|
29
28
|
accentHex_terracotta: string;
|
|
@@ -54,7 +53,7 @@ function paramValue(arg: unknown, key: string): string {
|
|
|
54
53
|
return typeof result === "string" ? result : "";
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
function build(pendingAccent: string
|
|
56
|
+
function build(pendingAccent: string): State {
|
|
58
57
|
const flags: Record<string, boolean> = {};
|
|
59
58
|
for (const id of ACCENT_IDS) {
|
|
60
59
|
flags[`selected_${id}`] = id === pendingAccent;
|
|
@@ -63,8 +62,7 @@ function build(pendingAccent: string, brandAccent: string): State {
|
|
|
63
62
|
return {
|
|
64
63
|
...flags,
|
|
65
64
|
pendingAccent,
|
|
66
|
-
|
|
67
|
-
accentHex_brand: brandAccent || ACCENT_META.amber.hex,
|
|
65
|
+
accentHex_brand: "",
|
|
68
66
|
accentHex_amber: ACCENT_META.amber.hex,
|
|
69
67
|
accentHex_terracotta: ACCENT_META.terracotta.hex,
|
|
70
68
|
accentHex_sage: ACCENT_META.sage.hex,
|
|
@@ -84,24 +82,21 @@ const svc = defineService<State, {
|
|
|
84
82
|
apply: (state: State) => State;
|
|
85
83
|
reset: (state: State) => State;
|
|
86
84
|
}>("himiBrandedAppearance", {
|
|
87
|
-
state: build(initialAccent()
|
|
85
|
+
state: build(initialAccent()),
|
|
88
86
|
actions: {
|
|
89
|
-
// onAppear: re-read the persisted accent
|
|
90
|
-
//
|
|
91
|
-
sync: (
|
|
92
|
-
const brandAccent = paramValue(arg, "brandAccent") || state.brandAccent;
|
|
93
|
-
return build(initialAccent(), brandAccent);
|
|
94
|
-
},
|
|
87
|
+
// onAppear: re-read the persisted accent so the swatches reflect reality. An older
|
|
88
|
+
// descriptor may still pass a `brandAccent`; it is not used (the Brand swatch is the token).
|
|
89
|
+
sync: () => build(initialAccent()),
|
|
95
90
|
// Tapping an accent swatch marks it pending (persisted on Apply).
|
|
96
91
|
selectAccent: (state, arg) => {
|
|
97
92
|
const id = paramValue(arg, "id");
|
|
98
93
|
if (!isAccentId(id)) return state;
|
|
99
|
-
return build(id
|
|
94
|
+
return build(id);
|
|
100
95
|
},
|
|
101
96
|
// Apply: persist the accent; the home worker re-reads it on launch.
|
|
102
97
|
apply: (state) => {
|
|
103
98
|
try { storage()?.setItem(ACCENT_KEY, state.pendingAccent); } catch { /* best-effort */ }
|
|
104
|
-
return build(state.pendingAccent
|
|
99
|
+
return build(state.pendingAccent);
|
|
105
100
|
},
|
|
106
101
|
// Reset: clear the override, reverting to the brand accent.
|
|
107
102
|
reset: (state) => {
|
|
@@ -110,7 +105,7 @@ const svc = defineService<State, {
|
|
|
110
105
|
if (store?.removeItem) store.removeItem(ACCENT_KEY);
|
|
111
106
|
else store?.setItem(ACCENT_KEY, "");
|
|
112
107
|
} catch { /* best-effort */ }
|
|
113
|
-
return build(DEFAULT_ACCENT
|
|
108
|
+
return build(DEFAULT_ACCENT);
|
|
114
109
|
},
|
|
115
110
|
},
|
|
116
111
|
});
|
|
@@ -338,11 +338,11 @@ function storedLayout(): string | null {
|
|
|
338
338
|
function storedAccent(): string {
|
|
339
339
|
try { return storage()?.getItem(ACCENT_KEY) ?? ""; } catch { return ""; }
|
|
340
340
|
}
|
|
341
|
-
//
|
|
342
|
-
//
|
|
343
|
-
//
|
|
344
|
-
function resolveAccent(
|
|
345
|
-
return resolveAccentColor(storedAccent()
|
|
341
|
+
// The member's chosen accent (storage), else "" — the surface keeps its accentPrimary token,
|
|
342
|
+
// which is the brand. An older descriptor's `brandAccent` param is ignored: it was a copy of
|
|
343
|
+
// the brand that a hand edit of tokens.json left behind.
|
|
344
|
+
function resolveAccent(_arg?: unknown): string {
|
|
345
|
+
return resolveAccentColor(storedAccent());
|
|
346
346
|
}
|
|
347
347
|
|
|
348
348
|
// onAppear param reader (the himi-branded-lite-cms pattern): the descriptor
|
|
@@ -1886,7 +1886,6 @@ const SCREENS = runtimeSetting({
|
|
|
1886
1886
|
"verticals": "[\"store\",\"portfolio\",\"events\",\"blog\"]",
|
|
1887
1887
|
"homeModules": "[{\"id\":\"saved\",\"label\":\"Saved on this device\",\"dataSource\":\"device.saved_items\",\"emptyWhen\":[\"noSavedContent\"]},{\"id\":\"section_0\",\"label\":\"Selected work\",\"dataSource\":\"showcaseFirst.section0\",\"emptyWhen\":[\"noPostCards\"]},{\"id\":\"section_1\",\"label\":\"Discover 2\",\"dataSource\":\"showcaseFirst.section1\"},{\"id\":\"section_2\",\"label\":\"Prints & editions\",\"dataSource\":\"showcaseFirst.section2\",\"emptyWhen\":[\"noFeaturedProducts\"]},{\"id\":\"section_3\",\"label\":\"Exhibitions & fairs\",\"dataSource\":\"showcaseFirst.section3\"}]",
|
|
1888
1888
|
"ownerDefaultLayout": "showcaseFirst",
|
|
1889
|
-
"brandAccent": "#B0511F",
|
|
1890
1889
|
"copy": "{\"home.aboutTitle\":\"About the studio\",\"home.contactCta\":\"Get in touch\",\"home.exhibitionsTitle\":\"Exhibitions & fairs\",\"home.onboardingBody\":\"Browse the latest work, pick up a print, and catch the next exhibition — all in one place.\",\"home.printsTitle\":\"Prints & editions\",\"home.viewWorkCta\":\"View all work\",\"home.workSubtitle\":\"The latest pieces, straight from the studio.\",\"home.workTitle\":\"Selected work\"}"
|
|
1891
1890
|
}
|
|
1892
1891
|
}
|
|
@@ -4327,10 +4326,7 @@ const SCREENS = runtimeSetting({
|
|
|
4327
4326
|
"bottom": 28
|
|
4328
4327
|
},
|
|
4329
4328
|
"onAppear": {
|
|
4330
|
-
"actionId": "tier5.himiBrandedAppearance.sync"
|
|
4331
|
-
"params": {
|
|
4332
|
-
"brandAccent": "#B0511F"
|
|
4333
|
-
}
|
|
4329
|
+
"actionId": "tier5.himiBrandedAppearance.sync"
|
|
4334
4330
|
}
|
|
4335
4331
|
}
|
|
4336
4332
|
},
|
|
@@ -134,12 +134,14 @@ export function isAccentId(x: unknown): x is AccentId {
|
|
|
134
134
|
return typeof x === "string" && (ACCENT_IDS as readonly string[]).includes(x);
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
/** Resolve an accent id to
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
137
|
+
/** Resolve an accent id to its curated hex, or "" for `brand` and any unknown value.
|
|
138
|
+
* "" is deliberate: a bound `backgroundColorPath` that resolves empty keeps the surface's
|
|
139
|
+
* own `accentPrimary` token on every renderer, and that token IS the brand — after a
|
|
140
|
+
* `site analyze --apply` and after a hand edit of tokens.json alike. A brand colour copied
|
|
141
|
+
* into the descriptor instead (the old `brandAccent` param) went stale on the second path:
|
|
142
|
+
* the Home pill kept the template's blue after a rebrand. */
|
|
143
|
+
export function accentColor(id: string): string {
|
|
144
|
+
return isAccentId(id) ? ACCENT_META[id].hex : "";
|
|
143
145
|
}
|
|
144
146
|
|
|
145
147
|
/** Content-derived default: booking intent > deep catalog > editorial (blog-forward) > balanced.
|
|
@@ -19,11 +19,10 @@ import {
|
|
|
19
19
|
interface State {
|
|
20
20
|
/** The pending accent id (persisted on Apply, re-read by the home worker). */
|
|
21
21
|
pendingAccent: string;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
// NOT per-row `$item.` fields, so each static swatch binds its own flat field.
|
|
22
|
+
// Per-accent swatch colors. backgroundColorPath resolves `$service:` paths but NOT
|
|
23
|
+
// per-row `$item.` fields, so each static swatch binds its own flat field.
|
|
24
|
+
// `accentHex_brand` is "" on purpose: the swatch keeps its own accentPrimary token,
|
|
25
|
+
// which is the brand (see accentColor in _shared/himi-layouts.ts).
|
|
27
26
|
accentHex_brand: string;
|
|
28
27
|
accentHex_amber: string;
|
|
29
28
|
accentHex_terracotta: string;
|
|
@@ -54,7 +53,7 @@ function paramValue(arg: unknown, key: string): string {
|
|
|
54
53
|
return typeof result === "string" ? result : "";
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
function build(pendingAccent: string
|
|
56
|
+
function build(pendingAccent: string): State {
|
|
58
57
|
const flags: Record<string, boolean> = {};
|
|
59
58
|
for (const id of ACCENT_IDS) {
|
|
60
59
|
flags[`selected_${id}`] = id === pendingAccent;
|
|
@@ -63,8 +62,7 @@ function build(pendingAccent: string, brandAccent: string): State {
|
|
|
63
62
|
return {
|
|
64
63
|
...flags,
|
|
65
64
|
pendingAccent,
|
|
66
|
-
|
|
67
|
-
accentHex_brand: brandAccent || ACCENT_META.amber.hex,
|
|
65
|
+
accentHex_brand: "",
|
|
68
66
|
accentHex_amber: ACCENT_META.amber.hex,
|
|
69
67
|
accentHex_terracotta: ACCENT_META.terracotta.hex,
|
|
70
68
|
accentHex_sage: ACCENT_META.sage.hex,
|
|
@@ -84,24 +82,21 @@ const svc = defineService<State, {
|
|
|
84
82
|
apply: (state: State) => State;
|
|
85
83
|
reset: (state: State) => State;
|
|
86
84
|
}>("himiBrandedAppearance", {
|
|
87
|
-
state: build(initialAccent()
|
|
85
|
+
state: build(initialAccent()),
|
|
88
86
|
actions: {
|
|
89
|
-
// onAppear: re-read the persisted accent
|
|
90
|
-
//
|
|
91
|
-
sync: (
|
|
92
|
-
const brandAccent = paramValue(arg, "brandAccent") || state.brandAccent;
|
|
93
|
-
return build(initialAccent(), brandAccent);
|
|
94
|
-
},
|
|
87
|
+
// onAppear: re-read the persisted accent so the swatches reflect reality. An older
|
|
88
|
+
// descriptor may still pass a `brandAccent`; it is not used (the Brand swatch is the token).
|
|
89
|
+
sync: () => build(initialAccent()),
|
|
95
90
|
// Tapping an accent swatch marks it pending (persisted on Apply).
|
|
96
91
|
selectAccent: (state, arg) => {
|
|
97
92
|
const id = paramValue(arg, "id");
|
|
98
93
|
if (!isAccentId(id)) return state;
|
|
99
|
-
return build(id
|
|
94
|
+
return build(id);
|
|
100
95
|
},
|
|
101
96
|
// Apply: persist the accent; the home worker re-reads it on launch.
|
|
102
97
|
apply: (state) => {
|
|
103
98
|
try { storage()?.setItem(ACCENT_KEY, state.pendingAccent); } catch { /* best-effort */ }
|
|
104
|
-
return build(state.pendingAccent
|
|
99
|
+
return build(state.pendingAccent);
|
|
105
100
|
},
|
|
106
101
|
// Reset: clear the override, reverting to the brand accent.
|
|
107
102
|
reset: (state) => {
|
|
@@ -110,7 +105,7 @@ const svc = defineService<State, {
|
|
|
110
105
|
if (store?.removeItem) store.removeItem(ACCENT_KEY);
|
|
111
106
|
else store?.setItem(ACCENT_KEY, "");
|
|
112
107
|
} catch { /* best-effort */ }
|
|
113
|
-
return build(DEFAULT_ACCENT
|
|
108
|
+
return build(DEFAULT_ACCENT);
|
|
114
109
|
},
|
|
115
110
|
},
|
|
116
111
|
});
|
|
@@ -338,11 +338,11 @@ function storedLayout(): string | null {
|
|
|
338
338
|
function storedAccent(): string {
|
|
339
339
|
try { return storage()?.getItem(ACCENT_KEY) ?? ""; } catch { return ""; }
|
|
340
340
|
}
|
|
341
|
-
//
|
|
342
|
-
//
|
|
343
|
-
//
|
|
344
|
-
function resolveAccent(
|
|
345
|
-
return resolveAccentColor(storedAccent()
|
|
341
|
+
// The member's chosen accent (storage), else "" — the surface keeps its accentPrimary token,
|
|
342
|
+
// which is the brand. An older descriptor's `brandAccent` param is ignored: it was a copy of
|
|
343
|
+
// the brand that a hand edit of tokens.json left behind.
|
|
344
|
+
function resolveAccent(_arg?: unknown): string {
|
|
345
|
+
return resolveAccentColor(storedAccent());
|
|
346
346
|
}
|
|
347
347
|
|
|
348
348
|
// onAppear param reader (the himi-branded-lite-cms pattern): the descriptor
|
|
@@ -1941,7 +1941,6 @@ const SCREENS = runtimeSetting({
|
|
|
1941
1941
|
"verticals": "[\"restaurants\",\"events\",\"blog\"]",
|
|
1942
1942
|
"homeModules": "[{\"id\":\"saved\",\"label\":\"Saved on this device\",\"dataSource\":\"device.saved_items\",\"emptyWhen\":[\"noSavedContent\"]},{\"id\":\"section_0\",\"label\":\"__HIMI_APP_NAME__\",\"dataSource\":\"menuFirst.section0\",\"emptyWhen\":[\"hasDishHeroImage\"]},{\"id\":\"section_1\",\"label\":\"Discover 2\",\"dataSource\":\"menuFirst.section1\",\"emptyWhen\":[\"noMenuCategories\"]},{\"id\":\"section_2\",\"label\":\"Popular dishes\",\"dataSource\":\"menuFirst.section2\",\"emptyWhen\":[\"noPopularDishes\"]},{\"id\":\"section_3\",\"label\":\"Find us\",\"dataSource\":\"menuFirst.section3\"}]",
|
|
1943
1943
|
"ownerDefaultLayout": "menuFirst",
|
|
1944
|
-
"brandAccent": "#B8544A",
|
|
1945
1944
|
"copy": "{\"home.eventsTitle\":\"Wine nights & events\",\"home.findUsTitle\":\"Find us\",\"home.hoursTitle\":\"Opening hours\",\"home.onboardingBody\":\"Browse the menu, reserve a table, and keep up with wine nights and kitchen news — all in one place.\",\"home.popularSubtitle\":\"The plates everyone keeps coming back for.\",\"home.popularTitle\":\"Popular dishes\",\"home.reserveCta\":\"Reserve a table\"}"
|
|
1946
1945
|
}
|
|
1947
1946
|
}
|
|
@@ -4294,10 +4293,7 @@ const SCREENS = runtimeSetting({
|
|
|
4294
4293
|
"bottom": 28
|
|
4295
4294
|
},
|
|
4296
4295
|
"onAppear": {
|
|
4297
|
-
"actionId": "tier5.himiBrandedAppearance.sync"
|
|
4298
|
-
"params": {
|
|
4299
|
-
"brandAccent": "#B8544A"
|
|
4300
|
-
}
|
|
4296
|
+
"actionId": "tier5.himiBrandedAppearance.sync"
|
|
4301
4297
|
}
|
|
4302
4298
|
}
|
|
4303
4299
|
},
|
|
@@ -134,12 +134,14 @@ export function isAccentId(x: unknown): x is AccentId {
|
|
|
134
134
|
return typeof x === "string" && (ACCENT_IDS as readonly string[]).includes(x);
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
/** Resolve an accent id to
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
137
|
+
/** Resolve an accent id to its curated hex, or "" for `brand` and any unknown value.
|
|
138
|
+
* "" is deliberate: a bound `backgroundColorPath` that resolves empty keeps the surface's
|
|
139
|
+
* own `accentPrimary` token on every renderer, and that token IS the brand — after a
|
|
140
|
+
* `site analyze --apply` and after a hand edit of tokens.json alike. A brand colour copied
|
|
141
|
+
* into the descriptor instead (the old `brandAccent` param) went stale on the second path:
|
|
142
|
+
* the Home pill kept the template's blue after a rebrand. */
|
|
143
|
+
export function accentColor(id: string): string {
|
|
144
|
+
return isAccentId(id) ? ACCENT_META[id].hex : "";
|
|
143
145
|
}
|
|
144
146
|
|
|
145
147
|
/** Content-derived default: booking intent > deep catalog > editorial (blog-forward) > balanced.
|
|
@@ -19,11 +19,10 @@ import {
|
|
|
19
19
|
interface State {
|
|
20
20
|
/** The pending accent id (persisted on Apply, re-read by the home worker). */
|
|
21
21
|
pendingAccent: string;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
// NOT per-row `$item.` fields, so each static swatch binds its own flat field.
|
|
22
|
+
// Per-accent swatch colors. backgroundColorPath resolves `$service:` paths but NOT
|
|
23
|
+
// per-row `$item.` fields, so each static swatch binds its own flat field.
|
|
24
|
+
// `accentHex_brand` is "" on purpose: the swatch keeps its own accentPrimary token,
|
|
25
|
+
// which is the brand (see accentColor in _shared/himi-layouts.ts).
|
|
27
26
|
accentHex_brand: string;
|
|
28
27
|
accentHex_amber: string;
|
|
29
28
|
accentHex_terracotta: string;
|
|
@@ -54,7 +53,7 @@ function paramValue(arg: unknown, key: string): string {
|
|
|
54
53
|
return typeof result === "string" ? result : "";
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
function build(pendingAccent: string
|
|
56
|
+
function build(pendingAccent: string): State {
|
|
58
57
|
const flags: Record<string, boolean> = {};
|
|
59
58
|
for (const id of ACCENT_IDS) {
|
|
60
59
|
flags[`selected_${id}`] = id === pendingAccent;
|
|
@@ -63,8 +62,7 @@ function build(pendingAccent: string, brandAccent: string): State {
|
|
|
63
62
|
return {
|
|
64
63
|
...flags,
|
|
65
64
|
pendingAccent,
|
|
66
|
-
|
|
67
|
-
accentHex_brand: brandAccent || ACCENT_META.amber.hex,
|
|
65
|
+
accentHex_brand: "",
|
|
68
66
|
accentHex_amber: ACCENT_META.amber.hex,
|
|
69
67
|
accentHex_terracotta: ACCENT_META.terracotta.hex,
|
|
70
68
|
accentHex_sage: ACCENT_META.sage.hex,
|
|
@@ -84,24 +82,21 @@ const svc = defineService<State, {
|
|
|
84
82
|
apply: (state: State) => State;
|
|
85
83
|
reset: (state: State) => State;
|
|
86
84
|
}>("himiBrandedAppearance", {
|
|
87
|
-
state: build(initialAccent()
|
|
85
|
+
state: build(initialAccent()),
|
|
88
86
|
actions: {
|
|
89
|
-
// onAppear: re-read the persisted accent
|
|
90
|
-
//
|
|
91
|
-
sync: (
|
|
92
|
-
const brandAccent = paramValue(arg, "brandAccent") || state.brandAccent;
|
|
93
|
-
return build(initialAccent(), brandAccent);
|
|
94
|
-
},
|
|
87
|
+
// onAppear: re-read the persisted accent so the swatches reflect reality. An older
|
|
88
|
+
// descriptor may still pass a `brandAccent`; it is not used (the Brand swatch is the token).
|
|
89
|
+
sync: () => build(initialAccent()),
|
|
95
90
|
// Tapping an accent swatch marks it pending (persisted on Apply).
|
|
96
91
|
selectAccent: (state, arg) => {
|
|
97
92
|
const id = paramValue(arg, "id");
|
|
98
93
|
if (!isAccentId(id)) return state;
|
|
99
|
-
return build(id
|
|
94
|
+
return build(id);
|
|
100
95
|
},
|
|
101
96
|
// Apply: persist the accent; the home worker re-reads it on launch.
|
|
102
97
|
apply: (state) => {
|
|
103
98
|
try { storage()?.setItem(ACCENT_KEY, state.pendingAccent); } catch { /* best-effort */ }
|
|
104
|
-
return build(state.pendingAccent
|
|
99
|
+
return build(state.pendingAccent);
|
|
105
100
|
},
|
|
106
101
|
// Reset: clear the override, reverting to the brand accent.
|
|
107
102
|
reset: (state) => {
|
|
@@ -110,7 +105,7 @@ const svc = defineService<State, {
|
|
|
110
105
|
if (store?.removeItem) store.removeItem(ACCENT_KEY);
|
|
111
106
|
else store?.setItem(ACCENT_KEY, "");
|
|
112
107
|
} catch { /* best-effort */ }
|
|
113
|
-
return build(DEFAULT_ACCENT
|
|
108
|
+
return build(DEFAULT_ACCENT);
|
|
114
109
|
},
|
|
115
110
|
},
|
|
116
111
|
});
|
|
@@ -338,11 +338,11 @@ function storedLayout(): string | null {
|
|
|
338
338
|
function storedAccent(): string {
|
|
339
339
|
try { return storage()?.getItem(ACCENT_KEY) ?? ""; } catch { return ""; }
|
|
340
340
|
}
|
|
341
|
-
//
|
|
342
|
-
//
|
|
343
|
-
//
|
|
344
|
-
function resolveAccent(
|
|
345
|
-
return resolveAccentColor(storedAccent()
|
|
341
|
+
// The member's chosen accent (storage), else "" — the surface keeps its accentPrimary token,
|
|
342
|
+
// which is the brand. An older descriptor's `brandAccent` param is ignored: it was a copy of
|
|
343
|
+
// the brand that a hand edit of tokens.json left behind.
|
|
344
|
+
function resolveAccent(_arg?: unknown): string {
|
|
345
|
+
return resolveAccentColor(storedAccent());
|
|
346
346
|
}
|
|
347
347
|
|
|
348
348
|
// onAppear param reader (the himi-branded-lite-cms pattern): the descriptor
|
|
@@ -1419,8 +1419,7 @@ const SCREENS = runtimeSetting({
|
|
|
1419
1419
|
"params": {
|
|
1420
1420
|
"verticals": "[\"store\",\"blog\"]",
|
|
1421
1421
|
"homeModules": "[{\"id\":\"saved\",\"label\":\"Saved on this device\",\"dataSource\":\"device.saved_items\",\"emptyWhen\":[\"noSavedContent\"]},{\"id\":\"section_0\",\"label\":\"Shop the collection\",\"dataSource\":\"storeFirst.section0\"},{\"id\":\"section_1\",\"label\":\"Explore\",\"dataSource\":\"storeFirst.section1\"},{\"id\":\"section_2\",\"label\":\"Shop\",\"dataSource\":\"storeFirst.section2\"}]",
|
|
1422
|
-
"ownerDefaultLayout": "storeFirst"
|
|
1423
|
-
"brandAccent": "#B4552D"
|
|
1422
|
+
"ownerDefaultLayout": "storeFirst"
|
|
1424
1423
|
}
|
|
1425
1424
|
}
|
|
1426
1425
|
}
|
|
@@ -3772,10 +3771,7 @@ const SCREENS = runtimeSetting({
|
|
|
3772
3771
|
"bottom": 28
|
|
3773
3772
|
},
|
|
3774
3773
|
"onAppear": {
|
|
3775
|
-
"actionId": "tier5.himiBrandedAppearance.sync"
|
|
3776
|
-
"params": {
|
|
3777
|
-
"brandAccent": "#B4552D"
|
|
3778
|
-
}
|
|
3774
|
+
"actionId": "tier5.himiBrandedAppearance.sync"
|
|
3779
3775
|
}
|
|
3780
3776
|
}
|
|
3781
3777
|
},
|
|
@@ -134,12 +134,14 @@ export function isAccentId(x: unknown): x is AccentId {
|
|
|
134
134
|
return typeof x === "string" && (ACCENT_IDS as readonly string[]).includes(x);
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
/** Resolve an accent id to
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
137
|
+
/** Resolve an accent id to its curated hex, or "" for `brand` and any unknown value.
|
|
138
|
+
* "" is deliberate: a bound `backgroundColorPath` that resolves empty keeps the surface's
|
|
139
|
+
* own `accentPrimary` token on every renderer, and that token IS the brand — after a
|
|
140
|
+
* `site analyze --apply` and after a hand edit of tokens.json alike. A brand colour copied
|
|
141
|
+
* into the descriptor instead (the old `brandAccent` param) went stale on the second path:
|
|
142
|
+
* the Home pill kept the template's blue after a rebrand. */
|
|
143
|
+
export function accentColor(id: string): string {
|
|
144
|
+
return isAccentId(id) ? ACCENT_META[id].hex : "";
|
|
143
145
|
}
|
|
144
146
|
|
|
145
147
|
/** Content-derived default: booking intent > deep catalog > editorial (blog-forward) > balanced.
|