@foxpixel/react 0.2.2 → 0.2.3
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 +30 -5
- package/dist/index.d.ts +30 -5
- package/dist/index.js +113 -83
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +113 -83
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -124,7 +124,8 @@ function FoxPixelProvider({ children, config = {}, queryClient }) {
|
|
|
124
124
|
const value = useMemo(() => ({
|
|
125
125
|
client,
|
|
126
126
|
config,
|
|
127
|
-
queryClient: queryClient ?? null
|
|
127
|
+
queryClient: queryClient ?? null,
|
|
128
|
+
locale: config?.locale
|
|
128
129
|
}), [client, config, queryClient]);
|
|
129
130
|
return /* @__PURE__ */ jsx(FoxPixelContext.Provider, { value, children });
|
|
130
131
|
}
|
|
@@ -399,19 +400,18 @@ function useEditModeMessaging() {
|
|
|
399
400
|
if (!queryClient) return;
|
|
400
401
|
const { type, payload } = event.data || {};
|
|
401
402
|
if (type !== "FOXPIXEL_CONTENT_UPDATED" || !payload?.contentKey) return;
|
|
402
|
-
const { contentKey, newValue } = payload;
|
|
403
|
+
const { contentKey, newValue, locale } = payload;
|
|
404
|
+
const cacheKey2 = locale != null && locale !== "" ? [SITE_CONTENT_QUERY_KEY, contentKey, locale] : [SITE_CONTENT_QUERY_KEY, contentKey];
|
|
403
405
|
if (typeof newValue === "string") {
|
|
404
406
|
queryClient.setQueryData(
|
|
405
|
-
|
|
407
|
+
cacheKey2,
|
|
406
408
|
(prev) => ({
|
|
407
409
|
value: newValue,
|
|
408
410
|
contentType: prev?.contentType ?? "TEXT"
|
|
409
411
|
})
|
|
410
412
|
);
|
|
411
413
|
}
|
|
412
|
-
queryClient.invalidateQueries({
|
|
413
|
-
queryKey: [SITE_CONTENT_QUERY_KEY, contentKey]
|
|
414
|
-
});
|
|
414
|
+
queryClient.invalidateQueries({ queryKey: cacheKey2 });
|
|
415
415
|
};
|
|
416
416
|
window.addEventListener("message", handleMessage);
|
|
417
417
|
return () => window.removeEventListener("message", handleMessage);
|
|
@@ -421,20 +421,19 @@ function useEditModeMessaging() {
|
|
|
421
421
|
function useSendEditRequest() {
|
|
422
422
|
const isEditMode = useEditMode();
|
|
423
423
|
return useCallback2(
|
|
424
|
-
(contentKey, currentValue, contentType = "text", section, description) => {
|
|
424
|
+
(contentKey, currentValue, contentType = "text", section, description, locale) => {
|
|
425
425
|
if (!isEditMode) return;
|
|
426
426
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
427
|
+
const payload = {
|
|
428
|
+
contentKey,
|
|
429
|
+
currentValue,
|
|
430
|
+
contentType,
|
|
431
|
+
section,
|
|
432
|
+
description
|
|
433
|
+
};
|
|
434
|
+
if (locale != null && locale !== "") payload.locale = locale;
|
|
427
435
|
window.parent.postMessage(
|
|
428
|
-
{
|
|
429
|
-
type: "FOXPIXEL_EDIT_CONTENT",
|
|
430
|
-
payload: {
|
|
431
|
-
contentKey,
|
|
432
|
-
currentValue,
|
|
433
|
-
contentType,
|
|
434
|
-
section,
|
|
435
|
-
description
|
|
436
|
-
}
|
|
437
|
-
},
|
|
436
|
+
{ type: "FOXPIXEL_EDIT_CONTENT", payload },
|
|
438
437
|
"*"
|
|
439
438
|
);
|
|
440
439
|
}
|
|
@@ -445,20 +444,23 @@ function useSendEditRequest() {
|
|
|
445
444
|
|
|
446
445
|
// src/hooks/useSiteContentQuery.ts
|
|
447
446
|
import { useState as useState6, useEffect as useEffect6, useRef } from "react";
|
|
448
|
-
function
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
447
|
+
function queryKey(contentKey, locale) {
|
|
448
|
+
return locale != null && locale !== "" ? [SITE_CONTENT_QUERY_KEY, contentKey, locale] : [SITE_CONTENT_QUERY_KEY, contentKey];
|
|
449
|
+
}
|
|
450
|
+
function getCached(queryClient, contentKey, locale) {
|
|
451
|
+
const data = queryClient.getQueryData(
|
|
452
|
+
queryKey(contentKey, locale)
|
|
453
|
+
);
|
|
453
454
|
if (data == null) return void 0;
|
|
454
455
|
return { value: data.value ?? "", contentType: data.contentType ?? "TEXT" };
|
|
455
456
|
}
|
|
456
457
|
function useSiteContentQuery(contentKey, options) {
|
|
457
|
-
const { defaultValue } = options;
|
|
458
|
+
const { defaultValue, locale } = options;
|
|
459
|
+
const loc = locale != null && locale !== "" ? locale : void 0;
|
|
458
460
|
const { client, queryClient } = useFoxPixelContext();
|
|
459
461
|
const [state, setState] = useState6(() => {
|
|
460
462
|
if (queryClient) {
|
|
461
|
-
const cached = getCached(queryClient, contentKey);
|
|
463
|
+
const cached = getCached(queryClient, contentKey, loc);
|
|
462
464
|
if (cached) {
|
|
463
465
|
return { value: cached.value, isLoading: false, contentType: cached.contentType };
|
|
464
466
|
}
|
|
@@ -467,18 +469,20 @@ function useSiteContentQuery(contentKey, options) {
|
|
|
467
469
|
});
|
|
468
470
|
const contentKeyRef = useRef(contentKey);
|
|
469
471
|
contentKeyRef.current = contentKey;
|
|
472
|
+
const localeRef = useRef(loc);
|
|
473
|
+
localeRef.current = loc;
|
|
470
474
|
useEffect6(() => {
|
|
471
475
|
if (!queryClient) {
|
|
472
476
|
setState((s) => ({ ...s, value: defaultValue, isLoading: false }));
|
|
473
477
|
return;
|
|
474
478
|
}
|
|
475
479
|
const key = contentKeyRef.current;
|
|
476
|
-
const
|
|
480
|
+
const locCurrent = localeRef.current;
|
|
481
|
+
const qKey = queryKey(key, locCurrent);
|
|
477
482
|
const queryFn = async () => {
|
|
478
483
|
try {
|
|
479
|
-
const
|
|
480
|
-
|
|
481
|
-
);
|
|
484
|
+
const url = `/api/site/content/${encodeURIComponent(key)}` + (locCurrent ? `?locale=${encodeURIComponent(locCurrent)}` : "");
|
|
485
|
+
const content = await client.get(url);
|
|
482
486
|
if (!content) return null;
|
|
483
487
|
return {
|
|
484
488
|
value: content.value ?? "",
|
|
@@ -492,7 +496,7 @@ function useSiteContentQuery(contentKey, options) {
|
|
|
492
496
|
};
|
|
493
497
|
let cancelled = false;
|
|
494
498
|
queryClient.fetchQuery({
|
|
495
|
-
queryKey,
|
|
499
|
+
queryKey: qKey,
|
|
496
500
|
queryFn,
|
|
497
501
|
staleTime: 1e3 * 60 * 5,
|
|
498
502
|
retry: 1
|
|
@@ -508,8 +512,11 @@ function useSiteContentQuery(contentKey, options) {
|
|
|
508
512
|
setState((s) => ({ ...s, value: defaultValue, isLoading: false }));
|
|
509
513
|
});
|
|
510
514
|
const unsub = queryClient.getQueryCache().subscribe((event) => {
|
|
511
|
-
|
|
512
|
-
|
|
515
|
+
const q = event?.query;
|
|
516
|
+
const keyMatch = q?.queryKey?.[1] === key;
|
|
517
|
+
const locMatch = (q?.queryKey?.[2] ?? void 0) === locCurrent;
|
|
518
|
+
if (event?.type === "updated" && q && keyMatch && locMatch) {
|
|
519
|
+
const cached = getCached(queryClient, key, locCurrent);
|
|
513
520
|
if (cached && !cancelled) {
|
|
514
521
|
setState({
|
|
515
522
|
value: cached.value,
|
|
@@ -523,7 +530,7 @@ function useSiteContentQuery(contentKey, options) {
|
|
|
523
530
|
cancelled = true;
|
|
524
531
|
unsub();
|
|
525
532
|
};
|
|
526
|
-
}, [queryClient, contentKey, defaultValue, client]);
|
|
533
|
+
}, [queryClient, contentKey, defaultValue, client, loc]);
|
|
527
534
|
return state;
|
|
528
535
|
}
|
|
529
536
|
|
|
@@ -601,13 +608,17 @@ function Editable({
|
|
|
601
608
|
defaultValue,
|
|
602
609
|
as = "span",
|
|
603
610
|
multiline = false,
|
|
604
|
-
className
|
|
611
|
+
className,
|
|
612
|
+
locale: localeProp
|
|
605
613
|
}) {
|
|
606
614
|
const [isHovered, setIsHovered] = useState7(false);
|
|
615
|
+
const { locale: contextLocale } = useFoxPixelContext();
|
|
616
|
+
const locale = localeProp ?? contextLocale;
|
|
607
617
|
const isEditMode = useEditModeMessaging();
|
|
608
618
|
const sendEditRequest = useSendEditRequest();
|
|
609
619
|
const { value, isLoading, contentType } = useSiteContentQuery(contentKey, {
|
|
610
|
-
defaultValue
|
|
620
|
+
defaultValue,
|
|
621
|
+
locale
|
|
611
622
|
});
|
|
612
623
|
const section = contentKey.includes(".") ? contentKey.split(".")[0] : void 0;
|
|
613
624
|
useEffect7(() => {
|
|
@@ -625,11 +636,13 @@ function Editable({
|
|
|
625
636
|
contentKey,
|
|
626
637
|
value,
|
|
627
638
|
contentType?.toLowerCase() || "text",
|
|
628
|
-
section
|
|
639
|
+
section,
|
|
640
|
+
void 0,
|
|
641
|
+
locale
|
|
629
642
|
);
|
|
630
643
|
}
|
|
631
644
|
},
|
|
632
|
-
[isEditMode, contentKey, value, contentType, section, sendEditRequest]
|
|
645
|
+
[isEditMode, contentKey, value, contentType, section, sendEditRequest, locale]
|
|
633
646
|
);
|
|
634
647
|
if (isLoading) {
|
|
635
648
|
return createElement(as, {
|
|
@@ -702,13 +715,17 @@ function EditableHTML({
|
|
|
702
715
|
contentKey,
|
|
703
716
|
defaultValue,
|
|
704
717
|
as = "div",
|
|
705
|
-
className
|
|
718
|
+
className,
|
|
719
|
+
locale: localeProp
|
|
706
720
|
}) {
|
|
707
721
|
const [isHovered, setIsHovered] = useState7(false);
|
|
722
|
+
const { locale: contextLocale } = useFoxPixelContext();
|
|
723
|
+
const locale = localeProp ?? contextLocale;
|
|
708
724
|
const isEditMode = useEditModeMessaging();
|
|
709
725
|
const sendEditRequest = useSendEditRequest();
|
|
710
726
|
const { value, isLoading } = useSiteContentQuery(contentKey, {
|
|
711
|
-
defaultValue
|
|
727
|
+
defaultValue,
|
|
728
|
+
locale
|
|
712
729
|
});
|
|
713
730
|
const section = contentKey.includes(".") ? contentKey.split(".")[0] : void 0;
|
|
714
731
|
useEffect7(() => {
|
|
@@ -722,10 +739,10 @@ function EditableHTML({
|
|
|
722
739
|
if (isEditMode) {
|
|
723
740
|
e.preventDefault();
|
|
724
741
|
e.stopPropagation();
|
|
725
|
-
sendEditRequest(contentKey, value, "html", section);
|
|
742
|
+
sendEditRequest(contentKey, value, "html", section, void 0, locale);
|
|
726
743
|
}
|
|
727
744
|
},
|
|
728
|
-
[isEditMode, contentKey, value, section, sendEditRequest]
|
|
745
|
+
[isEditMode, contentKey, value, section, sendEditRequest, locale]
|
|
729
746
|
);
|
|
730
747
|
if (isLoading) {
|
|
731
748
|
return createElement(as, {
|
|
@@ -774,13 +791,17 @@ function EditableImage({
|
|
|
774
791
|
className,
|
|
775
792
|
width,
|
|
776
793
|
height,
|
|
777
|
-
priority = false
|
|
794
|
+
priority = false,
|
|
795
|
+
locale: localeProp
|
|
778
796
|
}) {
|
|
779
797
|
const [isHovered, setIsHovered] = useState7(false);
|
|
798
|
+
const { locale: contextLocale } = useFoxPixelContext();
|
|
799
|
+
const locale = localeProp ?? contextLocale;
|
|
780
800
|
const isEditMode = useEditModeMessaging();
|
|
781
801
|
const sendEditRequest = useSendEditRequest();
|
|
782
802
|
const { value: src, isLoading } = useSiteContentQuery(contentKey, {
|
|
783
|
-
defaultValue
|
|
803
|
+
defaultValue,
|
|
804
|
+
locale
|
|
784
805
|
});
|
|
785
806
|
const section = contentKey.includes(".") ? contentKey.split(".")[0] : void 0;
|
|
786
807
|
useEffect7(() => {
|
|
@@ -794,10 +815,10 @@ function EditableImage({
|
|
|
794
815
|
if (isEditMode) {
|
|
795
816
|
e.preventDefault();
|
|
796
817
|
e.stopPropagation();
|
|
797
|
-
sendEditRequest(contentKey, src, "image", section);
|
|
818
|
+
sendEditRequest(contentKey, src, "image", section, void 0, locale);
|
|
798
819
|
}
|
|
799
820
|
},
|
|
800
|
-
[isEditMode, contentKey, src, section, sendEditRequest]
|
|
821
|
+
[isEditMode, contentKey, src, section, sendEditRequest, locale]
|
|
801
822
|
);
|
|
802
823
|
if (isLoading) {
|
|
803
824
|
return /* @__PURE__ */ jsx6(
|
|
@@ -943,20 +964,20 @@ function useContactCapture() {
|
|
|
943
964
|
// src/hooks/useSiteContent.ts
|
|
944
965
|
import { useState as useState11, useEffect as useEffect9, useCallback as useCallback4 } from "react";
|
|
945
966
|
function useSiteContent(contentKey, options = {}) {
|
|
946
|
-
const { defaultValue = "", fetchOnMount = true } = options;
|
|
967
|
+
const { defaultValue = "", fetchOnMount = true, locale } = options;
|
|
947
968
|
const { client } = useFoxPixelContext();
|
|
948
969
|
const { user, hasPermission } = useAuth();
|
|
949
970
|
const [data, setData] = useState11(null);
|
|
950
971
|
const [isLoading, setIsLoading] = useState11(fetchOnMount);
|
|
951
972
|
const [error, setError] = useState11(null);
|
|
952
973
|
const canEdit = user !== null && hasPermission("site:content:update");
|
|
974
|
+
const queryLocale = locale != null && locale !== "" ? locale : void 0;
|
|
953
975
|
const fetchContent = useCallback4(async () => {
|
|
954
976
|
try {
|
|
955
977
|
setIsLoading(true);
|
|
956
978
|
setError(null);
|
|
957
|
-
const
|
|
958
|
-
|
|
959
|
-
);
|
|
979
|
+
const url = `/api/site/content/${encodeURIComponent(contentKey)}` + (queryLocale ? `?locale=${encodeURIComponent(queryLocale)}` : "");
|
|
980
|
+
const content = await client.get(url);
|
|
960
981
|
setData(content);
|
|
961
982
|
} catch (err) {
|
|
962
983
|
if (err?.status === 404) {
|
|
@@ -967,20 +988,22 @@ function useSiteContent(contentKey, options = {}) {
|
|
|
967
988
|
} finally {
|
|
968
989
|
setIsLoading(false);
|
|
969
990
|
}
|
|
970
|
-
}, [client, contentKey]);
|
|
991
|
+
}, [client, contentKey, queryLocale]);
|
|
971
992
|
const updateContent = useCallback4(async (newValue) => {
|
|
972
993
|
try {
|
|
973
994
|
setError(null);
|
|
995
|
+
const body = { value: newValue };
|
|
996
|
+
if (queryLocale) body.locale = queryLocale;
|
|
974
997
|
const updated = await client.put(
|
|
975
998
|
`/api/site/content/${encodeURIComponent(contentKey)}`,
|
|
976
|
-
|
|
999
|
+
body
|
|
977
1000
|
);
|
|
978
1001
|
setData(updated);
|
|
979
1002
|
} catch (err) {
|
|
980
1003
|
setError(err);
|
|
981
1004
|
throw err;
|
|
982
1005
|
}
|
|
983
|
-
}, [client, contentKey]);
|
|
1006
|
+
}, [client, contentKey, queryLocale]);
|
|
984
1007
|
useEffect9(() => {
|
|
985
1008
|
if (fetchOnMount) {
|
|
986
1009
|
fetchContent();
|
|
@@ -998,11 +1021,12 @@ function useSiteContent(contentKey, options = {}) {
|
|
|
998
1021
|
};
|
|
999
1022
|
}
|
|
1000
1023
|
function useSiteContents(contentKeys, options = {}) {
|
|
1001
|
-
const { defaults = {} } = options;
|
|
1024
|
+
const { defaults = {}, locale } = options;
|
|
1002
1025
|
const { client } = useFoxPixelContext();
|
|
1003
1026
|
const [data, setData] = useState11({});
|
|
1004
1027
|
const [isLoading, setIsLoading] = useState11(true);
|
|
1005
1028
|
const [error, setError] = useState11(null);
|
|
1029
|
+
const body = locale != null && locale !== "" ? { keys: contentKeys, locale } : contentKeys;
|
|
1006
1030
|
const fetchContents = useCallback4(async () => {
|
|
1007
1031
|
if (contentKeys.length === 0) {
|
|
1008
1032
|
setData({});
|
|
@@ -1014,7 +1038,7 @@ function useSiteContents(contentKeys, options = {}) {
|
|
|
1014
1038
|
setError(null);
|
|
1015
1039
|
const contents = await client.post(
|
|
1016
1040
|
"/api/site/content/batch",
|
|
1017
|
-
|
|
1041
|
+
body
|
|
1018
1042
|
);
|
|
1019
1043
|
setData(contents);
|
|
1020
1044
|
} catch (err) {
|
|
@@ -1022,7 +1046,7 @@ function useSiteContents(contentKeys, options = {}) {
|
|
|
1022
1046
|
} finally {
|
|
1023
1047
|
setIsLoading(false);
|
|
1024
1048
|
}
|
|
1025
|
-
}, [client, contentKeys.join(",")]);
|
|
1049
|
+
}, [client, contentKeys.join(","), locale]);
|
|
1026
1050
|
useEffect9(() => {
|
|
1027
1051
|
fetchContents();
|
|
1028
1052
|
}, [fetchContents]);
|
|
@@ -1041,25 +1065,25 @@ function useSiteContents(contentKeys, options = {}) {
|
|
|
1041
1065
|
refetch: fetchContents
|
|
1042
1066
|
};
|
|
1043
1067
|
}
|
|
1044
|
-
function useSiteContentSection(section) {
|
|
1068
|
+
function useSiteContentSection(section, options = {}) {
|
|
1069
|
+
const { locale } = options;
|
|
1045
1070
|
const { client } = useFoxPixelContext();
|
|
1046
1071
|
const [contents, setContents] = useState11([]);
|
|
1047
1072
|
const [isLoading, setIsLoading] = useState11(true);
|
|
1048
1073
|
const [error, setError] = useState11(null);
|
|
1074
|
+
const url = `/api/site/content/section/${encodeURIComponent(section)}` + (locale != null && locale !== "" ? `?locale=${encodeURIComponent(locale)}` : "");
|
|
1049
1075
|
const fetchContents = useCallback4(async () => {
|
|
1050
1076
|
try {
|
|
1051
1077
|
setIsLoading(true);
|
|
1052
1078
|
setError(null);
|
|
1053
|
-
const data = await client.get(
|
|
1054
|
-
`/api/site/content/section/${encodeURIComponent(section)}`
|
|
1055
|
-
);
|
|
1079
|
+
const data = await client.get(url);
|
|
1056
1080
|
setContents(data);
|
|
1057
1081
|
} catch (err) {
|
|
1058
1082
|
setError(err);
|
|
1059
1083
|
} finally {
|
|
1060
1084
|
setIsLoading(false);
|
|
1061
1085
|
}
|
|
1062
|
-
}, [client, section]);
|
|
1086
|
+
}, [client, section, locale]);
|
|
1063
1087
|
useEffect9(() => {
|
|
1064
1088
|
fetchContents();
|
|
1065
1089
|
}, [fetchContents]);
|
|
@@ -1072,33 +1096,39 @@ function useSiteContentSection(section) {
|
|
|
1072
1096
|
}
|
|
1073
1097
|
|
|
1074
1098
|
// src/prefetchSiteContent.ts
|
|
1099
|
+
function cacheKey(contentKey, locale) {
|
|
1100
|
+
return locale != null && locale !== "" ? [SITE_CONTENT_QUERY_KEY, contentKey, locale] : [SITE_CONTENT_QUERY_KEY, contentKey];
|
|
1101
|
+
}
|
|
1075
1102
|
async function prefetchSiteContent(queryClient, options) {
|
|
1076
|
-
const { apiUrl, apiKey, tenantId, contentKeys } = options;
|
|
1103
|
+
const { apiUrl, apiKey, tenantId, contentKeys, locale } = options;
|
|
1077
1104
|
const client = new FoxPixelHttpClient({ apiUrl, apiKey, tenantId });
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
)
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1105
|
+
const locales = locale == null ? [void 0] : Array.isArray(locale) ? locale : [locale];
|
|
1106
|
+
const tasks = [];
|
|
1107
|
+
for (const contentKey of contentKeys) {
|
|
1108
|
+
for (const loc of locales) {
|
|
1109
|
+
tasks.push(
|
|
1110
|
+
(async () => {
|
|
1111
|
+
try {
|
|
1112
|
+
const url = `/api/site/content/${encodeURIComponent(contentKey)}` + (loc != null && loc !== "" ? `?locale=${encodeURIComponent(loc)}` : "");
|
|
1113
|
+
const content = await client.get(url);
|
|
1114
|
+
queryClient.setQueryData(cacheKey(contentKey, loc), {
|
|
1115
|
+
value: content?.value ?? "",
|
|
1116
|
+
contentType: content?.contentType ?? "TEXT"
|
|
1117
|
+
});
|
|
1118
|
+
} catch (err) {
|
|
1119
|
+
const status = err?.response?.status;
|
|
1120
|
+
if (status === 404) {
|
|
1121
|
+
queryClient.setQueryData(cacheKey(contentKey, loc), {
|
|
1122
|
+
value: "",
|
|
1123
|
+
contentType: "TEXT"
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1089
1126
|
}
|
|
1090
|
-
)
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
value: "",
|
|
1096
|
-
contentType: "TEXT"
|
|
1097
|
-
});
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
})
|
|
1101
|
-
);
|
|
1127
|
+
})()
|
|
1128
|
+
);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
await Promise.all(tasks);
|
|
1102
1132
|
}
|
|
1103
1133
|
|
|
1104
1134
|
// src/blog/hooks.ts
|