orcs-design-system
Version:
TeamForm's Design System, aka: ORCS
389 lines (387 loc) • 18.5 kB
JavaScript
import React from "react";
import styled, { css, ThemeProvider } from "styled-components";
import PropTypes from "prop-types";
import { space, layout } from "styled-system";
import Avatar from "../Avatar";
import Icon from "../Icon";
import Flex from "../Flex";
import Loading from "../Loading";
import { themeGet } from "@styled-system/theme-get";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const TagWrapper = styled.div.withConfig({
displayName: "Tag__TagWrapper",
componentId: "sc-1dh2aa8-0"
})(["", " ", " display:flex;align-items:stretch;height:100%;min-height:", ";justify-content:center;> button{margin:0;}"], space, layout, props => props.small ? themeGet("tagScale.tagHeightSmall") : themeGet("tagScale.tagHeightDefault"));
const TagValue = styled.button.attrs(props => ({
"aria-pressed": props.selected
})).withConfig({
displayName: "Tag__TagValue",
componentId: "sc-1dh2aa8-1"
})(["-moz-appearance:none;-webkit-appearance:none;appearance:none;box-shadow:none;font-family:\"Open Sans\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;line-height:", ";display:flex;gap:", ";align-items:center;flex-wrap:wrap;font-size:", ";font-weight:", ";white-space:nowrap;position:relative;z-index:1;transition:", ";cursor:", ";border-radius:", ";border-top-right-radius:", ";border-bottom-right-radius:", ";border:solid 1px ", ";padding:", ";background-color:", ";color:", ";", ""], props => themeGet("fontSizes.1")(props), props => props.small ? "3px" : "4px", props => props.small ? themeGet("fontSizes.0")(props) : themeGet("fontSizes.1")(props), props => themeGet("fontWeights.2")(props), props => themeGet("transition.transitionDefault")(props), props => props.disabled ? "default" : "pointer", themeGet("tagScale.tagBorderRadius"), props => props.showEdit || props.showInfo || props.showRemove ? "0" : themeGet("tagScale.tagBorderRadius"), props => props.showEdit || props.showInfo || props.showRemove ? "0" : themeGet("tagScale.tagBorderRadius"), props => props.disabled ? themeGet("colors.greyLight")(props) : props.selected && props.highlighted ? themeGet("colors.warningLighter")(props) : props.highlighted ? themeGet("colors.warningDark")(props) : themeGet("colors.primary")(props), props => props.small ? themeGet("tagScale.tagPaddingSmall") : themeGet("tagScale.tagPaddingDefault"), props => props.disabled ? themeGet("colors.greyLighter")(props) : props.selected && props.highlighted ? themeGet("colors.warningLighter")(props) : props.highlighted ? themeGet("colors.white")(props) : props.selected ? themeGet("colors.primary")(props) : themeGet("colors.white")(props), props => props.disabled ? themeGet("colors.greyDarker")(props) : props.selected && props.highlighted ? themeGet("colors.black80")(props) : props.highlighted ? themeGet("colors.warningDarker")(props) : props.selected ? themeGet("colors.white")(props) : themeGet("colors.primary")(props), props => props.disabled ? css([""]) : css(["&:hover,&:focus{outline:0;border:", ";color:", ";background-color:", ";div{color:", ";}div[class*=\"TagType\"]{background-color:", ";}}"], props => props.selected && props.highlighted ? `solid 1px ${themeGet("colors.warningLight")(props)}` : props.highlighted ? `solid 1px ${themeGet("colors.warningDark")(props)}` : `solid 1px ${themeGet("colors.primaryDark")(props)}`, props => props.selected && props.highlighted ? themeGet("colors.black70")(props) : props.selected ? themeGet("colors.white")(props) : themeGet("colors.primaryDark")(props), props => props.selected && props.highlighted ? themeGet("colors.warningLight")(props) : props.selected ? themeGet("colors.primaryDark")(props) : props.highlighted ? themeGet("colors.warningLightest")(props) : themeGet("colors.primaryLightest")(props), props => props.selected && props.highlighted ? themeGet("colors.black70")(props) : props.highlighted ? themeGet("colors.warningDarkest")(props) : props.selected ? themeGet("colors.white")(props) : themeGet("colors.primaryDark")(props), props => props.selected && props.highlighted ? "rgba(255,255,255,0.3)" : props.highlighted ? themeGet("colors.warning30")(props) : props.selected ? "rgba(0,0,0,0.3)" : themeGet("colors.primary20")(props)));
const TagValueText = styled.div.withConfig({
displayName: "Tag__TagValueText",
componentId: "sc-1dh2aa8-2"
})(["text-decoration:", ";white-space:normal;word-break:break-word;max-width:100%;text-align:left;line-height:", ";padding-bottom:1px;"], props => props.showStrikeThrough ? "line-through" : "none", props => props.small ? themeGet("fontSizes.0")(props) : themeGet("fontSizes.1")(props));
const TagActionIconWrapper = styled(TagValue).withConfig({
displayName: "Tag__TagActionIconWrapper",
componentId: "sc-1dh2aa8-3"
})(["border-radius:", ";border-top-left-radius:0;border-bottom-left-radius:0;padding:", ";&:focus{z-index:2;}> span{line-height:0;}", ""], props => props.showRemove ? "0" : themeGet("tagScale.tagBorderRadius"), props => props.showRemove && props.small ? "0 3px 0 4px" : props.showRemove ? "0 5px 0 5px" : props.showInfo && props.small ? "0 8px 0 7px" : props.showInfo ? "0 10px 0 9px" : props.small ? "0 4px 0 3px" : "0 6px 0 5px", props => props.selected ? css(["border-left:", ";&:hover{border-left:", ";}"], props => props.selected && props.highlighted ? `solid 1px ${themeGet("colors.warningDarker")(props)}` : `solid 1px ${themeGet("colors.primaryDark")(props)}`, props => props.selected && props.highlighted ? `solid 1px ${themeGet("colors.warningDarker")(props)}` : `solid 1px ${themeGet("colors.primaryDark")(props)}`) : css(["border-left:0;&:hover,&:focus{background-color:", ";color:", ";border-left:0;}"], props => props.highlighted ? themeGet("colors.warningLightest")(props) : themeGet("colors.primaryLightest")(props), props => props.highlighted ? themeGet("colors.warningDarkest")(props) : themeGet("colors.primaryDark")(props)));
const TagRemoveIconWrapper = styled(TagValue).withConfig({
displayName: "Tag__TagRemoveIconWrapper",
componentId: "sc-1dh2aa8-4"
})(["border-radius:", ";border-top-left-radius:0;border-bottom-left-radius:0;padding:", ";&:focus{z-index:2;}", ""], themeGet("tagScale.tagBorderRadius"), props => props.small ? "2px 6px 2px 5px" : "2px 8px 2px 7px", props => props.selected ? css(["border-left:", ";&:hover{border-left:", ";}"], props => props.selected && props.highlighted ? `solid 1px ${themeGet("colors.warningDarker")(props)}` : `solid 1px ${themeGet("colors.primaryDark")(props)}`, props => props.selected && props.highlighted ? `solid 1px ${themeGet("colors.warningDarker")(props)}` : `solid 1px ${themeGet("colors.primaryDark")(props)}`) : css(["border-left:0;&:hover,&:focus{background-color:", ";border-left:0;color:", ";}"], props => props.highlighted ? themeGet("colors.warningLightest")(props) : themeGet("colors.primaryLightest")(props), props => props.highlighted ? themeGet("colors.warningDarkest")(props) : themeGet("colors.primaryDark")(props)));
const TagType = styled.div.withConfig({
displayName: "Tag__TagType",
componentId: "sc-1dh2aa8-5"
})(["text-transform:uppercase;padding:", ";line-height:1;white-space:normal;word-break:break-word;text-align:left;border-radius:", ";font-size:", ";background-color:", ";color:", ";"], props => props.small ? themeGet("space.2")(props) : themeGet("space.2")(props), props => themeGet("radii.1")(props), props => props.small ? "1rem" : themeGet("fontSizes.0")(props), props => props.disabled ? themeGet("colors.grey")(props) : props.selected && props.highlighted ? themeGet("colors.warningLightest")(props) : props.highlighted ? themeGet("colors.warning30")(props) : props.selected ? "rgba(0,0,0,0.25)" : themeGet("colors.primaryLightest")(props), props => props.disabled ? themeGet("colors.white")(props) : props.selected && props.highlighted ? themeGet("colors.black70")(props) : props.highlighted ? themeGet("colors.warningDarkest")(props) : props.selected ? themeGet("colors.white")(props) : themeGet("colors.primaryDark")(props));
const TagAvatarWrapper = styled.div.withConfig({
displayName: "Tag__TagAvatarWrapper",
componentId: "sc-1dh2aa8-6"
})(["margin-left:", ";"], props => props.small ? themeGet("tagScale.tagAvatarMarginLeftSmall") : themeGet("tagScale.tagAvatarMarginLeftDefault"));
const TagAvatar = styled(Avatar).withConfig({
displayName: "Tag__TagAvatar",
componentId: "sc-1dh2aa8-7"
})(["img[class*=\"Avatar__Image\"],div[class*=\"Avatar__Shape\"]{width:", ";height:", ";text-transform:uppercase;font-size:", ";background:", ";color:", ";}"], props => props.small ? themeGet("tagScale.tagAvatarSizeSmall") : themeGet("tagScale.tagAvatarSizeDefault"), props => props.small ? themeGet("tagScale.tagAvatarSizeSmall") : themeGet("tagScale.tagAvatarSizeDefault"), props => props.small ? themeGet("tagScale.tagAvatarFontSizeSmall") : themeGet("tagScale.tagAvatarFontSizeDefault"), props => props.disabled ? themeGet("colors.grey")(props) : props.selected && props.highlighted ? themeGet("colors.black70")(props) : props.selected ? "rgba(0,0,0,0.25)" : themeGet("colors.primaryLightest")(props), props => props.disabled ? themeGet("colors.white")(props) : props.selected && props.highlighted ? themeGet("colors.white")(props) : props.selected ? themeGet("colors.white")(props) : themeGet("colors.primaryDark")(props));
/**
* The top two rows are an example of how tags should be used when they are selectable/unselectable. There is the option to display the cross icon or not.
*
* The bottom row is when you want to show tags that aren't editable.
*/
export default function Tag(_ref) {
let {
selected,
onSelect,
disabled,
showRemove,
onRemove,
theme,
tagType,
showEdit,
onEdit,
showInfo,
onInfo,
showStrikeThrough,
children,
isPending,
ariaLabel,
small,
highlighted,
personEntity,
...props
} = _ref;
const component = /*#__PURE__*/_jsxs(TagWrapper, {
small: small,
...props,
children: [/*#__PURE__*/_jsxs(TagValue, {
selected: selected,
highlighted: highlighted,
disabled: disabled,
showEdit: showEdit,
showInfo: showInfo,
showRemove: showRemove,
onClick: onSelect,
small: small,
"aria-label": ariaLabel,
children: [/*#__PURE__*/_jsxs(Flex, {
flexWrap: "nowrap",
gap: props.small ? "3px" : "4px",
alignItems: "center",
children: [personEntity && /*#__PURE__*/_jsx(TagAvatarWrapper, {
children: /*#__PURE__*/_jsx(TagAvatar, {
selected: selected,
highlighted: highlighted,
disabled: disabled,
small: small,
imageAlt: `Avatar for ${children}`,
image: personEntity.avatarSrc,
initials: personEntity.initials
})
}), /*#__PURE__*/_jsxs(TagValueText, {
showStrikeThrough: showStrikeThrough,
small: small,
children: [showStrikeThrough && /*#__PURE__*/_jsx("span", {
className: "sr-only",
children: "Striked out:"
}), children]
})]
}), tagType && /*#__PURE__*/_jsx(TagType, {
selected: selected,
highlighted: highlighted,
disabled: disabled,
small: small,
children: tagType
}), isPending && /*#__PURE__*/_jsx(Loading, {})]
}), showEdit && /*#__PURE__*/_jsx(TagActionIconWrapper, {
selected: selected,
highlighted: highlighted,
disabled: disabled,
showRemove: showRemove,
onClick: onEdit,
small: small,
"aria-label": "Edit",
title: "Edit",
children: /*#__PURE__*/_jsx(Icon, {
icon: ["fas", "pen"],
size: "sm"
})
}), showInfo && /*#__PURE__*/_jsx(TagActionIconWrapper, {
selected: selected,
highlighted: highlighted,
disabled: disabled,
onClick: onInfo,
showInfo: showInfo,
small: small,
"aria-label": "View details",
title: "View details",
children: /*#__PURE__*/_jsx(Icon, {
icon: ["fas", "info"],
size: "sm"
})
}), showRemove && /*#__PURE__*/_jsx(TagRemoveIconWrapper, {
selected: selected,
highlighted: highlighted,
disabled: disabled,
onClick: onRemove,
small: small,
"aria-label": "Remove",
title: "Remove",
children: /*#__PURE__*/_jsx(Icon, {
icon: ["fas", "times"],
size: "sm"
})
})]
});
return theme ? /*#__PURE__*/_jsx(ThemeProvider, {
theme: theme,
children: component
}) : component;
}
Tag.propTypes = {
children: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]),
/** Adds selected styling to tag */
selected: PropTypes.bool,
/** On tag selected */
onSelect: PropTypes.func,
/** Shows the remove button */
showRemove: PropTypes.bool,
/** On tag remove button clicked */
onRemove: PropTypes.func,
/** Shows edit button */
showEdit: PropTypes.bool,
/** On tag edit button clicked */
onEdit: PropTypes.func,
/** Shows info button */
showInfo: PropTypes.bool,
/** On tag info button clicked */
onInfo: PropTypes.func,
/** Can add a type to a tag as text */
tagType: PropTypes.string,
/** Can add an img url for showing a person's avatar if the tag is used for a person */
personAvatar: PropTypes.string,
/** Adds disabled attribute and styling to tag */
disabled: PropTypes.bool,
/** Adds loading spinner to tag to indicate awaiting an action to complete */
isPending: PropTypes.bool,
/** Specifies the design theme */
theme: PropTypes.object,
/** Add a strikethrough to a tag value text */
showStrikeThrough: PropTypes.bool,
/** Applies the small variant styles */
small: PropTypes.bool,
/** Applies a highlighted style and colour to the tag */
highlighted: PropTypes.bool,
/** Allows you to set a person avatar image or initials */
personEntity: PropTypes.object,
/** Add ariaLabel text describing to screen readers what this tag button does when pressed. e.g. Apply filter or Navigate to tag. */
ariaLabel: PropTypes.string.isRequired
};
Tag.defaultProps = {
selected: false,
small: false,
highlighted: false,
disabled: false,
showEdit: false,
showInfo: false,
showRemove: false,
showStrikeThrough: false
};
Tag.__docgenInfo = {
"description": "The top two rows are an example of how tags should be used when they are selectable/unselectable. There is the option to display the cross icon or not.\n\nThe bottom row is when you want to show tags that aren't editable.",
"methods": [],
"displayName": "Tag",
"props": {
"selected": {
"defaultValue": {
"value": "false",
"computed": false
},
"description": "Adds selected styling to tag",
"type": {
"name": "bool"
},
"required": false
},
"small": {
"defaultValue": {
"value": "false",
"computed": false
},
"description": "Applies the small variant styles",
"type": {
"name": "bool"
},
"required": false
},
"highlighted": {
"defaultValue": {
"value": "false",
"computed": false
},
"description": "Applies a highlighted style and colour to the tag",
"type": {
"name": "bool"
},
"required": false
},
"disabled": {
"defaultValue": {
"value": "false",
"computed": false
},
"description": "Adds disabled attribute and styling to tag",
"type": {
"name": "bool"
},
"required": false
},
"showEdit": {
"defaultValue": {
"value": "false",
"computed": false
},
"description": "Shows edit button",
"type": {
"name": "bool"
},
"required": false
},
"showInfo": {
"defaultValue": {
"value": "false",
"computed": false
},
"description": "Shows info button",
"type": {
"name": "bool"
},
"required": false
},
"showRemove": {
"defaultValue": {
"value": "false",
"computed": false
},
"description": "Shows the remove button",
"type": {
"name": "bool"
},
"required": false
},
"showStrikeThrough": {
"defaultValue": {
"value": "false",
"computed": false
},
"description": "Add a strikethrough to a tag value text",
"type": {
"name": "bool"
},
"required": false
},
"children": {
"description": "",
"type": {
"name": "union",
"value": [{
"name": "node"
}, {
"name": "arrayOf",
"value": {
"name": "node"
}
}]
},
"required": false
},
"onSelect": {
"description": "On tag selected",
"type": {
"name": "func"
},
"required": false
},
"onRemove": {
"description": "On tag remove button clicked",
"type": {
"name": "func"
},
"required": false
},
"onEdit": {
"description": "On tag edit button clicked",
"type": {
"name": "func"
},
"required": false
},
"onInfo": {
"description": "On tag info button clicked",
"type": {
"name": "func"
},
"required": false
},
"tagType": {
"description": "Can add a type to a tag as text",
"type": {
"name": "string"
},
"required": false
},
"personAvatar": {
"description": "Can add an img url for showing a person's avatar if the tag is used for a person",
"type": {
"name": "string"
},
"required": false
},
"isPending": {
"description": "Adds loading spinner to tag to indicate awaiting an action to complete",
"type": {
"name": "bool"
},
"required": false
},
"theme": {
"description": "Specifies the design theme",
"type": {
"name": "object"
},
"required": false
},
"personEntity": {
"description": "Allows you to set a person avatar image or initials",
"type": {
"name": "object"
},
"required": false
},
"ariaLabel": {
"description": "Add ariaLabel text describing to screen readers what this tag button does when pressed. e.g. Apply filter or Navigate to tag.",
"type": {
"name": "string"
},
"required": true
}
}
};