@wasto/cms-components 1.5.16 → 1.5.18
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/index.d.mts +5 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.js +24 -5
- package/dist/index.mjs +24 -5
- package/package.json +1 -1
- package/src/components/header/Header.tsx +31 -10
package/dist/index.d.mts
CHANGED
|
@@ -95,9 +95,11 @@ type AppHeaderLogoElement = {
|
|
|
95
95
|
id: string;
|
|
96
96
|
type: "logo";
|
|
97
97
|
slot: AppHeaderSlot;
|
|
98
|
-
sourceType: "url" | "media";
|
|
98
|
+
sourceType: "url" | "media" | "bundled";
|
|
99
99
|
url?: string;
|
|
100
100
|
mediaId?: string;
|
|
101
|
+
/** `require(...)` d’un asset embarqué à l’export (ImageSource). */
|
|
102
|
+
module?: number;
|
|
101
103
|
};
|
|
102
104
|
type AppHeaderTitleElement = {
|
|
103
105
|
id: string;
|
|
@@ -141,8 +143,8 @@ type HeaderProps = {
|
|
|
141
143
|
*/
|
|
142
144
|
readonly headerConfig?: AppHeaderConfig | null;
|
|
143
145
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
+
* Padding safe-area top. Défaut `true` (header custom RN = edge-to-edge,
|
|
147
|
+
* il faut l’inset). Passer `false` seulement si le parent inset déjà.
|
|
146
148
|
*/
|
|
147
149
|
readonly safeTop?: boolean;
|
|
148
150
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -95,9 +95,11 @@ type AppHeaderLogoElement = {
|
|
|
95
95
|
id: string;
|
|
96
96
|
type: "logo";
|
|
97
97
|
slot: AppHeaderSlot;
|
|
98
|
-
sourceType: "url" | "media";
|
|
98
|
+
sourceType: "url" | "media" | "bundled";
|
|
99
99
|
url?: string;
|
|
100
100
|
mediaId?: string;
|
|
101
|
+
/** `require(...)` d’un asset embarqué à l’export (ImageSource). */
|
|
102
|
+
module?: number;
|
|
101
103
|
};
|
|
102
104
|
type AppHeaderTitleElement = {
|
|
103
105
|
id: string;
|
|
@@ -141,8 +143,8 @@ type HeaderProps = {
|
|
|
141
143
|
*/
|
|
142
144
|
readonly headerConfig?: AppHeaderConfig | null;
|
|
143
145
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
+
* Padding safe-area top. Défaut `true` (header custom RN = edge-to-edge,
|
|
147
|
+
* il faut l’inset). Passer `false` seulement si le parent inset déjà.
|
|
146
148
|
*/
|
|
147
149
|
readonly safeTop?: boolean;
|
|
148
150
|
};
|
package/dist/index.js
CHANGED
|
@@ -8264,6 +8264,7 @@ var DEFAULT_HEADER_ACTIONS = [
|
|
|
8264
8264
|
}
|
|
8265
8265
|
];
|
|
8266
8266
|
function resolveLogoUri(apiUrl, el) {
|
|
8267
|
+
if (el.sourceType === "bundled") return null;
|
|
8267
8268
|
const url = (el.url || "").trim();
|
|
8268
8269
|
if (url) return url;
|
|
8269
8270
|
if (el.sourceType === "media" || el.mediaId) {
|
|
@@ -8286,6 +8287,17 @@ function HeaderLogo({
|
|
|
8286
8287
|
element
|
|
8287
8288
|
}) {
|
|
8288
8289
|
const { apiUrl } = useWasto();
|
|
8290
|
+
if (element.sourceType === "bundled" && element.module != null) {
|
|
8291
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8292
|
+
import_react_native34.Image,
|
|
8293
|
+
{
|
|
8294
|
+
source: element.module,
|
|
8295
|
+
style: styles29.logo,
|
|
8296
|
+
resizeMode: "contain",
|
|
8297
|
+
accessibilityLabel: "Logo"
|
|
8298
|
+
}
|
|
8299
|
+
);
|
|
8300
|
+
}
|
|
8289
8301
|
const uri = resolveLogoUri(apiUrl, element);
|
|
8290
8302
|
if (!uri) return null;
|
|
8291
8303
|
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(HeaderLogoImage, { uri });
|
|
@@ -8295,8 +8307,10 @@ function CityLogoFallback() {
|
|
|
8295
8307
|
const appData = useOptionalAppData();
|
|
8296
8308
|
const logoMediaId = typeof appData?.city?.logoMediaId === "string" ? appData.city.logoMediaId : null;
|
|
8297
8309
|
const uri = publicMediaUrl(apiUrl, logoMediaId);
|
|
8298
|
-
if (
|
|
8299
|
-
|
|
8310
|
+
if (uri) return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(HeaderLogoImage, { uri });
|
|
8311
|
+
const cityName = typeof appData?.city?.name === "string" ? appData.city.name.trim() : "";
|
|
8312
|
+
if (cityName) return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Title, { text: cityName, level: "1" });
|
|
8313
|
+
return null;
|
|
8300
8314
|
}
|
|
8301
8315
|
function HeaderActionButton({
|
|
8302
8316
|
onPress,
|
|
@@ -8326,10 +8340,11 @@ function Header({
|
|
|
8326
8340
|
const { theme } = useTheme();
|
|
8327
8341
|
const t = resolveTheme(theme);
|
|
8328
8342
|
const themedStyles = createThemedStyles14(theme);
|
|
8329
|
-
const applyTopInset = safeTop ??
|
|
8343
|
+
const applyTopInset = safeTop ?? true;
|
|
8330
8344
|
const topInset = useSafeAreaPadding(applyTopInset ? ["top"] : []);
|
|
8331
8345
|
const { hasUnread } = useAnnouncements();
|
|
8332
8346
|
const { push } = useAppNavigation();
|
|
8347
|
+
const { apiUrl } = useWasto();
|
|
8333
8348
|
const screenTitle = (0, import_react35.useMemo)(
|
|
8334
8349
|
() => options.title ?? route.name,
|
|
8335
8350
|
[options.title, route.name]
|
|
@@ -8340,7 +8355,11 @@ function Header({
|
|
|
8340
8355
|
return raw.filter((el) => el.type !== "title");
|
|
8341
8356
|
}, [headerConfig]);
|
|
8342
8357
|
const hasCustomActions = elements.some((el) => el.type === "action");
|
|
8343
|
-
const
|
|
8358
|
+
const hasResolvableLogo = elements.some((el) => {
|
|
8359
|
+
if (el.type !== "logo") return false;
|
|
8360
|
+
if (el.sourceType === "bundled" && el.module != null) return true;
|
|
8361
|
+
return resolveLogoUri(apiUrl, el) != null;
|
|
8362
|
+
});
|
|
8344
8363
|
const bySlot = (0, import_react35.useMemo)(() => {
|
|
8345
8364
|
const left = [];
|
|
8346
8365
|
const center = [];
|
|
@@ -8463,7 +8482,7 @@ function Header({
|
|
|
8463
8482
|
}
|
|
8464
8483
|
) : null,
|
|
8465
8484
|
bySlot.left.map(renderElement),
|
|
8466
|
-
!
|
|
8485
|
+
!hasResolvableLogo ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(CityLogoFallback, {}) : null
|
|
8467
8486
|
] }),
|
|
8468
8487
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8469
8488
|
import_react_native34.View,
|
package/dist/index.mjs
CHANGED
|
@@ -8342,6 +8342,7 @@ var DEFAULT_HEADER_ACTIONS = [
|
|
|
8342
8342
|
}
|
|
8343
8343
|
];
|
|
8344
8344
|
function resolveLogoUri(apiUrl, el) {
|
|
8345
|
+
if (el.sourceType === "bundled") return null;
|
|
8345
8346
|
const url = (el.url || "").trim();
|
|
8346
8347
|
if (url) return url;
|
|
8347
8348
|
if (el.sourceType === "media" || el.mediaId) {
|
|
@@ -8364,6 +8365,17 @@ function HeaderLogo({
|
|
|
8364
8365
|
element
|
|
8365
8366
|
}) {
|
|
8366
8367
|
const { apiUrl } = useWasto();
|
|
8368
|
+
if (element.sourceType === "bundled" && element.module != null) {
|
|
8369
|
+
return /* @__PURE__ */ jsx41(
|
|
8370
|
+
Image11,
|
|
8371
|
+
{
|
|
8372
|
+
source: element.module,
|
|
8373
|
+
style: styles29.logo,
|
|
8374
|
+
resizeMode: "contain",
|
|
8375
|
+
accessibilityLabel: "Logo"
|
|
8376
|
+
}
|
|
8377
|
+
);
|
|
8378
|
+
}
|
|
8367
8379
|
const uri = resolveLogoUri(apiUrl, element);
|
|
8368
8380
|
if (!uri) return null;
|
|
8369
8381
|
return /* @__PURE__ */ jsx41(HeaderLogoImage, { uri });
|
|
@@ -8373,8 +8385,10 @@ function CityLogoFallback() {
|
|
|
8373
8385
|
const appData = useOptionalAppData();
|
|
8374
8386
|
const logoMediaId = typeof appData?.city?.logoMediaId === "string" ? appData.city.logoMediaId : null;
|
|
8375
8387
|
const uri = publicMediaUrl(apiUrl, logoMediaId);
|
|
8376
|
-
if (
|
|
8377
|
-
|
|
8388
|
+
if (uri) return /* @__PURE__ */ jsx41(HeaderLogoImage, { uri });
|
|
8389
|
+
const cityName = typeof appData?.city?.name === "string" ? appData.city.name.trim() : "";
|
|
8390
|
+
if (cityName) return /* @__PURE__ */ jsx41(Title, { text: cityName, level: "1" });
|
|
8391
|
+
return null;
|
|
8378
8392
|
}
|
|
8379
8393
|
function HeaderActionButton({
|
|
8380
8394
|
onPress,
|
|
@@ -8404,10 +8418,11 @@ function Header({
|
|
|
8404
8418
|
const { theme } = useTheme();
|
|
8405
8419
|
const t = resolveTheme(theme);
|
|
8406
8420
|
const themedStyles = createThemedStyles14(theme);
|
|
8407
|
-
const applyTopInset = safeTop ??
|
|
8421
|
+
const applyTopInset = safeTop ?? true;
|
|
8408
8422
|
const topInset = useSafeAreaPadding(applyTopInset ? ["top"] : []);
|
|
8409
8423
|
const { hasUnread } = useAnnouncements();
|
|
8410
8424
|
const { push } = useAppNavigation();
|
|
8425
|
+
const { apiUrl } = useWasto();
|
|
8411
8426
|
const screenTitle = useMemo20(
|
|
8412
8427
|
() => options.title ?? route.name,
|
|
8413
8428
|
[options.title, route.name]
|
|
@@ -8418,7 +8433,11 @@ function Header({
|
|
|
8418
8433
|
return raw.filter((el) => el.type !== "title");
|
|
8419
8434
|
}, [headerConfig]);
|
|
8420
8435
|
const hasCustomActions = elements.some((el) => el.type === "action");
|
|
8421
|
-
const
|
|
8436
|
+
const hasResolvableLogo = elements.some((el) => {
|
|
8437
|
+
if (el.type !== "logo") return false;
|
|
8438
|
+
if (el.sourceType === "bundled" && el.module != null) return true;
|
|
8439
|
+
return resolveLogoUri(apiUrl, el) != null;
|
|
8440
|
+
});
|
|
8422
8441
|
const bySlot = useMemo20(() => {
|
|
8423
8442
|
const left = [];
|
|
8424
8443
|
const center = [];
|
|
@@ -8541,7 +8560,7 @@ function Header({
|
|
|
8541
8560
|
}
|
|
8542
8561
|
) : null,
|
|
8543
8562
|
bySlot.left.map(renderElement),
|
|
8544
|
-
!
|
|
8563
|
+
!hasResolvableLogo ? /* @__PURE__ */ jsx41(CityLogoFallback, {}) : null
|
|
8545
8564
|
] }),
|
|
8546
8565
|
/* @__PURE__ */ jsx41(
|
|
8547
8566
|
View29,
|
package/package.json
CHANGED
|
@@ -27,9 +27,11 @@ export type AppHeaderLogoElement = {
|
|
|
27
27
|
id: string;
|
|
28
28
|
type: "logo";
|
|
29
29
|
slot: AppHeaderSlot;
|
|
30
|
-
sourceType: "url" | "media";
|
|
30
|
+
sourceType: "url" | "media" | "bundled";
|
|
31
31
|
url?: string;
|
|
32
32
|
mediaId?: string;
|
|
33
|
+
/** `require(...)` d’un asset embarqué à l’export (ImageSource). */
|
|
34
|
+
module?: number;
|
|
33
35
|
};
|
|
34
36
|
|
|
35
37
|
export type AppHeaderTitleElement = {
|
|
@@ -94,8 +96,8 @@ export type HeaderProps = {
|
|
|
94
96
|
*/
|
|
95
97
|
readonly headerConfig?: AppHeaderConfig | null;
|
|
96
98
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
+
* Padding safe-area top. Défaut `true` (header custom RN = edge-to-edge,
|
|
100
|
+
* il faut l’inset). Passer `false` seulement si le parent inset déjà.
|
|
99
101
|
*/
|
|
100
102
|
readonly safeTop?: boolean;
|
|
101
103
|
};
|
|
@@ -104,6 +106,7 @@ function resolveLogoUri(
|
|
|
104
106
|
apiUrl: string,
|
|
105
107
|
el: AppHeaderLogoElement,
|
|
106
108
|
): string | null {
|
|
109
|
+
if (el.sourceType === "bundled") return null;
|
|
107
110
|
const url = (el.url || "").trim();
|
|
108
111
|
if (url) return url;
|
|
109
112
|
// Fallback média (export parfois laisse mediaId si rewrite manqué)
|
|
@@ -130,6 +133,16 @@ function HeaderLogo({
|
|
|
130
133
|
readonly element: AppHeaderLogoElement;
|
|
131
134
|
}): ReactNode {
|
|
132
135
|
const { apiUrl } = useWasto();
|
|
136
|
+
if (element.sourceType === "bundled" && element.module != null) {
|
|
137
|
+
return (
|
|
138
|
+
<Image
|
|
139
|
+
source={element.module}
|
|
140
|
+
style={styles.logo as ImageStyle}
|
|
141
|
+
resizeMode="contain"
|
|
142
|
+
accessibilityLabel="Logo"
|
|
143
|
+
/>
|
|
144
|
+
);
|
|
145
|
+
}
|
|
133
146
|
const uri = resolveLogoUri(apiUrl, element);
|
|
134
147
|
if (!uri) return null;
|
|
135
148
|
return <HeaderLogoImage uri={uri} />;
|
|
@@ -143,8 +156,11 @@ function CityLogoFallback(): ReactNode {
|
|
|
143
156
|
? appData.city.logoMediaId
|
|
144
157
|
: null;
|
|
145
158
|
const uri = publicMediaUrl(apiUrl, logoMediaId);
|
|
146
|
-
if (
|
|
147
|
-
|
|
159
|
+
if (uri) return <HeaderLogoImage uri={uri} />;
|
|
160
|
+
const cityName =
|
|
161
|
+
typeof appData?.city?.name === "string" ? appData.city.name.trim() : "";
|
|
162
|
+
if (cityName) return <Title text={cityName} level="1" />;
|
|
163
|
+
return null;
|
|
148
164
|
}
|
|
149
165
|
|
|
150
166
|
function HeaderActionButton({
|
|
@@ -182,12 +198,12 @@ export function Header({
|
|
|
182
198
|
const { theme } = useTheme();
|
|
183
199
|
const t = resolveTheme(theme);
|
|
184
200
|
const themedStyles = createThemedStyles(theme);
|
|
185
|
-
//
|
|
186
|
-
|
|
187
|
-
const applyTopInset = safeTop ?? overlay;
|
|
201
|
+
// Header custom = plein écran sous le notch → inset requis (Page ne le re-ajoute plus).
|
|
202
|
+
const applyTopInset = safeTop ?? true;
|
|
188
203
|
const topInset = useSafeAreaPadding(applyTopInset ? ["top"] : []);
|
|
189
204
|
const { hasUnread } = useAnnouncements();
|
|
190
205
|
const { push } = useAppNavigation();
|
|
206
|
+
const { apiUrl } = useWasto();
|
|
191
207
|
|
|
192
208
|
const screenTitle = useMemo(
|
|
193
209
|
() => options.title ?? route.name,
|
|
@@ -202,7 +218,12 @@ export function Header({
|
|
|
202
218
|
return raw.filter((el) => el.type !== "title");
|
|
203
219
|
}, [headerConfig]);
|
|
204
220
|
const hasCustomActions = elements.some((el) => el.type === "action");
|
|
205
|
-
|
|
221
|
+
// Logo CMS sans URI / sans module bundlé → fallback ville.
|
|
222
|
+
const hasResolvableLogo = elements.some((el) => {
|
|
223
|
+
if (el.type !== "logo") return false;
|
|
224
|
+
if (el.sourceType === "bundled" && el.module != null) return true;
|
|
225
|
+
return resolveLogoUri(apiUrl, el) != null;
|
|
226
|
+
});
|
|
206
227
|
|
|
207
228
|
const bySlot = useMemo(() => {
|
|
208
229
|
const left: AppHeaderElement[] = [];
|
|
@@ -329,7 +350,7 @@ export function Header({
|
|
|
329
350
|
</HeaderActionButton>
|
|
330
351
|
) : null}
|
|
331
352
|
{bySlot.left.map(renderElement)}
|
|
332
|
-
{!
|
|
353
|
+
{!hasResolvableLogo ? <CityLogoFallback /> : null}
|
|
333
354
|
</View>
|
|
334
355
|
<View
|
|
335
356
|
style={styles.slotCenter}
|