Skip to content

Commit

Permalink
feat(theme-default): children, outline and fixes for Badge
Browse files Browse the repository at this point in the history
Improve built-in `<Badge>` components:
- Custom children: this is particularly useful for adding icons.
- `outline` support: more variations!
- Style tweak:
  - use CSS variables from containers to look consistent.
  - fixes default badge being invisible in Dark mode.
  - better vertically aligned with different headings.
- Changes to `type` props:
  - add `info` type to be consistent with containers.
  - `tip` is added as the new default.

Do note that even though this kept untyped `<Badge>` unchanged, it
does introduce a **benign** breaking change to `<Badge type="info">`.

Changes to Docs:
- Badges docs are updated to reflect the new usages and new types.
- This MR correct "Internal Components" to be "Built-in Components".
  (does not involve URL changes due to the use of fragments)
  • Loading branch information
Huxpro committed Oct 9, 2024
1 parent 2d07c67 commit 9ef097c
Show file tree
Hide file tree
Showing 8 changed files with 212 additions and 33 deletions.
6 changes: 3 additions & 3 deletions packages/document/docs/en/api/client-api/api-components.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Internal Components
# Built-in Components

import InternalComponents from '../../fragments/internal-components';
import BuiltinComponents from '../../fragments/builtin-components';

<InternalComponents />
<BuiltinComponents />
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,79 @@ The Badge component is used to display a badge. For example:
import { Badge } from '@theme';

function App() {
// Using text prop
return <Badge text="info" type="info" />;

// Using custom children
return (
<Badge>
<img
style={{ height: '18px' }}
src="https://lf3-static.bytednsdoc.com/obj/eden-cn/uhbfnupenuhf/rspress/rspress-logo.png"
/>
<span>Rspress</span>
</Badge>
);
}
```

The effect is as follows:

import { Badge } from '@theme';

<Badge text="tip" type="tip" />
<Badge text="info" type="info" />
<Badge text="warning" type="warning" />
<Badge text="danger" type="danger" />
<Badge text="outlined" outline />

Custom children:

import SearchSvg from '@theme-assets/github';

<Badge type="tip">
<img
style={{ height: '18px' }}
src="https://lf3-static.bytednsdoc.com/obj/eden-cn/uhbfnupenuhf/rspress/rspress-logo.png"
/>
<span>Rspress</span>
</Badge>

<Badge type="info">
<SearchSvg width="16" />
<span>Github</span>
</Badge>

Inlined with text <Badge text="Tip" />

##### H5 <Badge text="Info" type="info" />

#### H4 <Badge text="Warning" type="warning" />

### H3 <Badge text="Danger" type="danger" />

The types of props included are as follows:

```ts
interface BadgeProps {
// Used to set the text of the badge
text: string;
// Used to set the type of the badge
type?: 'info' | 'warning' | 'danger';
/**
* The content to display inside the badge. Can be a string or React nodes.
*/
children?: React.ReactNode;
/**
* The type of badge, which determines its color and style.
* @default 'tip'
*/
type?: 'tip' | 'info' | 'warning' | 'danger';
/**
* The text content to display inside the badge (for backwards compatibility).
*/
text?: string;
/**
* Whether to display the badge with an outline style.
* @default false
*/
outline?: boolean;
}
```

Expand Down
6 changes: 3 additions & 3 deletions packages/document/docs/en/guide/default-theme/components.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Internal Components
# Built-in Components

import InternalComponents from '../../fragments/internal-components'
import BuiltinComponents from '../../fragments/builtin-components';

<InternalComponents />
<BuiltinComponents />
4 changes: 2 additions & 2 deletions packages/document/docs/zh/api/client-api/api-components.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# 内置组件

import InternalComponents from '../../fragments/internal-components';
import BuiltinComponents from '../../fragments/builtin-components';

<InternalComponents />
<BuiltinComponents />
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,79 @@ Badge 组件用于展示状态的标记。使用方法如下:
import { Badge } from '@theme';

function App() {
// 使用 text 属性
return <Badge text="info" type="info" />;

// 使用自定义子元素
return (
<Badge>
<img
style={{ height: '18px' }}
src="https://lf3-static.bytednsdoc.com/obj/eden-cn/uhbfnupenuhf/rspress/rspress-logo.png"
/>
<span>Rspress</span>
</Badge>
);
}
```

效果如下:

import { Badge } from '@theme';

<Badge text="tip" type="tip" />
<Badge text="info" type="info" />
<Badge text="warning" type="warning" />
<Badge text="danger" type="danger" />
<Badge text="outlined" outline />

import SearchSvg from '@theme-assets/github';

自定义子元素:

<Badge type="tip">
<img
style={{ height: '18px' }}
src="https://lf3-static.bytednsdoc.com/obj/eden-cn/uhbfnupenuhf/rspress/rspress-logo.png"
/>
<span>Rspress</span>
</Badge>

<Badge type="info">
<SearchSvg width="16" />
<span>Github</span>
</Badge>

内联文本 <Badge text="Tip" />

##### H5 <Badge text="Info" type="info" />

#### H4 <Badge text="Warning" type="warning" />

### H3 <Badge text="Danger" type="danger" />

其中包含的 props 类型如下:

```ts
interface BadgeProps {
// 用于设置 badge 的文本
text: string;
// 用于设置 badge 的类型
type: 'info' | 'warning' | 'danger';
/**
* 在徽章内显示的内容。可以是字符串或 React 节点。
*/
children?: React.ReactNode;
/**
* 徽章的类型,决定其颜色和样式。
* @default 'tip'
*/
type?: 'tip' | 'info' | 'warning' | 'danger';
/**
* 在徽章内显示的文本内容(为了向后兼容)。
*/
text?: string;
/**
* 是否以轮廓样式显示徽章。
* @default false
*/
outline?: boolean;
}
```

Expand Down
4 changes: 2 additions & 2 deletions packages/document/docs/zh/guide/default-theme/components.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# 内置组件

import InternalComponents from '../../fragments/internal-components'
import BuiltinComponents from '../../fragments/builtin-components';

<InternalComponents />
<BuiltinComponents />
44 changes: 35 additions & 9 deletions packages/theme-default/src/components/Badge/index.module.scss
Original file line number Diff line number Diff line change
@@ -1,18 +1,44 @@
.badge {
padding: 0 10px;
line-height: 22px;
font-size: 12px;
font-weight: 500;
transition: color 0.25s;

&.tip {
color: var(--rp-container-tip-text);
background-color: var(--rp-container-tip-bg);
}

&.info {
color: #2e3440;
background-color: rgba(46, 52, 64, 0.16);
color: var(--rp-container-info-text);
background-color: var(--rp-container-info-bg);
}

&.warning {
color: #ad850e;
background-color: rgba(255, 197, 23, 0.16);
color: var(--rp-container-warning-text);
background-color: var(--rp-container-warning-bg);
}

&.danger {
color: #ab2131;
background-color: rgba(237, 60, 80, 0.16);
color: var(--rp-container-danger-text);
background-color: var(--rp-container-danger-bg);
}

&.outline {
border: 1px solid;

&.tip {
border-color: var(--rp-container-tip-border);
}

&.info {
border-color: var(--rp-container-info-border);
}

&.warning {
border-color: var(--rp-container-warning-border);
}

&.danger {
border-color: var(--rp-container-danger-border);
}
}
}
59 changes: 53 additions & 6 deletions packages/theme-default/src/components/Badge/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,64 @@
import styles from './index.module.scss';

interface BadgeProps {
text: string;
type: 'info' | 'warning' | 'danger';
/**
* The content to display inside the badge. Can be a string or React nodes.
*/
children?: React.ReactNode;
/**
* The type of badge, which determines its color and style.
* @default 'tip'
*/
type?: 'tip' | 'info' | 'warning' | 'danger';
/**
* The text content to display inside the badge (for backwards compatibility).
*/
text?: string;
/**
* Whether to display the badge with an outline style.
* @default false
*/
outline?: boolean;
}

export function Badge(props: BadgeProps) {
const { text, type = 'info' } = props;
/**
* A component that renders a styled badge with custom content.
*
* The Badge component displays a small, inline element with customizable content and appearance.
* It's useful for highlighting status, categories, or other short pieces of information.
*
* @param {BadgeProps} props - The properties for the Badge component.
* @returns {JSX.Element} A span element representing the badge.
*
* @example
* Using children:
* <Badge type="info">New</Badge>
* <Badge type="warning" outline>Experimental</Badge>
* <Badge type="danger">Deprecated</Badge>
* <Badge type="tip" outline><strong>Pro Tip:</strong> Use custom elements</Badge>
*
* Using text prop:
* <Badge text="New" type="info" />
* <Badge text="Experimental" type="warning" outline />
* <Badge text="Deprecated" type="danger" />
*/
export function Badge({
children,
type = 'tip',
text,
outline = false,
}: BadgeProps) {
const content = children || text;

return (
<span
className={`inline-block rounded-full border border-solid border-transparent font-medium ${styles.badge} ${styles[type]}`}
className={`inline-flex items-center justify-center rounded-full border border-solid ${
outline ? 'border-current' : 'border-transparent'
} font-semibold align-middle px-2.5 h-6 gap-1 text-xs ${styles.badge} ${styles[type]} ${
outline ? styles.outline : ''
}`}
>
{text}
{content}
</span>
);
}

0 comments on commit 9ef097c

Please sign in to comment.