@stack-spot/portal-layout 1.0.0 → 1.0.1
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/Toaster.d.ts +32 -0
- package/dist/components/Toaster.d.ts.map +1 -1
- package/dist/components/Toaster.js +26 -2
- package/dist/components/Toaster.js.map +1 -1
- package/dist/toaster.d.ts +2 -20
- package/dist/toaster.d.ts.map +1 -1
- package/dist/toaster.js +19 -17
- package/dist/toaster.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Toaster.tsx +72 -1
- package/src/toaster.tsx +20 -54
|
@@ -1,7 +1,39 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
1
2
|
import 'react-toastify/dist/ReactToastify.css';
|
|
2
3
|
export declare const TOASTER_CLOSE_BTN_CLASS = "btn-close";
|
|
3
4
|
/**
|
|
4
5
|
* Uses react-toastify to render a Toaster based on the Citric DS.
|
|
5
6
|
*/
|
|
6
7
|
export declare const Toaster: () => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export interface ToasterAction {
|
|
9
|
+
/**
|
|
10
|
+
* The button's label.
|
|
11
|
+
*/
|
|
12
|
+
label: string;
|
|
13
|
+
/**
|
|
14
|
+
* A function to run once the button is clicked.
|
|
15
|
+
*/
|
|
16
|
+
onClick?: (event: React.MouseEvent) => void;
|
|
17
|
+
/**
|
|
18
|
+
* If this is set, instead of a button, an anchor is rendered with this href.
|
|
19
|
+
*/
|
|
20
|
+
href?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Whether or not to close the toaster once the button is clicked.
|
|
23
|
+
* @default true
|
|
24
|
+
*/
|
|
25
|
+
closeOnClick?: boolean;
|
|
26
|
+
}
|
|
27
|
+
interface ToasterContentProps {
|
|
28
|
+
id: number | string;
|
|
29
|
+
actions?: ToasterAction[];
|
|
30
|
+
onClick?: (event: React.MouseEvent) => void;
|
|
31
|
+
title?: string;
|
|
32
|
+
message: React.ReactNode;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Renders a toaster with the default layout for toasters.
|
|
36
|
+
*/
|
|
37
|
+
export declare const ToasterContent: ({ id, message, actions, onClick, title }: ToasterContentProps) => import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
export {};
|
|
7
39
|
//# sourceMappingURL=Toaster.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toaster.d.ts","sourceRoot":"","sources":["../../src/components/Toaster.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Toaster.d.ts","sourceRoot":"","sources":["../../src/components/Toaster.tsx"],"names":[],"mappings":";AAOA,OAAO,uCAAuC,CAAA;AAK9C,eAAO,MAAM,uBAAuB,cAAc,CAAA;AAWlD;;GAEG;AACH,eAAO,MAAM,OAAO,+CAAqD,CAAA;AAEzE,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAC5C;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,UAAU,mBAAmB;IAC3B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;CAC1B;AAYD;;GAEG;AACH,eAAO,MAAM,cAAc,6CAA8C,mBAAmB,4CAyB3F,CAAA"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Flex, Text } from '@citric/core';
|
|
2
3
|
import { TimesMini } from '@citric/icons';
|
|
3
4
|
import { IconButton } from '@citric/ui';
|
|
4
|
-
import {
|
|
5
|
+
import { useAnchorTag } from '@stack-spot/portal-components/anchor';
|
|
6
|
+
import { useMemo } from 'react';
|
|
7
|
+
import { ToastContainer, toast } from 'react-toastify';
|
|
5
8
|
import 'react-toastify/dist/ReactToastify.css';
|
|
6
9
|
import { useDictionary } from '../dictionary.js';
|
|
7
10
|
export const TOASTER_CLOSE_BTN_CLASS = 'btn-close';
|
|
@@ -13,4 +16,25 @@ const CloseButton = ({ closeToast }) => {
|
|
|
13
16
|
* Uses react-toastify to render a Toaster based on the Citric DS.
|
|
14
17
|
*/
|
|
15
18
|
export const Toaster = () => _jsx(ToastContainer, { closeButton: CloseButton });
|
|
19
|
+
const actionStyle = {
|
|
20
|
+
background: 'transparent',
|
|
21
|
+
border: 'none',
|
|
22
|
+
padding: 0,
|
|
23
|
+
color: 'inherit',
|
|
24
|
+
font: 'inherit',
|
|
25
|
+
fontWeight: 500,
|
|
26
|
+
cursor: 'pointer',
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Renders a toaster with the default layout for toasters.
|
|
30
|
+
*/
|
|
31
|
+
export const ToasterContent = ({ id, message, actions, onClick, title }) => {
|
|
32
|
+
const Link = useAnchorTag();
|
|
33
|
+
const buttons = useMemo(() => actions?.map(({ label, href, onClick, closeOnClick = true }) => (_jsx(Text, { as: href ? Link : 'button', href: href, style: actionStyle, onClick: (event) => {
|
|
34
|
+
onClick?.(event);
|
|
35
|
+
if (closeOnClick)
|
|
36
|
+
toast.dismiss(id);
|
|
37
|
+
}, children: label }, label))), [actions]);
|
|
38
|
+
return (_jsxs("div", { onClick: onClick, children: [_jsx("h1", { style: { textTransform: 'capitalize' }, children: title }), typeof message === 'string' ? _jsx("p", { children: message }) : message, buttons?.length ? _jsx(Flex, { style: { gap: '12px', marginTop: '12px' }, children: buttons }) : null] }));
|
|
39
|
+
};
|
|
16
40
|
//# sourceMappingURL=Toaster.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toaster.js","sourceRoot":"","sources":["../../src/components/Toaster.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"Toaster.js","sourceRoot":"","sources":["../../src/components/Toaster.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAA;AACnE,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE/B,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,uCAAuC,CAAA;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAI7C,MAAM,CAAC,MAAM,uBAAuB,GAAG,WAAW,CAAA;AAElD,MAAM,WAAW,GAAG,CAAC,EAAE,UAAU,EAAoB,EAAE,EAAE;IACvD,MAAM,CAAC,GAAG,aAAa,EAAE,CAAA;IACzB,OAAO,CACL,KAAC,UAAU,IAAC,SAAS,EAAE,uBAAuB,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,YACnF,KAAC,SAAS,KAAG,GACF,CACd,CAAA;AACH,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,KAAC,cAAc,IAAC,WAAW,EAAE,WAAW,GAAI,CAAA;AA8BzE,MAAM,WAAW,GAAwB;IACvC,UAAU,EAAE,aAAa;IACzB,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,SAAS;IAChB,IAAI,EAAE,SAAS;IACf,UAAU,EAAE,GAAG;IACf,MAAM,EAAE,SAAS;CAClB,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAuB,EAAE,EAAE;IAC9F,MAAM,IAAI,GAAG,YAAY,EAAE,CAAA;IAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,CACxC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC,CACjD,KAAC,IAAI,IAEH,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAC1B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,CAAC,KAAuB,EAAE,EAAE;YACnC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAA;YAChB,IAAI,YAAY;gBAAE,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACrC,CAAC,YAEA,KAAK,IATD,KAAK,CAUL,CACR,CACF,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IACb,OAAO,CACL,eAAK,OAAO,EAAE,OAAO,aACnB,aAAI,KAAK,EAAE,EAAE,aAAa,EAAE,YAAY,EAAE,YAAG,KAAK,GAAM,EACvD,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,sBAAI,OAAO,GAAK,CAAC,CAAC,CAAC,OAAO,EACxD,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,KAAC,IAAI,IAAC,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAG,OAAO,GAAQ,CAAC,CAAC,CAAC,IAAI,IACvF,CACP,CAAA;AACH,CAAC,CAAA"}
|
package/dist/toaster.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="react" />
|
|
2
2
|
import 'react-toastify/dist/ReactToastify.css';
|
|
3
|
+
import { ToasterAction } from './components/Toaster.js';
|
|
3
4
|
type ToastType = 'error' | 'success' | 'warning' | 'info';
|
|
4
5
|
interface BaseOptions {
|
|
5
6
|
/**
|
|
@@ -34,25 +35,6 @@ interface BaseOptions {
|
|
|
34
35
|
*/
|
|
35
36
|
closeOnClick?: boolean;
|
|
36
37
|
}
|
|
37
|
-
interface ToasterAction {
|
|
38
|
-
/**
|
|
39
|
-
* The button's label.
|
|
40
|
-
*/
|
|
41
|
-
label: string;
|
|
42
|
-
/**
|
|
43
|
-
* A function to run once the button is clicked.
|
|
44
|
-
*/
|
|
45
|
-
onClick?: (event: React.MouseEvent) => void;
|
|
46
|
-
/**
|
|
47
|
-
* If this is set, instead of a button, an anchor is rendered with this href.
|
|
48
|
-
*/
|
|
49
|
-
href?: string;
|
|
50
|
-
/**
|
|
51
|
-
* Whether or not to close the toaster once the button is clicked.
|
|
52
|
-
* @default true
|
|
53
|
-
*/
|
|
54
|
-
closeOnClick?: boolean;
|
|
55
|
-
}
|
|
56
38
|
export interface DefaultToasterOptions extends BaseOptions {
|
|
57
39
|
/**
|
|
58
40
|
* The title of the toaster.
|
package/dist/toaster.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toaster.d.ts","sourceRoot":"","sources":["../src/toaster.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"toaster.d.ts","sourceRoot":"","sources":["../src/toaster.tsx"],"names":[],"mappings":";AAIA,OAAO,uCAAuC,CAAA;AAC9C,OAAO,EAAE,aAAa,EAAkB,MAAM,sBAAsB,CAAA;AAEpE,KAAK,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAA;AAEzD,UAAU,WAAW;IACnB;;;;OAIG;IACH,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB;;;OAGG;IACH,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC3B;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,qBAAsB,SAAQ,WAAW;IACxD;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;OAEG;IACH,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,KAAK,CAAC;CAChB;AAED,MAAM,WAAW,oBAAqB,SAAQ,WAAW;IACvD;;OAEG;IACH,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC;IAC5B,MAAM,EAAE,IAAI,CAAC;IACb;;OAEG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC;CAClC;AAED,MAAM,MAAM,cAAc,GAAG,qBAAqB,GAAG,oBAAoB,GAAG,KAAK,CAAC,SAAS,CAAA;AAyB3F,wBAAgB,WAAW,CAAC,oBAAoB,EAAE,qBAAqB,GAAG,MAAM,GAAG,MAAM,CAAA;AACzF,wBAAgB,WAAW,CAAC,mBAAmB,EAAE,oBAAoB,GAAG,MAAM,GAAG,MAAM,CAAA;AACvF,wBAAgB,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,GAAG,MAAM,GAAG,MAAM,CAAA;AAqCtE,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,QAEpD"}
|
package/dist/toaster.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
2
|
-
import {
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { IconBox } from '@citric/core';
|
|
3
3
|
import { CheckCircleFill, ExclamationCircleFill, ExclamationTriangleFill, InfoCircleFill } from '@citric/icons';
|
|
4
|
+
import { translate } from '@stack-spot/portal-translate';
|
|
4
5
|
import { toast } from 'react-toastify';
|
|
5
6
|
import 'react-toastify/dist/ReactToastify.css';
|
|
7
|
+
import { ToasterContent } from './components/Toaster.js';
|
|
6
8
|
const toasterConfig = {
|
|
7
9
|
error: {
|
|
8
10
|
element: _jsx(ExclamationCircleFill, {}),
|
|
@@ -36,23 +38,9 @@ export function showToaster(options) {
|
|
|
36
38
|
const bg = `var(--${config.color}-500)`;
|
|
37
39
|
const bgDark = `var(--${config.color}-600)`;
|
|
38
40
|
const fg = `var(--${config.color}-contrastText)`;
|
|
39
|
-
const actionStyle = {
|
|
40
|
-
background: 'transparent',
|
|
41
|
-
border: 'none',
|
|
42
|
-
padding: 0,
|
|
43
|
-
color: 'inherit',
|
|
44
|
-
font: 'inherit',
|
|
45
|
-
fontWeight: 500,
|
|
46
|
-
cursor: 'pointer',
|
|
47
|
-
};
|
|
48
|
-
const buttons = opts.custom ? null : opts.actions?.map(({ label, href, onClick, closeOnClick = true }) => (_jsx(Text, { as: href ? 'a' : 'button', href: href, style: actionStyle, onClick: (event) => {
|
|
49
|
-
onClick?.(event);
|
|
50
|
-
if (closeOnClick)
|
|
51
|
-
closeReactToaster(id);
|
|
52
|
-
}, children: label }, label)));
|
|
53
41
|
toast(opts.custom
|
|
54
42
|
? opts.message
|
|
55
|
-
: (
|
|
43
|
+
: _jsx(ToasterContent, { ...opts, id: id, title: opts.title ?? translate(dictionary)[type] }), {
|
|
56
44
|
toastId: id,
|
|
57
45
|
type,
|
|
58
46
|
autoClose: autoClose === false ? false : closeTime * 1000,
|
|
@@ -69,4 +57,18 @@ export function showToaster(options) {
|
|
|
69
57
|
export function closeReactToaster(id) {
|
|
70
58
|
toast.dismiss(id);
|
|
71
59
|
}
|
|
60
|
+
const dictionary = {
|
|
61
|
+
en: {
|
|
62
|
+
success: 'Success',
|
|
63
|
+
error: 'Error',
|
|
64
|
+
info: 'Info',
|
|
65
|
+
warning: 'Warning',
|
|
66
|
+
},
|
|
67
|
+
pt: {
|
|
68
|
+
success: 'Sucesso',
|
|
69
|
+
error: 'Erro',
|
|
70
|
+
info: 'Info',
|
|
71
|
+
warning: 'Atenção',
|
|
72
|
+
},
|
|
73
|
+
};
|
|
72
74
|
//# sourceMappingURL=toaster.js.map
|
package/dist/toaster.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toaster.js","sourceRoot":"","sources":["../src/toaster.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"toaster.js","sourceRoot":"","sources":["../src/toaster.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { Flex, Text } from '@citric/core'
|
|
1
2
|
import { TimesMini } from '@citric/icons'
|
|
2
3
|
import { IconButton } from '@citric/ui'
|
|
4
|
+
import { useAnchorTag } from '@stack-spot/portal-components/anchor'
|
|
5
|
+
import { useMemo } from 'react'
|
|
3
6
|
import type { CloseButton as DefaultCloseButton } from 'react-toastify'
|
|
4
|
-
import { ToastContainer } from 'react-toastify'
|
|
7
|
+
import { ToastContainer, toast } from 'react-toastify'
|
|
5
8
|
import 'react-toastify/dist/ReactToastify.css'
|
|
6
9
|
import { useDictionary } from '../dictionary'
|
|
7
10
|
|
|
@@ -22,3 +25,71 @@ const CloseButton = ({ closeToast }: CloseButtonProps) => {
|
|
|
22
25
|
* Uses react-toastify to render a Toaster based on the Citric DS.
|
|
23
26
|
*/
|
|
24
27
|
export const Toaster = () => <ToastContainer closeButton={CloseButton} />
|
|
28
|
+
|
|
29
|
+
export interface ToasterAction {
|
|
30
|
+
/**
|
|
31
|
+
* The button's label.
|
|
32
|
+
*/
|
|
33
|
+
label: string,
|
|
34
|
+
/**
|
|
35
|
+
* A function to run once the button is clicked.
|
|
36
|
+
*/
|
|
37
|
+
onClick?: (event: React.MouseEvent) => void,
|
|
38
|
+
/**
|
|
39
|
+
* If this is set, instead of a button, an anchor is rendered with this href.
|
|
40
|
+
*/
|
|
41
|
+
href?: string,
|
|
42
|
+
/**
|
|
43
|
+
* Whether or not to close the toaster once the button is clicked.
|
|
44
|
+
* @default true
|
|
45
|
+
*/
|
|
46
|
+
closeOnClick?: boolean,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface ToasterContentProps {
|
|
50
|
+
id: number | string,
|
|
51
|
+
actions?: ToasterAction[],
|
|
52
|
+
onClick?: (event: React.MouseEvent) => void,
|
|
53
|
+
title?: string,
|
|
54
|
+
message: React.ReactNode,
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const actionStyle: React.CSSProperties = {
|
|
58
|
+
background: 'transparent',
|
|
59
|
+
border: 'none',
|
|
60
|
+
padding: 0,
|
|
61
|
+
color: 'inherit',
|
|
62
|
+
font: 'inherit',
|
|
63
|
+
fontWeight: 500,
|
|
64
|
+
cursor: 'pointer',
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Renders a toaster with the default layout for toasters.
|
|
69
|
+
*/
|
|
70
|
+
export const ToasterContent = ({ id, message, actions, onClick, title }: ToasterContentProps) => {
|
|
71
|
+
const Link = useAnchorTag()
|
|
72
|
+
const buttons = useMemo(() => actions?.map(
|
|
73
|
+
({ label, href, onClick, closeOnClick = true }) => (
|
|
74
|
+
<Text
|
|
75
|
+
key={label}
|
|
76
|
+
as={href ? Link : 'button'}
|
|
77
|
+
href={href}
|
|
78
|
+
style={actionStyle}
|
|
79
|
+
onClick={(event: React.MouseEvent) => {
|
|
80
|
+
onClick?.(event)
|
|
81
|
+
if (closeOnClick) toast.dismiss(id)
|
|
82
|
+
}}
|
|
83
|
+
>
|
|
84
|
+
{label}
|
|
85
|
+
</Text>
|
|
86
|
+
),
|
|
87
|
+
), [actions])
|
|
88
|
+
return (
|
|
89
|
+
<div onClick={onClick}>
|
|
90
|
+
<h1 style={{ textTransform: 'capitalize' }}>{title}</h1>
|
|
91
|
+
{typeof message === 'string' ? <p>{message}</p> : message}
|
|
92
|
+
{buttons?.length ? <Flex style={{ gap: '12px', marginTop: '12px' }}>{buttons}</Flex> : null}
|
|
93
|
+
</div>
|
|
94
|
+
)
|
|
95
|
+
}
|
package/src/toaster.tsx
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IconBox, OneOfColorSchemesWithVariants } from '@citric/core'
|
|
2
2
|
import { CheckCircleFill, ExclamationCircleFill, ExclamationTriangleFill, InfoCircleFill } from '@citric/icons'
|
|
3
|
-
import
|
|
3
|
+
import { Dictionary, translate } from '@stack-spot/portal-translate'
|
|
4
4
|
import { toast } from 'react-toastify'
|
|
5
5
|
import 'react-toastify/dist/ReactToastify.css'
|
|
6
|
+
import { ToasterAction, ToasterContent } from './components/Toaster'
|
|
6
7
|
|
|
7
8
|
type ToastType = 'error' | 'success' | 'warning' | 'info'
|
|
8
9
|
|
|
@@ -40,26 +41,6 @@ interface BaseOptions {
|
|
|
40
41
|
closeOnClick?: boolean,
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
interface ToasterAction {
|
|
44
|
-
/**
|
|
45
|
-
* The button's label.
|
|
46
|
-
*/
|
|
47
|
-
label: string,
|
|
48
|
-
/**
|
|
49
|
-
* A function to run once the button is clicked.
|
|
50
|
-
*/
|
|
51
|
-
onClick?: (event: React.MouseEvent) => void,
|
|
52
|
-
/**
|
|
53
|
-
* If this is set, instead of a button, an anchor is rendered with this href.
|
|
54
|
-
*/
|
|
55
|
-
href?: string,
|
|
56
|
-
/**
|
|
57
|
-
* Whether or not to close the toaster once the button is clicked.
|
|
58
|
-
* @default true
|
|
59
|
-
*/
|
|
60
|
-
closeOnClick?: boolean,
|
|
61
|
-
}
|
|
62
|
-
|
|
63
44
|
export interface DefaultToasterOptions extends BaseOptions {
|
|
64
45
|
/**
|
|
65
46
|
* The title of the toaster.
|
|
@@ -127,41 +108,11 @@ export function showToaster(options: ToasterOptions): number | string {
|
|
|
127
108
|
const bg = `var(--${config.color}-500)`
|
|
128
109
|
const bgDark = `var(--${config.color}-600)`
|
|
129
110
|
const fg = `var(--${config.color}-contrastText)`
|
|
130
|
-
|
|
131
|
-
background: 'transparent',
|
|
132
|
-
border: 'none',
|
|
133
|
-
padding: 0,
|
|
134
|
-
color: 'inherit',
|
|
135
|
-
font: 'inherit',
|
|
136
|
-
fontWeight: 500,
|
|
137
|
-
cursor: 'pointer',
|
|
138
|
-
}
|
|
139
|
-
const buttons = opts.custom ? null : opts.actions?.map(
|
|
140
|
-
({ label, href, onClick, closeOnClick = true }) => (
|
|
141
|
-
<Text
|
|
142
|
-
key={label}
|
|
143
|
-
as={href ? 'a' : 'button'}
|
|
144
|
-
href={href}
|
|
145
|
-
style={actionStyle}
|
|
146
|
-
onClick={(event: React.MouseEvent) => {
|
|
147
|
-
onClick?.(event)
|
|
148
|
-
if (closeOnClick) closeReactToaster(id)
|
|
149
|
-
}}
|
|
150
|
-
>
|
|
151
|
-
{label}
|
|
152
|
-
</Text>
|
|
153
|
-
),
|
|
154
|
-
)
|
|
111
|
+
|
|
155
112
|
toast(
|
|
156
113
|
opts.custom
|
|
157
114
|
? opts.message
|
|
158
|
-
: (
|
|
159
|
-
<div onClick={opts.onClick}>
|
|
160
|
-
<h1 style={{ textTransform: 'capitalize' }}>{opts.title ?? type}</h1>
|
|
161
|
-
{typeof opts.message === 'string' ? <p>{opts.message}</p> : opts.message}
|
|
162
|
-
{buttons?.length ? <Flex style={{ gap: '12px', marginTop: '12px' }}>{buttons}</Flex> : null}
|
|
163
|
-
</div>
|
|
164
|
-
),
|
|
115
|
+
: <ToasterContent {...opts} id={id} title={opts.title ?? translate(dictionary)[type]} />,
|
|
165
116
|
{
|
|
166
117
|
toastId: id,
|
|
167
118
|
type,
|
|
@@ -185,3 +136,18 @@ export function showToaster(options: ToasterOptions): number | string {
|
|
|
185
136
|
export function closeReactToaster(id: number | string) {
|
|
186
137
|
toast.dismiss(id)
|
|
187
138
|
}
|
|
139
|
+
|
|
140
|
+
const dictionary = {
|
|
141
|
+
en: {
|
|
142
|
+
success: 'Success',
|
|
143
|
+
error: 'Error',
|
|
144
|
+
info: 'Info',
|
|
145
|
+
warning: 'Warning',
|
|
146
|
+
},
|
|
147
|
+
pt: {
|
|
148
|
+
success: 'Sucesso',
|
|
149
|
+
error: 'Erro',
|
|
150
|
+
info: 'Info',
|
|
151
|
+
warning: 'Atenção',
|
|
152
|
+
},
|
|
153
|
+
} satisfies Dictionary
|