flysoft-react-ui 1.0.8 → 1.0.9
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/components/utils/Avatar.d.ts.map +1 -1
- package/dist/components/utils/Avatar.js +2 -18
- package/dist/components/utils/Snackbar.d.ts.map +1 -1
- package/dist/components/utils/Snackbar.js +2 -2
- package/dist/components/utils/SnackbarContainer.d.ts.map +1 -1
- package/dist/components/utils/SnackbarContainer.js +3 -2
- package/dist/contexts/SnackbarContext.d.ts +19 -2
- package/dist/contexts/SnackbarContext.d.ts.map +1 -1
- package/dist/contexts/SnackbarContext.js +29 -9
- package/dist/contexts/index.d.ts +2 -2
- package/dist/contexts/index.d.ts.map +1 -1
- package/dist/contexts/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Avatar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Avatar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAoCxC,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CA2DxC,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React, { useState } from "react";
|
|
3
|
+
import { getInitialLetters } from "../../helpers";
|
|
3
4
|
/**
|
|
4
5
|
* Helper function to convert color names to CSS values
|
|
5
6
|
*/
|
|
@@ -28,23 +29,6 @@ const getColorValue = (color) => {
|
|
|
28
29
|
};
|
|
29
30
|
return colorMap[color.toLowerCase()] || color;
|
|
30
31
|
};
|
|
31
|
-
/**
|
|
32
|
-
* Helper function to extract initials from text
|
|
33
|
-
* Returns first letter of first word and first letter of last word (if multiple words)
|
|
34
|
-
*/
|
|
35
|
-
const getInitials = (text) => {
|
|
36
|
-
if (!text || text.trim().length === 0)
|
|
37
|
-
return "";
|
|
38
|
-
const words = text.trim().split(/\s+/);
|
|
39
|
-
if (words.length === 0)
|
|
40
|
-
return "";
|
|
41
|
-
const firstLetter = words[0].charAt(0).toUpperCase();
|
|
42
|
-
if (words.length === 1) {
|
|
43
|
-
return firstLetter;
|
|
44
|
-
}
|
|
45
|
-
const lastLetter = words[words.length - 1].charAt(0).toUpperCase();
|
|
46
|
-
return `${firstLetter}${lastLetter}`;
|
|
47
|
-
};
|
|
48
32
|
/**
|
|
49
33
|
* Avatar component displays a circular avatar with initials or an image
|
|
50
34
|
*
|
|
@@ -62,7 +46,7 @@ const getInitials = (text) => {
|
|
|
62
46
|
*/
|
|
63
47
|
export const Avatar = ({ text, image, bgColor = "gray-600", textColor = "white", size = "md", className = "", }) => {
|
|
64
48
|
const [imageError, setImageError] = useState(false);
|
|
65
|
-
const initials =
|
|
49
|
+
const initials = getInitialLetters(text);
|
|
66
50
|
const showImage = image && !imageError;
|
|
67
51
|
const sizeClasses = {
|
|
68
52
|
sm: "w-8 h-8 text-xs",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Snackbar.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Snackbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGtE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,
|
|
1
|
+
{"version":3,"file":"Snackbar.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Snackbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGtE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA+L5C,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React, { useEffect, useState, useRef, useCallback } from "react";
|
|
3
3
|
import { normalizeIconClass } from "./iconUtils";
|
|
4
|
-
export const Snackbar = ({ id, message, variant, duration = 3000, icon, iconLabel, onClose
|
|
4
|
+
export const Snackbar = React.memo(({ id, message, variant, duration = 3000, icon, iconLabel, onClose }) => {
|
|
5
5
|
const [progress, setProgress] = useState(100);
|
|
6
6
|
const [isClosing, setIsClosing] = useState(false);
|
|
7
7
|
const intervalRef = useRef(null);
|
|
@@ -119,4 +119,4 @@ export const Snackbar = ({ id, message, variant, duration = 3000, icon, iconLabe
|
|
|
119
119
|
width: `${progress}%`,
|
|
120
120
|
backgroundColor: "#00000050",
|
|
121
121
|
} }) })), displayIcon && (_jsx("div", { className: "flex-shrink-0 -mt-0.5", children: _jsx("i", { className: `${normalizeIconClass(displayIcon)} text-base`, "aria-hidden": !iconLabel, "aria-label": iconLabel }) })), _jsx("div", { className: "flex-1 min-w-0", children: _jsx("p", { className: "text-sm font-medium break-words max-w-full", children: message }) }), _jsx("button", { onClick: handleClose, className: "flex-shrink-0 ml-2 text-gray-600 hover:text-gray-800 transition-colors cursor-pointer", "aria-label": "Cerrar notificaci\u00F3n", type: "button", children: _jsx("i", { className: `${normalizeIconClass("fa-times")} text-sm` }) })] }) }));
|
|
122
|
-
};
|
|
122
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SnackbarContainer.d.ts","sourceRoot":"","sources":["../../../src/components/utils/SnackbarContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"SnackbarContainer.d.ts","sourceRoot":"","sources":["../../../src/components/utils/SnackbarContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EACL,WAAW,GACX,UAAU,GACV,cAAc,GACd,aAAa,GACb,YAAY,GACZ,eAAe,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAiD9D,CAAC"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { useSnackbarState, useSnackbarActions, } from "../../contexts/SnackbarContext";
|
|
4
4
|
import { Snackbar } from "./Snackbar";
|
|
5
5
|
export const SnackbarContainer = ({ position = "top-right", maxSnackbars = 5, }) => {
|
|
6
|
-
const
|
|
6
|
+
const snackbars = useSnackbarState();
|
|
7
|
+
const { removeSnackbar } = useSnackbarActions();
|
|
7
8
|
// Limitar el número de snackbars visibles
|
|
8
9
|
const visibleSnackbars = snackbars.slice(-maxSnackbars);
|
|
9
10
|
// Clases de posición
|
|
@@ -8,19 +8,36 @@ export interface SnackbarMessage {
|
|
|
8
8
|
icon?: string;
|
|
9
9
|
iconLabel?: string;
|
|
10
10
|
}
|
|
11
|
-
export interface
|
|
11
|
+
export interface SnackbarActionsType {
|
|
12
12
|
showSnackbar: (message: string, variant?: SnackbarVariant, options?: {
|
|
13
13
|
duration?: number;
|
|
14
14
|
icon?: string;
|
|
15
15
|
iconLabel?: string;
|
|
16
16
|
}) => void;
|
|
17
17
|
removeSnackbar: (id: string) => void;
|
|
18
|
+
}
|
|
19
|
+
export interface SnackbarContextType extends SnackbarActionsType {
|
|
18
20
|
snackbars: SnackbarMessage[];
|
|
19
21
|
}
|
|
20
22
|
interface SnackbarProviderProps {
|
|
21
23
|
children: ReactNode;
|
|
22
24
|
}
|
|
23
25
|
export declare const SnackbarProvider: React.FC<SnackbarProviderProps>;
|
|
24
|
-
export declare const
|
|
26
|
+
export declare const useSnackbarActions: () => SnackbarActionsType;
|
|
27
|
+
export declare const useSnackbarState: () => SnackbarMessage[];
|
|
28
|
+
/**
|
|
29
|
+
* Hook para acceder a todo el contexto de snackbars.
|
|
30
|
+
* NOTA: El uso de este hook causará re-renders cada vez que la lista de snackbars cambie.
|
|
31
|
+
* Si solo necesitas disparar snackbars, usa `useSnackbarActions`.
|
|
32
|
+
*/
|
|
33
|
+
export declare const useSnackbar: () => {
|
|
34
|
+
snackbars: SnackbarMessage[];
|
|
35
|
+
showSnackbar: (message: string, variant?: SnackbarVariant, options?: {
|
|
36
|
+
duration?: number;
|
|
37
|
+
icon?: string;
|
|
38
|
+
iconLabel?: string;
|
|
39
|
+
}) => void;
|
|
40
|
+
removeSnackbar: (id: string) => void;
|
|
41
|
+
};
|
|
25
42
|
export {};
|
|
26
43
|
//# sourceMappingURL=SnackbarContext.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SnackbarContext.d.ts","sourceRoot":"","sources":["../../src/contexts/SnackbarContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"SnackbarContext.d.ts","sourceRoot":"","sources":["../../src/contexts/SnackbarContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAMZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,WAAW,GACX,SAAS,GACT,SAAS,GACT,QAAQ,GACR,MAAM,CAAC;AAEX,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,CACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,eAAe,EACzB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,KACE,IAAI,CAAC;IACV,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,mBAAoB,SAAQ,mBAAmB;IAC9D,SAAS,EAAE,eAAe,EAAE,CAAC;CAC9B;AASD,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAiD5D,CAAC;AAEF,eAAO,MAAM,kBAAkB,QAAO,mBAQrC,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAO,eAAe,EAMlD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW;;kBArGR,CACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,eAAe,EACzB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,KACE,IAAI;oBACO,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI;CAuGrC,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import React, { createContext, useContext, useState, useCallback, } from "react";
|
|
3
|
-
const
|
|
2
|
+
import React, { createContext, useContext, useState, useCallback, useMemo, } from "react";
|
|
3
|
+
const SnackbarStateContext = createContext(undefined);
|
|
4
|
+
const SnackbarActionsContext = createContext(undefined);
|
|
4
5
|
export const SnackbarProvider = ({ children, }) => {
|
|
5
6
|
const [snackbars, setSnackbars] = useState([]);
|
|
6
7
|
const showSnackbar = useCallback((message, variant = "info", options) => {
|
|
@@ -18,17 +19,36 @@ export const SnackbarProvider = ({ children, }) => {
|
|
|
18
19
|
const removeSnackbar = useCallback((id) => {
|
|
19
20
|
setSnackbars((prev) => prev.filter((snackbar) => snackbar.id !== id));
|
|
20
21
|
}, []);
|
|
21
|
-
const
|
|
22
|
+
const actions = useMemo(() => ({
|
|
22
23
|
showSnackbar,
|
|
23
24
|
removeSnackbar,
|
|
24
|
-
|
|
25
|
-
};
|
|
26
|
-
return (_jsx(SnackbarContext.Provider, { value: value, children: children }));
|
|
25
|
+
}), [showSnackbar, removeSnackbar]);
|
|
26
|
+
return (_jsx(SnackbarActionsContext.Provider, { value: actions, children: _jsx(SnackbarStateContext.Provider, { value: snackbars, children: children }) }));
|
|
27
27
|
};
|
|
28
|
-
export const
|
|
29
|
-
const context = useContext(
|
|
28
|
+
export const useSnackbarActions = () => {
|
|
29
|
+
const context = useContext(SnackbarActionsContext);
|
|
30
30
|
if (context === undefined) {
|
|
31
|
-
throw new Error("
|
|
31
|
+
throw new Error("useSnackbarActions must be used within a SnackbarProvider");
|
|
32
32
|
}
|
|
33
33
|
return context;
|
|
34
34
|
};
|
|
35
|
+
export const useSnackbarState = () => {
|
|
36
|
+
const context = useContext(SnackbarStateContext);
|
|
37
|
+
if (context === undefined) {
|
|
38
|
+
throw new Error("useSnackbarState must be used within a SnackbarProvider");
|
|
39
|
+
}
|
|
40
|
+
return context;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Hook para acceder a todo el contexto de snackbars.
|
|
44
|
+
* NOTA: El uso de este hook causará re-renders cada vez que la lista de snackbars cambie.
|
|
45
|
+
* Si solo necesitas disparar snackbars, usa `useSnackbarActions`.
|
|
46
|
+
*/
|
|
47
|
+
export const useSnackbar = () => {
|
|
48
|
+
const state = useSnackbarState();
|
|
49
|
+
const actions = useSnackbarActions();
|
|
50
|
+
return useMemo(() => ({
|
|
51
|
+
...actions,
|
|
52
|
+
snackbars: state,
|
|
53
|
+
}), [actions, state]);
|
|
54
|
+
};
|
package/dist/contexts/index.d.ts
CHANGED
|
@@ -8,6 +8,6 @@ export { CrudProvider, CrudContext, useCrud } from "./CrudContext";
|
|
|
8
8
|
export type { CrudContextType } from "./CrudContext";
|
|
9
9
|
export { AppLayoutProvider, useAppLayout, useAppLayoutContext } from "./AppLayoutContext";
|
|
10
10
|
export type { AppLayoutContextType, NavbarInterface, LeftDrawerInterface, } from "./AppLayoutContext";
|
|
11
|
-
export { SnackbarProvider, useSnackbar } from "./SnackbarContext";
|
|
12
|
-
export type { SnackbarContextType, SnackbarMessage, SnackbarVariant, } from "./SnackbarContext";
|
|
11
|
+
export { SnackbarProvider, useSnackbar, useSnackbarActions, useSnackbarState, } from "./SnackbarContext";
|
|
12
|
+
export type { SnackbarContextType, SnackbarActionsType, SnackbarMessage, SnackbarVariant, } from "./SnackbarContext";
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contexts/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EACL,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AAGnC,YAAY,EAAE,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGtE,OAAO,EACL,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,YAAY,EACZ,MAAM,GACP,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC1D,YAAY,EACV,eAAe,EACf,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACnE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contexts/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EACL,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AAGnC,YAAY,EAAE,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGtE,OAAO,EACL,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,YAAY,EACZ,MAAM,GACP,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC1D,YAAY,EACV,eAAe,EACf,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACnE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,eAAe,GAChB,MAAM,mBAAmB,CAAC"}
|
package/dist/contexts/index.js
CHANGED
|
@@ -10,4 +10,4 @@ export { CrudProvider, CrudContext, useCrud } from "./CrudContext";
|
|
|
10
10
|
// AppLayout system exports
|
|
11
11
|
export { AppLayoutProvider, useAppLayout, useAppLayoutContext } from "./AppLayoutContext";
|
|
12
12
|
// Snackbar system exports
|
|
13
|
-
export { SnackbarProvider, useSnackbar } from "./SnackbarContext";
|
|
13
|
+
export { SnackbarProvider, useSnackbar, useSnackbarActions, useSnackbarState, } from "./SnackbarContext";
|