@wallavi/widget 1.2.0 → 1.3.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/index.d.mts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +62 -15
- package/dist/index.mjs +62 -15
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -111,8 +111,16 @@ interface BubbleWidgetProps extends ChatWidgetConfig {
|
|
|
111
111
|
bubbleSize?: number;
|
|
112
112
|
/** className applied to the chat panel */
|
|
113
113
|
panelClassName?: string;
|
|
114
|
+
/**
|
|
115
|
+
* Auto-fetch the agent's configuration from the Wallavi public API and apply it
|
|
116
|
+
* as defaults (profilePicture, chatIcon, colors, messages, autoOpen, keyboardShortcut…).
|
|
117
|
+
* The client only needs to pass `agentId` — everything else self-configures.
|
|
118
|
+
* Pass `autoConfig={false}` if you are providing all props manually.
|
|
119
|
+
* @default true
|
|
120
|
+
*/
|
|
121
|
+
autoConfig?: boolean;
|
|
114
122
|
}
|
|
115
|
-
declare function BubbleWidget({ position, width, height, expandedWidth, expandedHeight, keyboardShortcut, shortcutKey, autoOpen, bubbleIconUrl, bubbleSize, panelClassName, ...chatProps }: BubbleWidgetProps): react_jsx_runtime.JSX.Element;
|
|
123
|
+
declare function BubbleWidget({ position: positionProp, width, height, expandedWidth, expandedHeight, keyboardShortcut: keyboardShortcutProp, shortcutKey, autoOpen: autoOpenProp, bubbleIconUrl: bubbleIconUrlProp, bubbleSize, panelClassName, autoConfig, ...chatProps }: BubbleWidgetProps): react_jsx_runtime.JSX.Element;
|
|
116
124
|
|
|
117
125
|
declare function ChatWidget({ agentId, workspaceId, agentName, displayName, profilePicture, userMessageColor, initialMessages, suggestedMessages, messagePlaceholder, watermark, watermarkLogoUrl, footer, theme, showThinking, regenerateMessage, persist, onNavigate, hideCloseButton, source, userContext, playgroundOverrides, className, onClose, onReset, }: ChatWidgetProps): react_jsx_runtime.JSX.Element;
|
|
118
126
|
|
package/dist/index.d.ts
CHANGED
|
@@ -111,8 +111,16 @@ interface BubbleWidgetProps extends ChatWidgetConfig {
|
|
|
111
111
|
bubbleSize?: number;
|
|
112
112
|
/** className applied to the chat panel */
|
|
113
113
|
panelClassName?: string;
|
|
114
|
+
/**
|
|
115
|
+
* Auto-fetch the agent's configuration from the Wallavi public API and apply it
|
|
116
|
+
* as defaults (profilePicture, chatIcon, colors, messages, autoOpen, keyboardShortcut…).
|
|
117
|
+
* The client only needs to pass `agentId` — everything else self-configures.
|
|
118
|
+
* Pass `autoConfig={false}` if you are providing all props manually.
|
|
119
|
+
* @default true
|
|
120
|
+
*/
|
|
121
|
+
autoConfig?: boolean;
|
|
114
122
|
}
|
|
115
|
-
declare function BubbleWidget({ position, width, height, expandedWidth, expandedHeight, keyboardShortcut, shortcutKey, autoOpen, bubbleIconUrl, bubbleSize, panelClassName, ...chatProps }: BubbleWidgetProps): react_jsx_runtime.JSX.Element;
|
|
123
|
+
declare function BubbleWidget({ position: positionProp, width, height, expandedWidth, expandedHeight, keyboardShortcut: keyboardShortcutProp, shortcutKey, autoOpen: autoOpenProp, bubbleIconUrl: bubbleIconUrlProp, bubbleSize, panelClassName, autoConfig, ...chatProps }: BubbleWidgetProps): react_jsx_runtime.JSX.Element;
|
|
116
124
|
|
|
117
125
|
declare function ChatWidget({ agentId, workspaceId, agentName, displayName, profilePicture, userMessageColor, initialMessages, suggestedMessages, messagePlaceholder, watermark, watermarkLogoUrl, footer, theme, showThinking, regenerateMessage, persist, onNavigate, hideCloseButton, source, userContext, playgroundOverrides, className, onClose, onReset, }: ChatWidgetProps): react_jsx_runtime.JSX.Element;
|
|
118
126
|
|
package/dist/index.js
CHANGED
|
@@ -710,6 +710,7 @@ function ChatWidget({
|
|
|
710
710
|
);
|
|
711
711
|
}
|
|
712
712
|
var cn4 = (...inputs) => tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
713
|
+
var WALLAVI_API = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_API_URL ?? "https://wallavi-production.up.railway.app" : "https://wallavi-production.up.railway.app";
|
|
713
714
|
function DefaultIcon() {
|
|
714
715
|
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", style: { width: 26, height: 26 }, children: [
|
|
715
716
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "12", fill: "currentColor", opacity: 0.12 }),
|
|
@@ -732,17 +733,18 @@ function MinimizeIcon() {
|
|
|
732
733
|
return /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", style: { width: 12, height: 12 }, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 14h6v6M20 10h-6V4M14 10l7-7M3 21l7-7", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
733
734
|
}
|
|
734
735
|
function BubbleWidget({
|
|
735
|
-
position
|
|
736
|
+
position: positionProp,
|
|
736
737
|
width = 360,
|
|
737
738
|
height = 580,
|
|
738
739
|
expandedWidth = 640,
|
|
739
740
|
expandedHeight = "calc(100vh - 100px)",
|
|
740
|
-
keyboardShortcut = false,
|
|
741
|
+
keyboardShortcut: keyboardShortcutProp = false,
|
|
741
742
|
shortcutKey = "k",
|
|
742
|
-
autoOpen = false,
|
|
743
|
-
bubbleIconUrl,
|
|
743
|
+
autoOpen: autoOpenProp = false,
|
|
744
|
+
bubbleIconUrl: bubbleIconUrlProp,
|
|
744
745
|
bubbleSize = 52,
|
|
745
746
|
panelClassName,
|
|
747
|
+
autoConfig = true,
|
|
746
748
|
// ChatWidgetConfig props
|
|
747
749
|
...chatProps
|
|
748
750
|
}) {
|
|
@@ -750,16 +752,50 @@ function BubbleWidget({
|
|
|
750
752
|
const [expanded, setExpanded] = react.useState(false);
|
|
751
753
|
const panelRef = react.useRef(null);
|
|
752
754
|
const autoOpenedRef = react.useRef(false);
|
|
755
|
+
const [remoteConfig, setRemoteConfig] = react.useState({});
|
|
756
|
+
const [resolvedBubbleIcon, setResolvedBubbleIcon] = react.useState(bubbleIconUrlProp);
|
|
757
|
+
const [resolvedAutoOpen, setResolvedAutoOpen] = react.useState(autoOpenProp);
|
|
758
|
+
const [resolvedKeyboardShortcut, setResolvedKeyboardShortcut] = react.useState(keyboardShortcutProp);
|
|
759
|
+
const [resolvedPosition, setResolvedPosition] = react.useState(positionProp ?? "bottom-right");
|
|
753
760
|
react.useEffect(() => {
|
|
754
|
-
if (!
|
|
755
|
-
|
|
756
|
-
|
|
761
|
+
if (!autoConfig) return;
|
|
762
|
+
fetch(`${WALLAVI_API}/api/public/widget/${chatProps.agentId}`).then((r) => r.json()).then((body) => {
|
|
763
|
+
const cfg = body?.data ?? {};
|
|
764
|
+
const remote = {};
|
|
765
|
+
if (cfg.profilePicture != null) remote.profilePicture = cfg.profilePicture;
|
|
766
|
+
if (cfg.displayName != null) remote.displayName = cfg.displayName;
|
|
767
|
+
if (cfg.theme) remote.theme = cfg.theme;
|
|
768
|
+
if (cfg.userMessageColor) remote.userMessageColor = cfg.userMessageColor;
|
|
769
|
+
if (Array.isArray(cfg.initialMessages) && cfg.initialMessages.length > 0) remote.initialMessages = cfg.initialMessages;
|
|
770
|
+
if (Array.isArray(cfg.suggestedMessages)) remote.suggestedMessages = cfg.suggestedMessages;
|
|
771
|
+
if (cfg.messagePlaceholder != null) remote.messagePlaceholder = cfg.messagePlaceholder;
|
|
772
|
+
if (cfg.watermark != null) remote.watermark = cfg.watermark;
|
|
773
|
+
if (cfg.footer != null) remote.footer = cfg.footer;
|
|
774
|
+
if (cfg.showThinking != null) remote.showThinking = cfg.showThinking;
|
|
775
|
+
if (cfg.regenerateMessage != null) remote.regenerateMessage = cfg.regenerateMessage;
|
|
776
|
+
setRemoteConfig(remote);
|
|
777
|
+
if (!bubbleIconUrlProp) {
|
|
778
|
+
const icon = cfg.chatIcon || cfg.profilePicture;
|
|
779
|
+
if (icon) setResolvedBubbleIcon(icon);
|
|
780
|
+
}
|
|
781
|
+
if (!autoOpenProp && cfg.autoOpen) setResolvedAutoOpen(true);
|
|
782
|
+
if (!keyboardShortcutProp && cfg.keyboardShortcut) setResolvedKeyboardShortcut(true);
|
|
783
|
+
if (!positionProp && cfg.alignChatBubbleButton) {
|
|
784
|
+
setResolvedPosition(cfg.alignChatBubbleButton === "left" ? "bottom-left" : "bottom-right");
|
|
785
|
+
}
|
|
786
|
+
}).catch(() => {
|
|
787
|
+
});
|
|
788
|
+
}, [autoConfig, chatProps.agentId]);
|
|
789
|
+
react.useEffect(() => {
|
|
790
|
+
if (!resolvedAutoOpen || autoOpenedRef.current) return;
|
|
791
|
+
const dismissedUntil = Number(localStorage.getItem("wallavi_bubble_dismissed") ?? 0);
|
|
792
|
+
if (dismissedUntil < Date.now()) {
|
|
757
793
|
autoOpenedRef.current = true;
|
|
758
794
|
setOpen(true);
|
|
759
795
|
}
|
|
760
|
-
}, [
|
|
796
|
+
}, [resolvedAutoOpen]);
|
|
761
797
|
react.useEffect(() => {
|
|
762
|
-
if (!
|
|
798
|
+
if (!resolvedKeyboardShortcut) return;
|
|
763
799
|
const handler = (e) => {
|
|
764
800
|
if ((e.metaKey || e.ctrlKey) && e.key === shortcutKey) {
|
|
765
801
|
e.preventDefault();
|
|
@@ -768,7 +804,7 @@ function BubbleWidget({
|
|
|
768
804
|
};
|
|
769
805
|
window.addEventListener("keydown", handler);
|
|
770
806
|
return () => window.removeEventListener("keydown", handler);
|
|
771
|
-
}, [
|
|
807
|
+
}, [resolvedKeyboardShortcut, shortcutKey]);
|
|
772
808
|
react.useEffect(() => {
|
|
773
809
|
if (!open) return;
|
|
774
810
|
const id = setTimeout(() => {
|
|
@@ -776,12 +812,23 @@ function BubbleWidget({
|
|
|
776
812
|
}, 50);
|
|
777
813
|
return () => clearTimeout(id);
|
|
778
814
|
}, [open]);
|
|
815
|
+
const definedChatProps = Object.fromEntries(
|
|
816
|
+
Object.entries(chatProps).filter(([, v]) => v !== void 0)
|
|
817
|
+
);
|
|
818
|
+
const mergedConfig = {
|
|
819
|
+
...remoteConfig,
|
|
820
|
+
...definedChatProps,
|
|
821
|
+
// Required fields must always come from chatProps
|
|
822
|
+
agentId: chatProps.agentId,
|
|
823
|
+
agentName: chatProps.agentName
|
|
824
|
+
};
|
|
779
825
|
const handleClose = () => {
|
|
780
826
|
setOpen(false);
|
|
781
|
-
|
|
827
|
+
const expires = Date.now() + 24 * 60 * 60 * 1e3;
|
|
828
|
+
localStorage.setItem("wallavi_bubble_dismissed", String(expires));
|
|
782
829
|
};
|
|
783
830
|
const toggleExpanded = () => setExpanded((v) => !v);
|
|
784
|
-
const isLeft =
|
|
831
|
+
const isLeft = resolvedPosition === "bottom-left";
|
|
785
832
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
786
833
|
"div",
|
|
787
834
|
{
|
|
@@ -872,7 +919,7 @@ function BubbleWidget({
|
|
|
872
919
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
873
920
|
ChatWidget,
|
|
874
921
|
{
|
|
875
|
-
...
|
|
922
|
+
...mergedConfig,
|
|
876
923
|
hideCloseButton: true,
|
|
877
924
|
className: cn4("shadow-2xl h-full", panelClassName)
|
|
878
925
|
}
|
|
@@ -902,10 +949,10 @@ function BubbleWidget({
|
|
|
902
949
|
background: open ? "var(--foreground, #19191c)" : "var(--background, #fff)",
|
|
903
950
|
color: open ? "var(--background, #fff)" : "var(--foreground, #19191c)"
|
|
904
951
|
},
|
|
905
|
-
children: open ? /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {}) :
|
|
952
|
+
children: open ? /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {}) : resolvedBubbleIcon ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
906
953
|
"img",
|
|
907
954
|
{
|
|
908
|
-
src:
|
|
955
|
+
src: resolvedBubbleIcon,
|
|
909
956
|
alt: "Open chat",
|
|
910
957
|
style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
|
|
911
958
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -684,6 +684,7 @@ function ChatWidget({
|
|
|
684
684
|
);
|
|
685
685
|
}
|
|
686
686
|
var cn4 = (...inputs) => twMerge(clsx(inputs));
|
|
687
|
+
var WALLAVI_API = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_API_URL ?? "https://wallavi-production.up.railway.app" : "https://wallavi-production.up.railway.app";
|
|
687
688
|
function DefaultIcon() {
|
|
688
689
|
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", style: { width: 26, height: 26 }, children: [
|
|
689
690
|
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "12", fill: "currentColor", opacity: 0.12 }),
|
|
@@ -706,17 +707,18 @@ function MinimizeIcon() {
|
|
|
706
707
|
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", style: { width: 12, height: 12 }, children: /* @__PURE__ */ jsx("path", { d: "M4 14h6v6M20 10h-6V4M14 10l7-7M3 21l7-7", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
707
708
|
}
|
|
708
709
|
function BubbleWidget({
|
|
709
|
-
position
|
|
710
|
+
position: positionProp,
|
|
710
711
|
width = 360,
|
|
711
712
|
height = 580,
|
|
712
713
|
expandedWidth = 640,
|
|
713
714
|
expandedHeight = "calc(100vh - 100px)",
|
|
714
|
-
keyboardShortcut = false,
|
|
715
|
+
keyboardShortcut: keyboardShortcutProp = false,
|
|
715
716
|
shortcutKey = "k",
|
|
716
|
-
autoOpen = false,
|
|
717
|
-
bubbleIconUrl,
|
|
717
|
+
autoOpen: autoOpenProp = false,
|
|
718
|
+
bubbleIconUrl: bubbleIconUrlProp,
|
|
718
719
|
bubbleSize = 52,
|
|
719
720
|
panelClassName,
|
|
721
|
+
autoConfig = true,
|
|
720
722
|
// ChatWidgetConfig props
|
|
721
723
|
...chatProps
|
|
722
724
|
}) {
|
|
@@ -724,16 +726,50 @@ function BubbleWidget({
|
|
|
724
726
|
const [expanded, setExpanded] = useState(false);
|
|
725
727
|
const panelRef = useRef(null);
|
|
726
728
|
const autoOpenedRef = useRef(false);
|
|
729
|
+
const [remoteConfig, setRemoteConfig] = useState({});
|
|
730
|
+
const [resolvedBubbleIcon, setResolvedBubbleIcon] = useState(bubbleIconUrlProp);
|
|
731
|
+
const [resolvedAutoOpen, setResolvedAutoOpen] = useState(autoOpenProp);
|
|
732
|
+
const [resolvedKeyboardShortcut, setResolvedKeyboardShortcut] = useState(keyboardShortcutProp);
|
|
733
|
+
const [resolvedPosition, setResolvedPosition] = useState(positionProp ?? "bottom-right");
|
|
727
734
|
useEffect(() => {
|
|
728
|
-
if (!
|
|
729
|
-
|
|
730
|
-
|
|
735
|
+
if (!autoConfig) return;
|
|
736
|
+
fetch(`${WALLAVI_API}/api/public/widget/${chatProps.agentId}`).then((r) => r.json()).then((body) => {
|
|
737
|
+
const cfg = body?.data ?? {};
|
|
738
|
+
const remote = {};
|
|
739
|
+
if (cfg.profilePicture != null) remote.profilePicture = cfg.profilePicture;
|
|
740
|
+
if (cfg.displayName != null) remote.displayName = cfg.displayName;
|
|
741
|
+
if (cfg.theme) remote.theme = cfg.theme;
|
|
742
|
+
if (cfg.userMessageColor) remote.userMessageColor = cfg.userMessageColor;
|
|
743
|
+
if (Array.isArray(cfg.initialMessages) && cfg.initialMessages.length > 0) remote.initialMessages = cfg.initialMessages;
|
|
744
|
+
if (Array.isArray(cfg.suggestedMessages)) remote.suggestedMessages = cfg.suggestedMessages;
|
|
745
|
+
if (cfg.messagePlaceholder != null) remote.messagePlaceholder = cfg.messagePlaceholder;
|
|
746
|
+
if (cfg.watermark != null) remote.watermark = cfg.watermark;
|
|
747
|
+
if (cfg.footer != null) remote.footer = cfg.footer;
|
|
748
|
+
if (cfg.showThinking != null) remote.showThinking = cfg.showThinking;
|
|
749
|
+
if (cfg.regenerateMessage != null) remote.regenerateMessage = cfg.regenerateMessage;
|
|
750
|
+
setRemoteConfig(remote);
|
|
751
|
+
if (!bubbleIconUrlProp) {
|
|
752
|
+
const icon = cfg.chatIcon || cfg.profilePicture;
|
|
753
|
+
if (icon) setResolvedBubbleIcon(icon);
|
|
754
|
+
}
|
|
755
|
+
if (!autoOpenProp && cfg.autoOpen) setResolvedAutoOpen(true);
|
|
756
|
+
if (!keyboardShortcutProp && cfg.keyboardShortcut) setResolvedKeyboardShortcut(true);
|
|
757
|
+
if (!positionProp && cfg.alignChatBubbleButton) {
|
|
758
|
+
setResolvedPosition(cfg.alignChatBubbleButton === "left" ? "bottom-left" : "bottom-right");
|
|
759
|
+
}
|
|
760
|
+
}).catch(() => {
|
|
761
|
+
});
|
|
762
|
+
}, [autoConfig, chatProps.agentId]);
|
|
763
|
+
useEffect(() => {
|
|
764
|
+
if (!resolvedAutoOpen || autoOpenedRef.current) return;
|
|
765
|
+
const dismissedUntil = Number(localStorage.getItem("wallavi_bubble_dismissed") ?? 0);
|
|
766
|
+
if (dismissedUntil < Date.now()) {
|
|
731
767
|
autoOpenedRef.current = true;
|
|
732
768
|
setOpen(true);
|
|
733
769
|
}
|
|
734
|
-
}, [
|
|
770
|
+
}, [resolvedAutoOpen]);
|
|
735
771
|
useEffect(() => {
|
|
736
|
-
if (!
|
|
772
|
+
if (!resolvedKeyboardShortcut) return;
|
|
737
773
|
const handler = (e) => {
|
|
738
774
|
if ((e.metaKey || e.ctrlKey) && e.key === shortcutKey) {
|
|
739
775
|
e.preventDefault();
|
|
@@ -742,7 +778,7 @@ function BubbleWidget({
|
|
|
742
778
|
};
|
|
743
779
|
window.addEventListener("keydown", handler);
|
|
744
780
|
return () => window.removeEventListener("keydown", handler);
|
|
745
|
-
}, [
|
|
781
|
+
}, [resolvedKeyboardShortcut, shortcutKey]);
|
|
746
782
|
useEffect(() => {
|
|
747
783
|
if (!open) return;
|
|
748
784
|
const id = setTimeout(() => {
|
|
@@ -750,12 +786,23 @@ function BubbleWidget({
|
|
|
750
786
|
}, 50);
|
|
751
787
|
return () => clearTimeout(id);
|
|
752
788
|
}, [open]);
|
|
789
|
+
const definedChatProps = Object.fromEntries(
|
|
790
|
+
Object.entries(chatProps).filter(([, v]) => v !== void 0)
|
|
791
|
+
);
|
|
792
|
+
const mergedConfig = {
|
|
793
|
+
...remoteConfig,
|
|
794
|
+
...definedChatProps,
|
|
795
|
+
// Required fields must always come from chatProps
|
|
796
|
+
agentId: chatProps.agentId,
|
|
797
|
+
agentName: chatProps.agentName
|
|
798
|
+
};
|
|
753
799
|
const handleClose = () => {
|
|
754
800
|
setOpen(false);
|
|
755
|
-
|
|
801
|
+
const expires = Date.now() + 24 * 60 * 60 * 1e3;
|
|
802
|
+
localStorage.setItem("wallavi_bubble_dismissed", String(expires));
|
|
756
803
|
};
|
|
757
804
|
const toggleExpanded = () => setExpanded((v) => !v);
|
|
758
|
-
const isLeft =
|
|
805
|
+
const isLeft = resolvedPosition === "bottom-left";
|
|
759
806
|
return /* @__PURE__ */ jsxs(
|
|
760
807
|
"div",
|
|
761
808
|
{
|
|
@@ -846,7 +893,7 @@ function BubbleWidget({
|
|
|
846
893
|
children: /* @__PURE__ */ jsx(
|
|
847
894
|
ChatWidget,
|
|
848
895
|
{
|
|
849
|
-
...
|
|
896
|
+
...mergedConfig,
|
|
850
897
|
hideCloseButton: true,
|
|
851
898
|
className: cn4("shadow-2xl h-full", panelClassName)
|
|
852
899
|
}
|
|
@@ -876,10 +923,10 @@ function BubbleWidget({
|
|
|
876
923
|
background: open ? "var(--foreground, #19191c)" : "var(--background, #fff)",
|
|
877
924
|
color: open ? "var(--background, #fff)" : "var(--foreground, #19191c)"
|
|
878
925
|
},
|
|
879
|
-
children: open ? /* @__PURE__ */ jsx(CloseIcon, {}) :
|
|
926
|
+
children: open ? /* @__PURE__ */ jsx(CloseIcon, {}) : resolvedBubbleIcon ? /* @__PURE__ */ jsx(
|
|
880
927
|
"img",
|
|
881
928
|
{
|
|
882
|
-
src:
|
|
929
|
+
src: resolvedBubbleIcon,
|
|
883
930
|
alt: "Open chat",
|
|
884
931
|
style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
|
|
885
932
|
}
|