Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { ComponentProps } from 'react'
import { forwardRef } from 'react'
import { Button } from '@sim/emcn'

interface CanvasControlButtonProps
extends Omit<
ComponentProps<typeof Button>,
'variant' | 'size' | 'iconSize' | 'iconPadding' | 'shape' | 'className'
> {
active?: boolean
'aria-label': string
}

/** Square action in the canvas navigation toolbar. */
export const CanvasControlButton = forwardRef<HTMLButtonElement, CanvasControlButtonProps>(
({ active = false, ...props }, ref) => (
<Button {...props} ref={ref} variant={active ? 'active' : 'ghost-hover'} iconSize='regular' />
)
)
Comment thread
BillLeoutsakosvl346 marked this conversation as resolved.

CanvasControlButton.displayName = 'CanvasControlButton'
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
'use client'

/** biome-ignore assist/source/organizeImports: Keep the local feature import after shared hooks and stores, per AGENTS.md. */
import { memo, useCallback, useRef, useState } from 'react'
import {
Button,
ChevronDown,
Cursor,
chipHoverSurfaceClass,
cn,
disclosureChevronClass,
Hand,
Expand All @@ -32,6 +32,8 @@ import { useCanvasModeStore } from '@/stores/canvas-mode'
import { useUndoRedoStore } from '@/stores/undo-redo'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'

import { CanvasControlButton } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-controls/canvas-control-button'

const logger = createLogger('WorkflowControls')

/**
Expand Down Expand Up @@ -100,7 +102,7 @@ export const WorkflowControls = memo(function WorkflowControls() {
* CONTENT_WINDOW_GAP; these controls measure from the canvas floor and
* wall, so they take the 12 directly.
*/
className='absolute bottom-3 left-3 z-10 flex h-[36px] items-center gap-0.5 rounded-lg border border-[var(--border)] bg-[var(--surface-2)] p-1'
className='absolute bottom-3 left-3 z-10 flex h-9 items-center gap-0.5 rounded-lg border border-[var(--border)] bg-[var(--surface-2)] p-1'
onContextMenu={handleContextMenu}
>
{/* Canvas Mode Selector */}
Expand All @@ -109,23 +111,15 @@ export const WorkflowControls = memo(function WorkflowControls() {
<PopoverTrigger asChild>
<div className='flex cursor-pointer items-center gap-1'>
<Tooltip.Trigger asChild>
<Button
aria-label={mode === 'hand' ? 'Mover' : 'Pointer'}
className='size-[28px] rounded-sm p-0'
variant='active'
>
<CanvasControlButton aria-label={mode === 'hand' ? 'Mover' : 'Pointer'} active>
{mode === 'hand' ? (
<Hand className='size-[14px]' />
) : (
<Cursor className='size-[14px]' />
)}
</Button>
</CanvasControlButton>
</Tooltip.Trigger>
<Button
aria-label='Change canvas mode'
variant='ghost'
className={cn('size-[20px] rounded-sm p-0', chipHoverSurfaceClass)}
>
<Button aria-label='Change canvas mode' variant='ghost-hover' size='icon'>
Comment thread
BillLeoutsakosvl346 marked this conversation as resolved.
<ChevronDown
className={cn(disclosureChevronClass, isCanvasModeOpen && 'rotate-180')}
/>
Expand Down Expand Up @@ -160,15 +154,9 @@ export const WorkflowControls = memo(function WorkflowControls() {

<Tooltip.Root>
<Tooltip.Trigger asChild>
<Button
aria-label='Undo'
variant='ghost'
className={cn('size-[28px] rounded-sm p-0', chipHoverSurfaceClass)}
onClick={undo}
disabled={!canUndo}
>
<CanvasControlButton aria-label='Undo' onClick={undo} disabled={!canUndo}>
Comment thread
BillLeoutsakosvl346 marked this conversation as resolved.
<Undo className='size-[14px]' />
</Button>
</CanvasControlButton>
</Tooltip.Trigger>
<Tooltip.Content side='top'>
<Tooltip.Shortcut keys='⌘Z'>Undo</Tooltip.Shortcut>
Expand All @@ -177,15 +165,9 @@ export const WorkflowControls = memo(function WorkflowControls() {

<Tooltip.Root>
<Tooltip.Trigger asChild>
<Button
aria-label='Redo'
variant='ghost'
className={cn('size-[28px] rounded-sm p-0', chipHoverSurfaceClass)}
onClick={redo}
disabled={!canRedo}
>
<CanvasControlButton aria-label='Redo' onClick={redo} disabled={!canRedo}>
<Redo className='size-[14px]' />
</Button>
</CanvasControlButton>
</Tooltip.Trigger>
<Tooltip.Content side='top'>
<Tooltip.Shortcut keys='⌘⇧Z'>Redo</Tooltip.Shortcut>
Expand All @@ -196,14 +178,9 @@ export const WorkflowControls = memo(function WorkflowControls() {

<Tooltip.Root>
<Tooltip.Trigger asChild>
<Button
aria-label='Fit to View'
variant='ghost'
className={cn('size-[28px] rounded-sm p-0', chipHoverSurfaceClass)}
onClick={handleFitToView}
>
<CanvasControlButton aria-label='Fit to View' onClick={handleFitToView}>
<SelectAll className='size-[14px]' />
</Button>
</CanvasControlButton>
</Tooltip.Trigger>
<Tooltip.Content side='top'>
<Tooltip.Shortcut keys='⌘⇧F'>Fit to View</Tooltip.Shortcut>
Expand Down
3 changes: 3 additions & 0 deletions packages/emcn/src/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ const buttonVariants = cva(
tertiary:
'bg-[var(--brand-accent)] text-[var(--text-inverse)] hover-hover:text-[var(--text-inverse)] hover-hover:bg-[var(--brand-accent-hover)] dark:bg-[var(--brand-accent)] dark:hover-hover:bg-[var(--brand-accent-hover)] dark:text-[var(--text-inverse)] dark:hover-hover:text-[var(--text-inverse)]',
ghost: 'text-[var(--text-secondary)] hover-hover:text-[var(--text-primary)]',
'ghost-hover':
'text-[var(--text-secondary)] hover-hover:text-[var(--text-primary)] hover-hover:bg-[var(--surface-hover)]',
subtle:
'text-[var(--text-body)] hover-hover:text-[var(--text-body)] hover-hover:bg-[var(--surface-4)]',
'ghost-secondary': 'text-[var(--text-muted)] hover-hover:text-[var(--text-primary)]',
Expand Down Expand Up @@ -75,6 +77,7 @@ const buttonVariants = cva(
*/
{ size: 'icon', variant: 'quiet', className: 'text-[var(--text-icon-muted)]' },
{ size: 'icon', variant: 'ghost', className: 'text-[var(--text-icon-muted)]' },
{ size: 'icon', variant: 'ghost-hover', className: 'text-[var(--text-icon-muted)]' },
],
defaultVariants: {
variant: 'default',
Expand Down
Loading