diff --git a/packages/kumo-docs-astro/src/components/demos/PopoverDemo.tsx b/packages/kumo-docs-astro/src/components/demos/PopoverDemo.tsx
index b33afd6e6a..8c7dd1f973 100644
--- a/packages/kumo-docs-astro/src/components/demos/PopoverDemo.tsx
+++ b/packages/kumo-docs-astro/src/components/demos/PopoverDemo.tsx
@@ -200,7 +200,7 @@ export function PopoverVirtualAnchorDemo() {
{row.status}
-
- xs
-
-
sm
-
- The `size` prop on `Autocomplete.InputGroup` supports four variants matching the
- Input component: `xs`, `sm`, `base` (default), and `lg`.
+ The `size` prop on `Autocomplete.InputGroup` supports three variants matching
+ the Input component: `sm`, `base` (default), and `lg`. (`xs` is deprecated —
+ use `sm`.)
diff --git a/packages/kumo-docs-astro/src/pages/components/combobox.mdx b/packages/kumo-docs-astro/src/pages/components/combobox.mdx
index ab3a7ff80b..96aeea7769 100644
--- a/packages/kumo-docs-astro/src/pages/components/combobox.mdx
+++ b/packages/kumo-docs-astro/src/pages/components/combobox.mdx
@@ -95,8 +95,8 @@ export default function Example() {
### Sizes
- The Combobox supports four size variants that match the Input component: `xs`,
- `sm`, `base` (default), and `lg`.
+ The Combobox supports three size variants that match the Input component:
+ `sm`, `base` (default), and `lg`. (`xs` is deprecated — use `sm`.)
diff --git a/packages/kumo-docs-astro/src/pages/components/input-area.mdx b/packages/kumo-docs-astro/src/pages/components/input-area.mdx
index 8c1eb3a2c8..2c3db81837 100644
--- a/packages/kumo-docs-astro/src/pages/components/input-area.mdx
+++ b/packages/kumo-docs-astro/src/pages/components/input-area.mdx
@@ -132,7 +132,7 @@ export default function Example() {
### Sizes
-Four sizes available: `xs`, `sm`, `base` (default), `lg`.
+Three sizes available: `sm`, `base` (default), `lg`. (`xs` is deprecated — use `sm`.)
diff --git a/packages/kumo-docs-astro/src/pages/components/input-group.mdx b/packages/kumo-docs-astro/src/pages/components/input-group.mdx
index efb591ac72..9a42e6bdb3 100644
--- a/packages/kumo-docs-astro/src/pages/components/input-group.mdx
+++ b/packages/kumo-docs-astro/src/pages/components/input-group.mdx
@@ -170,8 +170,8 @@ export default function Example() {
### Sizes
- Four sizes: `xs`, `sm`, `base` (default), and `lg`. The size applies to the
- entire group.
+ Three sizes: `sm`, `base` (default), and `lg`. The size applies to the
+ entire group. (`xs` is deprecated — use `sm`.)
diff --git a/packages/kumo-docs-astro/src/pages/components/input.mdx b/packages/kumo-docs-astro/src/pages/components/input.mdx
index 9ee34763ac..dca0ed6e75 100644
--- a/packages/kumo-docs-astro/src/pages/components/input.mdx
+++ b/packages/kumo-docs-astro/src/pages/components/input.mdx
@@ -136,7 +136,7 @@ export default function Example() {
### Input Sizes
-Four sizes available: `xs`, `sm`, `base` (default), `lg`.
+Three sizes available: `sm`, `base` (default), `lg`. (`xs` is deprecated — use `sm`.)
diff --git a/packages/kumo-docs-astro/src/pages/components/toolbar.mdx b/packages/kumo-docs-astro/src/pages/components/toolbar.mdx
index b300c23238..3109c33d40 100644
--- a/packages/kumo-docs-astro/src/pages/components/toolbar.mdx
+++ b/packages/kumo-docs-astro/src/pages/components/toolbar.mdx
@@ -105,8 +105,8 @@ inline addon or suffix.
### Sizes
-The `size` prop supports `xs`, `sm`, `base`, and `lg`. Every supported toolbar
-item is locked to the same size.
+The `size` prop supports `sm`, `base`, and `lg`. Every supported toolbar
+item is locked to the same size. (`xs` is deprecated — use `sm`.)
diff --git a/packages/kumo-docs-astro/src/pages/tests/select.astro b/packages/kumo-docs-astro/src/pages/tests/select.astro
index e01b66e3be..47ad9be078 100644
--- a/packages/kumo-docs-astro/src/pages/tests/select.astro
+++ b/packages/kumo-docs-astro/src/pages/tests/select.astro
@@ -259,14 +259,13 @@ const [value, setValue] = useState(null);
9. Size Variants
- All four sizes match Input component sizing.
+ Three sizes match Input component sizing.
- {` // Extra small: h-5 (20px)
- // Small: h-6.5 (26px)
+ {` // Small: h-6.5 (26px)
// Default: h-9 (36px)
// Large: h-10 (40px)`}
diff --git a/packages/kumo-figma/src/build-theme-data.ts b/packages/kumo-figma/src/build-theme-data.ts
index b7c41df4b2..3f7fc30566 100644
--- a/packages/kumo-figma/src/build-theme-data.ts
+++ b/packages/kumo-figma/src/build-theme-data.ts
@@ -367,7 +367,7 @@ function generateSpacingScale(baseUnitPx: number): Record {
*/
function parseButtonCompactSizes(tsx: string): Record {
const sizes: Record = {};
- const sizeNames = ["xs", "sm", "base", "lg"];
+ const sizeNames = ["sm", "base", "lg"];
for (const name of sizeNames) {
// Match: xs: { classes: "size-3.5" }
@@ -421,7 +421,7 @@ console.log(
console.log("\n🔘 Parsing button.tsx compact sizes...");
const buttonCompactSizes = parseButtonCompactSizes(buttonTsx);
console.log(
- ` - Compact sizes: xs=${buttonCompactSizes.xs}px, sm=${buttonCompactSizes.sm}px, base=${buttonCompactSizes.base}px, lg=${buttonCompactSizes.lg}px`,
+ ` - Compact sizes: sm=${buttonCompactSizes.sm}px, base=${buttonCompactSizes.base}px, lg=${buttonCompactSizes.lg}px`,
);
// Generate full spacing scale
diff --git a/packages/kumo-figma/src/generators/button.ts b/packages/kumo-figma/src/generators/button.ts
index 98a259d1a3..7236682377 100644
--- a/packages/kumo-figma/src/generators/button.ts
+++ b/packages/kumo-figma/src/generators/button.ts
@@ -167,7 +167,6 @@ export function getButtonParsedShapeStyles(shape: string) {
* Parses size-* Tailwind classes to derive pixel values.
*
* Source: button.tsx KUMO_BUTTON_VARIANTS.compactSize
- * - xs: size-3.5 = 14px
* - sm: size-6.5 = 26px
* - base: size-9 = 36px
* - lg: size-10 = 40px
@@ -178,7 +177,6 @@ export function getButtonParsedShapeStyles(shape: string) {
export function getCompactSizeMap(): Record {
// Compact size classes from KUMO_BUTTON_VARIANTS.compactSize in button.tsx
const compactSizeClasses: Record = {
- xs: "size-3.5",
sm: "size-6.5",
base: "size-9",
lg: "size-10",
@@ -727,7 +725,7 @@ export async function generateButtonComponents(
];
// Define column headers for shape rows (sizes)
- const shapeColumnHeaders = ["xs", "sm", "base", "lg"];
+ const shapeColumnHeaders = ["sm", "base", "lg"];
// Track shape section column headers separately
const shapeColumnHeaderPositions: { x: number; text: string }[] = [];
diff --git a/packages/kumo-figma/src/generators/drift-detection.test.ts b/packages/kumo-figma/src/generators/drift-detection.test.ts
index 4875e5fcf7..43e0c03807 100644
--- a/packages/kumo-figma/src/generators/drift-detection.test.ts
+++ b/packages/kumo-figma/src/generators/drift-detection.test.ts
@@ -403,7 +403,6 @@ describe("Figma Plugin - Registry Sync Validation", () => {
// Expected compact sizes from Button COMPACT_SIZE_MAP (derived from registry)
const expectedSizes: Record = {
- xs: 14, // size-3.5 = 3.5 * 4 = 14px
sm: 26, // size-6.5 = 6.5 * 4 = 26px
base: 36, // size-9 = 9 * 4 = 36px
lg: 40, // size-10 = 10 * 4 = 40px
@@ -817,10 +816,10 @@ describe("Figma Plugin - Phase 6 Magic Number Enforcement", () => {
content,
);
- // Check for explicit hardcoded COMPACT_SIZE_MAP definition: { xs: 14, sm: 26, base: 36, lg: 40 }
+ // Check for explicit hardcoded COMPACT_SIZE_MAP definition: { sm: 26, base: 36, lg: 40 }
// This is the most drift-prone pattern - explicit recreation of button compact sizes
const hasHardcodedCompactMap =
- /(?:const|let|var)\s+COMPACT_SIZE_MAP[^=]*=\s*\{[^}]*xs:\s*14[^}]*sm:\s*26/.test(
+ /(?:const|let|var)\s+COMPACT_SIZE_MAP[^=]*=\s*\{[^}]*sm:\s*26[^}]*base:\s*36/.test(
content,
);
@@ -840,7 +839,6 @@ describe("Figma Plugin - Phase 6 Magic Number Enforcement", () => {
` 2. Replace hardcoded definitions:\n` +
` - const COMPACT_SIZE_MAP = FALLBACK_VALUES.buttonCompactSize;\n` +
` Or reference values directly:\n` +
- ` - FALLBACK_VALUES.buttonCompactSize.xs (14px)\n` +
` - FALLBACK_VALUES.buttonCompactSize.sm (26px)\n` +
` - FALLBACK_VALUES.buttonCompactSize.base (36px)\n` +
` - FALLBACK_VALUES.buttonCompactSize.lg (40px)\n`,
@@ -1214,7 +1212,6 @@ describe("Figma Plugin - CSS Theme Sync Validation", () => {
};
// Verify theme-data.json matches button.tsx source
- expect(themeData.kumo.buttonCompactSize.xs).toBe(extractSizeClass("xs"));
expect(themeData.kumo.buttonCompactSize.sm).toBe(extractSizeClass("sm"));
expect(themeData.kumo.buttonCompactSize.base).toBe(
extractSizeClass("base"),
@@ -1222,7 +1219,6 @@ describe("Figma Plugin - CSS Theme Sync Validation", () => {
expect(themeData.kumo.buttonCompactSize.lg).toBe(extractSizeClass("lg"));
// Verify expected values
- expect(themeData.kumo.buttonCompactSize.xs).toBe(14); // size-3.5 = 14px
expect(themeData.kumo.buttonCompactSize.sm).toBe(26); // size-6.5 = 26px
expect(themeData.kumo.buttonCompactSize.base).toBe(36); // size-9 = 36px
expect(themeData.kumo.buttonCompactSize.lg).toBe(40); // size-10 = 40px
diff --git a/packages/kumo-figma/src/generators/input-area.ts b/packages/kumo-figma/src/generators/input-area.ts
index 9da509dac9..ae46b84be5 100644
--- a/packages/kumo-figma/src/generators/input-area.ts
+++ b/packages/kumo-figma/src/generators/input-area.ts
@@ -74,7 +74,6 @@ function getSizeConfigFromRegistry(size: string) {
string,
{ minHeight: number; width: number }
> = {
- xs: { minHeight: 60, width: 200 },
sm: { minHeight: 72, width: 240 },
base: { minHeight: 88, width: 320 },
lg: { minHeight: 100, width: 360 },
@@ -124,7 +123,6 @@ const SIZE_CONFIG: Record<
width: number;
}
> = {
- xs: getSizeConfigFromRegistry("xs"),
sm: getSizeConfigFromRegistry("sm"),
base: getSizeConfigFromRegistry("base"),
lg: getSizeConfigFromRegistry("lg"),
diff --git a/packages/kumo-figma/src/generators/input.ts b/packages/kumo-figma/src/generators/input.ts
index 7313dcb418..03775e921d 100644
--- a/packages/kumo-figma/src/generators/input.ts
+++ b/packages/kumo-figma/src/generators/input.ts
@@ -84,7 +84,6 @@ function getSizeConfigFromRegistry(size: string) {
string,
{ height: number; paddingX: number; fontSize: number; borderRadius: number }
> = {
- xs: { height: 20, paddingX: 6, fontSize: 12, borderRadius: 2 },
sm: { height: 26, paddingX: 8, fontSize: 12, borderRadius: 6 },
base: { height: 36, paddingX: 12, fontSize: 16, borderRadius: 8 },
lg: { height: 40, paddingX: 16, fontSize: 16, borderRadius: 8 },
@@ -95,7 +94,6 @@ function getSizeConfigFromRegistry(size: string) {
// Layout-specific widths (not in registry - generator specific)
const widthMap: Record = {
- xs: 160,
sm: 200,
base: 280,
lg: 320,
@@ -123,7 +121,6 @@ const SIZE_CONFIG: Record<
width: number;
}
> = {
- xs: getSizeConfigFromRegistry("xs"),
sm: getSizeConfigFromRegistry("sm"),
base: getSizeConfigFromRegistry("base"),
lg: getSizeConfigFromRegistry("lg"),
diff --git a/packages/kumo-figma/src/generators/refresh-button.test.ts b/packages/kumo-figma/src/generators/refresh-button.test.ts
index 836d55e7e9..6791d965f0 100644
--- a/packages/kumo-figma/src/generators/refresh-button.test.ts
+++ b/packages/kumo-figma/src/generators/refresh-button.test.ts
@@ -42,7 +42,6 @@ describe("RefreshButton Generator - Registry Validation", () => {
it("should have all expected size variants in registry", () => {
expect(Array.isArray(sizeProp.values)).toBe(true);
expect(sizeProp.values.length).toBeGreaterThan(0);
- expect(sizeProp.values).toContain("xs");
expect(sizeProp.values).toContain("sm");
expect(sizeProp.values).toContain("base");
expect(sizeProp.values).toContain("lg");
@@ -103,7 +102,7 @@ describe("RefreshButton Generator - Compact Size Configuration", () => {
const COMPACT_SIZE_MAP = FALLBACK_VALUES.buttonCompactSize;
it("should have compact size mapping for all sizes", () => {
- expect(Object.keys(COMPACT_SIZE_MAP)).toHaveLength(4);
+ expect(Object.keys(COMPACT_SIZE_MAP)).toHaveLength(3);
for (const size of sizeProp.values) {
expect(
COMPACT_SIZE_MAP[size as keyof typeof COMPACT_SIZE_MAP],
@@ -125,7 +124,6 @@ describe("RefreshButton Generator - Compact Size Configuration", () => {
});
it("should have increasing size values", () => {
- expect(COMPACT_SIZE_MAP.sm).toBeGreaterThan(COMPACT_SIZE_MAP.xs);
expect(COMPACT_SIZE_MAP.base).toBeGreaterThan(COMPACT_SIZE_MAP.sm);
expect(COMPACT_SIZE_MAP.lg).toBeGreaterThan(COMPACT_SIZE_MAP.base);
});
@@ -134,14 +132,13 @@ describe("RefreshButton Generator - Compact Size Configuration", () => {
describe("RefreshButton Generator - Icon Size Configuration", () => {
// RefreshButton-specific icon sizes (not in shared.ts as these are component-specific)
const REFRESH_ICON_SIZE: Record = {
- xs: 12,
sm: 16,
base: 18,
lg: 20,
};
it("should have icon size mapping for all sizes", () => {
- expect(Object.keys(REFRESH_ICON_SIZE)).toHaveLength(4);
+ expect(Object.keys(REFRESH_ICON_SIZE)).toHaveLength(3);
for (const size of sizeProp.values) {
expect(REFRESH_ICON_SIZE[size]).toBeDefined();
expect(typeof REFRESH_ICON_SIZE[size]).toBe("number");
@@ -160,7 +157,7 @@ describe("RefreshButton Generator - Icon Size Configuration", () => {
});
it("should have increasing icon size values", () => {
- expect(Object.keys(REFRESH_ICON_SIZE)).toHaveLength(4);
+ expect(Object.keys(REFRESH_ICON_SIZE)).toHaveLength(3);
for (const size of sizeProp.values) {
expect(REFRESH_ICON_SIZE[size]).toBeDefined();
expect(typeof REFRESH_ICON_SIZE[size]).toBe("number");
@@ -170,14 +167,12 @@ describe("RefreshButton Generator - Icon Size Configuration", () => {
it("should have icon sizes smaller than button sizes", () => {
const REFRESH_ICON_SIZE: Record = {
- xs: 12,
sm: 16,
base: 18,
lg: 20,
};
const COMPACT_SIZE_MAP: Record = {
- xs: 14,
sm: 26,
base: 36,
lg: 40,
@@ -190,18 +185,15 @@ describe("RefreshButton Generator - Icon Size Configuration", () => {
it("should have increasing icon size values", () => {
const REFRESH_ICON_SIZE: Record = {
- xs: 12,
sm: 16,
base: 18,
lg: 20,
};
- const xs = REFRESH_ICON_SIZE.xs;
const sm = REFRESH_ICON_SIZE.sm;
const base = REFRESH_ICON_SIZE.base;
const lg = REFRESH_ICON_SIZE.lg;
- expect(sm).toBeGreaterThan(xs);
expect(base).toBeGreaterThan(sm);
expect(lg).toBeGreaterThan(base);
});
@@ -282,8 +274,8 @@ describe("RefreshButton Generator - Size Styles Parsing", () => {
describe("RefreshButton Generator - Complete Variant Data", () => {
it("should have size values array", () => {
expect(Array.isArray(sizeProp.values)).toBe(true);
- expect(sizeProp.values.length).toBe(4);
- expect(sizeProp.values).toEqual(["xs", "sm", "base", "lg"]);
+ expect(sizeProp.values.length).toBe(3);
+ expect(sizeProp.values).toEqual(["sm", "base", "lg"]);
});
it("should have loading state options", () => {
@@ -299,7 +291,7 @@ describe("RefreshButton Generator - Complete Variant Data", () => {
const loadingOptions = [false, true];
const totalCombinations = sizes.length * loadingOptions.length;
- expect(totalCombinations).toBe(8);
+ expect(totalCombinations).toBe(6);
});
it("should have consistent data structure for all sizes", () => {
@@ -319,21 +311,19 @@ describe("RefreshButton Generator - Complete Variant Data", () => {
it("should have all required configuration maps", () => {
const COMPACT_SIZE_MAP: Record = {
- xs: 14,
sm: 26,
base: 36,
lg: 40,
};
const REFRESH_ICON_SIZE: Record = {
- xs: 12,
sm: 16,
base: 18,
lg: 20,
};
- expect(Object.keys(COMPACT_SIZE_MAP)).toHaveLength(4);
- expect(Object.keys(REFRESH_ICON_SIZE)).toHaveLength(4);
+ expect(Object.keys(COMPACT_SIZE_MAP)).toHaveLength(3);
+ expect(Object.keys(REFRESH_ICON_SIZE)).toHaveLength(3);
// Verify all size values have mappings
for (const size of sizeProp.values) {
diff --git a/packages/kumo-figma/src/generators/refresh-button.ts b/packages/kumo-figma/src/generators/refresh-button.ts
index cc2ecdde6f..18d0c1ee29 100644
--- a/packages/kumo-figma/src/generators/refresh-button.ts
+++ b/packages/kumo-figma/src/generators/refresh-button.ts
@@ -61,7 +61,6 @@ const sizeProp = buttonProps.size as {
* Uses FALLBACK_VALUES.iconSize from shared.ts to prevent drift
*/
const REFRESH_ICON_SIZE: Record = {
- xs: FALLBACK_VALUES.iconSize.xs, // size-3 = 12px
sm: FALLBACK_VALUES.iconSize.sm, // size-4 = 16px
base: FALLBACK_VALUES.iconSize.medium, // size-4.5 = 18px
lg: FALLBACK_VALUES.iconSize.base, // size-5 = 20px
diff --git a/packages/kumo-figma/src/generators/sensitive-input.test.ts b/packages/kumo-figma/src/generators/sensitive-input.test.ts
index 84788d2227..8d7687aa02 100644
--- a/packages/kumo-figma/src/generators/sensitive-input.test.ts
+++ b/packages/kumo-figma/src/generators/sensitive-input.test.ts
@@ -42,7 +42,6 @@ describe("SensitiveInput Generator - Registry Validation", () => {
// Verify size values match Input component
expect(Array.isArray(sizeProIf.values)).toBe(true);
expect(sizeProIf.values.length).toBeGreaterThan(0);
- expect(sizeProIf.values).toContain("xs");
expect(sizeProIf.values).toContain("sm");
expect(sizeProIf.values).toContain("base");
expect(sizeProIf.values).toContain("lg");
@@ -104,8 +103,7 @@ describe("SensitiveInput Generator - Registry Validation", () => {
describe("SensitiveInput Generator - Size Configuration", () => {
it("should export size values", () => {
expect(Array.isArray(SENSITIVE_INPUT_SIZE_VALUES)).toBe(true);
- expect(SENSITIVE_INPUT_SIZE_VALUES.length).toBe(4);
- expect(SENSITIVE_INPUT_SIZE_VALUES).toContain("xs");
+ expect(SENSITIVE_INPUT_SIZE_VALUES.length).toBe(3);
expect(SENSITIVE_INPUT_SIZE_VALUES).toContain("sm");
expect(SENSITIVE_INPUT_SIZE_VALUES).toContain("base");
expect(SENSITIVE_INPUT_SIZE_VALUES).toContain("lg");
@@ -180,7 +178,7 @@ describe("SensitiveInput Generator - WithLabel Configuration", () => {
describe("SensitiveInput Generator - Component Variant Combinations", () => {
it("should generate correct number of variant combinations", () => {
- // 4 sizes × 2 variants × 3 states × 2 modes × 2 withLabel = 96 total combinations
+ // 3 sizes × 2 variants × 3 states × 2 modes × 2 withLabel = 72 total combinations
const expectedCombinations =
SENSITIVE_INPUT_SIZE_VALUES.length *
SENSITIVE_INPUT_VARIANT_VALUES.length *
@@ -188,7 +186,7 @@ describe("SensitiveInput Generator - Component Variant Combinations", () => {
SENSITIVE_INPUT_MODE_VALUES.length *
2; // withLabel (false, true)
- expect(expectedCombinations).toBe(96);
+ expect(expectedCombinations).toBe(72);
});
it("should validate all size values are valid", () => {
diff --git a/packages/kumo-figma/src/generators/sensitive-input.ts b/packages/kumo-figma/src/generators/sensitive-input.ts
index 568e0a16f6..0772e3f31e 100644
--- a/packages/kumo-figma/src/generators/sensitive-input.ts
+++ b/packages/kumo-figma/src/generators/sensitive-input.ts
@@ -73,7 +73,6 @@ const VARIANT_VALUES = variantProp.values;
* Width mapping for SensitiveInput (layout-specific)
*/
const SIZE_WIDTHS: Record = {
- xs: 200,
sm: 220,
base: 280,
lg: 320,
@@ -83,7 +82,6 @@ const SIZE_WIDTHS: Record = {
* Icon size mapping for SensitiveInput (layout-specific)
*/
const ICON_SIZES: Record = {
- xs: "sm",
sm: "sm",
base: "base",
lg: "base",
@@ -120,12 +118,6 @@ function getSizeConfigFromRegistry(size: string): {
string,
{ height: number; paddingX: number; fontSize: number; borderRadius: number }
> = {
- xs: {
- height: 20,
- paddingX: 6,
- fontSize: 12,
- borderRadius: BORDER_RADIUS.xs,
- },
sm: {
height: 26,
paddingX: 8,
diff --git a/packages/kumo-figma/src/generators/shared.ts b/packages/kumo-figma/src/generators/shared.ts
index 29c0cf52da..ada3276026 100644
--- a/packages/kumo-figma/src/generators/shared.ts
+++ b/packages/kumo-figma/src/generators/shared.ts
@@ -435,8 +435,6 @@ export const FALLBACK_VALUES = {
* Generated from: button.tsx KUMO_BUTTON_VARIANTS.compactSize
*/
buttonCompactSize: {
- /** Extra small compact button (size-3.5) */
- xs: themeData.computed.buttonCompactSize.xs,
/** Small compact button (size-6.5) */
sm: themeData.computed.buttonCompactSize.sm,
/** Base compact button (size-9) */
diff --git a/packages/kumo/scripts/component-registry/metadata.ts b/packages/kumo/scripts/component-registry/metadata.ts
index c78928eb92..5b1a2116f8 100644
--- a/packages/kumo/scripts/component-registry/metadata.ts
+++ b/packages/kumo/scripts/component-registry/metadata.ts
@@ -889,7 +889,6 @@ export const COMPONENT_STYLING_METADATA: Record = {
},
InputArea: {
sizeVariants: {
- xs: { minHeight: 60, width: 200 },
sm: { minHeight: 72, width: 240 },
base: { minHeight: 88, width: 320 },
lg: { minHeight: 100, width: 360 },
diff --git a/packages/kumo/src/components/autocomplete/autocomplete.test.tsx b/packages/kumo/src/components/autocomplete/autocomplete.test.tsx
index 431c5ba8ec..a1cc995995 100644
--- a/packages/kumo/src/components/autocomplete/autocomplete.test.tsx
+++ b/packages/kumo/src/components/autocomplete/autocomplete.test.tsx
@@ -44,7 +44,6 @@ describe("Autocomplete", () => {
// Variants export
it("exports KUMO_AUTOCOMPLETE_VARIANTS with size axis", () => {
- expect(KUMO_AUTOCOMPLETE_VARIANTS.size.xs).toBeDefined();
expect(KUMO_AUTOCOMPLETE_VARIANTS.size.sm).toBeDefined();
expect(KUMO_AUTOCOMPLETE_VARIANTS.size.base).toBeDefined();
expect(KUMO_AUTOCOMPLETE_VARIANTS.size.lg).toBeDefined();
diff --git a/packages/kumo/src/components/autocomplete/autocomplete.tsx b/packages/kumo/src/components/autocomplete/autocomplete.tsx
index c93facbe66..cc2f278072 100644
--- a/packages/kumo/src/components/autocomplete/autocomplete.tsx
+++ b/packages/kumo/src/components/autocomplete/autocomplete.tsx
@@ -25,7 +25,6 @@ export type KumoAutocompleteSize = keyof typeof KUMO_AUTOCOMPLETE_VARIANTS.size;
export interface KumoAutocompleteVariantsProps {
/**
* Size of the autocomplete input. Matches Input component sizes.
- * - `"xs"` — Extra small for compact UIs (h-5 / 20px)
* - `"sm"` — Small for secondary fields (h-6.5 / 26px)
* - `"base"` — Default size (h-9 / 36px)
* - `"lg"` — Large for prominent fields (h-10 / 40px)
diff --git a/packages/kumo/src/components/banner/banner-action.tsx b/packages/kumo/src/components/banner/banner-action.tsx
index 4df98f62ca..be448311a8 100644
--- a/packages/kumo/src/components/banner/banner-action.tsx
+++ b/packages/kumo/src/components/banner/banner-action.tsx
@@ -26,10 +26,9 @@ export type BannerActionVariant = Extract<
/**
* Size of a `Banner.Action`, matching the equivalent `Button` size specs.
- * - `"xs"` — extra small for dense/compact banners.
* - `"sm"` — small (default), the standard banner CTA size.
*/
-export type BannerActionSize = Extract;
+export type BannerActionSize = Extract;
/** Value shared from the `Banner` root to its `Banner.Action` children. */
export interface BannerActionContextValue {
@@ -43,8 +42,8 @@ export interface BannerActionContextValue {
* Propagates the banner's variant and action size to `Banner.Action`
* children so each CTA can self-style without prop drilling:
* - `variant` — selects the matching accent color.
- * - `size` — a compact `size="sm"` banner renders actions at `"xs"`, and a
- * `"base"` banner renders them at `"sm"`.
+ * - `size` — currently always `"sm"`; retained on the context for future
+ * flexibility.
*
* The `Banner` root always overrides these defaults via a Provider; the literals
* mirror a default, base-size banner (kept as literals to avoid a runtime import
diff --git a/packages/kumo/src/components/banner/banner.test.tsx b/packages/kumo/src/components/banner/banner.test.tsx
index 0faa017a28..f11f3f5567 100644
--- a/packages/kumo/src/components/banner/banner.test.tsx
+++ b/packages/kumo/src/components/banner/banner.test.tsx
@@ -146,7 +146,7 @@ describe("Banner", () => {
expect(className).not.toContain("items-start");
});
- it("defaults Banner.Action children to xs in an sm banner", () => {
+ it("defaults Banner.Action children to sm in an sm banner", () => {
render(
{
);
const cta = screen.getByTestId("cta");
- // Inherits the banner's size => xs (h-5), not the standalone sm default (h-6.5).
- expect(cta.className).toContain("h-5");
- expect(cta.className).toContain("px-1.5");
+ // Both banner sizes render actions at sm now that Button no longer has xs.
+ expect(cta.className).toContain("h-6.5");
+ expect(cta.className).toContain("px-2");
});
it("matches an icon-only action to the text action height in an sm banner", () => {
@@ -179,9 +179,8 @@ describe("Banner", () => {
);
const cta = screen.getByTestId("cta");
- expect(cta.className).toContain("h-5");
- expect(cta.className).toContain("px-1.5");
- expect(cta.className).not.toContain("size-3.5");
+ expect(cta.className).toContain("h-6.5");
+ expect(cta.className).toContain("px-2");
});
it("renders title and description inline in an sm banner", () => {
diff --git a/packages/kumo/src/components/banner/banner.tsx b/packages/kumo/src/components/banner/banner.tsx
index 4e956c7c4f..1e9e4b78bd 100644
--- a/packages/kumo/src/components/banner/banner.tsx
+++ b/packages/kumo/src/components/banner/banner.tsx
@@ -66,6 +66,9 @@ export type KumoBannerSize = keyof typeof KUMO_BANNER_VARIANTS.size;
* the container classes). `row` is the title↔action flex gap, `icon` the icon
* wrapper height, `description` the description text size, and `action` the size
* that child `Banner.Action`s inherit via {@link BannerActionContext}.
+ *
+ * Both banner sizes render their actions at `"sm"` now that `Button` no longer
+ * offers an `"xs"` size.
*/
const BANNER_SIZE_PARTS: Record<
KumoBannerSize,
@@ -81,7 +84,7 @@ const BANNER_SIZE_PARTS: Record<
row: "gap-2",
icon: "h-[1.25em]",
description: "text-sm",
- action: "xs",
+ action: "sm",
},
};
@@ -186,10 +189,9 @@ export interface BannerProps extends Omit<
*/
variant?: KumoBannerVariant;
/**
- * Size of the banner. A `"sm"` banner uses tighter spacing and `text-sm`,
- * renders a Kumo `Link` action inline with the description, and sets its
- * `Banner.Action` children to the `"xs"` size — suited to dialogs and other
- * tight spaces.
+ * Size of the banner. A `"sm"` banner uses tighter spacing and `text-sm`
+ * and renders a Kumo `Link` action inline with the description — suited to
+ * dialogs and other tight spaces.
* @default "base"
*/
size?: KumoBannerSize;
diff --git a/packages/kumo/src/components/button/button.tsx b/packages/kumo/src/components/button/button.tsx
index b5f59bd1dc..b0ef37db43 100644
--- a/packages/kumo/src/components/button/button.tsx
+++ b/packages/kumo/src/components/button/button.tsx
@@ -23,10 +23,6 @@ export const KUMO_BUTTON_VARIANTS = {
},
},
size: {
- xs: {
- classes: "h-5 gap-1 rounded-sm px-1.5 text-xs",
- description: "Extra small button for compact UIs",
- },
sm: {
classes: "h-6.5 gap-1 rounded-md px-2 text-xs",
description: "Small button for secondary actions",
@@ -41,7 +37,6 @@ export const KUMO_BUTTON_VARIANTS = {
},
},
compactSize: {
- xs: { classes: "size-3.5" },
sm: { classes: "size-6.5" },
base: { classes: "size-9" },
lg: { classes: "size-10" },
@@ -102,7 +97,6 @@ export interface KumoButtonVariantsProps {
shape?: KumoButtonShape;
/**
* Button size.
- * - `"xs"` — Extra small for compact UIs
* - `"sm"` — Small for secondary actions
* - `"base"` — Default size
* - `"lg"` — Large for primary CTAs
diff --git a/packages/kumo/src/components/combobox/combobox.test.tsx b/packages/kumo/src/components/combobox/combobox.test.tsx
index 80c03af840..aea2443914 100644
--- a/packages/kumo/src/components/combobox/combobox.test.tsx
+++ b/packages/kumo/src/components/combobox/combobox.test.tsx
@@ -44,7 +44,7 @@ describe("Combobox", () => {
// Variants export
it("exports KUMO_COMBOBOX_VARIANTS with size and inputSide axes", () => {
- expect(KUMO_COMBOBOX_VARIANTS.size.xs).toBeDefined();
+ expect(KUMO_COMBOBOX_VARIANTS.size.sm).toBeDefined();
expect(KUMO_COMBOBOX_VARIANTS.size.base).toBeDefined();
expect(KUMO_COMBOBOX_VARIANTS.inputSide.right).toBeDefined();
expect(KUMO_COMBOBOX_VARIANTS.inputSide.top).toBeDefined();
diff --git a/packages/kumo/src/components/combobox/combobox.tsx b/packages/kumo/src/components/combobox/combobox.tsx
index 22414692cf..b6f752b73a 100644
--- a/packages/kumo/src/components/combobox/combobox.tsx
+++ b/packages/kumo/src/components/combobox/combobox.tsx
@@ -54,7 +54,6 @@ export type KumoComboboxInputSide =
export interface KumoComboboxVariantsProps {
/**
* Size of the combobox trigger. Matches Input component sizes.
- * - `"xs"` — Extra small for compact UIs (h-5 / 20px)
* - `"sm"` — Small for secondary fields (h-6.5 / 26px)
* - `"base"` — Default size (h-9 / 36px)
* - `"lg"` — Large for prominent fields (h-10 / 40px)
@@ -251,7 +250,6 @@ const triggerValueIconStyles: Record<
KumoComboboxSize,
{ padding: string; iconSize: number; iconRight: string }
> = {
- xs: { padding: "pr-5", iconSize: 12, iconRight: "right-1" },
sm: { padding: "pr-6", iconSize: 14, iconRight: "right-1.5" },
base: { padding: "pr-8", iconSize: 16, iconRight: "right-2" },
lg: { padding: "pr-10", iconSize: 18, iconRight: "right-3" },
@@ -295,12 +293,6 @@ const triggerInputIconStyles: Record<
KumoComboboxSize,
{ padding: string; iconSize: number; clearRight: string; caretRight: string }
> = {
- xs: {
- padding: "pr-7",
- iconSize: 12,
- clearRight: "right-5",
- caretRight: "right-1",
- },
sm: {
padding: "pr-9",
iconSize: 14,
@@ -514,7 +506,6 @@ function Chip({
// Map size to min-height class for TriggerMultipleWithInput
const sizeToMinHeight: Record = {
- xs: "min-h-5",
sm: "min-h-6.5",
base: "min-h-9",
lg: "min-h-10",
diff --git a/packages/kumo/src/components/input-group/context.ts b/packages/kumo/src/components/input-group/context.ts
index 8612854f71..1ffba17cf9 100644
--- a/packages/kumo/src/components/input-group/context.ts
+++ b/packages/kumo/src/components/input-group/context.ts
@@ -50,16 +50,6 @@ export interface InputGroupSizeTokens {
}
export const INPUT_GROUP_SIZE: Record = {
- xs: {
- inputOuter: "px-1.5",
- addonOuterStart: "pl-1.5",
- addonOuterEnd: "pr-1.5",
- addonButtonOuterStart: "pl-1",
- addonButtonOuterEnd: "pr-1",
- suffixPad: "pr-1.5",
- fontSize: "text-xs",
- iconSize: 10,
- },
sm: {
inputOuter: "px-2",
addonOuterStart: "pl-1.5",
@@ -95,10 +85,6 @@ export const INPUT_GROUP_SIZE: Record = {
// Build the has-[] container classes that reduce input padding when addons
// are present. These are static strings so Tailwind JIT can detect them.
export const INPUT_GROUP_HAS_CLASSES: Record = {
- xs: [
- "has-[[data-slot=input-group-addon-start]]:[&_input]:pl-1",
- "has-[[data-slot=input-group-addon-end]]:[&_input]:pr-1",
- ].join(" "),
sm: [
"has-[[data-slot=input-group-addon-start]]:[&_input]:pl-1.5",
"has-[[data-slot=input-group-addon-end]]:[&_input]:pr-1.5",
diff --git a/packages/kumo/src/components/input-group/input-group-button.tsx b/packages/kumo/src/components/input-group/input-group-button.tsx
index e0c0bfea07..bc4a5f2375 100644
--- a/packages/kumo/src/components/input-group/input-group-button.tsx
+++ b/packages/kumo/src/components/input-group/input-group-button.tsx
@@ -18,10 +18,11 @@ import {
* In container mode, buttons render "one size down" so they stay visually
* subordinate to the input. In individual mode the size passes through
* unchanged (pagination / toolbar buttons should match the input height).
+ *
+ * `sm` has no smaller sibling now that `xs` is removed, so it stays at `sm`.
*/
const COMPACT_BUTTON_SIZE: Record = {
- xs: "xs",
- sm: "xs",
+ sm: "sm",
base: "sm",
lg: "base",
};
diff --git a/packages/kumo/src/components/input-group/input-group.test.tsx b/packages/kumo/src/components/input-group/input-group.test.tsx
index c40aa4f16f..591070f485 100644
--- a/packages/kumo/src/components/input-group/input-group.test.tsx
+++ b/packages/kumo/src/components/input-group/input-group.test.tsx
@@ -347,12 +347,12 @@ describe("InputGroup", () => {
});
// Regression test: addon padding tokens must be static pl-/pr- strings
- // so Tailwind JIT can detect them. Dynamic "px-N".replace() broke xs/sm.
- it.each(["xs", "sm", "base", "lg"] as const)(
+ // so Tailwind JIT can detect them. Dynamic "px-N".replace() broke sizes
+ // in the past.
+ it.each(["sm", "base", "lg"] as const)(
"start addon has correct padding class for size %s",
(size: KumoInputSize) => {
const labels: Record = {
- xs: "Extra Small",
sm: "Small",
base: "Base (default)",
lg: "Large",
@@ -375,7 +375,7 @@ describe("InputGroup", () => {
// Ensure all addonOuter tokens are static directional classes
// (not symmetric px- that would need runtime string replacement)
it("all addon tokens use static pl-/pr- classes (not px-)", () => {
- for (const size of ["xs", "sm", "base", "lg"] as const) {
+ for (const size of ["sm", "base", "lg"] as const) {
const tokens = INPUT_GROUP_SIZE[size];
expect(tokens.addonOuterStart).toMatch(/^pl-/);
expect(tokens.addonOuterEnd).toMatch(/^pr-/);
@@ -562,7 +562,7 @@ describe("InputGroup", () => {
);
});
- it.each(["xs", "sm", "base", "lg"] as const)(
+ it.each(["sm", "base", "lg"] as const)(
"passes correct icon size for InputGroup size %s",
(groupSize: KumoInputSize) => {
render(
diff --git a/packages/kumo/src/components/input-group/input-group.tsx b/packages/kumo/src/components/input-group/input-group.tsx
index 8471897c2d..17cb738e13 100644
--- a/packages/kumo/src/components/input-group/input-group.tsx
+++ b/packages/kumo/src/components/input-group/input-group.tsx
@@ -28,10 +28,6 @@ export { type InputGroupSuffixProps } from "./input-group-suffix";
export const KUMO_INPUT_GROUP_VARIANTS = {
size: {
- xs: {
- classes: "h-6 text-xs",
- description: "Extra small size.",
- },
sm: {
classes: "h-7 text-xs",
description: "Small size.",
diff --git a/packages/kumo/src/components/input/input-area.tsx b/packages/kumo/src/components/input/input-area.tsx
index e2273ebf2a..cf38cc724a 100644
--- a/packages/kumo/src/components/input/input-area.tsx
+++ b/packages/kumo/src/components/input/input-area.tsx
@@ -1,4 +1,4 @@
-import { inputVariants } from "./input";
+import { inputVariants, type KumoInputSize } from "./input";
import { cn } from "../../utils/cn";
import {
useCallback,
@@ -286,7 +286,8 @@ export const Textarea = InputArea;
export type InputAreaProps = {
onValueChange?: (value: string) => void;
variant?: "default" | "error";
- size?: "xs" | "sm" | "base" | "lg";
+ /** Textarea size. */
+ size?: KumoInputSize;
// Then other custom props
children?: React.ReactNode;
className?: string;
diff --git a/packages/kumo/src/components/input/input.test.tsx b/packages/kumo/src/components/input/input.test.tsx
index 0662b6cd5d..5a6fb50142 100644
--- a/packages/kumo/src/components/input/input.test.tsx
+++ b/packages/kumo/src/components/input/input.test.tsx
@@ -62,11 +62,6 @@ describe("Input", () => {
expect(screen.getByRole("textbox").className).toContain("h-9");
});
- it("renders with size 'xs'", () => {
- render( );
- expect(screen.getByRole("textbox").className).toContain("h-5");
- });
-
it("renders with size 'sm'", () => {
render( );
expect(screen.getByRole("textbox").className).toContain("h-6.5");
@@ -214,7 +209,6 @@ describe("Input", () => {
// Variants export
it("exports KUMO_INPUT_VARIANTS with size and variant axes", () => {
- expect(KUMO_INPUT_VARIANTS.size.xs).toBeDefined();
expect(KUMO_INPUT_VARIANTS.size.sm).toBeDefined();
expect(KUMO_INPUT_VARIANTS.size.base).toBeDefined();
expect(KUMO_INPUT_VARIANTS.size.lg).toBeDefined();
diff --git a/packages/kumo/src/components/input/input.tsx b/packages/kumo/src/components/input/input.tsx
index 9d4cf52acf..61147913f3 100644
--- a/packages/kumo/src/components/input/input.tsx
+++ b/packages/kumo/src/components/input/input.tsx
@@ -15,10 +15,6 @@ import {
/** Input size and variant definitions mapping names to their Tailwind classes. */
export const KUMO_INPUT_VARIANTS = {
size: {
- xs: {
- classes: "h-5 gap-1 rounded-sm px-1.5 text-xs",
- description: "Extra small input for compact UIs",
- },
sm: {
classes: "h-6.5 gap-1 rounded-md px-2 text-xs",
description: "Small input for secondary fields",
@@ -51,7 +47,6 @@ export const KUMO_INPUT_DEFAULT_VARIANTS = {
export const KUMO_INPUT_STYLING = {
dimensions: {
- xs: { height: 20, paddingX: 6, fontSize: 12, borderRadius: 2, width: 160 },
sm: { height: 26, paddingX: 8, fontSize: 12, borderRadius: 6, width: 200 },
base: {
height: 36,
@@ -82,7 +77,6 @@ export type KumoInputVariant = keyof typeof KUMO_INPUT_VARIANTS.variant;
export interface KumoInputVariantsProps {
/**
* Input size.
- * - `"xs"` — Extra small for compact UIs
* - `"sm"` — Small for secondary fields
* - `"base"` — Default size
* - `"lg"` — Large for prominent fields
diff --git a/packages/kumo/src/components/label/label.tsx b/packages/kumo/src/components/label/label.tsx
index 4142bc8b2c..1eb4fad808 100644
--- a/packages/kumo/src/components/label/label.tsx
+++ b/packages/kumo/src/components/label/label.tsx
@@ -104,7 +104,7 @@ export function Label({
render={
diff --git a/packages/kumo/src/components/select/select.test.tsx b/packages/kumo/src/components/select/select.test.tsx
index 0926e899a1..5bd876e022 100644
--- a/packages/kumo/src/components/select/select.test.tsx
+++ b/packages/kumo/src/components/select/select.test.tsx
@@ -7,15 +7,15 @@ describe("Select", () => {
describe("size", () => {
it("applies size classes to the trigger", () => {
const { container } = render(
-
+
Option A
,
);
const trigger = container.querySelector('[role="combobox"]');
expect(trigger).toBeTruthy();
- expect(trigger?.className).toContain("h-5");
- expect(trigger?.className).toContain("px-1.5");
+ expect(trigger?.className).toContain("h-6.5");
+ expect(trigger?.className).toContain("px-2");
expect(trigger?.className).toContain("text-xs");
});
});
diff --git a/packages/kumo/src/components/select/select.tsx b/packages/kumo/src/components/select/select.tsx
index df2c6864f2..8f4c37efac 100644
--- a/packages/kumo/src/components/select/select.tsx
+++ b/packages/kumo/src/components/select/select.tsx
@@ -66,7 +66,6 @@ export type KumoSelectSize = keyof typeof KUMO_SELECT_VARIANTS.size;
export interface KumoSelectVariantsProps {
/**
* Size of the select trigger. Matches Input component sizes.
- * - `"xs"` — Extra small for compact UIs (h-5 / 20px)
* - `"sm"` — Small for secondary fields (h-6.5 / 26px)
* - `"base"` — Default size (h-9 / 36px)
* - `"lg"` — Large for prominent fields (h-10 / 40px)
@@ -89,7 +88,6 @@ const triggerIconStyles: Record<
KumoInputSize,
{ iconSize: number; className: string }
> = {
- xs: { iconSize: 12, className: "text-kumo-subtle" },
sm: { iconSize: 14, className: "text-kumo-subtle" },
base: { iconSize: 16, className: "text-kumo-subtle" },
lg: { iconSize: 18, className: "text-kumo-subtle" },
diff --git a/packages/kumo/src/components/sensitive-input/sensitive-input.tsx b/packages/kumo/src/components/sensitive-input/sensitive-input.tsx
index dc68aee19b..5b6a9dbcf0 100644
--- a/packages/kumo/src/components/sensitive-input/sensitive-input.tsx
+++ b/packages/kumo/src/components/sensitive-input/sensitive-input.tsx
@@ -51,7 +51,6 @@ export interface SensitiveInputProps extends Omit<
onCopy?: () => void;
/**
* Size of the input.
- * - `"xs"` — Extra small for compact UIs
* - `"sm"` — Small for secondary fields
* - `"base"` — Default input size
* - `"lg"` — Large for prominent fields
@@ -320,7 +319,7 @@ export const SensitiveInput = forwardRef(
!disabled && (mode === "revealed" || (mode === "empty" && hasValue));
// Icon sizes matching input sizes
- const iconSize = size === "xs" || size === "sm" ? "size-3" : "size-4";
+ const iconSize = size === "sm" ? "size-3" : "size-4";
const containerClassName = cn(
inputVariants({ size, variant, parentFocusIndicator: true }),
@@ -349,7 +348,6 @@ export const SensitiveInput = forwardRef(
tabIndex={isMaskedWithValue ? -1 : 0}
className={cn(
"kumo-input-placeholder w-full border-0 bg-transparent p-0 text-kumo-default ring-0 outline-none disabled:cursor-not-allowed disabled:text-kumo-subtle",
- size === "xs" && "pr-5",
size === "sm" && "pr-6",
size === "base" && "pr-8",
size === "lg" && "pr-10",
@@ -364,12 +362,10 @@ export const SensitiveInput = forwardRef(
className={cn(
"pointer-events-none absolute inset-y-0 left-0 flex items-center overflow-hidden select-none",
// Match input pr padding (space for icon)
- size === "xs" && "right-5",
size === "sm" && "right-6",
size === "base" && "right-8",
size === "lg" && "right-10",
// Match the padding from inputVariants
- size === "xs" && "px-1.5",
size === "sm" && "px-2",
size === "base" && "px-3",
size === "lg" && "px-4",
@@ -417,7 +413,6 @@ export const SensitiveInput = forwardRef(
// Defensive styles to prevent global CSS pollution (e.g., button { background: gray })
"m-0 inline-flex h-auto min-h-0 items-center justify-center border-none bg-transparent p-0 shadow-none",
// Match right padding from inputVariants
- size === "xs" && "right-1.5",
size === "sm" && "right-2",
size === "base" && "right-3",
size === "lg" && "right-4",
diff --git a/packages/kumo/src/components/toolbar/toolbar.tsx b/packages/kumo/src/components/toolbar/toolbar.tsx
index e5b4dec84a..ee429241d9 100644
--- a/packages/kumo/src/components/toolbar/toolbar.tsx
+++ b/packages/kumo/src/components/toolbar/toolbar.tsx
@@ -13,10 +13,6 @@ import { InputGroup } from "../input-group/input-group";
export const KUMO_TOOLBAR_VARIANTS = {
size: {
- xs: {
- classes: "text-xs",
- description: "Extra small toolbar for compact UIs",
- },
sm: {
classes: "text-xs",
description: "Small toolbar for secondary controls",