@edifice.io/react 2.6.6-develop-b2school.20260924114544 → 2.6.6-develop-b2school.20260924174112

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.
@@ -1,13 +1,14 @@
1
1
  import { jsx, Fragment, jsxs } from "react/jsx-runtime";
2
- import { forwardRef, useState, useRef, useCallback, useImperativeHandle, useLayoutEffect, useEffect } from "react";
2
+ import { forwardRef, useState, useRef, useCallback, useEffect, useImperativeHandle, useLayoutEffect } from "react";
3
3
  import clsx from "clsx";
4
4
  import { useTranslation } from "react-i18next";
5
- import SvgIconAlertCircle from "../../modules/icons/components/IconAlertCircle.js";
5
+ import SvgIconAlertTriangle from "../../modules/icons/components/IconAlertTriangle.js";
6
+ import SvgIconClose from "../../modules/icons/components/IconClose.js";
6
7
  import SvgIconError from "../../modules/icons/components/IconError.js";
7
8
  import SvgIconInfoCircle from "../../modules/icons/components/IconInfoCircle.js";
8
9
  import SvgIconSuccessOutline from "../../modules/icons/components/IconSuccessOutline.js";
9
- import Button from "../Button/Button.js";
10
- const Alert = /* @__PURE__ */ forwardRef(({
10
+ import ButtonBeta from "../ButtonBeta/ButtonBeta.js";
11
+ const TOAST_EXIT_ANIMATION_DURATION = 240, getToastAnimationClass = (position, isClosing) => position === "top-left" || position === "bottom-left" ? isClosing ? "alert-slide-out-left" : "alert-slide-in-left" : position === "top-right" || position === "bottom-right" ? isClosing ? "alert-slide-out-right" : "alert-slide-in-right" : isClosing ? "alert-fade-out" : "alert-fade-in", Alert = /* @__PURE__ */ forwardRef(({
11
12
  type = "success",
12
13
  className = "",
13
14
  children,
@@ -21,31 +22,53 @@ const Alert = /* @__PURE__ */ forwardRef(({
21
22
  onClose,
22
23
  onVisibilityChange
23
24
  }, ref) => {
24
- const [isVisible, setVisibleStatus] = useState(!0), refAlert = useRef(null), {
25
+ const [isVisible, setVisibleStatus] = useState(!0), [isClosing, setIsClosing] = useState(!1), refAlert = useRef(null), {
25
26
  t
26
27
  } = useTranslation(), hide = useCallback(() => {
28
+ if (isToast) {
29
+ setIsClosing(!0);
30
+ return;
31
+ }
27
32
  setVisibleStatus(!1), onClose == null || onClose();
28
- }, [onClose]);
33
+ }, [isToast, onClose]);
34
+ useEffect(() => {
35
+ if (!isClosing)
36
+ return;
37
+ const timeoutId = setTimeout(() => {
38
+ setVisibleStatus(!1), onClose == null || onClose();
39
+ }, TOAST_EXIT_ANIMATION_DURATION);
40
+ return () => clearTimeout(timeoutId);
41
+ }, [isClosing, onClose]);
42
+ const handleToastClick = () => {
43
+ isToast && !isConfirm && hide();
44
+ };
29
45
  useImperativeHandle(ref, () => ({
30
46
  show,
31
47
  hide,
32
48
  ...refAlert.current
33
49
  })), useLayoutEffect(() => {
34
50
  onVisibilityChange == null || onVisibilityChange(isVisible);
35
- }, [isVisible, onVisibilityChange]), useEffect(() => {
36
- autoClose && isVisible && setTimeout(() => {
37
- hide();
38
- }, autoCloseDelay);
39
- }, [autoClose, autoCloseDelay, hide, isVisible]);
40
- const show = () => {
41
- setVisibleStatus(!0);
51
+ }, [isVisible, onVisibilityChange]);
52
+ const shouldAutoClose = autoClose && isVisible && !isClosing, showProgress = autoClose && isToast && !isDismissible && !isClosing, remainingRef = useRef(autoCloseDelay), timeoutRef = useRef(), startedAtRef = useRef(0), [isPaused, setIsPaused] = useState(!1), clearAutoCloseTimeout = useCallback(() => {
53
+ timeoutRef.current && (clearTimeout(timeoutRef.current), timeoutRef.current = void 0);
54
+ }, []);
55
+ useEffect(() => {
56
+ if (shouldAutoClose)
57
+ return remainingRef.current = autoCloseDelay, startedAtRef.current = Date.now(), timeoutRef.current = setTimeout(hide, autoCloseDelay), clearAutoCloseTimeout;
58
+ }, [shouldAutoClose, autoCloseDelay, hide, clearAutoCloseTimeout]);
59
+ const handleMouseEnter = () => {
60
+ !shouldAutoClose || isPaused || (clearAutoCloseTimeout(), remainingRef.current = Math.max(remainingRef.current - (Date.now() - startedAtRef.current), 0), setIsPaused(!0));
61
+ }, handleMouseLeave = () => {
62
+ !shouldAutoClose || !isPaused || (startedAtRef.current = Date.now(), timeoutRef.current = setTimeout(hide, remainingRef.current), setIsPaused(!1));
63
+ }, show = () => {
64
+ setIsClosing(!1), setVisibleStatus(!0);
42
65
  }, mapping = {
43
66
  success: {
44
67
  icon: /* @__PURE__ */ jsx(SvgIconSuccessOutline, {}),
45
68
  classModifier: "alert-success"
46
69
  },
47
70
  warning: {
48
- icon: /* @__PURE__ */ jsx(SvgIconAlertCircle, {}),
71
+ icon: /* @__PURE__ */ jsx(SvgIconAlertTriangle, {}),
49
72
  classModifier: "alert-warning"
50
73
  },
51
74
  info: {
@@ -58,21 +81,22 @@ const Alert = /* @__PURE__ */ forwardRef(({
58
81
  }
59
82
  }, toastClasses = {
60
83
  "is-dismissible": isDismissible,
61
- "is-toast ": isToast
84
+ "is-toast": isToast
62
85
  }, confirmClasses = {
63
86
  "is-confirm": isConfirm
64
- }, divContainerClasses = clsx("alert gap-12", mapping[type].classModifier, toastClasses, confirmClasses, position, className);
65
- return /* @__PURE__ */ jsx(Fragment, { children: isVisible ? /* @__PURE__ */ jsxs("div", { ref: refAlert, className: divContainerClasses, role: "alert", children: [
87
+ }, divContainerClasses = clsx("alert gap-12", mapping[type].classModifier, toastClasses, confirmClasses, position, isToast && getToastAnimationClass(position, isClosing), className);
88
+ return /* @__PURE__ */ jsx(Fragment, { children: isVisible ? /* @__PURE__ */ jsxs("div", { ref: refAlert, className: divContainerClasses, role: "alert", onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onClick: handleToastClick, children: [
66
89
  !isConfirm && mapping[type].icon,
67
90
  /* @__PURE__ */ jsx("div", { className: "alert-content small flex-grow-1", children }),
68
- button && /* @__PURE__ */ jsxs("div", { className: "ms-12", children: [
91
+ button && /* @__PURE__ */ jsxs("div", { className: "alert-actions", onClick: (e) => e.stopPropagation(), children: [
69
92
  button,
70
- " ",
71
- isConfirm && /* @__PURE__ */ jsx(Button, { onClick: hide, children: t("close") })
93
+ isConfirm && /* @__PURE__ */ jsx(ButtonBeta, { onClick: hide, children: t("close") })
72
94
  ] }),
73
- (isDismissible || isConfirm) && /* @__PURE__ */ jsx("div", { className: "btn-close-container", children: /* @__PURE__ */ jsx("button", { type: "button", className: "btn-close", "data-bs-dismiss": "alert", "aria-label": t("close"), onClick: hide }) }),
74
- autoClose && /* @__PURE__ */ jsx("div", { className: "alert-progress", style: {
75
- transform: "scaleX(0)"
95
+ (isDismissible || isConfirm) && /* @__PURE__ */ jsx("div", { className: "btn-close-container", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx(ButtonBeta, { type: "button", leftIcon: /* @__PURE__ */ jsx(SvgIconClose, {}), variant: "ghost", color: "tertiary", "aria-label": t("close"), title: t("close"), onClick: hide }) }),
96
+ showProgress && /* @__PURE__ */ jsx("div", { className: clsx("alert-progress", {
97
+ "is-paused": isPaused
98
+ }), style: {
99
+ "--alert-progress-duration": `${autoCloseDelay}ms`
76
100
  } })
77
101
  ] }) : null });
78
102
  });
@@ -1,7 +1,6 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Suspense, lazy } from "react";
3
3
  import clsx from "clsx";
4
- import { Toaster } from "react-hot-toast";
5
4
  import { useTranslation } from "react-i18next";
6
5
  import { useEdificeTheme } from "../../providers/EdificeThemeProvider/EdificeThemeProvider.hook.js";
7
6
  import { useOverlay } from "../PageLayout/hook/useOverlay.js";
@@ -9,11 +8,12 @@ import Header from "./components/Header.js";
9
8
  import HeaderNotificationsOverlay from "./components/HeaderNotificationsOverlay.js";
10
9
  import useUiOverride from "../../hooks/useUiOverride/useUiOverride.js";
11
10
  import useBackground from "../../hooks/useBackground/useBackground.js";
11
+ import useToast from "../../hooks/useToast/useToast.js";
12
12
  import useCookiesConsent from "../../hooks/useCookiesConsent/useCookiesConsent.js";
13
13
  import useZendeskGuide from "../../hooks/useZendeskGuide/useZendeskGuide.js";
14
14
  import useCantoo from "../../hooks/useCantoo/useCantoo.js";
15
15
  import Alert from "../Alert/Alert.js";
16
- import Button from "../Button/Button.js";
16
+ import ButtonBeta from "../ButtonBeta/ButtonBeta.js";
17
17
  const HeaderV2 = /* @__PURE__ */ lazy(() => import("../../modules/homepage/components/Header/Header.js")), Layout = ({
18
18
  children,
19
19
  headless = !1,
@@ -29,7 +29,7 @@ const HeaderV2 = /* @__PURE__ */ lazy(() => import("../../modules/homepage/compo
29
29
  isBackgroundImageOverridden
30
30
  } = useBackground(), {
31
31
  toggleOverlay
32
- } = useOverlay(), {
32
+ } = useOverlay(), toast = useToast(), {
33
33
  t
34
34
  } = useTranslation(), {
35
35
  showCookiesConsent,
@@ -42,9 +42,7 @@ const HeaderV2 = /* @__PURE__ */ lazy(() => import("../../modules/homepage/compo
42
42
  "container-fluid": !headless,
43
43
  "rounded-4 border": (theme == null ? void 0 : theme.is1d) && !headless,
44
44
  "mt-24": (theme == null ? void 0 : theme.is1d) && !headless
45
- }, className), renderHeader = headless ? null : isHeaderV2 ? /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(HeaderV2, { src: theme == null ? void 0 : theme.basePath, dataProduct: override == null ? void 0 : override.theme, onNotificationsClick: toggleOverlay }) }) : /* @__PURE__ */ jsx(Header, { is1d: theme == null ? void 0 : theme.is1d, src: theme == null ? void 0 : theme.basePath }), renderNotificationsOverlay = !headless && isHeaderV2 && /* @__PURE__ */ jsx(HeaderNotificationsOverlay, {}), renderCookies = showCookiesConsent && /* @__PURE__ */ jsx(Alert, { type: "info", className: "m-12 rgpd", isConfirm: !0, position: "bottom-right", button: /* @__PURE__ */ jsx(Button, { color: "tertiary", variant: "ghost", onClick: handleConsultCookies, children: t("rgpd.cookies.banner.button.consult") }), onClose: handleCloseCookiesConsent, children: t("rgpd.cookies.banner.text1") }), renderToaster = /* @__PURE__ */ jsx(Toaster, { containerClassName: "toaster-container", toastOptions: {
46
- position: "top-right"
47
- } });
45
+ }, className), renderHeader = headless ? null : isHeaderV2 ? /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(HeaderV2, { src: theme == null ? void 0 : theme.basePath, dataProduct: override == null ? void 0 : override.theme, onNotificationsClick: toggleOverlay }) }) : /* @__PURE__ */ jsx(Header, { is1d: theme == null ? void 0 : theme.is1d, src: theme == null ? void 0 : theme.basePath }), renderNotificationsOverlay = !headless && isHeaderV2 && /* @__PURE__ */ jsx(HeaderNotificationsOverlay, {}), renderCookies = showCookiesConsent && /* @__PURE__ */ jsx(Alert, { type: "info", className: "m-12 rgpd", isConfirm: !0, position: "bottom-right", button: /* @__PURE__ */ jsx(ButtonBeta, { variant: "outline", onClick: handleConsultCookies, children: t("rgpd.cookies.banner.button.consult") }), onClose: handleCloseCookiesConsent, children: t("rgpd.cookies.banner.text1") }), renderToaster = toast.renderToaster();
48
46
  return /* @__PURE__ */ jsxs("div", { "data-product": productOverride, "data-background": theme != null && theme.is1d ? void 0 : background, className: clsx("layout", {
49
47
  "layout-has-background-image": isBackgroundImageOverridden
50
48
  }), children: [
@@ -1,6 +1,7 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { useMemo, Children, isValidElement } from "react";
3
3
  import clsx from "clsx";
4
+ import { useTranslation } from "react-i18next";
4
5
  import PageLayoutBreadcrumb from "./components/PageLayoutBreadcrumb.js";
5
6
  import PageLayoutContent from "./components/PageLayoutContent.js";
6
7
  import PageLayoutHeader from "./components/PageLayoutHeader.js";
@@ -9,6 +10,10 @@ import PageLayoutOverlay from "./components/PageLayoutOverlay.js";
9
10
  import PageLayoutSidebarLeft from "./components/PageLayoutSidebarLeft.js";
10
11
  import PageLayoutSidebarRight from "./components/PageLayoutSidebarRight.js";
11
12
  import { PageLayoutContext } from "./PageLayoutContext.js";
13
+ import useCookiesConsent from "../../hooks/useCookiesConsent/useCookiesConsent.js";
14
+ import useToast from "../../hooks/useToast/useToast.js";
15
+ import Alert from "../Alert/Alert.js";
16
+ import ButtonBeta from "../ButtonBeta/ButtonBeta.js";
12
17
  function analyzeChildren(children) {
13
18
  let hasLeftSidebar = !1, hasRightSidebar = !1, breadcrumb = null, overlay = null, helpZone = null;
14
19
  const headerChildren = [], mainChildren = [];
@@ -59,11 +64,17 @@ const Root = ({
59
64
  className,
60
65
  ...props
61
66
  }) => {
62
- const contextValue = useMemo(() => ({
67
+ const {
68
+ t
69
+ } = useTranslation(), {
70
+ showCookiesConsent,
71
+ handleConsultCookies,
72
+ handleCloseCookiesConsent
73
+ } = useCookiesConsent(), contextValue = useMemo(() => ({
63
74
  variant,
64
75
  scrollMode,
65
76
  noPadding
66
- }), [variant, scrollMode, noPadding]), {
77
+ }), [variant, scrollMode, noPadding]), renderToaster = useToast().renderToaster(), {
67
78
  hasLeftSidebar,
68
79
  hasRightSidebar,
69
80
  breadcrumb,
@@ -86,9 +97,11 @@ const Root = ({
86
97
  isFullpage && breadcrumb,
87
98
  mainChildren
88
99
  ] }),
89
- overlay
100
+ overlay,
101
+ showCookiesConsent && /* @__PURE__ */ jsx(Alert, { type: "info", isConfirm: !0, position: "bottom-right", button: /* @__PURE__ */ jsx(ButtonBeta, { variant: "outline", onClick: handleConsultCookies, children: t("rgpd.cookies.banner.button.consult") }), onClose: handleCloseCookiesConsent, children: t("rgpd.cookies.banner.text1") })
90
102
  ] }),
91
- helpZone
103
+ helpZone,
104
+ renderToaster
92
105
  ] });
93
106
  }, PageLayout = Object.assign(Root, {
94
107
  Header: PageLayoutHeader,
@@ -7,6 +7,7 @@ export interface CustomToastOptions {
7
7
  duration?: number;
8
8
  }
9
9
  export default function useToast(): {
10
+ renderToaster: () => import("react/jsx-runtime").JSX.Element;
10
11
  success: (message: string | ReactNode, options?: CustomToastOptions) => string;
11
12
  error: (message: string | ReactNode, options?: CustomToastOptions) => string;
12
13
  info: (message: string | ReactNode, options?: CustomToastOptions) => string;
@@ -1,27 +1,30 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import toast from "react-hot-toast";
2
+ import toast, { Toaster } from "react-hot-toast";
3
3
  import Alert from "../../components/Alert/Alert.js";
4
4
  const DEFAULT_POSITION = "top-right", DEFAULT_DURATION = 5e3;
5
5
  function useToast() {
6
6
  return {
7
- success: (message, options) => toast.custom(/* @__PURE__ */ jsx(Alert, { type: "success", isToast: !0, isDismissible: options == null ? void 0 : options.isDismissible, className: "mb-12", children: message }), {
7
+ renderToaster: () => /* @__PURE__ */ jsx(Toaster, { containerClassName: "toaster-container", toastOptions: {
8
+ position: "top-right"
9
+ } }),
10
+ success: (message, options) => toast.custom((t) => /* @__PURE__ */ jsx(Alert, { type: "success", isToast: !0, isDismissible: options == null ? void 0 : options.isDismissible, autoClose: !(options != null && options.isDismissible), autoCloseDelay: (options == null ? void 0 : options.duration) ?? DEFAULT_DURATION, onClose: () => toast.dismiss(t.id), className: "mb-12", children: message }), {
8
11
  id: options == null ? void 0 : options.id,
9
- duration: (options == null ? void 0 : options.duration) ?? DEFAULT_DURATION,
12
+ duration: 1 / 0,
10
13
  position: (options == null ? void 0 : options.position) ?? DEFAULT_POSITION
11
14
  }),
12
- error: (message, options) => toast.custom(/* @__PURE__ */ jsx(Alert, { type: "danger", isToast: !0, isDismissible: options == null ? void 0 : options.isDismissible, className: "mb-12", children: message }), {
15
+ error: (message, options) => toast.custom((t) => /* @__PURE__ */ jsx(Alert, { type: "danger", isToast: !0, isDismissible: options == null ? void 0 : options.isDismissible, autoClose: !(options != null && options.isDismissible), autoCloseDelay: (options == null ? void 0 : options.duration) ?? DEFAULT_DURATION, onClose: () => toast.dismiss(t.id), className: "mb-12", children: message }), {
13
16
  id: options == null ? void 0 : options.id,
14
- duration: (options == null ? void 0 : options.duration) ?? DEFAULT_DURATION,
17
+ duration: 1 / 0,
15
18
  position: (options == null ? void 0 : options.position) ?? DEFAULT_POSITION
16
19
  }),
17
- info: (message, options) => toast.custom(/* @__PURE__ */ jsx(Alert, { type: "info", isToast: !0, isDismissible: options == null ? void 0 : options.isDismissible, className: "mb-12", children: message }), {
20
+ info: (message, options) => toast.custom((t) => /* @__PURE__ */ jsx(Alert, { type: "info", isToast: !0, isDismissible: options == null ? void 0 : options.isDismissible, autoClose: !(options != null && options.isDismissible), autoCloseDelay: (options == null ? void 0 : options.duration) ?? DEFAULT_DURATION, onClose: () => toast.dismiss(t.id), className: "mb-12", children: message }), {
18
21
  id: options == null ? void 0 : options.id,
19
- duration: (options == null ? void 0 : options.duration) ?? DEFAULT_DURATION,
22
+ duration: 1 / 0,
20
23
  position: (options == null ? void 0 : options.position) ?? DEFAULT_POSITION
21
24
  }),
22
- warning: (message, options) => toast.custom(/* @__PURE__ */ jsx(Alert, { type: "warning", isToast: !0, isDismissible: options == null ? void 0 : options.isDismissible, className: "mb-12", children: message }), {
25
+ warning: (message, options) => toast.custom((t) => /* @__PURE__ */ jsx(Alert, { type: "warning", isToast: !0, isDismissible: options == null ? void 0 : options.isDismissible, autoClose: !(options != null && options.isDismissible), autoCloseDelay: (options == null ? void 0 : options.duration) ?? DEFAULT_DURATION, onClose: () => toast.dismiss(t.id), className: "mb-12", children: message }), {
23
26
  id: options == null ? void 0 : options.id,
24
- duration: (options == null ? void 0 : options.duration) ?? DEFAULT_DURATION,
27
+ duration: 1 / 0,
25
28
  position: (options == null ? void 0 : options.position) ?? DEFAULT_POSITION
26
29
  }),
27
30
  loading: toast.loading,
@@ -1,6 +1,8 @@
1
1
  import { odeServices } from "@edifice.io/client";
2
2
  import { useQuery, useInfiniteQuery, useMutation, useQueryClient, queryOptions, infiniteQueryOptions } from "@tanstack/react-query";
3
+ import { useTranslation } from "react-i18next";
3
4
  import { notificationService } from "../api/index.js";
5
+ import useToast from "../../../../../../hooks/useToast/useToast.js";
4
6
  const notificationQueryKeys = {
5
7
  all: () => ["notifications"],
6
8
  notifications: (types = []) => [...notificationQueryKeys.all(), "list", types],
@@ -52,7 +54,9 @@ const notificationQueryKeys = {
52
54
  }, useReportNotification = () => useMutation({
53
55
  mutationFn: (id) => notificationService.reportNotification(id)
54
56
  }), useDeleteNotification = () => {
55
- const queryClient = useQueryClient();
57
+ const {
58
+ t
59
+ } = useTranslation(), toast = useToast(), queryClient = useQueryClient();
56
60
  return useMutation({
57
61
  mutationFn: (id) => notificationService.deleteNotification(id),
58
62
  onSuccess: (_data, id) => {
@@ -61,7 +65,10 @@ const notificationQueryKeys = {
61
65
  }, (data) => data && {
62
66
  ...data,
63
67
  pages: data.pages.map((page) => page.filter((notification) => notification._id !== id))
64
- });
68
+ }), toast.success(t("homepage.notifications.options.delete.success"));
69
+ },
70
+ onError: () => {
71
+ toast.error(t("homepage.notifications.options.delete.error"));
65
72
  }
66
73
  });
67
74
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edifice.io/react",
3
- "version": "2.6.6-develop-b2school.20260924114544",
3
+ "version": "2.6.6-develop-b2school.20260924174112",
4
4
  "description": "Edifice React Library",
5
5
  "keywords": [
6
6
  "react",
@@ -140,9 +140,9 @@
140
140
  "swiper": "10.1.0",
141
141
  "ua-parser-js": "1.0.36",
142
142
  "zustand": "4.5.7",
143
- "@edifice.io/bootstrap": "2.6.6-develop-b2school.20260924114544",
144
- "@edifice.io/tiptap-extensions": "2.6.6-develop-b2school.20260924114544",
145
- "@edifice.io/utilities": "2.6.6-develop-b2school.20260924114544"
143
+ "@edifice.io/bootstrap": "2.6.6-develop-b2school.20260924174112",
144
+ "@edifice.io/tiptap-extensions": "2.6.6-develop-b2school.20260924174112",
145
+ "@edifice.io/utilities": "2.6.6-develop-b2school.20260924174112"
146
146
  },
147
147
  "devDependencies": {
148
148
  "@babel/plugin-transform-react-pure-annotations": "7.27.1",
@@ -173,8 +173,8 @@
173
173
  "vite": "5.4.14",
174
174
  "vite-plugin-dts": "4.5.4",
175
175
  "vite-tsconfig-paths": "5.1.4",
176
- "@edifice.io/client": "2.6.6-develop-b2school.20260924114544",
177
- "@edifice.io/config": "2.6.6-develop-b2school.20260924114544"
176
+ "@edifice.io/client": "2.6.6-develop-b2school.20260924174112",
177
+ "@edifice.io/config": "2.6.6-develop-b2school.20260924174112"
178
178
  },
179
179
  "peerDependencies": {
180
180
  "@react-spring/web": "9.7.5",