From ceda6e0315523a967e607318bd7cd4838da1e07a Mon Sep 17 00:00:00 2001 From: AssisrMatheus Date: Tue, 2 Nov 2021 17:01:36 -0300 Subject: [PATCH] feat: added badge component --- postcss.config.js | 2 +- .../Templates/Project/Planner/index.tsx | 14 +++- src/components/UI/Badge/index.css | 67 +++++++++++++++ src/components/UI/Badge/index.tsx | 81 +++++++++++++++++++ src/components/UI/NavbarButton/index.tsx | 22 ++--- src/components/UI/index.css | 1 + 6 files changed, 173 insertions(+), 14 deletions(-) create mode 100644 src/components/UI/Badge/index.css create mode 100644 src/components/UI/Badge/index.tsx diff --git a/postcss.config.js b/postcss.config.js index fdc618f..b8fed25 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,8 +1,8 @@ module.exports = { plugins: { 'postcss-import': {}, // Import must come before tailwind + 'tailwindcss/nesting': {}, tailwindcss: {}, - 'postcss-nested': {}, 'postcss-combine-media-query': {}, // Media query must come before duplicated-selectors 'postcss-combine-duplicated-selectors': {}, autoprefixer: {} diff --git a/src/components/Templates/Project/Planner/index.tsx b/src/components/Templates/Project/Planner/index.tsx index 7b74770..8615d99 100644 --- a/src/components/Templates/Project/Planner/index.tsx +++ b/src/components/Templates/Project/Planner/index.tsx @@ -16,6 +16,7 @@ import AppLayout from '../../../Layouts/AppLayout'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faCartShopping, faBarsStaggered, faBars } from '@fortawesome/free-solid-svg-icons'; import NavbarButton from '../../../UI/NavbarButton'; +import { Badge } from '../../../UI/Badge'; const LoadingState: React.FC = () => { const [imageLoaded, setImageLoaded] = useState(false); @@ -151,7 +152,11 @@ const PlannerTemplate: React.FC = ({ slug, data, loading, <> } + icon={(className) => ( + + + + )} /> @@ -159,7 +164,12 @@ const PlannerTemplate: React.FC = ({ slug, data, loading, } - icon={() => } + icon={(className) => ( + + )} /> diff --git a/src/components/UI/Badge/index.css b/src/components/UI/Badge/index.css new file mode 100644 index 0000000..39a43da --- /dev/null +++ b/src/components/UI/Badge/index.css @@ -0,0 +1,67 @@ +@layer components { + .mui-badge { + @apply relative inline-flex align-middle flex-shrink-0; + } + + .mui-badge-content { + @apply absolute z-10 pointer-events-none select-none flex flex-row flex-wrap items-center justify-center text-center text-white bg-mui-placeholder-color; + + transform-origin: 100% 0%; + + &.mui-badge-placement-top-right { + @apply top-0 right-0; + transform: translate(50%, -50%); + } + + &.mui-badge-placement-bottom-right { + @apply bottom-0 right-0; + transform: translate(50%, 50%); + } + + &.mui-badge-placement-bottom-left { + @apply bottom-0 left-0; + transform: translate(-50%, 50%); + } + + &.mui-badge-placement-top-left { + @apply top-0 left-0; + transform: translate(-50%, -50%); + } + + &.pulse { + &::before { + @apply animate-ping opacity-75 bg-mui-placeholder-color absolute inset-0 rounded-full; + z-index: -1; + + /* Displays the before pseudoelement */ + content: ''; + } + } + } + + .mui-badge-default { + @apply mui-badge-content h-5 min-w-5 text-xs; + + padding: 0 6px; + border-radius: 10px; + } + + .mui-badge-mini { + @apply mui-badge-content; + height: 14px; + min-width: 14px; + + /* Styles the text */ + font-size: 0.65rem; + line-height: 0.8rem; + + padding: 0 3px; + border-radius: 10px; + } + + .mui-badge-dot { + @apply mui-badge-content h-2 min-w-2 p-0; + + border-radius: 4px; + } +} diff --git a/src/components/UI/Badge/index.tsx b/src/components/UI/Badge/index.tsx new file mode 100644 index 0000000..5ae7b5a --- /dev/null +++ b/src/components/UI/Badge/index.tsx @@ -0,0 +1,81 @@ +import React, { useMemo } from 'react'; +import classnames from 'classnames'; + +const variantClassnameMap = { + default: 'mui-badge-default', + mini: 'mui-badge-mini', + dot: 'mui-badge-dot' +}; + +const placementClassnameMap = { + ['top-right']: 'mui-badge-placement-top-right', + ['bottom-right']: 'mui-badge-placement-bottom-right', + ['top-left']: 'mui-badge-placement-top-left', + ['bottom-left']: 'mui-badge-placement-bottom-left' +}; + +export type BadgeProps = { + /** + * The badge display number or text + */ + content?: number | string; + /** + * The maximum number until the badge will add a "+" sign, only taken into consideration if `content` is of type number + * + * @default 9 + */ + maxValue?: number; + /** + * Whether or not the badge should have a pulsing effect + */ + pulse?: boolean; + /** + * The badge variant + * + * @default default + */ + variant?: keyof typeof variantClassnameMap; + /** + * The badge placement + * + * @default top-right + */ + placement?: keyof typeof placementClassnameMap; +}; + +/** + * A badge + * + * @param props the component props + * @param props.content The badge display number or text + * @param props.maxValue The maximum number until the badge will add a "+" sign, only taken into consideration if `content` is of type number + * @param props.pulse Whether or not the badge should have a pulsing effect + * @param props.variant The badge variant + * @param props.placement The bagge placement + * @param props.children the provided children + */ +export const Badge: React.FC = ({ + content: propsContent, + maxValue = 9, + pulse, + variant = 'default', + placement = 'top-right', + children +}) => { + const content = useMemo( + () => + typeof propsContent === 'number' ? (propsContent > maxValue ? `${maxValue}+` : `${propsContent}`) : propsContent, + [propsContent, maxValue] + ); + + return ( +
+ {children} + {content && ( + + {variant !== 'dot' && content} + + )} +
+ ); +}; diff --git a/src/components/UI/NavbarButton/index.tsx b/src/components/UI/NavbarButton/index.tsx index e83d2f6..98c5831 100644 --- a/src/components/UI/NavbarButton/index.tsx +++ b/src/components/UI/NavbarButton/index.tsx @@ -1,22 +1,22 @@ type NavbarButtonProps = { - icon?: () => React.ReactNode; + icon?: (className: string) => React.ReactNode; iconPosition?: 'left' | 'right'; content?: string | React.ReactNode; }; const NavbarButton: React.FC = ({ icon, iconPosition, content }) => ( ); diff --git a/src/components/UI/index.css b/src/components/UI/index.css index a879578..adf9733 100644 --- a/src/components/UI/index.css +++ b/src/components/UI/index.css @@ -8,3 +8,4 @@ @import './Modal'; @import './Tooltip'; @import './Dropdown'; +@import './Badge';