From fe72af448322e883349586c4dd209f0052d87367 Mon Sep 17 00:00:00 2001
From: Dan Hedgecock <8461733+DHedgecock@users.noreply.github.com>
Date: Sat, 8 Oct 2022 19:35:42 -0700
Subject: [PATCH] Update: Badge ready for production use (#501)
---
src/api-types.ts | 5 ++
src/components/Badge/Badge.spec.js | 8 ++-
src/components/Badge/Badge.stories.mdx | 10 ++--
src/components/Badge/Badge.styles.ts | 23 ++++++---
src/components/Badge/Badge.ts | 49 ++++++++++++-------
.../transforms-components/code.js | 3 +-
.../transforms-components/output.js | 6 ++-
src/plugin-babel/plugin.ts | 3 +-
8 files changed, 75 insertions(+), 32 deletions(-)
diff --git a/src/api-types.ts b/src/api-types.ts
index 8cc020c9..d7bcface 100644
--- a/src/api-types.ts
+++ b/src/api-types.ts
@@ -4,6 +4,11 @@
* creating documentation.
*/
+export {
+ type BadgePropsDefaults,
+ type BadgePropsOverrides,
+} from './components/Badge/Badge'
+export { type BadgeStyles } from './components/Badge/Badge.styles'
export {
type ButtonPropsDefaults,
type ButtonPropsOverrides,
diff --git a/src/components/Badge/Badge.spec.js b/src/components/Badge/Badge.spec.js
index f8b145d7..89e3b27e 100644
--- a/src/components/Badge/Badge.spec.js
+++ b/src/components/Badge/Badge.spec.js
@@ -6,11 +6,17 @@ import { Badge } from './Badge'
describe('', () => {
elementTests(Badge)
- it('When color is passed, then badge-color className is rendered', () => {
+ it('When color is passed, then badge color className is rendered', () => {
render(Badge)
expect(screen.getByText('Badge')).toHaveClass('C9Y-Badge-primaryColor')
})
+
+ it('When size is passed, then badge size className is rendered', () => {
+ render(Badge)
+
+ expect(screen.getByText('Badge')).toHaveClass('C9Y-Badge-largeSize')
+ })
})
// Snapshots
diff --git a/src/components/Badge/Badge.stories.mdx b/src/components/Badge/Badge.stories.mdx
index 814e04d2..f5ff0613 100644
--- a/src/components/Badge/Badge.stories.mdx
+++ b/src/components/Badge/Badge.stories.mdx
@@ -13,8 +13,12 @@ Badges provide status information.
Badge
-## Empty badges
+## Sizes
-The `:empty` selector is used to hide empty badges by default:
+Pass a `size` to set a badge size:
-
+
+ Badge
+ Badge
+ Badge
+
diff --git a/src/components/Badge/Badge.styles.ts b/src/components/Badge/Badge.styles.ts
index 39da96c2..a343a7fa 100644
--- a/src/components/Badge/Badge.styles.ts
+++ b/src/components/Badge/Badge.styles.ts
@@ -5,17 +5,14 @@ import { Theme } from '../../theme/theme'
// --------------------------------------------------------
export const badgeStyles = (theme: Theme): BadgeStyles => ({
+ // BASE
'.C9Y-Badge-base': {
display: 'inline-flex',
alignItems: 'center',
whiteSpace: 'nowrap',
-
- // Empty badges collapse automatically
- '&:empty': {
- display: 'none',
- },
},
+ // VARIANTS
'.C9Y-Badge-filled': {
padding: '4px 8px',
color: theme.colors.inverse,
@@ -26,11 +23,21 @@ export const badgeStyles = (theme: Theme): BadgeStyles => ({
lineHeight: 1,
// 💡 Use em with font-size and padding to auto-scale with text
},
+
+ // SIZES
+ '.C9Y-Badge-smallSize': {
+ fontSize: theme.fontSize.sm,
+ padding: '2px 6px',
+ },
+ '.C9Y-Badge-largeSize': {
+ fontSize: theme.fontSize.body,
+ padding: '6px 12px',
+ },
})
export interface BadgeStyles {
- '.C9Y-Badge-base': {
- '&:empty': CSSProperties
- } & CSSProperties
+ '.C9Y-Badge-base': CSSProperties
'.C9Y-Badge-filled': CSSProperties
+ '.C9Y-Badge-smallSize': CSSProperties
+ '.C9Y-Badge-largeSize': CSSProperties
}
diff --git a/src/components/Badge/Badge.ts b/src/components/Badge/Badge.ts
index 45590ac6..65986299 100644
--- a/src/components/Badge/Badge.ts
+++ b/src/components/Badge/Badge.ts
@@ -1,36 +1,47 @@
-import React from 'react'
+import React, { forwardRef } from 'react'
import { element } from '../../utils/element-creator'
-import { MergeTypes, Resolve } from '../../utils/types'
+import { DistributiveOmit, MergeTypes } from '../../utils/types'
import { UtilityProps } from '../../utils/utility-classes'
import { useThemeProps } from '../Provider/Provider'
-// Module augmentation interface for overriding component props' types
+/** Module augmentation interface for overriding component props' types */
export interface BadgePropsOverrides {}
export interface BadgePropsDefaults {
- /** Variant color */
color?: 'primary'
- /** Display variant */
+ size?: 'small' | 'large'
+ /** Display style */
variant?: 'filled'
}
-export type BadgeProps = Resolve> &
- Omit &
- React.ComponentPropsWithoutRef<'div'>
+export type BadgePropsBase = Omit<
+ UtilityProps,
+ 'color'
+> &
+ MergeTypes & { as?: Elem }
-// ✨ Nice display type for IntelliSense
+export type BadgeProps = BadgePropsBase &
+ DistributiveOmit, keyof BadgePropsBase>
+
+/**
+ * Badge provides a label for describing elements.
+ * @example
+ * ```tsx
+ *
+ * Delightful
+ *
+ * ```
+ * @see [📝 Badge docs](https://componentry.design/docs/components/badge)
+ */
export interface Badge {
- (props: BadgeProps): React.ReactElement | null
+ (props: BadgeProps): React.ReactElement
displayName?: string
}
-/**
- * [Badge component 📝](https://componentry.design/components/badge)
- * @experimental
- */
-export const Badge: Badge = (props) => {
+export const Badge = forwardRef((props, ref) => {
const {
color,
+ size,
variant = 'filled',
...rest
} = {
@@ -39,11 +50,15 @@ export const Badge: Badge = (props) => {
}
return element({
+ ref,
componentCx: [
`C9Y-Badge-base C9Y-Badge-${variant}`,
- { [`C9Y-Badge-${color}Color`]: color },
+ {
+ [`C9Y-Badge-${color}Color`]: color,
+ [`C9Y-Badge-${size}Size`]: size,
+ },
],
...rest,
})
-}
+}) as Badge
Badge.displayName = 'Badge'
diff --git a/src/plugin-babel/__fixtures__/transforms-components/code.js b/src/plugin-babel/__fixtures__/transforms-components/code.js
index b92655be..27ced3a1 100644
--- a/src/plugin-babel/__fixtures__/transforms-components/code.js
+++ b/src/plugin-babel/__fixtures__/transforms-components/code.js
@@ -1,4 +1,4 @@
-import { Block, Flex, Grid, Paper, Text } from 'componentry'
+import { Badge, Block, Flex, Grid, Paper, Text } from 'componentry'
export default function Test() {
// Test that:
@@ -10,6 +10,7 @@ export default function Test() {
Precompiled for
SPEED
+ Delightful
)
diff --git a/src/plugin-babel/__fixtures__/transforms-components/output.js b/src/plugin-babel/__fixtures__/transforms-components/output.js
index d3fb8b87..33f417ab 100644
--- a/src/plugin-babel/__fixtures__/transforms-components/output.js
+++ b/src/plugin-babel/__fixtures__/transforms-components/output.js
@@ -1,4 +1,4 @@
-import { Block, Flex, Grid, Paper, Text } from 'componentry'
+import { Badge, Block, Flex, Grid, Paper, Text } from 'componentry'
import { jsx as _jsx } from 'react/jsx-runtime'
import { jsxs as _jsxs } from 'react/jsx-runtime'
export default function Test() {
@@ -19,6 +19,10 @@ export default function Test() {
/*#__PURE__*/ _jsx('div', {
children: 'SPEED',
}),
+ /*#__PURE__*/ _jsx('div', {
+ className: 'C9Y-Badge-base C9Y-Badge-filled',
+ children: 'Delightful',
+ }),
],
}),
})
diff --git a/src/plugin-babel/plugin.ts b/src/plugin-babel/plugin.ts
index 676254e7..d7fac830 100644
--- a/src/plugin-babel/plugin.ts
+++ b/src/plugin-babel/plugin.ts
@@ -1,5 +1,6 @@
import { NodePath, PluginObj, PluginPass, types as t } from '@babel/core'
+import { Badge } from '../components/Badge/Badge'
import { Block } from '../components/Block/Block'
import { Flex } from '../components/Flex/Flex'
import { Grid } from '../components/Grid/Grid'
@@ -11,7 +12,7 @@ import { loadConfig } from '../config/load-config'
import { parseAttributes } from './parse-attributes'
import { prepareAttributes } from './prepare-attributes'
-const components = { Block, Flex, Grid, Paper, Text } as unknown as {
+const components = { Badge, Block, Flex, Grid, Paper, Text } as unknown as {
[component: string]: EvaluatedForwardRef
}