From 3bfc42b43e8ef1b8357094e694f3a7a7d7304bfb Mon Sep 17 00:00:00 2001 From: nanda Date: Wed, 19 Aug 2026 10:11:14 -0700 Subject: [PATCH] feat: adjust sm size to match type scale + make bigger --- .changeset/standardize-small-controls.md | 5 ++++ .../src/components/demos/ToolbarDemo.tsx | 4 +-- .../src/pages/components/toolbar.mdx | 14 +++++------ packages/kumo-figma/src/generators/button.ts | 4 +-- .../src/generators/drift-detection.test.ts | 8 +++--- packages/kumo-figma/src/generators/input.ts | 2 +- .../src/generators/refresh-button.test.ts | 22 ++++++---------- .../src/generators/sensitive-input.ts | 4 +-- packages/kumo-figma/src/generators/shared.ts | 2 +- .../src/parsers/tailwind-to-figma.ts | 4 +-- .../scripts/component-registry/metadata.ts | 14 +++++------ .../components/autocomplete/autocomplete.tsx | 2 +- .../src/components/banner/banner.test.tsx | 8 +++--- .../src/components/button/button.test.tsx | 9 +++++++ .../kumo/src/components/button/button.tsx | 4 +-- .../clipboard-text/clipboard-text.test.tsx | 8 ++++++ .../clipboard-text/clipboard-text.tsx | 2 +- .../kumo/src/components/combobox/combobox.tsx | 4 +-- .../src/components/input-group/context.ts | 2 +- .../input-group/input-group.test.tsx | 8 +++++- .../components/input-group/input-group.tsx | 2 +- .../kumo/src/components/input/input.test.tsx | 5 +++- packages/kumo/src/components/input/input.tsx | 4 +-- .../kumo/src/components/select/select.tsx | 2 +- .../kumo/src/components/tabs/tabs.test.tsx | 9 +++++++ packages/kumo/src/components/tabs/tabs.tsx | 12 ++++----- .../kumo/src/components/toolbar/toolbar.tsx | 25 ++++++++++++------- 27 files changed, 114 insertions(+), 75 deletions(-) create mode 100644 .changeset/standardize-small-controls.md diff --git a/.changeset/standardize-small-controls.md b/.changeset/standardize-small-controls.md new file mode 100644 index 0000000000..1ace199d25 --- /dev/null +++ b/.changeset/standardize-small-controls.md @@ -0,0 +1,5 @@ +--- +"@cloudflare/kumo": patch +--- + +Standardize small interactive controls at 30px high with the base text size, including medium corner radii for small toolbars, and restore `Toolbar size="sm"` as a supported API while keeping `xs` and `lg` deprecated. diff --git a/packages/kumo-docs-astro/src/components/demos/ToolbarDemo.tsx b/packages/kumo-docs-astro/src/components/demos/ToolbarDemo.tsx index d21fe4c28e..8d69fe6cff 100644 --- a/packages/kumo-docs-astro/src/components/demos/ToolbarDemo.tsx +++ b/packages/kumo-docs-astro/src/components/demos/ToolbarDemo.tsx @@ -23,11 +23,11 @@ export function ToolbarDemo() { ); } -/** @deprecated Toolbar size customization remains for compatibility. */ +/** Supported compact and default Toolbar sizes. */ export function ToolbarSizesDemo() { return (
- {(["xs", "sm", "base", "lg"] as const).map((size) => ( + {(["sm", "base"] as const).map((size) => (
{size} diff --git a/packages/kumo-docs-astro/src/pages/components/toolbar.mdx b/packages/kumo-docs-astro/src/pages/components/toolbar.mdx index 60ebe6e3b4..63c6e1dd55 100644 --- a/packages/kumo-docs-astro/src/pages/components/toolbar.mdx +++ b/packages/kumo-docs-astro/src/pages/components/toolbar.mdx @@ -78,7 +78,7 @@ export default function Example() { Toolbar item components intentionally own grouped control presentation: - Every `Toolbar.*` control uses the `base` size by default. -- The Toolbar `size` prop remains available for compatibility but is deprecated; omit it for the base size. +- Set `size="sm"` for a compact 30px-high toolbar with medium corner radii. - `Toolbar.Button` always renders with quiet toolbar button styling. - `Toolbar.InputGroup` passes props directly to `InputGroup` with the resolved toolbar size. - Give Select `render={}` to compose its trigger into the toolbar. @@ -133,11 +133,11 @@ inline addon or suffix. -### Deprecated sizing +### Sizing -The `size` prop still supports `xs`, `sm`, `base`, and `lg` for compatibility, -but it is deprecated and will be removed in a future major release. Omit it to -use the default `base` size. +Use `size="sm"` for compact toolbars or omit `size` to use the default `base` +size. The legacy `xs` and `lg` values are deprecated and remain available only +for backwards compatibility. @@ -187,10 +187,10 @@ options instead. Toolbar controls rendered as one grouped card. - size Deprecated + size "xs" | "sm" | "base" | "lg" "base" - Sets every supported item size. Omit this deprecated prop to use the default base size. + Sets every supported item size. Use "sm" for compact toolbars; "xs" and "lg" are deprecated compatibility values. className diff --git a/packages/kumo-figma/src/generators/button.ts b/packages/kumo-figma/src/generators/button.ts index 98a259d1a3..d7e8f9387c 100644 --- a/packages/kumo-figma/src/generators/button.ts +++ b/packages/kumo-figma/src/generators/button.ts @@ -168,7 +168,7 @@ export function getButtonParsedShapeStyles(shape: string) { * * Source: button.tsx KUMO_BUTTON_VARIANTS.compactSize * - xs: size-3.5 = 14px - * - sm: size-6.5 = 26px + * - sm: size-7.5 = 30px * - base: size-9 = 36px * - lg: size-10 = 40px * @@ -179,7 +179,7 @@ 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", + sm: "size-7.5", base: "size-9", lg: "size-10", }; diff --git a/packages/kumo-figma/src/generators/drift-detection.test.ts b/packages/kumo-figma/src/generators/drift-detection.test.ts index 4875e5fcf7..49a9f908d5 100644 --- a/packages/kumo-figma/src/generators/drift-detection.test.ts +++ b/packages/kumo-figma/src/generators/drift-detection.test.ts @@ -404,7 +404,7 @@ 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 + sm: 30, // size-7.5 = 7.5 * 4 = 30px base: 36, // size-9 = 9 * 4 = 36px lg: 40, // size-10 = 10 * 4 = 40px }; @@ -817,7 +817,7 @@ 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: { xs: 14, sm: 30, 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( @@ -841,7 +841,7 @@ describe("Figma Plugin - Phase 6 Magic Number Enforcement", () => { ` - 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.sm (30px)\n` + ` - FALLBACK_VALUES.buttonCompactSize.base (36px)\n` + ` - FALLBACK_VALUES.buttonCompactSize.lg (40px)\n`, ); @@ -1223,7 +1223,7 @@ describe("Figma Plugin - CSS Theme Sync Validation", () => { // 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.sm).toBe(30); // size-7.5 = 30px 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.ts b/packages/kumo-figma/src/generators/input.ts index 7313dcb418..198632c39c 100644 --- a/packages/kumo-figma/src/generators/input.ts +++ b/packages/kumo-figma/src/generators/input.ts @@ -85,7 +85,7 @@ function getSizeConfigFromRegistry(size: 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 }, + sm: { height: 30, paddingX: 8, fontSize: 14, borderRadius: 6 }, base: { height: 36, paddingX: 12, fontSize: 16, borderRadius: 8 }, lg: { height: 40, paddingX: 16, fontSize: 16, borderRadius: 8 }, }; diff --git a/packages/kumo-figma/src/generators/refresh-button.test.ts b/packages/kumo-figma/src/generators/refresh-button.test.ts index 836d55e7e9..e3f28e40b6 100644 --- a/packages/kumo-figma/src/generators/refresh-button.test.ts +++ b/packages/kumo-figma/src/generators/refresh-button.test.ts @@ -176,15 +176,12 @@ describe("RefreshButton Generator - Icon Size Configuration", () => { lg: 20, }; - const COMPACT_SIZE_MAP: Record = { - xs: 14, - sm: 26, - base: 36, - lg: 40, - }; + const COMPACT_SIZE_MAP = FALLBACK_VALUES.buttonCompactSize; for (const size of sizeProp.values) { - expect(REFRESH_ICON_SIZE[size]).toBeLessThan(COMPACT_SIZE_MAP[size]); + expect(REFRESH_ICON_SIZE[size]).toBeLessThan( + COMPACT_SIZE_MAP[size as keyof typeof COMPACT_SIZE_MAP], + ); } }); @@ -318,12 +315,7 @@ 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 COMPACT_SIZE_MAP = FALLBACK_VALUES.buttonCompactSize; const REFRESH_ICON_SIZE: Record = { xs: 12, @@ -337,7 +329,9 @@ describe("RefreshButton Generator - Complete Variant Data", () => { // Verify all size values have mappings for (const size of sizeProp.values) { - expect(COMPACT_SIZE_MAP[size]).toBeDefined(); + expect( + COMPACT_SIZE_MAP[size as keyof typeof COMPACT_SIZE_MAP], + ).toBeDefined(); expect(REFRESH_ICON_SIZE[size]).toBeDefined(); } }); diff --git a/packages/kumo-figma/src/generators/sensitive-input.ts b/packages/kumo-figma/src/generators/sensitive-input.ts index 568e0a16f6..fa782a0a00 100644 --- a/packages/kumo-figma/src/generators/sensitive-input.ts +++ b/packages/kumo-figma/src/generators/sensitive-input.ts @@ -127,9 +127,9 @@ function getSizeConfigFromRegistry(size: string): { borderRadius: BORDER_RADIUS.xs, }, sm: { - height: 26, + height: 30, paddingX: 8, - fontSize: 12, + fontSize: 14, borderRadius: BORDER_RADIUS.md, }, base: { diff --git a/packages/kumo-figma/src/generators/shared.ts b/packages/kumo-figma/src/generators/shared.ts index 29c0cf52da..0d1be0b5ea 100644 --- a/packages/kumo-figma/src/generators/shared.ts +++ b/packages/kumo-figma/src/generators/shared.ts @@ -437,7 +437,7 @@ export const FALLBACK_VALUES = { buttonCompactSize: { /** Extra small compact button (size-3.5) */ xs: themeData.computed.buttonCompactSize.xs, - /** Small compact button (size-6.5) */ + /** Small compact button (size-7.5) */ sm: themeData.computed.buttonCompactSize.sm, /** Base compact button (size-9) */ base: themeData.computed.buttonCompactSize.base, diff --git a/packages/kumo-figma/src/parsers/tailwind-to-figma.ts b/packages/kumo-figma/src/parsers/tailwind-to-figma.ts index 42d713ed34..70d5f048a1 100644 --- a/packages/kumo-figma/src/parsers/tailwind-to-figma.ts +++ b/packages/kumo-figma/src/parsers/tailwind-to-figma.ts @@ -255,7 +255,7 @@ export function parseTailwindClasses(classes: string): ParsedStyles { continue; } - // Height: h-5, h-6.5, h-9, h-10 + // Height: h-5, h-7.5, h-9, h-10 const heightMatch = cls.match(/^h-(\d+\.?\d*)$/); if (heightMatch) { result.height = getOrDefault( @@ -266,7 +266,7 @@ export function parseTailwindClasses(classes: string): ParsedStyles { continue; } - // Size (width and height): size-3.5, size-6.5, size-9, size-10 + // Size (width and height): size-3.5, size-7.5, size-9, size-10 const sizeMatch = cls.match(/^size-(\d+\.?\d*)$/); if (sizeMatch) { const size = getOrDefault( diff --git a/packages/kumo/scripts/component-registry/metadata.ts b/packages/kumo/scripts/component-registry/metadata.ts index c78928eb92..38af7b2fab 100644 --- a/packages/kumo/scripts/component-registry/metadata.ts +++ b/packages/kumo/scripts/component-registry/metadata.ts @@ -630,21 +630,21 @@ export const COMPONENT_STYLING_METADATA: Record = { base: "bg-kumo-control text-kumo-default ring ring-kumo-line", sizes: { xs: "h-5 gap-1 rounded-sm px-1.5 text-xs", - sm: "h-6.5 gap-1 rounded-md px-2 text-xs", + sm: "h-7.5 gap-1 rounded-md px-2 text-base", base: "h-9 gap-1.5 rounded-lg px-3 text-base", lg: "h-10 gap-2 rounded-lg px-4 text-base", }, }, sizeVariants: { sm: { - height: 26, - classes: "text-xs", + height: 30, + classes: "text-base", buttonSize: "sm", dimensions: { paddingX: 8, gap: 1, borderRadius: 6, - fontSize: 12, + fontSize: 14, }, }, base: { @@ -722,11 +722,11 @@ export const COMPONENT_STYLING_METADATA: Record = { }, }, sm: { - height: 26, - classes: "h-6.5 gap-1 rounded-md px-2 text-xs", + height: 30, + classes: "h-7.5 gap-1 rounded-md px-2 text-base", dimensions: { paddingX: 8, - fontSize: 12, + fontSize: 14, borderRadius: 6, }, }, diff --git a/packages/kumo/src/components/autocomplete/autocomplete.tsx b/packages/kumo/src/components/autocomplete/autocomplete.tsx index c93facbe66..c69dec2550 100644 --- a/packages/kumo/src/components/autocomplete/autocomplete.tsx +++ b/packages/kumo/src/components/autocomplete/autocomplete.tsx @@ -26,7 +26,7 @@ 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) + * - `"sm"` — Small for secondary fields (h-7.5 / 30px) * - `"base"` — Default size (h-9 / 36px) * - `"lg"` — Large for prominent fields (h-10 / 40px) * @default "base" diff --git a/packages/kumo/src/components/banner/banner.test.tsx b/packages/kumo/src/components/banner/banner.test.tsx index 0faa017a28..30ec66d9b7 100644 --- a/packages/kumo/src/components/banner/banner.test.tsx +++ b/packages/kumo/src/components/banner/banner.test.tsx @@ -112,7 +112,7 @@ describe("Banner", () => { ); const cta = screen.getByTestId("cta"); - expect(cta.className).toContain("h-6.5"); + expect(cta.className).toContain("h-7.5"); expect(cta.className).toContain("px-2"); expect(cta.getAttribute("aria-label")).toBe("Dismiss"); expect(screen.getByTestId("icon")).toBeTruthy(); @@ -128,9 +128,9 @@ describe("Banner", () => { ); const cta = screen.getByTestId("cta"); - expect(cta.className).toContain("h-6.5"); + expect(cta.className).toContain("h-7.5"); expect(cta.className).toContain("px-2"); - expect(cta.className).toContain("text-xs"); + expect(cta.className).toContain("text-base"); }); it("applies compact spacing for the sm banner size", () => { @@ -157,7 +157,7 @@ describe("Banner", () => { ); const cta = screen.getByTestId("cta"); - // Inherits the banner's size => xs (h-5), not the standalone sm default (h-6.5). + // Inherits the banner's size => xs (h-5), not the standalone sm default (h-7.5). expect(cta.className).toContain("h-5"); expect(cta.className).toContain("px-1.5"); }); diff --git a/packages/kumo/src/components/button/button.test.tsx b/packages/kumo/src/components/button/button.test.tsx index ed2cf490df..d791ad3e29 100644 --- a/packages/kumo/src/components/button/button.test.tsx +++ b/packages/kumo/src/components/button/button.test.tsx @@ -66,6 +66,15 @@ describe("Button", () => { expect(button.classList.contains("select-text")).toBe(false); }); + it("uses the standardized small control size", () => { + const classes = buttonVariants({ size: "sm" }); + const compactClasses = buttonVariants({ size: "sm", shape: "square" }); + + expect(classes).toContain("h-7.5"); + expect(classes).toContain("text-base"); + expect(compactClasses).toContain("size-7.5"); + }); + it("forwards ref to the ); diff --git a/packages/kumo/src/components/button/button.tsx b/packages/kumo/src/components/button/button.tsx index a8e50b53d0..18b26e5768 100644 --- a/packages/kumo/src/components/button/button.tsx +++ b/packages/kumo/src/components/button/button.tsx @@ -28,7 +28,7 @@ export const KUMO_BUTTON_VARIANTS = { description: "Extra small button for compact UIs", }, sm: { - classes: "h-6.5 gap-1 rounded-md px-2 text-xs", + classes: "h-7.5 gap-1 rounded-md px-2 text-base", description: "Small button for secondary actions", }, base: { @@ -42,7 +42,7 @@ export const KUMO_BUTTON_VARIANTS = { }, compactSize: { xs: { classes: "size-3.5" }, - sm: { classes: "size-6.5" }, + sm: { classes: "size-7.5" }, base: { classes: "size-9" }, lg: { classes: "size-10" }, }, diff --git a/packages/kumo/src/components/clipboard-text/clipboard-text.test.tsx b/packages/kumo/src/components/clipboard-text/clipboard-text.test.tsx index 7ba08e8c2d..c8a0e0f3b4 100644 --- a/packages/kumo/src/components/clipboard-text/clipboard-text.test.tsx +++ b/packages/kumo/src/components/clipboard-text/clipboard-text.test.tsx @@ -46,6 +46,14 @@ describe("ClipboardText", () => { ).toBeTruthy(); }); + it("uses the standardized small control size", () => { + render(); + const clipboardText = screen.getByText("sk_live_abc123").parentElement; + + expect(clipboardText?.className).toContain("h-7.5"); + expect(clipboardText?.className).toContain("text-base"); + }); + it("copies text and announces copied state without tooltip", async () => { render(); diff --git a/packages/kumo/src/components/clipboard-text/clipboard-text.tsx b/packages/kumo/src/components/clipboard-text/clipboard-text.tsx index 1ca98539c2..59e496fdb2 100644 --- a/packages/kumo/src/components/clipboard-text/clipboard-text.tsx +++ b/packages/kumo/src/components/clipboard-text/clipboard-text.tsx @@ -16,7 +16,7 @@ const COPIED_FEEDBACK_MS = 1500; export const KUMO_CLIPBOARD_TEXT_VARIANTS = { size: { sm: { - classes: "text-xs", + classes: "text-base", buttonSize: "sm" as const, description: "Small clipboard text for compact UIs", }, diff --git a/packages/kumo/src/components/combobox/combobox.tsx b/packages/kumo/src/components/combobox/combobox.tsx index 2a46ebdaa9..04c023885d 100644 --- a/packages/kumo/src/components/combobox/combobox.tsx +++ b/packages/kumo/src/components/combobox/combobox.tsx @@ -55,7 +55,7 @@ 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) + * - `"sm"` — Small for secondary fields (h-7.5 / 30px) * - `"base"` — Default size (h-9 / 36px) * - `"lg"` — Large for prominent fields (h-10 / 40px) * @default "base" @@ -544,7 +544,7 @@ function Chip({ // Map size to min-height class for TriggerMultipleWithInput const sizeToMinHeight: Record = { xs: "min-h-5", - sm: "min-h-6.5", + sm: "min-h-7.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..4de259f1d7 100644 --- a/packages/kumo/src/components/input-group/context.ts +++ b/packages/kumo/src/components/input-group/context.ts @@ -67,7 +67,7 @@ export const INPUT_GROUP_SIZE: Record = { addonButtonOuterStart: "pl-1", addonButtonOuterEnd: "pr-1", suffixPad: "pr-2", - fontSize: "text-xs", + fontSize: "text-base", iconSize: 13, }, 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..702390cc33 100644 --- a/packages/kumo/src/components/input-group/input-group.test.tsx +++ b/packages/kumo/src/components/input-group/input-group.test.tsx @@ -3,7 +3,7 @@ import type { Icon, IconProps } from "@phosphor-icons/react"; import { describe, expect, it, vi } from "vite-plus/test"; import { fireEvent, render, screen, within } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; -import { InputGroup } from "./input-group"; +import { InputGroup, KUMO_INPUT_GROUP_VARIANTS } from "./input-group"; import { INPUT_GROUP_SIZE, detectFocusMode } from "./context"; import type { KumoInputSize } from "../input/input"; @@ -322,6 +322,12 @@ describe("InputGroup", () => { }); describe("size variants", () => { + it("uses the standardized small control size", () => { + expect(KUMO_INPUT_GROUP_VARIANTS.size.sm.classes).toContain("h-7.5"); + expect(KUMO_INPUT_GROUP_VARIANTS.size.sm.classes).toContain("text-base"); + expect(INPUT_GROUP_SIZE.sm.fontSize).toBe("text-base"); + }); + it("applies size to input", () => { const { rerender } = 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..cee462bad5 100644 --- a/packages/kumo/src/components/input-group/input-group.tsx +++ b/packages/kumo/src/components/input-group/input-group.tsx @@ -33,7 +33,7 @@ export const KUMO_INPUT_GROUP_VARIANTS = { description: "Extra small size.", }, sm: { - classes: "h-7 text-xs", + classes: "h-7.5 text-base", description: "Small size.", }, base: { diff --git a/packages/kumo/src/components/input/input.test.tsx b/packages/kumo/src/components/input/input.test.tsx index 0662b6cd5d..6383cba4db 100644 --- a/packages/kumo/src/components/input/input.test.tsx +++ b/packages/kumo/src/components/input/input.test.tsx @@ -69,7 +69,10 @@ describe("Input", () => { it("renders with size 'sm'", () => { render(); - expect(screen.getByRole("textbox").className).toContain("h-6.5"); + const input = screen.getByRole("textbox"); + + expect(input.className).toContain("h-7.5"); + expect(input.className).toContain("text-base"); }); it("renders with size 'lg'", () => { diff --git a/packages/kumo/src/components/input/input.tsx b/packages/kumo/src/components/input/input.tsx index 9d4cf52acf..627473320d 100644 --- a/packages/kumo/src/components/input/input.tsx +++ b/packages/kumo/src/components/input/input.tsx @@ -20,7 +20,7 @@ export const KUMO_INPUT_VARIANTS = { description: "Extra small input for compact UIs", }, sm: { - classes: "h-6.5 gap-1 rounded-md px-2 text-xs", + classes: "h-7.5 gap-1 rounded-md px-2 text-base", description: "Small input for secondary fields", }, base: { @@ -52,7 +52,7 @@ 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 }, + sm: { height: 30, paddingX: 8, fontSize: 14, borderRadius: 6, width: 200 }, base: { height: 36, paddingX: 12, diff --git a/packages/kumo/src/components/select/select.tsx b/packages/kumo/src/components/select/select.tsx index 1291cb7fc7..b8d165dc42 100644 --- a/packages/kumo/src/components/select/select.tsx +++ b/packages/kumo/src/components/select/select.tsx @@ -67,7 +67,7 @@ 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) + * - `"sm"` — Small for secondary fields (h-7.5 / 30px) * - `"base"` — Default size (h-9 / 36px) * - `"lg"` — Large for prominent fields (h-10 / 40px) * @default "base" diff --git a/packages/kumo/src/components/tabs/tabs.test.tsx b/packages/kumo/src/components/tabs/tabs.test.tsx index 27f72c5326..1490a3976d 100644 --- a/packages/kumo/src/components/tabs/tabs.test.tsx +++ b/packages/kumo/src/components/tabs/tabs.test.tsx @@ -19,6 +19,15 @@ const extraTabs = [ ]; describe("Tabs", () => { + it("uses the standardized small control size", () => { + render(); + + expect(screen.getByRole("tablist").className).toContain("h-7.5"); + expect(screen.getByRole("tab", { name: "Overview" }).className).toContain( + "text-base", + ); + }); + it("forwards nativeButton=false for link-rendered tabs", () => { const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); diff --git a/packages/kumo/src/components/tabs/tabs.tsx b/packages/kumo/src/components/tabs/tabs.tsx index f76480d7eb..04560f301a 100644 --- a/packages/kumo/src/components/tabs/tabs.tsx +++ b/packages/kumo/src/components/tabs/tabs.tsx @@ -71,7 +71,7 @@ export interface KumoTabsVariantsProps { /** * Tab size. * - `"base"` — Default size (h-9, text-base) - * - `"sm"` — Compact size (h-6.5, text-xs) — matches Input size="sm" + * - `"sm"` — Compact size (h-7.5, text-base) — matches Input size="sm" * @default "base" */ size?: (typeof KUMO_TABS_VARIANTS.size)[number]; @@ -208,7 +208,7 @@ export function Tabs({
)} @@ -222,10 +222,9 @@ export function Tabs({ className={cn( "kumo-tabs-list relative flex min-w-0 shrink scroll-px-(--scroll-fade-width) items-stretch overflow-x-auto overflow-y-hidden [--scroll-fade-width:3rem]", isSegmented && "rounded-lg bg-kumo-recessed px-0.5", - isSegmented && (isSm ? "h-6.5 rounded-md" : "h-9"), + isSegmented && (isSm ? "h-7.5 rounded-md" : "h-9"), isOverflowing && "cursor-grab active:cursor-grabbing", - isUnderline && "gap-4 border-b border-kumo-hairline pb-2", - isUnderline && (isSm ? "h-6.5" : "h-7.5"), + isUnderline && "h-7.5 gap-4 border-b border-kumo-hairline pb-2", listClassName, )} > @@ -245,11 +244,10 @@ export function Tabs({ }); }} className={cn( - "relative z-2 flex items-center rounded bg-transparent whitespace-nowrap focus:ring-kumo-focus/50 focus:outline-none focus-visible:ring-2 focus-visible:ring-kumo-brand", + "relative z-2 flex items-center rounded bg-transparent text-base whitespace-nowrap focus:ring-kumo-focus/50 focus:outline-none focus-visible:ring-2 focus-visible:ring-kumo-brand", isOverflowing ? "cursor-grab active:cursor-grabbing" : "cursor-pointer", - isSm ? "text-xs" : "text-base", isSegmented && "my-0.5 text-kumo-subtle hover:text-kumo-default focus-visible:ring-inset aria-selected:text-kumo-default", isSegmented && (isSm ? "rounded-sm px-2" : "rounded-md px-2.5"), diff --git a/packages/kumo/src/components/toolbar/toolbar.tsx b/packages/kumo/src/components/toolbar/toolbar.tsx index 64fe651a57..c24645c6f6 100644 --- a/packages/kumo/src/components/toolbar/toolbar.tsx +++ b/packages/kumo/src/components/toolbar/toolbar.tsx @@ -11,42 +11,49 @@ import { Button as KumoButton, type ButtonProps } from "../button/button"; import { Input as KumoInput, type InputProps } from "../input/input"; import { InputGroup } from "../input-group/input-group"; -/** @deprecated Toolbar size customization is deprecated. Omit `size` to use the default base size. */ +/** Toolbar size variant definitions. */ export const KUMO_TOOLBAR_VARIANTS = { size: { + /** @deprecated Use `"sm"` for compact toolbars. */ xs: { classes: "text-xs", - description: "Extra small toolbar for compact UIs", + description: "Deprecated extra small toolbar size", }, sm: { - classes: "text-xs", + classes: "rounded-md text-base", description: "Small toolbar for secondary controls", }, base: { classes: "text-base", description: "Default toolbar size", }, + /** @deprecated Use `"base"` for the default toolbar size. */ lg: { classes: "text-base", - description: "Large toolbar for prominent controls", + description: "Deprecated large toolbar size", }, }, } as const; -/** @deprecated Toolbar size customization is deprecated. Omit `size` to use the default base size. */ +/** Default Toolbar variants. */ export const KUMO_TOOLBAR_DEFAULT_VARIANTS = { size: "base", } as const; -/** @deprecated Toolbar size customization is deprecated. Omit `size` to use the default base size. */ +/** + * Toolbar size. `"sm"` and `"base"` are supported; `"xs"` and `"lg"` are + * deprecated compatibility values. + */ export type ToolbarSize = keyof typeof KUMO_TOOLBAR_VARIANTS.size; export interface ToolbarProps extends Omit { /** Toolbar controls rendered as one grouped card. */ children: React.ReactNode; /** - * Locks every toolbar item to this size. - * @deprecated Omit this prop to use the default base size. Toolbar size customization will be removed in a future major release. + * Locks every toolbar item to this size. Use `"sm"` for compact toolbars or + * `"base"` for the default size. `"xs"` and `"lg"` are deprecated and + * remain available only for backwards compatibility. + * @default "base" */ size?: ToolbarSize; } @@ -105,7 +112,7 @@ const Root = React.forwardRef( data-kumo-component="Toolbar" className={cn( "inline-flex w-fit items-stretch rounded-lg bg-kumo-control shadow-xs ring ring-kumo-line", - "[&>*:first-child]:rounded-l-lg [&>*:not([aria-hidden='true']):not([type='hidden']):not(:has(~_:not([aria-hidden='true']):not([type='hidden'])))]:rounded-r-lg", + "[&>*:first-child]:rounded-l-[inherit] [&>*:not([aria-hidden='true']):not([type='hidden']):not(:has(~_:not([aria-hidden='true']):not([type='hidden'])))]:rounded-r-[inherit]", "[&>*_[data-kumo-toolbar-input]:focus]:rounded-[inherit]", "[&>*:not([aria-hidden='true']):not(:first-child)]:border-l [&>*:not([aria-hidden='true']):not(:first-child)]:border-kumo-line", KUMO_TOOLBAR_VARIANTS.size[size].classes,