Skip to content

Commit 366afbb

Browse files
Bill LeoutsakosBill Leoutsakos
authored andcommitted
refactor(emcn): centralize compact icon button sizing
1 parent 3f245d7 commit 366afbb

12 files changed

Lines changed: 125 additions & 21 deletions

File tree

‎apps/sim/app/workspace/[workspaceId]/components/find-bar/find-bar.tsx‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ export const FindBar = memo(function FindBar({
129129
type='button'
130130
variant='ghost'
131131
size='icon'
132-
className='size-6 shrink-0'
132+
iconSize='compact'
133+
className='shrink-0'
133134
aria-label={showReplace ? 'Hide replace' : 'Show replace'}
134135
aria-expanded={showReplace}
135136
onClick={() => setShowReplace((visible) => !visible)}
@@ -179,7 +180,8 @@ export const FindBar = memo(function FindBar({
179180
type='button'
180181
variant='ghost'
181182
size='icon'
182-
className='size-6 shrink-0'
183+
iconSize='compact'
184+
className='shrink-0'
183185
aria-label='Previous match'
184186
title='Previous match (Shift+Enter)'
185187
disabled={!navEnabled}
@@ -191,7 +193,8 @@ export const FindBar = memo(function FindBar({
191193
type='button'
192194
variant='ghost'
193195
size='icon'
194-
className='size-6 shrink-0'
196+
iconSize='compact'
197+
className='shrink-0'
195198
aria-label='Next match'
196199
title='Next match (Enter)'
197200
disabled={!navEnabled}
@@ -203,7 +206,8 @@ export const FindBar = memo(function FindBar({
203206
type='button'
204207
variant='ghost'
205208
size='icon'
206-
className='size-6 shrink-0'
209+
iconSize='compact'
210+
className='shrink-0'
207211
aria-label='Close find'
208212
title='Close (Esc)'
209213
onClick={onClose}

‎apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/components/browser-session/browser-find-bar.tsx‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ export function BrowserFindBar({ inputRef, onClose, scopeId }: BrowserFindBarPro
106106
size='sm'
107107
aria-label='Previous match'
108108
disabled={!result?.matches}
109-
className='size-[24px] shrink-0 p-0'
109+
iconSize='compact-fixed'
110+
className='shrink-0'
110111
onClick={() => step('back')}
111112
>
112113
<ArrowUp className='size-[13px]' />
@@ -117,7 +118,8 @@ export function BrowserFindBar({ inputRef, onClose, scopeId }: BrowserFindBarPro
117118
size='sm'
118119
aria-label='Next match'
119120
disabled={!result?.matches}
120-
className='size-[24px] shrink-0 p-0'
121+
iconSize='compact-fixed'
122+
className='shrink-0'
121123
onClick={() => step('forward')}
122124
>
123125
<ArrowDown className='size-[13px]' />
@@ -127,7 +129,8 @@ export function BrowserFindBar({ inputRef, onClose, scopeId }: BrowserFindBarPro
127129
variant='ghost-secondary'
128130
size='sm'
129131
aria-label='Close find bar'
130-
className='size-[24px] shrink-0 p-0'
132+
iconSize='compact-fixed'
133+
className='shrink-0'
131134
onClick={dismiss}
132135
>
133136
<X className='size-[13px]' />

‎apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/workflow-sidebar/workflow-sidebar.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,8 @@ export function WorkflowSidebarBody({
730730
'noopener,noreferrer'
731731
)
732732
}
733-
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)]'
733+
iconSize='compact-fixed'
734+
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)]'
734735
>
735736
<SquareArrowUpRight className='size-[12px]' />
736737
</Button>

‎apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import { useWorkflowStore } from '@/stores/workflows/workflow/store'
3636
const DEFAULT_DUPLICATE_OFFSET = { x: 50, y: 50 }
3737

3838
const ACTION_BUTTON_STYLES = [
39-
'size-[24px] rounded-md p-0',
39+
'rounded-md',
4040
'border-none bg-transparent text-[var(--text-icon)]',
4141
'hover-hover:bg-[var(--surface-5)] hover-hover:text-[var(--text-primary)]!',
4242
'dark:hover-hover:bg-[var(--surface-4)]',
@@ -472,6 +472,7 @@ export const ActionBar = memo(
472472
}
473473
if (canRunBlock) handleRunFromBlockClick()
474474
}}
475+
iconSize='compact-fixed'
475476
className={cn(getActionButtonStyles('run'), isWorkflowRunning && 'group/run')}
476477
disabled={!canStopWorkflow && !canRunBlock}
477478
>
@@ -517,6 +518,7 @@ export const ActionBar = memo(
517518
collaborativeBatchToggleBlockEnabled([blockId])
518519
}
519520
}}
521+
iconSize='compact-fixed'
520522
className={getActionButtonStyles('enabled')}
521523
disabled={
522524
isWorkflowRunning ||
@@ -553,6 +555,7 @@ export const ActionBar = memo(
553555
<DropdownMenuTrigger asChild>
554556
<Button
555557
variant='ghost'
558+
iconSize='compact-fixed'
556559
className={getActionButtonStyles('color')}
557560
disabled={
558561
isWorkflowRunning ||
@@ -618,6 +621,7 @@ export const ActionBar = memo(
618621
collaborativeBatchToggleLocked([blockId])
619622
}
620623
}}
624+
iconSize='compact-fixed'
621625
className={getActionButtonStyles('lock')}
622626
disabled={isWorkflowRunning || disabled || (isLocked && isParentLocked)}
623627
>
@@ -650,6 +654,7 @@ export const ActionBar = memo(
650654
handleDuplicateBlock()
651655
}
652656
}}
657+
iconSize='compact-fixed'
653658
className={getActionButtonStyles('duplicate')}
654659
disabled={isWorkflowRunning || disabled || isLocked || isParentLocked}
655660
>
@@ -682,6 +687,7 @@ export const ActionBar = memo(
682687
)
683688
}
684689
}}
690+
iconSize='compact-fixed'
685691
className={getActionButtonStyles('remove')}
686692
disabled={
687693
isWorkflowRunning ||
@@ -717,6 +723,7 @@ export const ActionBar = memo(
717723
collaborativeBatchRemoveBlocks([blockId])
718724
}
719725
}}
726+
iconSize='compact-fixed'
720727
className={getActionButtonStyles('delete')}
721728
disabled={isWorkflowRunning || disabled || isLocked || isParentLocked}
722729
>

‎apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/file-upload/file-upload.tsx‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ function SingleFileSelector({
212212
aria-label='Remove file'
213213
type='button'
214214
variant='ghost'
215-
className='-translate-y-1/2 absolute top-1/2 right-[28px] z-10 size-6 p-0'
215+
iconSize='compact'
216+
className='-translate-y-1/2 absolute top-1/2 right-[28px] z-10'
216217
onClick={onClear}
217218
disabled={isDeleting}
218219
>
@@ -766,7 +767,8 @@ export function FileUpload({
766767
aria-label='Remove file'
767768
type='button'
768769
variant='ghost'
769-
className='-translate-y-1/2 absolute top-1/2 right-[4px] size-6 p-0'
770+
iconSize='compact'
771+
className='-translate-y-1/2 absolute top-1/2 right-[4px]'
770772
onClick={(e) => handleRemoveFile(file, e)}
771773
disabled={isDeleting}
772774
>

‎apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/messages-input/messages-input.tsx‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,8 @@ export function MessagesInput({
661661
deleteMessage(index)
662662
}}
663663
disabled={disabled}
664-
className='-my-1 -mr-1 size-6 p-0'
664+
iconSize='compact'
665+
className='-my-1 -mr-1'
665666
aria-label='Delete message'
666667
>
667668
<Trash className='size-3' />
@@ -673,7 +674,8 @@ export function MessagesInput({
673674
moveMessageUp(index)
674675
}}
675676
disabled={disabled || index === 0}
676-
className='-my-1 -mr-1 size-6 p-0'
677+
iconSize='compact'
678+
className='-my-1 -mr-1'
677679
aria-label='Move message up'
678680
>
679681
<ChevronUp className='size-3' />
@@ -685,7 +687,8 @@ export function MessagesInput({
685687
moveMessageDown(index)
686688
}}
687689
disabled={disabled || index === currentMessages.length - 1}
688-
className='-my-1 -mr-1 size-6 p-0'
690+
iconSize='compact'
691+
className='-my-1 -mr-1'
689692
aria-label='Move message down'
690693
>
691694
<ChevronDown className='size-3' />
@@ -699,7 +702,8 @@ export function MessagesInput({
699702
addMessageAfter(index)
700703
}}
701704
disabled={disabled}
702-
className='-mr-1.5 -my-1 size-6 p-0'
705+
iconSize='compact'
706+
className='-mr-1.5 -my-1'
703707
aria-label='Add message below'
704708
>
705709
<Plus className='size-3.5' />

‎apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/selector-combobox/selector-combobox.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,8 @@ export function SelectorCombobox({
340340
aria-label='Clear selection'
341341
type='button'
342342
variant='ghost'
343-
className='-translate-y-1/2 absolute top-1/2 right-[28px] z-10 size-6 p-0'
343+
iconSize='compact'
344+
className='-translate-y-1/2 absolute top-1/2 right-[28px] z-10'
344345
onClick={handleClear}
345346
>
346347
<X className='size-4 opacity-50 hover-hover:opacity-100' />

‎apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/editor.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,8 @@ export function Editor() {
611611
type='button'
612612
variant='ghost'
613613
onClick={handleOpenChildWorkflow}
614-
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)]'
614+
iconSize='compact-fixed'
615+
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)]'
615616
>
616617
<SquareArrowUpRight className='size-[12px]' />
617618
</Button>

‎apps/sim/app/workspace/[workspaceId]/w/components/preview/components/preview-editor/preview-editor.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1398,7 +1398,8 @@ function PreviewEditorContent({
13981398
type='button'
13991399
variant='ghost'
14001400
onClick={handleExpandChildWorkflow}
1401-
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)]'
1401+
iconSize='compact-fixed'
1402+
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)]'
14021403
>
14031404
{isExecutionMode && onDrillDown ? (
14041405
<Expand className='size-[12px]' />
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/** @vitest-environment node */
2+
import { Button } from '@sim/emcn'
3+
import { renderToStaticMarkup } from 'react-dom/server'
4+
import { describe, expect, it } from 'vitest'
5+
6+
function normalizeClasses(markup: string) {
7+
return markup.replace(
8+
/class="([^"]+)"/g,
9+
(_, classes: string) => `class="${classes.split(/\s+/).sort().join(' ')}"`
10+
)
11+
}
12+
13+
/** The three existing Button treatments used by compact product actions. */
14+
const TREATMENTS = [
15+
{ size: undefined, variant: 'ghost' },
16+
{ size: 'sm', variant: 'ghost-secondary' },
17+
{ size: 'icon', variant: 'ghost' },
18+
] as const
19+
20+
describe('Button iconSize', () => {
21+
for (const [iconSize, previousClass] of [
22+
['compact', 'size-6 p-0'],
23+
['compact-fixed', 'size-[24px] p-0'],
24+
] as const) {
25+
it.each(TREATMENTS)(
26+
`preserves the ${iconSize} treatment with size=$size and variant=$variant`,
27+
(treatment) => {
28+
const icon = <svg className='size-[14px]' strokeWidth={1.55} aria-hidden='true' />
29+
const before = renderToStaticMarkup(
30+
<Button
31+
{...treatment}
32+
type='button'
33+
aria-label='Previous match'
34+
className={`${previousClass} shrink-0`}
35+
>
36+
{icon}
37+
</Button>
38+
)
39+
const after = renderToStaticMarkup(
40+
<Button
41+
{...treatment}
42+
type='button'
43+
aria-label='Previous match'
44+
iconSize={iconSize}
45+
className='shrink-0'
46+
>
47+
{icon}
48+
</Button>
49+
)
50+
expect(normalizeClasses(after)).toBe(normalizeClasses(before))
51+
}
52+
)
53+
}
54+
55+
it('allows explicit padding and consumer width to take precedence', () => {
56+
const markup = renderToStaticMarkup(
57+
<Button iconSize='compact-fixed' iconPadding='sm' className='w-[40px]!' aria-label='Run' />
58+
)
59+
expect(markup).toContain('size-[24px]')
60+
expect(markup).toContain('w-[40px]!')
61+
expect(markup).toContain('p-1')
62+
expect(markup).not.toContain('p-0')
63+
expect(markup).not.toContain('iconSize')
64+
expect(markup).not.toContain('iconPadding')
65+
})
66+
})

0 commit comments

Comments
 (0)