Skip to content

Commit

Permalink
feat: added badge component
Browse files Browse the repository at this point in the history
  • Loading branch information
AssisrMatheus committed Nov 2, 2021
1 parent 7146b40 commit ceda6e0
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 14 deletions.
2 changes: 1 addition & 1 deletion postcss.config.js
Original file line number Diff line number Diff line change
@@ -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: {}
Expand Down
14 changes: 12 additions & 2 deletions src/components/Templates/Project/Planner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -151,15 +152,24 @@ const PlannerTemplate: React.FC<PlannerTemplateProps> = ({ slug, data, loading,
<>
<NavbarButton
iconPosition="left"
icon={() => <FontAwesomeIcon icon={faCartShopping} className="text-2xl" />}
icon={(className) => (
<Badge content="0">
<FontAwesomeIcon icon={faCartShopping} className={classNames('text-2xl', className)} />
</Badge>
)}
/>

<Link href="/projects">
<a className="flex items-center justify-center">
<NavbarButton
iconPosition="right"
content={<FormattedMessage id="build.projectsPageNav" />}
icon={() => <FontAwesomeIcon icon={faBarsStaggered} className="text-2xl text-mui-primary" />}
icon={(className) => (
<FontAwesomeIcon
icon={faBarsStaggered}
className={classNames('text-2xl text-mui-primary', className)}
/>
)}
/>
</a>
</Link>
Expand Down
67 changes: 67 additions & 0 deletions src/components/UI/Badge/index.css
Original file line number Diff line number Diff line change
@@ -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;
}
}
81 changes: 81 additions & 0 deletions src/components/UI/Badge/index.tsx
Original file line number Diff line number Diff line change
@@ -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<BadgeProps> = ({
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 (
<div className="mui-badge">
{children}
{content && (
<span className={classnames(variantClassnameMap[variant], placementClassnameMap[placement], { pulse })}>
{variant !== 'dot' && content}
</span>
)}
</div>
);
};
22 changes: 11 additions & 11 deletions src/components/UI/NavbarButton/index.tsx
Original file line number Diff line number Diff line change
@@ -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<NavbarButtonProps> = ({ icon, iconPosition, content }) => (
<button className="flex items-center justify-center p-4 hover:bg-mui-gray-50 transition-colors duration-75 group gap-2">
{iconPosition === 'left' && icon && (
<span className="group-hover:scale-125 transition-transform duration-75 group-active:scale-100 group-active:transition-none">
{icon()}
</span>
)}
{iconPosition === 'left' &&
icon &&
icon(
'group-hover:scale-125 transition-transform duration-75 group-active:scale-100 group-active:transition-none'
)}
{content && <span className="text-sm font-bold uppercase">{content}</span>}
{iconPosition === 'right' && icon && (
<span className="group-hover:scale-125 transition-transform duration-75 group-active:scale-100 group-active:transition-none">
{icon()}
</span>
)}
{iconPosition === 'right' &&
icon &&
icon(
'group-hover:scale-125 transition-transform duration-75 group-active:scale-100 group-active:transition-none'
)}
</button>
);

Expand Down
1 change: 1 addition & 0 deletions src/components/UI/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
@import './Modal';
@import './Tooltip';
@import './Dropdown';
@import './Badge';

0 comments on commit ceda6e0

Please sign in to comment.