diff --git a/libs/ui/.storybook/public/defaultTheme.json b/libs/ui/.storybook/public/defaultTheme.json
index 4318392..fda8462 100644
--- a/libs/ui/.storybook/public/defaultTheme.json
+++ b/libs/ui/.storybook/public/defaultTheme.json
@@ -1194,6 +1194,9 @@
"whiteSpace": "nowrap"
},
"size": {
+ "xs": {
+ "height": "16px"
+ },
"sm": {
"height": "28px"
},
diff --git a/libs/ui/llms.txt b/libs/ui/llms.txt
index f8a0abe..757d251 100644
--- a/libs/ui/llms.txt
+++ b/libs/ui/llms.txt
@@ -84,7 +84,7 @@ Pre-built indexes for quick discovery:
> Run `yarn build:ui` to regenerate. Do not edit the block between the markers manually.
-66 components total — generated from libs/ui/src/ai/schemas/ on 2026-07-23.
+66 components total — generated from libs/ui/src/ai/schemas/ on 2026-07-24.
## Other
@@ -1118,7 +1118,7 @@ Import: `import { Badge } from 'gd-design-library'`
Badge component for displaying small pieces of information, status indicators, counts, or labels. Supports multiple variants and visual options with icon support. A2UI SPEC: use top-level "label" for badge text, top-level "iconStart" for the leading badge icon, and top-level "iconEnd" for the trailing badge icon. Legacy top-level "icon" is still accepted as a fallback alias for "iconStart". The renderer maps those icon names to the underlying Badge `iconStart?: ReactNode` and `iconEnd?: ReactNode` props internally, so do not pass raw React nodes in the A2UI payload.
-**Props:** `label`: string, `variant`: "primary"|"secondary"|"tertiary"|"quaternary"|"quinary", `size`: "sm"|"md"|"lg", `appearance`: "filled"|"filledLight"|"outline"|"outlineFilledLight", `disabled`: boolean, `iconStart`: string *(+2 more)*
+**Props:** `label`: string, `variant`: "primary"|"secondary"|"tertiary"|"quaternary"|"quinary", `size`: "xs"|"sm"|"md"|"lg", `appearance`: "filled"|"filledLight"|"outline"|"outlineFilledLight", `disabled`: boolean, `iconStart`: string *(+2 more)*
**Examples:**
`New`
@@ -1127,6 +1127,7 @@ Badge component for displaying small pieces of information, status indicators, c
`Tertiary Badge`
`Quaternary Badge`
`Quinary Badge`
+ `Extra Small Badge`
`Small Badge`
`Medium Badge`
`}>With Icon`
diff --git a/libs/ui/src/ai/README.md b/libs/ui/src/ai/README.md
index 17739fb..7d99ac8 100644
--- a/libs/ui/src/ai/README.md
+++ b/libs/ui/src/ai/README.md
@@ -594,7 +594,7 @@ yarn test:ai:watch
-_66 components total — generated from `libs/ui/src/ai/schemas/` on 2026-07-23._
+_66 components total — generated from `libs/ui/src/ai/schemas/` on 2026-07-24._
### Other
@@ -1379,7 +1379,7 @@ Badge component for displaying small pieces of information, status indicators, c
| ------------ | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `label` | `string` | Badge text or count to display (maps to children) |
| `variant` | `"primary"` \| `"secondary"` \| `"tertiary"` \| `"quaternary"` \| `"quinary"` | Visual style variant of the badge |
-| `size` | `"sm"` \| `"md"` \| `"lg"` | Size of the badge |
+| `size` | `"xs"` \| `"sm"` \| `"md"` \| `"lg"` | Size of the badge |
| `appearance` | `"filled"` \| `"filledLight"` \| `"outline"` \| `"outlineFilledLight"` | Visual fill style of the badge |
| `disabled` | `boolean` | Whether the badge is disabled |
| `iconStart` | `string` | Leading icon name from the shared A2UI icon catalog. The renderer converts this to the underlying Badge `iconStart?: ReactNode` prop. Preferred over the legacy `icon` alias. |
diff --git a/libs/ui/src/ai/a2ui/component-map.ts b/libs/ui/src/ai/a2ui/component-map.ts
index 2079c18..6a614f8 100644
--- a/libs/ui/src/ai/a2ui/component-map.ts
+++ b/libs/ui/src/ai/a2ui/component-map.ts
@@ -200,7 +200,7 @@ export type A2UIIconCatalog = typeof A2UI_ICON_CATALOG;
*
* @example
* getA2UIPropEnum('button', 'variant') // ['primary', 'secondary', ...]
- * getA2UIPropEnum('badge', 'size') // ['sm', 'md', 'lg']
+ * getA2UIPropEnum('badge', 'size') // ['xs', 'sm', 'md', 'lg']
*/
export function getA2UIPropEnum(a2uiType: string, propName: string): readonly string[] {
const schema = aiComponentsSchema.components.find((c) => (c as ExtendedComponentSchema).a2uiName === a2uiType);
diff --git a/libs/ui/src/ai/schemas/components/Badge.ts b/libs/ui/src/ai/schemas/components/Badge.ts
index b87e544..bf54127 100644
--- a/libs/ui/src/ai/schemas/components/Badge.ts
+++ b/libs/ui/src/ai/schemas/components/Badge.ts
@@ -27,7 +27,7 @@ const component = {
name: 'size',
type: 'string',
description: 'Size of the badge',
- enum: ['sm', 'md', 'lg'] as const,
+ enum: ['xs', 'sm', 'md', 'lg'] as const,
},
{
name: 'appearance',
@@ -57,6 +57,7 @@ const component = {
'Tertiary Badge',
'Quaternary Badge',
'Quinary Badge',
+ 'Extra Small Badge',
'Small Badge',
'Medium Badge',
'}>With Icon',
diff --git a/libs/ui/src/components/atoms/Badge/Badge.stories.tsx b/libs/ui/src/components/atoms/Badge/Badge.stories.tsx
index 31052e7..97b2755 100644
--- a/libs/ui/src/components/atoms/Badge/Badge.stories.tsx
+++ b/libs/ui/src/components/atoms/Badge/Badge.stories.tsx
@@ -49,9 +49,9 @@ const meta: Meta = {
},
},
size: {
- description: 'Size of the badge (sm, md, lg)',
+ description: 'Size of the badge (xs, sm, md, lg)',
control: { type: 'select' },
- options: ['sm', 'md', 'lg'],
+ options: ['xs', 'sm', 'md', 'lg'],
table: {
category: 'Visual Style',
defaultValue: { summary: 'md' },
@@ -404,7 +404,7 @@ The \`Badge\` component is used to display small pieces of information, such as
- Variants: Primary, Secondary, Tertiary, Quaternary, Quinary
- Appearances: Filled, FilledLight, Outline, OutlineFilledLight
-- Sizes: Small (sm), Medium (md), Large (lg)
+- Sizes: Extra Small (xs), Small (sm), Medium (md), Large (lg)
- Icons: Support for start and end icons
- Disabled: Support for disabled state
- Flexible: Consumes Box styles for full layout control
@@ -434,6 +434,7 @@ export const Default: Story = {
export const Sizes: Story = {
render: () => (
+ Extra Small
Small
Medium
Large
@@ -442,10 +443,11 @@ export const Sizes: Story = {
parameters: {
docs: {
description: {
- story: 'Badge component in all available sizes: small, medium, and large.',
+ story: 'Badge component in all available sizes: extra small, small, medium, and large.',
},
source: {
code: `
+ Extra Small
Small
Medium
Large
@@ -709,6 +711,9 @@ export const Disabled: Story = {
Sizes Disabled:
+
+ Extra Small
+
Small
@@ -748,6 +753,7 @@ export const Disabled: Story = {
Sizes Disabled:
+ Extra Small
Small
Medium
}>
diff --git a/libs/ui/src/components/atoms/Badge/Badge.types.ts b/libs/ui/src/components/atoms/Badge/Badge.types.ts
index fcf6a42..c22c18d 100644
--- a/libs/ui/src/components/atoms/Badge/Badge.types.ts
+++ b/libs/ui/src/components/atoms/Badge/Badge.types.ts
@@ -5,7 +5,7 @@ import type { BoxCssComponentProps, BoxCssComponentStyledProps } from '@componen
export type BadgeVariant = 'primary' | 'secondary' | 'tertiary' | 'quaternary' | 'quinary';
export type BadgeAppearance = 'outline' | 'outlineFilledLight' | 'filled' | 'filledLight';
-export type BadgeSize = 'sm' | 'md' | 'lg';
+export type BadgeSize = 'xs' | 'sm' | 'md' | 'lg';
export interface BadgeProps extends BoxCssComponentProps, PropsWithChildren {
variant?: EnumOrPrimitive;
diff --git a/libs/ui/src/tokens/badge.ts b/libs/ui/src/tokens/badge.ts
index 2bbdc78..9b81337 100644
--- a/libs/ui/src/tokens/badge.ts
+++ b/libs/ui/src/tokens/badge.ts
@@ -8,6 +8,16 @@ export const badge = {
whiteSpace: 'nowrap',
},
size: {
+ xs: {
+ height: '16px',
+ borderRadius: (theme: Record) => get(theme, 'radius.default', 'theme.radius.default'),
+ padding: (theme: Record) => `0 ${get(theme, 'spacing.sm', 'theme.spacing.sm')}`,
+ fontSize: (theme: Record) => get(theme, 'font.size.caption', 'theme.font.size.caption'),
+ lineHeight: (theme: Record) =>
+ get(theme, 'font.line.height.caption', 'theme.font.line.height.caption'),
+ fontWeight: (theme: Record) => get(theme, 'font.weight.normal', 'theme.font.weight.normal'),
+ gap: (theme: Record) => get(theme, 'spacing.xs', 'theme.spacing.xs'),
+ },
sm: {
height: '28px',
borderRadius: (theme: Record) => get(theme, 'radius.default', 'theme.radius.default'),