Skip to content

Commit

Permalink
feat: badges
Browse files Browse the repository at this point in the history
  • Loading branch information
maxholman committed Dec 4, 2022
1 parent 7d8645f commit decc1f8
Show file tree
Hide file tree
Showing 3 changed files with 207 additions and 0 deletions.
97 changes: 97 additions & 0 deletions lib/badges.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { createVar, style, styleVariants } from '@vanilla-extract/css';
import { calc } from '@vanilla-extract/css-utils';
import { genericVars } from './design-system.css.js';
import { colorThemeVars } from './schemes/color.css.js';
import { hsl } from './utils.js';

export type BadgeVariant =
| 'standard'
| 'neutral'
| 'ghost'
| 'subtle'
| 'transparent';

const basePadding = createVar();

const base = style({
vars: {
[basePadding]: genericVars.space.nano,
},
cursor: 'default',
borderStyle: 'solid',
display: 'flex',
fontSize: genericVars.text.size.nano,
fontWeight: genericVars.text.weight.medium,
textTransform: 'uppercase',
borderWidth: genericVars.border.weight.hairline,
borderRadius: genericVars.radius.small,
flexDirection: 'row',
alignItems: 'center',
padding: `${calc(basePadding).divide(2).toString()} ${basePadding}`,
justifyContent: 'center',
letterSpacing: 'initial',
});

const hue = createVar();

export const badgeToneVariants = styleVariants(
colorThemeVars.tones,
(value) => ({
vars: {
[hue]: value.h,
},
// backgroundColor: hsl(value.h, 100, 80),
// borderColor: hsl(value.h, 60, 70),
// color: hsl(value.h, 20, 20),
}),
);

export const variants: Record<
BadgeVariant,
{
backgroundColor?: string;
color: string;
borderColor: string;
}
> = {
standard: {
backgroundColor: hsl(hue, colorThemeVars.accent.s, colorThemeVars.accent.l),
color: hsl(hue, colorThemeVars.accent.s, 100),
borderColor: hsl(hue, colorThemeVars.accent.s, 50),
},
neutral: {
backgroundColor: hsl(colorThemeVars.accent.h, 10, 50),
color: hsl(colorThemeVars.accent.h, 10, '90%'),
borderColor: hsl(colorThemeVars.accent.h, colorThemeVars.accent.s, '90%'),
},
ghost: {
color: hsl(colorThemeVars.accent.h, colorThemeVars.accent.s, 50),
borderColor: hsl(colorThemeVars.accent.h, colorThemeVars.accent.s, 50),
},
subtle: {
backgroundColor: hsl(colorThemeVars.accent.h, colorThemeVars.accent.s, 90),
color: hsl(colorThemeVars.accent.h, colorThemeVars.accent.s, 40),
borderColor: hsl(colorThemeVars.accent.h, colorThemeVars.accent.s, 90),
},
transparent: {
backgroundColor: 'transparent',
color: 'inherit',
borderColor: 'transparent',
},
};

export const badgeVariantClasses = styleVariants(variants, (variant) => [
base,
{
...(variant.backgroundColor && {
backgroundColor: variant.backgroundColor,
}),
color: variant.color,
borderColor: variant.borderColor,
},
]);

// export const inlineBleedClass = style({
// marginTop: calc(genericVars.space.small).negate().toString(),
// marginBottom: calc(`${genericVars.space.small}`).negate().toString(),
// });
49 changes: 49 additions & 0 deletions lib/badges.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { ClassValue, clsx } from 'clsx';
import type { FC } from 'react';
import {
badgeToneVariants,
BadgeVariant,
badgeVariantClasses,
} from './badges.css.js';
import { Box, BoxBasedComponentProps } from './core.js';
import type { Align } from './layout.css.js';
import type { Tone } from './schemes/color.css.js';

export type BadgeProps = {
className?: ClassValue;
variant?: BadgeVariant;
align?: Align;
tone?: Tone;
};

export const Badge: FC<
BoxBasedComponentProps<'span' | 'a' | 'button', BadgeProps>
> = ({
component = 'span',
variant = 'standard',
tone = 'info',
align,
className,
children,
...props
}) => (
<Box
component={component}
className={clsx(
className,
badgeToneVariants[tone],
badgeVariantClasses[variant],
)}
{...props}
>
{children}
</Box>
);

export const BadgeLink: FC<
Omit<BoxBasedComponentProps<'a' | 'button', BadgeProps>, 'component'> & {
href?: string;
}
> = (props) => (
<Badge component={'href' in props ? 'a' : 'button'} {...props} />
);
61 changes: 61 additions & 0 deletions src/pages/badges.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type { FC } from 'react';
import { Badge } from '../../lib/badges.js';
import { Block, Inline } from '../../lib/layout.js';
import { Grid } from '../../lib/main.js';
import { Panel } from '../../lib/panel.js';
import { Heading, Text } from '../../lib/typography.js';

export const BadgesPage: FC = () => (
<Panel variant="ghost" space="huge">
<Block>
<Heading level="3">Badges</Heading>

<Grid cols="3">
<Panel variant="subtle">
<Inline>
<Heading level="4">Default Badge</Heading>
<Badge>Active</Badge>
</Inline>
<Text>And some text</Text>
</Panel>
<Panel variant="standard">
<Inline>
<Heading level="4">DBS Visa 4352</Heading>
<Badge tone="warn">Expires Soon</Badge>
</Inline>
<Text>And some text</Text>
</Panel>
<Panel variant="transparent">
<Inline>
<Heading level="4">Default Badge</Heading>
<Badge tone="promo">50% Off</Badge>
</Inline>
<Text>And some text</Text>
</Panel>
<Panel variant="ghost">
<Inline>
<Heading level="4">Trial Account</Heading>
<Badge tone="critical">Expired</Badge>
</Inline>
<Text>Upgrade now</Text>
</Panel>
<Panel variant="ghost">
<Inline>
<Heading level="4">Messages (4)</Heading>
<Badge tone="positive">New</Badge>
</Inline>
<Text>You've got mail!</Text>
</Panel>
</Grid>

<Inline>
<Badge variant="ghost" tone="warn">
Ghost Warn
</Badge>
</Inline>
<Inline>
<Badge variant="subtle">Subtle Info</Badge>
</Inline>
</Block>
</Panel>
);

0 comments on commit decc1f8

Please sign in to comment.