diff --git a/apps/sim/app/workspace/[workspaceId]/components/find-bar/find-bar.tsx b/apps/sim/app/workspace/[workspaceId]/components/find-bar/find-bar.tsx index ceb2b0b709b..6ec4de4377e 100644 --- a/apps/sim/app/workspace/[workspaceId]/components/find-bar/find-bar.tsx +++ b/apps/sim/app/workspace/[workspaceId]/components/find-bar/find-bar.tsx @@ -129,7 +129,8 @@ export const FindBar = memo(function FindBar({ type='button' variant='ghost' size='icon' - className='size-6 shrink-0' + iconSize='compact' + className='shrink-0' aria-label={showReplace ? 'Hide replace' : 'Show replace'} aria-expanded={showReplace} onClick={() => setShowReplace((visible) => !visible)} @@ -179,7 +180,8 @@ export const FindBar = memo(function FindBar({ type='button' variant='ghost' size='icon' - className='size-6 shrink-0' + iconSize='compact' + className='shrink-0' aria-label='Previous match' title='Previous match (Shift+Enter)' disabled={!navEnabled} @@ -191,7 +193,8 @@ export const FindBar = memo(function FindBar({ type='button' variant='ghost' size='icon' - className='size-6 shrink-0' + iconSize='compact' + className='shrink-0' aria-label='Next match' title='Next match (Enter)' disabled={!navEnabled} @@ -203,7 +206,8 @@ export const FindBar = memo(function FindBar({ type='button' variant='ghost' size='icon' - className='size-6 shrink-0' + iconSize='compact' + className='shrink-0' aria-label='Close find' title='Close (Esc)' onClick={onClose} diff --git a/apps/sim/app/workspace/[workspaceId]/components/message-actions/message-actions.test.tsx b/apps/sim/app/workspace/[workspaceId]/components/message-actions/message-actions.test.tsx index 0f57c5c0551..e2aa9d94339 100644 --- a/apps/sim/app/workspace/[workspaceId]/components/message-actions/message-actions.test.tsx +++ b/apps/sim/app/workspace/[workspaceId]/components/message-actions/message-actions.test.tsx @@ -1,7 +1,7 @@ /** * @vitest-environment jsdom */ -import { act, type ReactNode } from 'react' +import { act, type ComponentProps, type ReactNode } from 'react' import { createRoot, type Root } from 'react-dom/client' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' @@ -19,6 +19,11 @@ vi.mock('next/navigation', () => ({ })) vi.mock('@sim/emcn', () => ({ + Button: ({ + variant, + iconSize, + ...props + }: ComponentProps<'button'> & { variant?: string; iconSize?: string }) => + {copied ? 'Copied message' : 'Copy message'} @@ -180,27 +180,29 @@ export const MessageActions = memo(function MessageActions({ <> - + Good response - + Bad response @@ -209,15 +211,16 @@ export const MessageActions = memo(function MessageActions({ {canFork && ( - + Fork in new chat diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/components/browser-session/browser-find-bar.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/components/browser-session/browser-find-bar.tsx index a3f9e23198d..8313c2c549e 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/components/browser-session/browser-find-bar.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/components/browser-session/browser-find-bar.tsx @@ -106,7 +106,8 @@ export function BrowserFindBar({ inputRef, onClose, scopeId }: BrowserFindBarPro size='sm' aria-label='Previous match' disabled={!result?.matches} - className='size-[24px] shrink-0 p-0' + iconSize='compact-fixed' + className='shrink-0' onClick={() => step('back')} > @@ -117,7 +118,8 @@ export function BrowserFindBar({ inputRef, onClose, scopeId }: BrowserFindBarPro size='sm' aria-label='Next match' disabled={!result?.matches} - className='size-[24px] shrink-0 p-0' + iconSize='compact-fixed' + className='shrink-0' onClick={() => step('forward')} > @@ -127,7 +129,8 @@ export function BrowserFindBar({ inputRef, onClose, scopeId }: BrowserFindBarPro variant='ghost-secondary' size='sm' aria-label='Close find bar' - className='size-[24px] shrink-0 p-0' + iconSize='compact-fixed' + className='shrink-0' onClick={dismiss} > diff --git a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/workflow-sidebar/workflow-sidebar.tsx b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/workflow-sidebar/workflow-sidebar.tsx index 18b04cfd5b2..2c53382bf54 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/workflow-sidebar/workflow-sidebar.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/workflow-sidebar/workflow-sidebar.tsx @@ -730,7 +730,8 @@ export function WorkflowSidebarBody({ 'noopener,noreferrer' ) } - className='absolute right-[6px] bottom-1.5 z-10 size-[24px] cursor-pointer border border-[var(--border)] bg-[var(--surface-2)] p-0 hover-hover:bg-[var(--surface-4)]' + iconSize='compact-fixed' + className='absolute right-[6px] bottom-1.5 z-10 cursor-pointer border border-[var(--border)] bg-[var(--surface-2)] hover-hover:bg-[var(--surface-4)]' > diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx index c42c236d1c3..4bd3f1c6c00 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx @@ -36,7 +36,7 @@ import { useWorkflowStore } from '@/stores/workflows/workflow/store' const DEFAULT_DUPLICATE_OFFSET = { x: 50, y: 50 } const ACTION_BUTTON_STYLES = [ - 'size-[24px] rounded-md p-0', + 'rounded-md', 'border-none bg-transparent text-[var(--text-icon)]', 'hover-hover:bg-[var(--surface-5)] hover-hover:text-[var(--text-primary)]!', 'dark:hover-hover:bg-[var(--surface-4)]', @@ -472,6 +472,7 @@ export const ActionBar = memo( } if (canRunBlock) handleRunFromBlockClick() }} + iconSize='compact-fixed' className={cn(getActionButtonStyles('run'), isWorkflowRunning && 'group/run')} disabled={!canStopWorkflow && !canRunBlock} > @@ -517,6 +518,7 @@ export const ActionBar = memo( collaborativeBatchToggleBlockEnabled([blockId]) } }} + iconSize='compact-fixed' className={getActionButtonStyles('enabled')} disabled={ isWorkflowRunning || @@ -553,6 +555,7 @@ export const ActionBar = memo( diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/preview/components/preview-editor/preview-editor.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/preview/components/preview-editor/preview-editor.tsx index 6a1ce331611..a583115eaa6 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/preview/components/preview-editor/preview-editor.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/components/preview/components/preview-editor/preview-editor.tsx @@ -1398,7 +1398,8 @@ function PreviewEditorContent({ type='button' variant='ghost' onClick={handleExpandChildWorkflow} - className='absolute right-[6px] bottom-1.5 z-10 size-[24px] cursor-pointer border border-[var(--border)] bg-[var(--surface-2)] p-0 hover-hover:bg-[var(--surface-4)]' + iconSize='compact-fixed' + className='absolute right-[6px] bottom-1.5 z-10 cursor-pointer border border-[var(--border)] bg-[var(--surface-2)] hover-hover:bg-[var(--surface-4)]' > {isExecutionMode && onDrillDown ? ( diff --git a/packages/emcn/src/components/bulk-action-button/bulk-action-button.tsx b/packages/emcn/src/components/bulk-action-button/bulk-action-button.tsx index b24e402e274..8088e98f093 100644 --- a/packages/emcn/src/components/bulk-action-button/bulk-action-button.tsx +++ b/packages/emcn/src/components/bulk-action-button/bulk-action-button.tsx @@ -18,7 +18,8 @@ export const bulkActionButtonVariants = cva( } ) -export interface BulkActionButtonProps extends Omit { +export interface BulkActionButtonProps + extends Omit { /** Accessible name for the icon action; tooltip content is supplied separately. */ 'aria-label': string /** diff --git a/packages/emcn/src/components/button/button.test.tsx b/packages/emcn/src/components/button/button.test.tsx new file mode 100644 index 00000000000..c0b4fc35df3 --- /dev/null +++ b/packages/emcn/src/components/button/button.test.tsx @@ -0,0 +1,67 @@ +/** @vitest-environment node */ +/** biome-ignore assist/source/organizeImports: Preserve the documented core/external/UI import order. */ +import { renderToStaticMarkup } from 'react-dom/server' +import { describe, expect, it } from 'vitest' +import { Button } from '@sim/emcn' + +function normalizeClasses(markup: string) { + return markup.replace( + /class="([^"]+)"/g, + (_, classes: string) => `class="${classes.split(/\s+/).sort().join(' ')}"` + ) +} + +/** The three existing Button treatments used by compact product actions. */ +const TREATMENTS = [ + { size: undefined, variant: 'ghost' }, + { size: 'sm', variant: 'ghost-secondary' }, + { size: 'icon', variant: 'ghost' }, +] as const + +describe('Button iconSize', () => { + for (const [iconSize, previousClass] of [ + ['compact', 'size-6 p-0'], + ['compact-fixed', 'size-[24px] p-0'], + ] as const) { + it.each(TREATMENTS)( + `preserves the ${iconSize} treatment with size=$size and variant=$variant`, + (treatment) => { + const icon = + const before = renderToStaticMarkup( + + ) + const after = renderToStaticMarkup( + + ) + expect(normalizeClasses(after)).toBe(normalizeClasses(before)) + } + ) + } + + it('allows explicit padding and consumer width to take precedence', () => { + const markup = renderToStaticMarkup( + + */ + iconSize?: VariantProps['iconSize'] /** * Symmetric padding for icon actions whose content or layout determines their size. * Preserves the selected size's typography, corner radius and icon stroke. @@ -85,11 +98,11 @@ export interface ButtonProps } const Button = forwardRef( - ({ className, variant, size, iconPadding, ...props }, ref) => { + ({ className, variant, size, iconSize, iconPadding, ...props }, ref) => { return (