orcs-design-system
Version:
TeamForm's Design System, aka: ORCS
364 lines • 11 kB
JavaScript
import React, { useState } from "react";
import PropTypes from "prop-types";
import styled, { ThemeProvider } from "styled-components";
import Icon from "../Icon";
import Loading from "../Loading";
import { css } from "@styled-system/css";
import shouldForwardProp from "@styled-system/should-forward-prop";
import { space, layout, position, variant, compose } from "styled-system";
import { themeGet } from "@styled-system/theme-get";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const NotificationStyles = compose(space, layout, position);
const NotificationWrapper = styled("div").withConfig({
shouldForwardProp,
displayName: "Notification__NotificationWrapper",
componentId: "sc-1p26rkq-0"
}).attrs(props => ({
className: props.notifClass
}))(props => css({
position: "relative",
color: props.altStyle ? themeGet("colors.black90")(props) : themeGet("colors.white")(props),
fontSize: themeGet("fontSizes.1")(props),
fontWeight: themeGet("fontWeights.2")(props),
px: "s",
py: "s",
cursor: "default",
display: "flex",
alignItems: "center",
justifyContent: "flex-start",
borderRadius: themeGet("radii.1")(props),
bg: props.altStyle ? themeGet("colors.primaryLighter")(props) : themeGet("colors.primaryDark")(props),
"&.floating": {
zIndex: "13",
position: "fixed"
},
"&.centered": {
left: "50%",
transform: "translateX(-50%)",
right: "auto"
}
}), props => variant({
prop: "colour",
variants: {
success: {
bg: props.altStyle ? themeGet("colors.successLightest")(props) : themeGet("colors.successDark")(props),
color: props.altStyle ? themeGet("colors.black90")(props) : themeGet("colors.white")(props)
},
danger: {
bg: props.altStyle ? themeGet("colors.dangerLightest")(props) : themeGet("colors.dangerDark")(props),
color: props.altStyle ? themeGet("colors.black90")(props) : themeGet("colors.white")(props)
},
warning: {
bg: props.altStyle ? themeGet("colors.warningLightest")(props) : themeGet("colors.warning")(props),
color: props.altStyle ? themeGet("colors.black90")(props) : themeGet("colors.white")(props)
},
default: {}
}
}), variant({
variants: {
success: {
bg: themeGet("colors.successDark")
},
danger: {
bg: themeGet("colors.dangerDark")
},
warning: {
bg: themeGet("colors.warningLight"),
color: themeGet("colors.black80")
},
default: {
bg: themeGet("colors.primaryDark")
}
}
}), NotificationStyles);
const NotificationContent = styled("p").withConfig({
displayName: "Notification__NotificationContent",
componentId: "sc-1p26rkq-1"
})(props => css({
lineHeight: themeGet("fontSizes.3")(props),
pr: props.closable === false ? "0" : "s"
}));
const CloseButton = styled("button").withConfig({
displayName: "Notification__CloseButton",
componentId: "sc-1p26rkq-2"
})(props => css({
appearance: "none",
bg: "transparent",
p: "0",
paddingLeft: "1",
paddingRight: "1",
border: "none",
ml: "auto",
cursor: "pointer",
opacity: "0.7",
transition: themeGet("transition.transitionDefault")(props),
color: themeGet("colors.white")(props),
"&:hover, &:focus": {
outline: "0",
opacity: "1"
}
}));
const NotificationIcon = styled(Icon).withConfig({
displayName: "Notification__NotificationIcon",
componentId: "sc-1p26rkq-3"
})(props => css({
color: props.altStyle ? themeGet("colors.black70")(props) : themeGet("colors.white")(props),
fontSize: themeGet("fontSizes.2")(props),
mr: "s"
}));
export default function Notification(_ref) {
let {
icon,
colour,
floating,
children,
top,
right,
bottom,
left,
centered,
closable,
onDismiss,
theme,
iconProps,
loading,
altStyle,
...props
} = _ref;
const [dismissed, handleDismiss] = useState(false);
const onToggle = () => {
if (!dismissed) {
handleDismiss(true);
if (onDismiss) {
onDismiss(true);
}
} else {
handleDismiss(false);
}
};
let notifClass;
if (floating) {
if (centered) {
notifClass = "floating centered";
} else {
notifClass = "floating";
}
} else {
notifClass = "";
}
if (dismissed) {
return null;
}
const component = /*#__PURE__*/_jsxs(NotificationWrapper, {
colour: colour,
floating: floating,
top: top,
right: right,
bottom: bottom,
left: left,
centered: centered,
iconProps: iconProps,
notifClass: notifClass,
role: "alert",
altStyle: altStyle,
...props,
children: [icon && /*#__PURE__*/_jsx(NotificationIcon, {
colour: colour,
icon: icon,
altStyle: altStyle,
...iconProps
}), loading && /*#__PURE__*/_jsx(Loading, {
small: true,
inverted: !altStyle,
mr: "s"
}), /*#__PURE__*/_jsx(NotificationContent, {
closable: closable,
children: children
}), closable && /*#__PURE__*/_jsx(CloseButton, {
className: "close-button",
tabIndex: "0",
onClick: onToggle,
"aria-label": "Close Notification",
children: /*#__PURE__*/_jsx(Icon, {
icon: ["fas", "times"],
size: "lg",
color: altStyle ? "black70" : "white"
})
})]
});
return theme ? /*#__PURE__*/_jsx(ThemeProvider, {
theme: theme,
children: component
}) : component;
}
Notification.propTypes = {
children: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]),
/** Applies an icon to notification with specified name. */
icon: PropTypes.array,
/** Specifies the props of the icon -- see `Icon` component for accepted props */
iconProps: PropTypes.object,
/** Specifies notification colour */
colour: PropTypes.oneOf(["success", "warning", "danger", "primary"]),
/** Specifies if the `Icon` should show the loading style. */
loading: PropTypes.bool,
/** Positions notification floating over content, instead of inline. Must be combined with top, right, bottom, left or centered props to correctly position in your desired location */
floating: PropTypes.bool,
/** Specifies the position of a floating notification from top of browser window (units must be specified) */
top: PropTypes.string,
/** Specifies the position of a floating notification from right of browser window (units must be specified) */
right: PropTypes.string,
/** Specifies the position of a floating notification from bottom of browser window (units must be specified) */
bottom: PropTypes.string,
/** Specifies the position of a floating notification from left of browser window (units must be specified) */
left: PropTypes.string,
/** Horizontally centers a floating notification. If you use this, you don't need to specify left or right props, only top or bottom depending on if you want the notification to sit at the top or bottom of the screen */
centered: PropTypes.bool,
/** A callback function for the dismiss operation.*/
onDismiss: PropTypes.func,
/** Showing the close button, default to true.*/
closable: PropTypes.bool,
/** Specifies if the notification should use the alternate style. */
altStyle: PropTypes.bool,
/** Specifies the system design theme. */
theme: PropTypes.object
};
Notification.defaultProps = {
closable: true
};
Notification.__docgenInfo = {
"description": "",
"methods": [],
"displayName": "Notification",
"props": {
"closable": {
"defaultValue": {
"value": "true",
"computed": false
},
"description": "Showing the close button, default to true.",
"type": {
"name": "bool"
},
"required": false
},
"children": {
"description": "",
"type": {
"name": "union",
"value": [{
"name": "node"
}, {
"name": "arrayOf",
"value": {
"name": "node"
}
}]
},
"required": false
},
"icon": {
"description": "Applies an icon to notification with specified name.",
"type": {
"name": "array"
},
"required": false
},
"iconProps": {
"description": "Specifies the props of the icon -- see `Icon` component for accepted props",
"type": {
"name": "object"
},
"required": false
},
"colour": {
"description": "Specifies notification colour",
"type": {
"name": "enum",
"value": [{
"value": "\"success\"",
"computed": false
}, {
"value": "\"warning\"",
"computed": false
}, {
"value": "\"danger\"",
"computed": false
}, {
"value": "\"primary\"",
"computed": false
}]
},
"required": false
},
"loading": {
"description": "Specifies if the `Icon` should show the loading style.",
"type": {
"name": "bool"
},
"required": false
},
"floating": {
"description": "Positions notification floating over content, instead of inline. Must be combined with top, right, bottom, left or centered props to correctly position in your desired location",
"type": {
"name": "bool"
},
"required": false
},
"top": {
"description": "Specifies the position of a floating notification from top of browser window (units must be specified)",
"type": {
"name": "string"
},
"required": false
},
"right": {
"description": "Specifies the position of a floating notification from right of browser window (units must be specified)",
"type": {
"name": "string"
},
"required": false
},
"bottom": {
"description": "Specifies the position of a floating notification from bottom of browser window (units must be specified)",
"type": {
"name": "string"
},
"required": false
},
"left": {
"description": "Specifies the position of a floating notification from left of browser window (units must be specified)",
"type": {
"name": "string"
},
"required": false
},
"centered": {
"description": "Horizontally centers a floating notification. If you use this, you don't need to specify left or right props, only top or bottom depending on if you want the notification to sit at the top or bottom of the screen",
"type": {
"name": "bool"
},
"required": false
},
"onDismiss": {
"description": "A callback function for the dismiss operation.",
"type": {
"name": "func"
},
"required": false
},
"altStyle": {
"description": "Specifies if the notification should use the alternate style.",
"type": {
"name": "bool"
},
"required": false
},
"theme": {
"description": "Specifies the system design theme.",
"type": {
"name": "object"
},
"required": false
}
}
};