@sproutsocial/seeds-react-banner 1.0.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/.eslintrc.js +4 -0
- package/.turbo/turbo-build.log +21 -0
- package/CHANGELOG.md +7 -0
- package/dist/esm/index.js +130 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.d.mts +22 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +167 -0
- package/dist/index.js.map +1 -0
- package/jest.config.js +9 -0
- package/package.json +47 -0
- package/src/Banner.tsx +80 -0
- package/src/BannerTypes.ts +30 -0
- package/src/__tests__/Banner.typetest.tsx +52 -0
- package/src/__tests__/features.test.tsx +100 -0
- package/src/index.stories.tsx +140 -0
- package/src/index.ts +5 -0
- package/src/styles.ts +49 -0
- package/tsconfig.json +9 -0
- package/tsup.config.ts +12 -0
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
yarn run v1.22.22
|
|
2
|
+
$ tsup --dts
|
|
3
|
+
CLI Building entry: src/index.ts
|
|
4
|
+
CLI Using tsconfig: tsconfig.json
|
|
5
|
+
CLI tsup v8.0.2
|
|
6
|
+
CLI Using tsup config: /home/runner/work/seeds/seeds/seeds-react/seeds-react-banner/tsup.config.ts
|
|
7
|
+
CLI Target: es2022
|
|
8
|
+
CLI Cleaning output folder
|
|
9
|
+
CJS Build start
|
|
10
|
+
ESM Build start
|
|
11
|
+
CJS dist/index.js 5.46 KB
|
|
12
|
+
CJS dist/index.js.map 6.58 KB
|
|
13
|
+
CJS ⚡️ Build success in 64ms
|
|
14
|
+
ESM dist/esm/index.js 3.29 KB
|
|
15
|
+
ESM dist/esm/index.js.map 6.44 KB
|
|
16
|
+
ESM ⚡️ Build success in 64ms
|
|
17
|
+
DTS Build start
|
|
18
|
+
DTS ⚡️ Build success in 15624ms
|
|
19
|
+
DTS dist/index.d.ts 1.17 KB
|
|
20
|
+
DTS dist/index.d.mts 1.17 KB
|
|
21
|
+
Done in 18.84s.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// src/Banner.tsx
|
|
2
|
+
import "react";
|
|
3
|
+
import Box from "@sproutsocial/seeds-react-box";
|
|
4
|
+
import Button from "@sproutsocial/seeds-react-button";
|
|
5
|
+
import Icon2 from "@sproutsocial/seeds-react-icon";
|
|
6
|
+
|
|
7
|
+
// src/styles.ts
|
|
8
|
+
import styled, { css } from "styled-components";
|
|
9
|
+
import { COMMON, LAYOUT } from "@sproutsocial/seeds-react-system-props";
|
|
10
|
+
import Icon from "@sproutsocial/seeds-react-icon";
|
|
11
|
+
|
|
12
|
+
// src/BannerTypes.ts
|
|
13
|
+
import "react";
|
|
14
|
+
|
|
15
|
+
// src/styles.ts
|
|
16
|
+
var Container = styled.div(
|
|
17
|
+
(props) => css`
|
|
18
|
+
display: flex;
|
|
19
|
+
overflow: hidden;
|
|
20
|
+
align-items: center;
|
|
21
|
+
justify-content: space-between;
|
|
22
|
+
color: ${props.theme.colors.text.body};
|
|
23
|
+
border-radius: ${props.theme.radii.outer};
|
|
24
|
+
font-family: ${props.theme.fontFamily};
|
|
25
|
+
${props.theme.typography[200]}
|
|
26
|
+
padding: ${props.theme.space[300]};
|
|
27
|
+
border: 1px solid ${props.theme.colors.container.border[props.type]};
|
|
28
|
+
background-color: ${props.theme.colors.container.background[props.type]};
|
|
29
|
+
|
|
30
|
+
a,
|
|
31
|
+
button {
|
|
32
|
+
font-weight: ${props.theme.fontWeights.semibold};
|
|
33
|
+
color: ${props.theme.colors.text.body};
|
|
34
|
+
font-size: inherit;
|
|
35
|
+
&:hover {
|
|
36
|
+
color: ${props.theme.colors.text.body};
|
|
37
|
+
text-decoration: underline;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
> span:not(.Icon) {
|
|
42
|
+
display: block;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
${COMMON}
|
|
46
|
+
${LAYOUT}
|
|
47
|
+
`
|
|
48
|
+
);
|
|
49
|
+
var styles_default = Container;
|
|
50
|
+
var StyledBannerIcon = styled(Icon)`
|
|
51
|
+
align-self: flex-start;
|
|
52
|
+
min-width: 16px;
|
|
53
|
+
`;
|
|
54
|
+
|
|
55
|
+
// src/Banner.tsx
|
|
56
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
57
|
+
var getBannerIconName = (type) => {
|
|
58
|
+
switch (type) {
|
|
59
|
+
case "success":
|
|
60
|
+
return "circle-check-outline";
|
|
61
|
+
case "error":
|
|
62
|
+
return "triangle-exclamation-outline";
|
|
63
|
+
case "warning":
|
|
64
|
+
return "triangle-exclamation-outline";
|
|
65
|
+
case "opportunity":
|
|
66
|
+
return "sparkle-outline";
|
|
67
|
+
case "info":
|
|
68
|
+
default:
|
|
69
|
+
return "circle-i-outline";
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var getBannerIconColor = (type) => {
|
|
73
|
+
switch (type) {
|
|
74
|
+
case "success":
|
|
75
|
+
return "icon.success";
|
|
76
|
+
case "error":
|
|
77
|
+
return "icon.error";
|
|
78
|
+
case "warning":
|
|
79
|
+
return "icon.warning";
|
|
80
|
+
case "opportunity":
|
|
81
|
+
return "icon.opportunity";
|
|
82
|
+
case "info":
|
|
83
|
+
default:
|
|
84
|
+
return "icon.info";
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
var Banner = ({
|
|
88
|
+
type = "info",
|
|
89
|
+
text,
|
|
90
|
+
onClose,
|
|
91
|
+
closeButtonLabel = "Close",
|
|
92
|
+
typeIconProps,
|
|
93
|
+
...rest
|
|
94
|
+
}) => {
|
|
95
|
+
return /* @__PURE__ */ jsx(
|
|
96
|
+
styles_default,
|
|
97
|
+
{
|
|
98
|
+
type,
|
|
99
|
+
"data-qa-alert": "",
|
|
100
|
+
"data-qa-alert-type": type,
|
|
101
|
+
"data-qa-alert-text": text,
|
|
102
|
+
...rest,
|
|
103
|
+
children: /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", width: 1, children: [
|
|
104
|
+
/* @__PURE__ */ jsx(
|
|
105
|
+
StyledBannerIcon,
|
|
106
|
+
{
|
|
107
|
+
name: getBannerIconName(type),
|
|
108
|
+
color: getBannerIconColor(type),
|
|
109
|
+
className: "Icon",
|
|
110
|
+
fixedWidth: true,
|
|
111
|
+
mt: 100,
|
|
112
|
+
mr: 350,
|
|
113
|
+
...typeIconProps
|
|
114
|
+
}
|
|
115
|
+
),
|
|
116
|
+
text,
|
|
117
|
+
onClose && /* @__PURE__ */ jsx(Box, { ml: "auto", pl: 400, alignSelf: "flex-start", children: /* @__PURE__ */ jsx(Button, { p: 0, onClick: onClose, ariaLabel: closeButtonLabel, children: /* @__PURE__ */ jsx(Icon2, { name: "x-outline", "aria-hidden": true }) }) })
|
|
118
|
+
] })
|
|
119
|
+
}
|
|
120
|
+
);
|
|
121
|
+
};
|
|
122
|
+
var Banner_default = Banner;
|
|
123
|
+
|
|
124
|
+
// src/index.ts
|
|
125
|
+
var src_default = Banner_default;
|
|
126
|
+
export {
|
|
127
|
+
Banner_default as Banner,
|
|
128
|
+
src_default as default
|
|
129
|
+
};
|
|
130
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/Banner.tsx","../../src/styles.ts","../../src/BannerTypes.ts","../../src/index.ts"],"sourcesContent":["import * as React from \"react\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Button from \"@sproutsocial/seeds-react-button\";\nimport Icon from \"@sproutsocial/seeds-react-icon\";\nimport Container, { StyledBannerIcon } from \"./styles\";\nimport type { TypeBannerProps, EnumBannerType } from \"./BannerTypes\";\n\nconst getBannerIconName = (type: EnumBannerType) => {\n switch (type) {\n case \"success\":\n return \"circle-check-outline\";\n case \"error\":\n return \"triangle-exclamation-outline\";\n case \"warning\":\n return \"triangle-exclamation-outline\";\n case \"opportunity\":\n return \"sparkle-outline\";\n case \"info\":\n default:\n return \"circle-i-outline\";\n }\n};\n\nconst getBannerIconColor = (type: EnumBannerType) => {\n switch (type) {\n case \"success\":\n return \"icon.success\";\n case \"error\":\n return \"icon.error\";\n case \"warning\":\n return \"icon.warning\";\n case \"opportunity\":\n return \"icon.opportunity\";\n case \"info\":\n default:\n return \"icon.info\";\n }\n};\n\n/** TODO: change to 'info' type by default in future version */\nconst Banner = ({\n type = \"info\",\n text,\n onClose,\n closeButtonLabel = \"Close\",\n typeIconProps,\n ...rest\n}: TypeBannerProps) => {\n return (\n <Container\n type={type}\n data-qa-alert=\"\"\n data-qa-alert-type={type}\n data-qa-alert-text={text}\n {...rest}\n >\n <Box display=\"flex\" alignItems=\"center\" width={1}>\n <StyledBannerIcon\n name={getBannerIconName(type)}\n color={getBannerIconColor(type)}\n className=\"Icon\"\n fixedWidth\n mt={100}\n mr={350}\n {...typeIconProps}\n />\n {text}\n {onClose && (\n <Box ml=\"auto\" pl={400} alignSelf=\"flex-start\">\n <Button p={0} onClick={onClose} ariaLabel={closeButtonLabel}>\n <Icon name=\"x-outline\" aria-hidden />\n </Button>\n </Box>\n )}\n </Box>\n </Container>\n );\n};\n\nexport default Banner;\n","import styled, { css } from \"styled-components\";\nimport { COMMON, LAYOUT } from \"@sproutsocial/seeds-react-system-props\";\nimport Icon from \"@sproutsocial/seeds-react-icon\";\nimport { type EnumBannerType } from \"./BannerTypes\";\n\ntype TypeProps = {\n type: EnumBannerType;\n};\n\nconst Container = styled.div<TypeProps>(\n (props) => css`\n display: flex;\n overflow: hidden;\n align-items: center;\n justify-content: space-between;\n color: ${props.theme.colors.text.body};\n border-radius: ${props.theme.radii.outer};\n font-family: ${props.theme.fontFamily};\n ${props.theme.typography[200]}\n padding: ${props.theme.space[300]};\n border: 1px solid ${props.theme.colors.container.border[props.type]};\n background-color: ${props.theme.colors.container.background[props.type]};\n\n a,\n button {\n font-weight: ${props.theme.fontWeights.semibold};\n color: ${props.theme.colors.text.body};\n font-size: inherit;\n &:hover {\n color: ${props.theme.colors.text.body};\n text-decoration: underline;\n }\n }\n\n > span:not(.Icon) {\n display: block;\n }\n\n ${COMMON}\n ${LAYOUT}\n `\n);\n\nexport default Container;\n\nexport const StyledBannerIcon = styled(Icon)`\n align-self: flex-start;\n min-width: 16px;\n`;\n","import * as React from \"react\";\nimport type { TypeStyledComponentsCommonProps } from \"@sproutsocial/seeds-react-system-props\";\nimport type {\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeIconProps } from \"@sproutsocial/seeds-react-icon\";\n\nexport type EnumBannerType =\n | \"success\"\n | \"info\"\n | \"error\"\n | \"warning\"\n | \"opportunity\";\n\nexport interface TypeBannerProps\n extends Omit<React.ComponentPropsWithoutRef<\"div\">, \"color\">,\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n TypeStyledComponentsCommonProps {\n text: React.ReactNode;\n /** Type of banner. */\n type?: EnumBannerType;\n /** Show the close icon in the banner with an action when clicked */\n onClose?: () => void;\n /** Close icon aria label */\n closeButtonLabel?: string;\n /** Icon props that can be passed to the Type specific Icon */\n typeIconProps?: Partial<Omit<TypeIconProps, \"name\">>;\n}\n","import Banner from \"./Banner\";\n\nexport default Banner;\nexport { Banner };\nexport * from \"./BannerTypes\";\n"],"mappings":";AAAA,OAAuB;AACvB,OAAO,SAAS;AAChB,OAAO,YAAY;AACnB,OAAOA,WAAU;;;ACHjB,OAAO,UAAU,WAAW;AAC5B,SAAS,QAAQ,cAAc;AAC/B,OAAO,UAAU;;;ACFjB,OAAuB;;;ADSvB,IAAM,YAAY,OAAO;AAAA,EACvB,CAAC,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,aAKA,MAAM,MAAM,OAAO,KAAK,IAAI;AAAA,qBACpB,MAAM,MAAM,MAAM,KAAK;AAAA,mBACzB,MAAM,MAAM,UAAU;AAAA,MACnC,MAAM,MAAM,WAAW,GAAG,CAAC;AAAA,eAClB,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA,wBACb,MAAM,MAAM,OAAO,UAAU,OAAO,MAAM,IAAI,CAAC;AAAA,wBAC/C,MAAM,MAAM,OAAO,UAAU,WAAW,MAAM,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,qBAItD,MAAM,MAAM,YAAY,QAAQ;AAAA,eACtC,MAAM,MAAM,OAAO,KAAK,IAAI;AAAA;AAAA;AAAA,iBAG1B,MAAM,MAAM,OAAO,KAAK,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASvC,MAAM;AAAA,MACN,MAAM;AAAA;AAEZ;AAEA,IAAO,iBAAQ;AAER,IAAM,mBAAmB,OAAO,IAAI;AAAA;AAAA;AAAA;;;ADWrC,SACE,KADF;AAjDN,IAAM,oBAAoB,CAAC,SAAyB;AAClD,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL;AACE,aAAO;AAAA,EACX;AACF;AAEA,IAAM,qBAAqB,CAAC,SAAyB;AACnD,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL;AACE,aAAO;AAAA,EACX;AACF;AAGA,IAAM,SAAS,CAAC;AAAA,EACd,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,mBAAmB;AAAA,EACnB;AAAA,EACA,GAAG;AACL,MAAuB;AACrB,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,iBAAc;AAAA,MACd,sBAAoB;AAAA,MACpB,sBAAoB;AAAA,MACnB,GAAG;AAAA,MAEJ,+BAAC,OAAI,SAAQ,QAAO,YAAW,UAAS,OAAO,GAC7C;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,kBAAkB,IAAI;AAAA,YAC5B,OAAO,mBAAmB,IAAI;AAAA,YAC9B,WAAU;AAAA,YACV,YAAU;AAAA,YACV,IAAI;AAAA,YACJ,IAAI;AAAA,YACH,GAAG;AAAA;AAAA,QACN;AAAA,QACC;AAAA,QACA,WACC,oBAAC,OAAI,IAAG,QAAO,IAAI,KAAK,WAAU,cAChC,8BAAC,UAAO,GAAG,GAAG,SAAS,SAAS,WAAW,kBACzC,8BAACC,OAAA,EAAK,MAAK,aAAY,eAAW,MAAC,GACrC,GACF;AAAA,SAEJ;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,iBAAQ;;;AG7Ef,IAAO,cAAQ;","names":["Icon","Icon"]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { TypeSystemCommonProps, TypeSystemLayoutProps, TypeStyledComponentsCommonProps } from '@sproutsocial/seeds-react-system-props';
|
|
4
|
+
import { TypeIconProps } from '@sproutsocial/seeds-react-icon';
|
|
5
|
+
|
|
6
|
+
type EnumBannerType = "success" | "info" | "error" | "warning" | "opportunity";
|
|
7
|
+
interface TypeBannerProps extends Omit<React.ComponentPropsWithoutRef<"div">, "color">, TypeSystemCommonProps, TypeSystemLayoutProps, TypeStyledComponentsCommonProps {
|
|
8
|
+
text: React.ReactNode;
|
|
9
|
+
/** Type of banner. */
|
|
10
|
+
type?: EnumBannerType;
|
|
11
|
+
/** Show the close icon in the banner with an action when clicked */
|
|
12
|
+
onClose?: () => void;
|
|
13
|
+
/** Close icon aria label */
|
|
14
|
+
closeButtonLabel?: string;
|
|
15
|
+
/** Icon props that can be passed to the Type specific Icon */
|
|
16
|
+
typeIconProps?: Partial<Omit<TypeIconProps, "name">>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** TODO: change to 'info' type by default in future version */
|
|
20
|
+
declare const Banner: ({ type, text, onClose, closeButtonLabel, typeIconProps, ...rest }: TypeBannerProps) => react_jsx_runtime.JSX.Element;
|
|
21
|
+
|
|
22
|
+
export { Banner, type EnumBannerType, type TypeBannerProps, Banner as default };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { TypeSystemCommonProps, TypeSystemLayoutProps, TypeStyledComponentsCommonProps } from '@sproutsocial/seeds-react-system-props';
|
|
4
|
+
import { TypeIconProps } from '@sproutsocial/seeds-react-icon';
|
|
5
|
+
|
|
6
|
+
type EnumBannerType = "success" | "info" | "error" | "warning" | "opportunity";
|
|
7
|
+
interface TypeBannerProps extends Omit<React.ComponentPropsWithoutRef<"div">, "color">, TypeSystemCommonProps, TypeSystemLayoutProps, TypeStyledComponentsCommonProps {
|
|
8
|
+
text: React.ReactNode;
|
|
9
|
+
/** Type of banner. */
|
|
10
|
+
type?: EnumBannerType;
|
|
11
|
+
/** Show the close icon in the banner with an action when clicked */
|
|
12
|
+
onClose?: () => void;
|
|
13
|
+
/** Close icon aria label */
|
|
14
|
+
closeButtonLabel?: string;
|
|
15
|
+
/** Icon props that can be passed to the Type specific Icon */
|
|
16
|
+
typeIconProps?: Partial<Omit<TypeIconProps, "name">>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** TODO: change to 'info' type by default in future version */
|
|
20
|
+
declare const Banner: ({ type, text, onClose, closeButtonLabel, typeIconProps, ...rest }: TypeBannerProps) => react_jsx_runtime.JSX.Element;
|
|
21
|
+
|
|
22
|
+
export { Banner, type EnumBannerType, type TypeBannerProps, Banner as default };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
Banner: () => Banner_default,
|
|
34
|
+
default: () => src_default
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(src_exports);
|
|
37
|
+
|
|
38
|
+
// src/Banner.tsx
|
|
39
|
+
var React2 = require("react");
|
|
40
|
+
var import_seeds_react_box = __toESM(require("@sproutsocial/seeds-react-box"));
|
|
41
|
+
var import_seeds_react_button = __toESM(require("@sproutsocial/seeds-react-button"));
|
|
42
|
+
var import_seeds_react_icon2 = __toESM(require("@sproutsocial/seeds-react-icon"));
|
|
43
|
+
|
|
44
|
+
// src/styles.ts
|
|
45
|
+
var import_styled_components = __toESM(require("styled-components"));
|
|
46
|
+
var import_seeds_react_system_props = require("@sproutsocial/seeds-react-system-props");
|
|
47
|
+
var import_seeds_react_icon = __toESM(require("@sproutsocial/seeds-react-icon"));
|
|
48
|
+
|
|
49
|
+
// src/BannerTypes.ts
|
|
50
|
+
var React = require("react");
|
|
51
|
+
|
|
52
|
+
// src/styles.ts
|
|
53
|
+
var Container = import_styled_components.default.div(
|
|
54
|
+
(props) => import_styled_components.css`
|
|
55
|
+
display: flex;
|
|
56
|
+
overflow: hidden;
|
|
57
|
+
align-items: center;
|
|
58
|
+
justify-content: space-between;
|
|
59
|
+
color: ${props.theme.colors.text.body};
|
|
60
|
+
border-radius: ${props.theme.radii.outer};
|
|
61
|
+
font-family: ${props.theme.fontFamily};
|
|
62
|
+
${props.theme.typography[200]}
|
|
63
|
+
padding: ${props.theme.space[300]};
|
|
64
|
+
border: 1px solid ${props.theme.colors.container.border[props.type]};
|
|
65
|
+
background-color: ${props.theme.colors.container.background[props.type]};
|
|
66
|
+
|
|
67
|
+
a,
|
|
68
|
+
button {
|
|
69
|
+
font-weight: ${props.theme.fontWeights.semibold};
|
|
70
|
+
color: ${props.theme.colors.text.body};
|
|
71
|
+
font-size: inherit;
|
|
72
|
+
&:hover {
|
|
73
|
+
color: ${props.theme.colors.text.body};
|
|
74
|
+
text-decoration: underline;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
> span:not(.Icon) {
|
|
79
|
+
display: block;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
${import_seeds_react_system_props.COMMON}
|
|
83
|
+
${import_seeds_react_system_props.LAYOUT}
|
|
84
|
+
`
|
|
85
|
+
);
|
|
86
|
+
var styles_default = Container;
|
|
87
|
+
var StyledBannerIcon = (0, import_styled_components.default)(import_seeds_react_icon.default)`
|
|
88
|
+
align-self: flex-start;
|
|
89
|
+
min-width: 16px;
|
|
90
|
+
`;
|
|
91
|
+
|
|
92
|
+
// src/Banner.tsx
|
|
93
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
94
|
+
var getBannerIconName = (type) => {
|
|
95
|
+
switch (type) {
|
|
96
|
+
case "success":
|
|
97
|
+
return "circle-check-outline";
|
|
98
|
+
case "error":
|
|
99
|
+
return "triangle-exclamation-outline";
|
|
100
|
+
case "warning":
|
|
101
|
+
return "triangle-exclamation-outline";
|
|
102
|
+
case "opportunity":
|
|
103
|
+
return "sparkle-outline";
|
|
104
|
+
case "info":
|
|
105
|
+
default:
|
|
106
|
+
return "circle-i-outline";
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
var getBannerIconColor = (type) => {
|
|
110
|
+
switch (type) {
|
|
111
|
+
case "success":
|
|
112
|
+
return "icon.success";
|
|
113
|
+
case "error":
|
|
114
|
+
return "icon.error";
|
|
115
|
+
case "warning":
|
|
116
|
+
return "icon.warning";
|
|
117
|
+
case "opportunity":
|
|
118
|
+
return "icon.opportunity";
|
|
119
|
+
case "info":
|
|
120
|
+
default:
|
|
121
|
+
return "icon.info";
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
var Banner = ({
|
|
125
|
+
type = "info",
|
|
126
|
+
text,
|
|
127
|
+
onClose,
|
|
128
|
+
closeButtonLabel = "Close",
|
|
129
|
+
typeIconProps,
|
|
130
|
+
...rest
|
|
131
|
+
}) => {
|
|
132
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
133
|
+
styles_default,
|
|
134
|
+
{
|
|
135
|
+
type,
|
|
136
|
+
"data-qa-alert": "",
|
|
137
|
+
"data-qa-alert-type": type,
|
|
138
|
+
"data-qa-alert-text": text,
|
|
139
|
+
...rest,
|
|
140
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_seeds_react_box.default, { display: "flex", alignItems: "center", width: 1, children: [
|
|
141
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
142
|
+
StyledBannerIcon,
|
|
143
|
+
{
|
|
144
|
+
name: getBannerIconName(type),
|
|
145
|
+
color: getBannerIconColor(type),
|
|
146
|
+
className: "Icon",
|
|
147
|
+
fixedWidth: true,
|
|
148
|
+
mt: 100,
|
|
149
|
+
mr: 350,
|
|
150
|
+
...typeIconProps
|
|
151
|
+
}
|
|
152
|
+
),
|
|
153
|
+
text,
|
|
154
|
+
onClose && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_box.default, { ml: "auto", pl: 400, alignSelf: "flex-start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_button.default, { p: 0, onClick: onClose, ariaLabel: closeButtonLabel, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_icon2.default, { name: "x-outline", "aria-hidden": true }) }) })
|
|
155
|
+
] })
|
|
156
|
+
}
|
|
157
|
+
);
|
|
158
|
+
};
|
|
159
|
+
var Banner_default = Banner;
|
|
160
|
+
|
|
161
|
+
// src/index.ts
|
|
162
|
+
var src_default = Banner_default;
|
|
163
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
164
|
+
0 && (module.exports = {
|
|
165
|
+
Banner
|
|
166
|
+
});
|
|
167
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/Banner.tsx","../src/styles.ts","../src/BannerTypes.ts"],"sourcesContent":["import Banner from \"./Banner\";\n\nexport default Banner;\nexport { Banner };\nexport * from \"./BannerTypes\";\n","import * as React from \"react\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Button from \"@sproutsocial/seeds-react-button\";\nimport Icon from \"@sproutsocial/seeds-react-icon\";\nimport Container, { StyledBannerIcon } from \"./styles\";\nimport type { TypeBannerProps, EnumBannerType } from \"./BannerTypes\";\n\nconst getBannerIconName = (type: EnumBannerType) => {\n switch (type) {\n case \"success\":\n return \"circle-check-outline\";\n case \"error\":\n return \"triangle-exclamation-outline\";\n case \"warning\":\n return \"triangle-exclamation-outline\";\n case \"opportunity\":\n return \"sparkle-outline\";\n case \"info\":\n default:\n return \"circle-i-outline\";\n }\n};\n\nconst getBannerIconColor = (type: EnumBannerType) => {\n switch (type) {\n case \"success\":\n return \"icon.success\";\n case \"error\":\n return \"icon.error\";\n case \"warning\":\n return \"icon.warning\";\n case \"opportunity\":\n return \"icon.opportunity\";\n case \"info\":\n default:\n return \"icon.info\";\n }\n};\n\n/** TODO: change to 'info' type by default in future version */\nconst Banner = ({\n type = \"info\",\n text,\n onClose,\n closeButtonLabel = \"Close\",\n typeIconProps,\n ...rest\n}: TypeBannerProps) => {\n return (\n <Container\n type={type}\n data-qa-alert=\"\"\n data-qa-alert-type={type}\n data-qa-alert-text={text}\n {...rest}\n >\n <Box display=\"flex\" alignItems=\"center\" width={1}>\n <StyledBannerIcon\n name={getBannerIconName(type)}\n color={getBannerIconColor(type)}\n className=\"Icon\"\n fixedWidth\n mt={100}\n mr={350}\n {...typeIconProps}\n />\n {text}\n {onClose && (\n <Box ml=\"auto\" pl={400} alignSelf=\"flex-start\">\n <Button p={0} onClick={onClose} ariaLabel={closeButtonLabel}>\n <Icon name=\"x-outline\" aria-hidden />\n </Button>\n </Box>\n )}\n </Box>\n </Container>\n );\n};\n\nexport default Banner;\n","import styled, { css } from \"styled-components\";\nimport { COMMON, LAYOUT } from \"@sproutsocial/seeds-react-system-props\";\nimport Icon from \"@sproutsocial/seeds-react-icon\";\nimport { type EnumBannerType } from \"./BannerTypes\";\n\ntype TypeProps = {\n type: EnumBannerType;\n};\n\nconst Container = styled.div<TypeProps>(\n (props) => css`\n display: flex;\n overflow: hidden;\n align-items: center;\n justify-content: space-between;\n color: ${props.theme.colors.text.body};\n border-radius: ${props.theme.radii.outer};\n font-family: ${props.theme.fontFamily};\n ${props.theme.typography[200]}\n padding: ${props.theme.space[300]};\n border: 1px solid ${props.theme.colors.container.border[props.type]};\n background-color: ${props.theme.colors.container.background[props.type]};\n\n a,\n button {\n font-weight: ${props.theme.fontWeights.semibold};\n color: ${props.theme.colors.text.body};\n font-size: inherit;\n &:hover {\n color: ${props.theme.colors.text.body};\n text-decoration: underline;\n }\n }\n\n > span:not(.Icon) {\n display: block;\n }\n\n ${COMMON}\n ${LAYOUT}\n `\n);\n\nexport default Container;\n\nexport const StyledBannerIcon = styled(Icon)`\n align-self: flex-start;\n min-width: 16px;\n`;\n","import * as React from \"react\";\nimport type { TypeStyledComponentsCommonProps } from \"@sproutsocial/seeds-react-system-props\";\nimport type {\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeIconProps } from \"@sproutsocial/seeds-react-icon\";\n\nexport type EnumBannerType =\n | \"success\"\n | \"info\"\n | \"error\"\n | \"warning\"\n | \"opportunity\";\n\nexport interface TypeBannerProps\n extends Omit<React.ComponentPropsWithoutRef<\"div\">, \"color\">,\n TypeSystemCommonProps,\n TypeSystemLayoutProps,\n TypeStyledComponentsCommonProps {\n text: React.ReactNode;\n /** Type of banner. */\n type?: EnumBannerType;\n /** Show the close icon in the banner with an action when clicked */\n onClose?: () => void;\n /** Close icon aria label */\n closeButtonLabel?: string;\n /** Icon props that can be passed to the Type specific Icon */\n typeIconProps?: Partial<Omit<TypeIconProps, \"name\">>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,SAAuB;AACvB,6BAAgB;AAChB,gCAAmB;AACnB,IAAAC,2BAAiB;;;ACHjB,+BAA4B;AAC5B,sCAA+B;AAC/B,8BAAiB;;;ACFjB,YAAuB;;;ADSvB,IAAM,YAAY,yBAAAC,QAAO;AAAA,EACvB,CAAC,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,aAKA,MAAM,MAAM,OAAO,KAAK,IAAI;AAAA,qBACpB,MAAM,MAAM,MAAM,KAAK;AAAA,mBACzB,MAAM,MAAM,UAAU;AAAA,MACnC,MAAM,MAAM,WAAW,GAAG,CAAC;AAAA,eAClB,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA,wBACb,MAAM,MAAM,OAAO,UAAU,OAAO,MAAM,IAAI,CAAC;AAAA,wBAC/C,MAAM,MAAM,OAAO,UAAU,WAAW,MAAM,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,qBAItD,MAAM,MAAM,YAAY,QAAQ;AAAA,eACtC,MAAM,MAAM,OAAO,KAAK,IAAI;AAAA;AAAA;AAAA,iBAG1B,MAAM,MAAM,OAAO,KAAK,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASvC,sCAAM;AAAA,MACN,sCAAM;AAAA;AAEZ;AAEA,IAAO,iBAAQ;AAER,IAAM,uBAAmB,yBAAAA,SAAO,wBAAAC,OAAI;AAAA;AAAA;AAAA;;;ADWrC;AAjDN,IAAM,oBAAoB,CAAC,SAAyB;AAClD,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL;AACE,aAAO;AAAA,EACX;AACF;AAEA,IAAM,qBAAqB,CAAC,SAAyB;AACnD,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL;AACE,aAAO;AAAA,EACX;AACF;AAGA,IAAM,SAAS,CAAC;AAAA,EACd,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,mBAAmB;AAAA,EACnB;AAAA,EACA,GAAG;AACL,MAAuB;AACrB,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,iBAAc;AAAA,MACd,sBAAoB;AAAA,MACpB,sBAAoB;AAAA,MACnB,GAAG;AAAA,MAEJ,uDAAC,uBAAAC,SAAA,EAAI,SAAQ,QAAO,YAAW,UAAS,OAAO,GAC7C;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,kBAAkB,IAAI;AAAA,YAC5B,OAAO,mBAAmB,IAAI;AAAA,YAC9B,WAAU;AAAA,YACV,YAAU;AAAA,YACV,IAAI;AAAA,YACJ,IAAI;AAAA,YACH,GAAG;AAAA;AAAA,QACN;AAAA,QACC;AAAA,QACA,WACC,4CAAC,uBAAAA,SAAA,EAAI,IAAG,QAAO,IAAI,KAAK,WAAU,cAChC,sDAAC,0BAAAC,SAAA,EAAO,GAAG,GAAG,SAAS,SAAS,WAAW,kBACzC,sDAAC,yBAAAC,SAAA,EAAK,MAAK,aAAY,eAAW,MAAC,GACrC,GACF;AAAA,SAEJ;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,iBAAQ;;;AD7Ef,IAAO,cAAQ;","names":["React","import_seeds_react_icon","styled","Icon","Box","Button","Icon"]}
|
package/jest.config.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sproutsocial/seeds-react-banner",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Seeds React Banner",
|
|
5
|
+
"author": "Sprout Social, Inc.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"module": "dist/esm/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsup --dts",
|
|
12
|
+
"build:debug": "tsup --dts --metafile",
|
|
13
|
+
"dev": "tsup --watch --dts",
|
|
14
|
+
"clean": "rm -rf .turbo dist",
|
|
15
|
+
"clean:modules": "rm -rf node_modules",
|
|
16
|
+
"typecheck": "tsc --noEmit",
|
|
17
|
+
"test": "jest",
|
|
18
|
+
"test:watch": "jest --watch --coverage=false"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@sproutsocial/seeds-react-theme": "^*",
|
|
22
|
+
"@sproutsocial/seeds-react-system-props": "^*",
|
|
23
|
+
"@sproutsocial/seeds-react-box": "*",
|
|
24
|
+
"@sproutsocial/seeds-react-button": "*",
|
|
25
|
+
"@sproutsocial/seeds-react-icon": "*"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/react": "^18.0.0",
|
|
29
|
+
"@types/styled-components": "^5.1.26",
|
|
30
|
+
"@sproutsocial/eslint-config-seeds": "*",
|
|
31
|
+
"react": "^18.0.0",
|
|
32
|
+
"styled-components": "^5.2.3",
|
|
33
|
+
"tsup": "^8.0.2",
|
|
34
|
+
"typescript": "^5.6.2",
|
|
35
|
+
"@sproutsocial/seeds-tsconfig": "*",
|
|
36
|
+
"@sproutsocial/seeds-testing": "*",
|
|
37
|
+
"@sproutsocial/seeds-react-testing-library": "*",
|
|
38
|
+
"@sproutsocial/seeds-react-text": "*",
|
|
39
|
+
"@sproutsocial/seeds-react-link": "*"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"styled-components": "^5.2.3"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18"
|
|
46
|
+
}
|
|
47
|
+
}
|
package/src/Banner.tsx
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import Box from "@sproutsocial/seeds-react-box";
|
|
3
|
+
import Button from "@sproutsocial/seeds-react-button";
|
|
4
|
+
import Icon from "@sproutsocial/seeds-react-icon";
|
|
5
|
+
import Container, { StyledBannerIcon } from "./styles";
|
|
6
|
+
import type { TypeBannerProps, EnumBannerType } from "./BannerTypes";
|
|
7
|
+
|
|
8
|
+
const getBannerIconName = (type: EnumBannerType) => {
|
|
9
|
+
switch (type) {
|
|
10
|
+
case "success":
|
|
11
|
+
return "circle-check-outline";
|
|
12
|
+
case "error":
|
|
13
|
+
return "triangle-exclamation-outline";
|
|
14
|
+
case "warning":
|
|
15
|
+
return "triangle-exclamation-outline";
|
|
16
|
+
case "opportunity":
|
|
17
|
+
return "sparkle-outline";
|
|
18
|
+
case "info":
|
|
19
|
+
default:
|
|
20
|
+
return "circle-i-outline";
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const getBannerIconColor = (type: EnumBannerType) => {
|
|
25
|
+
switch (type) {
|
|
26
|
+
case "success":
|
|
27
|
+
return "icon.success";
|
|
28
|
+
case "error":
|
|
29
|
+
return "icon.error";
|
|
30
|
+
case "warning":
|
|
31
|
+
return "icon.warning";
|
|
32
|
+
case "opportunity":
|
|
33
|
+
return "icon.opportunity";
|
|
34
|
+
case "info":
|
|
35
|
+
default:
|
|
36
|
+
return "icon.info";
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/** TODO: change to 'info' type by default in future version */
|
|
41
|
+
const Banner = ({
|
|
42
|
+
type = "info",
|
|
43
|
+
text,
|
|
44
|
+
onClose,
|
|
45
|
+
closeButtonLabel = "Close",
|
|
46
|
+
typeIconProps,
|
|
47
|
+
...rest
|
|
48
|
+
}: TypeBannerProps) => {
|
|
49
|
+
return (
|
|
50
|
+
<Container
|
|
51
|
+
type={type}
|
|
52
|
+
data-qa-alert=""
|
|
53
|
+
data-qa-alert-type={type}
|
|
54
|
+
data-qa-alert-text={text}
|
|
55
|
+
{...rest}
|
|
56
|
+
>
|
|
57
|
+
<Box display="flex" alignItems="center" width={1}>
|
|
58
|
+
<StyledBannerIcon
|
|
59
|
+
name={getBannerIconName(type)}
|
|
60
|
+
color={getBannerIconColor(type)}
|
|
61
|
+
className="Icon"
|
|
62
|
+
fixedWidth
|
|
63
|
+
mt={100}
|
|
64
|
+
mr={350}
|
|
65
|
+
{...typeIconProps}
|
|
66
|
+
/>
|
|
67
|
+
{text}
|
|
68
|
+
{onClose && (
|
|
69
|
+
<Box ml="auto" pl={400} alignSelf="flex-start">
|
|
70
|
+
<Button p={0} onClick={onClose} ariaLabel={closeButtonLabel}>
|
|
71
|
+
<Icon name="x-outline" aria-hidden />
|
|
72
|
+
</Button>
|
|
73
|
+
</Box>
|
|
74
|
+
)}
|
|
75
|
+
</Box>
|
|
76
|
+
</Container>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export default Banner;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { TypeStyledComponentsCommonProps } from "@sproutsocial/seeds-react-system-props";
|
|
3
|
+
import type {
|
|
4
|
+
TypeSystemCommonProps,
|
|
5
|
+
TypeSystemLayoutProps,
|
|
6
|
+
} from "@sproutsocial/seeds-react-system-props";
|
|
7
|
+
import type { TypeIconProps } from "@sproutsocial/seeds-react-icon";
|
|
8
|
+
|
|
9
|
+
export type EnumBannerType =
|
|
10
|
+
| "success"
|
|
11
|
+
| "info"
|
|
12
|
+
| "error"
|
|
13
|
+
| "warning"
|
|
14
|
+
| "opportunity";
|
|
15
|
+
|
|
16
|
+
export interface TypeBannerProps
|
|
17
|
+
extends Omit<React.ComponentPropsWithoutRef<"div">, "color">,
|
|
18
|
+
TypeSystemCommonProps,
|
|
19
|
+
TypeSystemLayoutProps,
|
|
20
|
+
TypeStyledComponentsCommonProps {
|
|
21
|
+
text: React.ReactNode;
|
|
22
|
+
/** Type of banner. */
|
|
23
|
+
type?: EnumBannerType;
|
|
24
|
+
/** Show the close icon in the banner with an action when clicked */
|
|
25
|
+
onClose?: () => void;
|
|
26
|
+
/** Close icon aria label */
|
|
27
|
+
closeButtonLabel?: string;
|
|
28
|
+
/** Icon props that can be passed to the Type specific Icon */
|
|
29
|
+
typeIconProps?: Partial<Omit<TypeIconProps, "name">>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import Banner from "../Banner";
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
5
|
+
function BannerTypes() {
|
|
6
|
+
return (
|
|
7
|
+
<>
|
|
8
|
+
<Banner text="Banner Text" />
|
|
9
|
+
<Banner text="Banner Text" type="success" />
|
|
10
|
+
<Banner text="Banner Text" type="info" />
|
|
11
|
+
<Banner text="Banner Text" type="error" />
|
|
12
|
+
<Banner text="Banner Text" type="warning" />
|
|
13
|
+
<Banner text="Banner Text" type="opportunity" />
|
|
14
|
+
<Banner
|
|
15
|
+
text="Banner Text"
|
|
16
|
+
mb="400"
|
|
17
|
+
maxWidth="400px"
|
|
18
|
+
display={["flex", "block", "contents"]}
|
|
19
|
+
/>
|
|
20
|
+
<Banner
|
|
21
|
+
text="Banner Text"
|
|
22
|
+
onClose={() => console.log("valid")}
|
|
23
|
+
closeButtonLabel="Close the banner"
|
|
24
|
+
/>
|
|
25
|
+
<Banner
|
|
26
|
+
text="Banner Text"
|
|
27
|
+
type="warning"
|
|
28
|
+
typeIconProps={{ "aria-label": "Warning" }}
|
|
29
|
+
/>
|
|
30
|
+
<Banner
|
|
31
|
+
text="Warning: Banner Text"
|
|
32
|
+
type="warning"
|
|
33
|
+
typeIconProps={{ "aria-hidden": true }}
|
|
34
|
+
/>
|
|
35
|
+
{/* @ts-expect-error - test that invalid type is rejected */}
|
|
36
|
+
<Banner text="Banner Text" type="invalid" />
|
|
37
|
+
{/* @ts-expect-error - test that invalid onClose is rejected */}
|
|
38
|
+
<Banner text="Banner Text" onClose="invalid" />
|
|
39
|
+
<Banner
|
|
40
|
+
text="Banner Text"
|
|
41
|
+
// @ts-expect-error - test that invalid closeButtonLabel is rejected
|
|
42
|
+
closeButtonLabel={() => console.log("invalid")}
|
|
43
|
+
/>
|
|
44
|
+
<Banner
|
|
45
|
+
text="Banner Text"
|
|
46
|
+
type="warning"
|
|
47
|
+
// @ts-expect-error - test that typeIconProps does not allow name
|
|
48
|
+
typeIconProps={{ name: "sparkles" }}
|
|
49
|
+
/>
|
|
50
|
+
</>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render, screen } from "@sproutsocial/seeds-react-testing-library";
|
|
3
|
+
import Banner from "../Banner";
|
|
4
|
+
|
|
5
|
+
describe("Banner", () => {
|
|
6
|
+
it("should render as info when no type is provided", () => {
|
|
7
|
+
render(<Banner text="Banner Text" />);
|
|
8
|
+
|
|
9
|
+
expect(screen.getByText("Banner Text")).toBeInTheDocument();
|
|
10
|
+
expect(screen.getByDataQaLabel({ icon: "circle-i-outline" })).toBeTruthy();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("should render with success type", () => {
|
|
14
|
+
render(<Banner text="Banner Text" type="success" />);
|
|
15
|
+
|
|
16
|
+
expect(screen.getByText("Banner Text")).toBeInTheDocument();
|
|
17
|
+
expect(
|
|
18
|
+
screen.getByDataQaLabel({ icon: "circle-check-outline" })
|
|
19
|
+
).toBeTruthy();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("should render with info type", () => {
|
|
23
|
+
render(<Banner text="Banner Text" type="info" />);
|
|
24
|
+
|
|
25
|
+
expect(screen.getByText("Banner Text")).toBeInTheDocument();
|
|
26
|
+
expect(screen.getByDataQaLabel({ icon: "circle-i-outline" })).toBeTruthy();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("should render with error type", () => {
|
|
30
|
+
render(<Banner text="Banner Text" type="error" />);
|
|
31
|
+
|
|
32
|
+
expect(screen.getByText("Banner Text")).toBeInTheDocument();
|
|
33
|
+
expect(
|
|
34
|
+
screen.getByDataQaLabel({ icon: "triangle-exclamation-outline" })
|
|
35
|
+
).toBeTruthy();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("should render with warning type", () => {
|
|
39
|
+
render(<Banner text="Banner Text" type="warning" />);
|
|
40
|
+
|
|
41
|
+
expect(screen.getByText("Banner Text")).toBeInTheDocument();
|
|
42
|
+
expect(
|
|
43
|
+
screen.getByDataQaLabel({ icon: "triangle-exclamation-outline" })
|
|
44
|
+
).toBeTruthy();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should render with opportunity type", () => {
|
|
48
|
+
render(<Banner text="Banner Text" type="opportunity" />);
|
|
49
|
+
|
|
50
|
+
expect(screen.getByText("Banner Text")).toBeInTheDocument();
|
|
51
|
+
expect(screen.getByDataQaLabel({ icon: "sparkle-outline" })).toBeTruthy();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("should render with onClose x icon", () => {
|
|
55
|
+
render(<Banner text="Banner Text" onClose={() => console.log("valid")} />);
|
|
56
|
+
|
|
57
|
+
expect(screen.getByText("Banner Text")).toBeInTheDocument();
|
|
58
|
+
expect(screen.getByDataQaLabel({ icon: "x-outline" })).toBeTruthy();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("should render with onClose x icon and closeButtonLabel aria-label", () => {
|
|
62
|
+
render(
|
|
63
|
+
<Banner
|
|
64
|
+
text="Banner Text"
|
|
65
|
+
onClose={() => console.log("valid")}
|
|
66
|
+
closeButtonLabel="Close the banner"
|
|
67
|
+
/>
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
expect(screen.getByText("Banner Text")).toBeInTheDocument();
|
|
71
|
+
expect(screen.getByDataQaLabel({ icon: "x-outline" })).toBeTruthy();
|
|
72
|
+
expect(screen.getByLabelText("Close the banner")).toBeInTheDocument();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("should should set icon aria-label when typeIconProps includes aria-label", () => {
|
|
76
|
+
render(
|
|
77
|
+
<Banner
|
|
78
|
+
text="Banner Text"
|
|
79
|
+
type="warning"
|
|
80
|
+
typeIconProps={{ "aria-label": "Warning" }}
|
|
81
|
+
/>
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
expect(screen.getByText("Banner Text")).toBeInTheDocument();
|
|
85
|
+
expect(screen.getByRole("img", { name: "Warning" })).toBeInTheDocument();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("should should set icon aria-hidden when typeIconProps includes aria-hidden", () => {
|
|
89
|
+
render(
|
|
90
|
+
<Banner
|
|
91
|
+
text="Warning: Banner Text"
|
|
92
|
+
type="warning"
|
|
93
|
+
typeIconProps={{ "aria-hidden": true }}
|
|
94
|
+
/>
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
expect(screen.getByText("Warning: Banner Text")).toBeInTheDocument();
|
|
98
|
+
expect(screen.getByRole("img", { hidden: true })).toBeInTheDocument();
|
|
99
|
+
});
|
|
100
|
+
});
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Banner, type TypeBannerProps, type EnumBannerType } from "./";
|
|
3
|
+
import { Box } from "@sproutsocial/seeds-react-box";
|
|
4
|
+
import { Link } from "@sproutsocial/seeds-react-link";
|
|
5
|
+
import { Text } from "@sproutsocial/seeds-react-text";
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
title: "Components/Banner",
|
|
9
|
+
component: Banner,
|
|
10
|
+
argTypes: {
|
|
11
|
+
type: {
|
|
12
|
+
options: ["success", "info", "error", "warning", "opportunity"],
|
|
13
|
+
control: { type: "select" },
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
args: {
|
|
17
|
+
type: "success",
|
|
18
|
+
typeIconProps: { "aria-label": "Success" },
|
|
19
|
+
text: "This is a success message!",
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const findText = (bannerType: TypeBannerProps["type"]) => {
|
|
24
|
+
switch (bannerType) {
|
|
25
|
+
case "warning":
|
|
26
|
+
return "This is a warning message!";
|
|
27
|
+
case "opportunity":
|
|
28
|
+
return "This is an opportunity message!";
|
|
29
|
+
case "error":
|
|
30
|
+
return "This is an error message!";
|
|
31
|
+
case "info":
|
|
32
|
+
return "This is an informative message!";
|
|
33
|
+
case "success":
|
|
34
|
+
default:
|
|
35
|
+
return "This is a success message!";
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const permutations = (args: TypeBannerProps) => (
|
|
40
|
+
<Banner
|
|
41
|
+
text={findText(args.type)}
|
|
42
|
+
type={args.type}
|
|
43
|
+
typeIconProps={{ "aria-label": args.type }}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
permutations.storyName = "Permutations";
|
|
48
|
+
|
|
49
|
+
export const links = (args: TypeBannerProps) => (
|
|
50
|
+
<Banner
|
|
51
|
+
type={args.type}
|
|
52
|
+
typeIconProps={args.typeIconProps}
|
|
53
|
+
text={
|
|
54
|
+
<Box
|
|
55
|
+
width={1}
|
|
56
|
+
display="flex"
|
|
57
|
+
alignItems="center"
|
|
58
|
+
justifyContent="space-between"
|
|
59
|
+
>
|
|
60
|
+
<Text>{findText(args.type)}</Text>
|
|
61
|
+
<Text>
|
|
62
|
+
<Link href="/">Learn more</Link>
|
|
63
|
+
</Text>
|
|
64
|
+
</Box>
|
|
65
|
+
}
|
|
66
|
+
/>
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
links.storyName = "With link";
|
|
70
|
+
|
|
71
|
+
export const buttons = (args: TypeBannerProps) => (
|
|
72
|
+
<Banner
|
|
73
|
+
type={args.type}
|
|
74
|
+
typeIconProps={args.typeIconProps}
|
|
75
|
+
text={
|
|
76
|
+
<Box
|
|
77
|
+
width={1}
|
|
78
|
+
display="flex"
|
|
79
|
+
alignItems="center"
|
|
80
|
+
justifyContent="space-between"
|
|
81
|
+
>
|
|
82
|
+
<Text>{findText(args.type)}</Text>
|
|
83
|
+
<Text>
|
|
84
|
+
<Link onClick={() => alert("Clicked")}>Learn more</Link>
|
|
85
|
+
</Text>
|
|
86
|
+
</Box>
|
|
87
|
+
}
|
|
88
|
+
/>
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
buttons.storyName = "With button";
|
|
92
|
+
|
|
93
|
+
export const multiline = (args: TypeBannerProps) => (
|
|
94
|
+
<Box width="416px">
|
|
95
|
+
<Banner
|
|
96
|
+
text={args.text}
|
|
97
|
+
type={args.type}
|
|
98
|
+
typeIconProps={args.typeIconProps}
|
|
99
|
+
/>
|
|
100
|
+
</Box>
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
multiline.args = {
|
|
104
|
+
text: "A very long opportunity message that is going to stretch to multiple lines, while the icon stays aligned with the first line.",
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
multiline.storyName = "With multiline text";
|
|
108
|
+
|
|
109
|
+
export const closeable = (args: TypeBannerProps) => (
|
|
110
|
+
<Banner
|
|
111
|
+
text={args.text}
|
|
112
|
+
type={args.type}
|
|
113
|
+
typeIconProps={args.typeIconProps}
|
|
114
|
+
onClose={() => alert("Testing...")}
|
|
115
|
+
closeButtonLabel="Close the banner"
|
|
116
|
+
/>
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
closeable.args = {
|
|
120
|
+
text: "This is a banner that has a closeable x icon with an onClose callback.",
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
closeable.storyName = "With OnClose callback";
|
|
124
|
+
|
|
125
|
+
export const hiddenIcon = (args: TypeBannerProps) => (
|
|
126
|
+
<Banner
|
|
127
|
+
text={args.text}
|
|
128
|
+
type={args.type}
|
|
129
|
+
typeIconProps={args.typeIconProps}
|
|
130
|
+
onClose={() => alert("Testing...")}
|
|
131
|
+
closeButtonLabel="Close the banner"
|
|
132
|
+
/>
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
hiddenIcon.args = {
|
|
136
|
+
text: "Success! This is a banner that hides the icon from screen readers!",
|
|
137
|
+
typeIconProps: { "aria-hidden": true },
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
hiddenIcon.storyName = "With aria-hidden Icon";
|
package/src/index.ts
ADDED
package/src/styles.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import styled, { css } from "styled-components";
|
|
2
|
+
import { COMMON, LAYOUT } from "@sproutsocial/seeds-react-system-props";
|
|
3
|
+
import Icon from "@sproutsocial/seeds-react-icon";
|
|
4
|
+
import { type EnumBannerType } from "./BannerTypes";
|
|
5
|
+
|
|
6
|
+
type TypeProps = {
|
|
7
|
+
type: EnumBannerType;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const Container = styled.div<TypeProps>(
|
|
11
|
+
(props) => css`
|
|
12
|
+
display: flex;
|
|
13
|
+
overflow: hidden;
|
|
14
|
+
align-items: center;
|
|
15
|
+
justify-content: space-between;
|
|
16
|
+
color: ${props.theme.colors.text.body};
|
|
17
|
+
border-radius: ${props.theme.radii.outer};
|
|
18
|
+
font-family: ${props.theme.fontFamily};
|
|
19
|
+
${props.theme.typography[200]}
|
|
20
|
+
padding: ${props.theme.space[300]};
|
|
21
|
+
border: 1px solid ${props.theme.colors.container.border[props.type]};
|
|
22
|
+
background-color: ${props.theme.colors.container.background[props.type]};
|
|
23
|
+
|
|
24
|
+
a,
|
|
25
|
+
button {
|
|
26
|
+
font-weight: ${props.theme.fontWeights.semibold};
|
|
27
|
+
color: ${props.theme.colors.text.body};
|
|
28
|
+
font-size: inherit;
|
|
29
|
+
&:hover {
|
|
30
|
+
color: ${props.theme.colors.text.body};
|
|
31
|
+
text-decoration: underline;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
> span:not(.Icon) {
|
|
36
|
+
display: block;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
${COMMON}
|
|
40
|
+
${LAYOUT}
|
|
41
|
+
`
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
export default Container;
|
|
45
|
+
|
|
46
|
+
export const StyledBannerIcon = styled(Icon)`
|
|
47
|
+
align-self: flex-start;
|
|
48
|
+
min-width: 16px;
|
|
49
|
+
`;
|
package/tsconfig.json
ADDED
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { defineConfig } from "tsup";
|
|
2
|
+
|
|
3
|
+
export default defineConfig((options) => ({
|
|
4
|
+
entry: ["src/index.ts"],
|
|
5
|
+
format: ["cjs", "esm"],
|
|
6
|
+
clean: true,
|
|
7
|
+
legacyOutput: true,
|
|
8
|
+
dts: options.dts,
|
|
9
|
+
external: ["react"],
|
|
10
|
+
sourcemap: true,
|
|
11
|
+
metafile: options.metafile,
|
|
12
|
+
}));
|