Skip to content

Commit 8847c6d

Browse files
committed
fix(mobile): keep floating tools and actions within visible bounds
1 parent cd39f33 commit 8847c6d

21 files changed

Lines changed: 183 additions & 125 deletions

File tree

‎apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/document.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1310,7 +1310,7 @@ export function Document({
13101310
/>
13111311

13121312
<ActionBar
1313-
className={tablePagination ? 'bottom-[72px]' : undefined}
1313+
className={tablePagination ? 'bottom-[max(72px,env(safe-area-inset-bottom))]' : undefined}
13141314
selectedCount={selectedChunks.size}
13151315
onEnable={disabledCount > 0 && !isConnectorDocument ? handleBulkEnable : undefined}
13161316
onDisable={enabledCount > 0 && !isConnectorDocument ? handleBulkDisable : undefined}

‎apps/sim/app/workspace/[workspaceId]/knowledge/[id]/base.tsx‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1353,7 +1353,9 @@ export function KnowledgeBase({
13531353
}}
13541354
overlay={
13551355
<ActionBar
1356-
className={totalPages > 1 ? 'bottom-[72px]' : undefined}
1356+
className={
1357+
totalPages > 1 ? 'bottom-[max(72px,env(safe-area-inset-bottom))]' : undefined
1358+
}
13571359
selectedCount={selectedDocuments.size}
13581360
onEnable={disabledCount > 0 ? handleBulkEnable : undefined}
13591361
onDisable={enabledCount > 0 ? handleBulkDisable : undefined}

‎apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/action-bar/action-bar.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export function ActionBar({
5252
exit={{ opacity: 0, y: 10 }}
5353
transition={{ duration: 0.2 }}
5454
className={cn(
55-
'-translate-x-1/2 fixed bottom-6 left-1/2 z-[var(--z-dropdown)] max-md:max-w-[calc(100%-2rem)]',
55+
'-translate-x-1/2 fixed bottom-[max(1.5rem,env(safe-area-inset-bottom))] left-1/2 z-[var(--z-dropdown)] max-md:max-w-[calc(100%-2rem)]',
5656
className
5757
)}
5858
>

‎apps/sim/app/workspace/[workspaceId]/settings/components/activity-log/activity-log.tsx‎

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -168,41 +168,43 @@ export function ActivityLog({
168168
const hasTrailingColumn = entries.some((entry) => entry.trailing != null)
169169

170170
return (
171-
<div className='min-w-0 overflow-x-auto'>
172-
<div
173-
className={cn(
174-
'flex flex-col md:min-w-0',
175-
hasTrailingColumn ? 'min-w-[800px]' : 'min-w-[700px]'
176-
)}
177-
>
178-
<div className='flex items-center gap-3 px-3 pb-1 text-[var(--text-tertiary)] text-caption'>
179-
<span className='w-[160px] shrink-0'>Timestamp</span>
180-
<span className={cn(EVENT_COLUMN_WIDTH_CLASS[eventColumn], 'shrink-0')}>
181-
{eventLabel}
182-
</span>
183-
<span className='min-w-0 flex-1'>{descriptionLabel}</span>
184-
<span className='w-[160px] shrink-0 text-right'>Actor</span>
185-
{/* Row actions carry no header, but the column must still be reserved
171+
<div className='min-w-0'>
172+
<div className='overflow-x-auto'>
173+
<div
174+
className={cn(
175+
'flex flex-col md:min-w-0',
176+
hasTrailingColumn ? 'min-w-[800px]' : 'min-w-[700px]'
177+
)}
178+
>
179+
<div className='flex items-center gap-3 px-3 pb-1 text-[var(--text-tertiary)] text-caption'>
180+
<span className='w-[160px] shrink-0'>Timestamp</span>
181+
<span className={cn(EVENT_COLUMN_WIDTH_CLASS[eventColumn], 'shrink-0')}>
182+
{eventLabel}
183+
</span>
184+
<span className='min-w-0 flex-1'>{descriptionLabel}</span>
185+
<span className='w-[160px] shrink-0 text-right'>Actor</span>
186+
{/* Row actions carry no header, but the column must still be reserved
186187
here or every label above would sit left of the data below it. */}
187-
{hasTrailingColumn && (
188-
<span className={cn(TRAILING_COLUMN_WIDTH_CLASS, 'shrink-0')} aria-hidden />
188+
{hasTrailingColumn && (
189+
<span className={cn(TRAILING_COLUMN_WIDTH_CLASS, 'shrink-0')} aria-hidden />
190+
)}
191+
</div>
192+
193+
{entries.length > 0 && (
194+
<div className='flex flex-col gap-0.5'>
195+
{entries.map((entry) => (
196+
<ActivityLogRow
197+
key={entry.id}
198+
entry={entry}
199+
eventColumn={eventColumn}
200+
hasTrailingColumn={hasTrailingColumn}
201+
/>
202+
))}
203+
</div>
189204
)}
190205
</div>
191-
192-
{entries.length > 0 && (
193-
<div className='flex flex-col gap-0.5'>
194-
{entries.map((entry) => (
195-
<ActivityLogRow
196-
key={entry.id}
197-
entry={entry}
198-
eventColumn={eventColumn}
199-
hasTrailingColumn={hasTrailingColumn}
200-
/>
201-
))}
202-
{footer}
203-
</div>
204-
)}
205206
</div>
207+
{entries.length > 0 && footer && <div className='mt-0.5'>{footer}</div>}
206208
{entries.length === 0 && emptyState}
207209
</div>
208210
)

‎apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-action-bar/table-action-bar.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export function TableActionBar({
8585
exit={{ opacity: 0, y: 10 }}
8686
transition={{ duration: 0.2 }}
8787
className={cn(
88-
'-translate-x-1/2 pointer-events-none absolute bottom-6 left-1/2 z-50 max-md:max-w-[calc(100%-2rem)]',
88+
'-translate-x-1/2 pointer-events-none absolute bottom-[max(1.5rem,env(safe-area-inset-bottom))] left-1/2 z-50 max-md:max-w-[calc(100%-2rem)]',
8989
className
9090
)}
9191
>

‎apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/chat/chat.test.tsx‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,6 @@ vi.mock('@/app/workspace/[workspaceId]/w/[workflowId]/components/chat/components
2222
ChatMessage: () => null,
2323
OutputSelect: () => null,
2424
}))
25-
vi.mock('@/app/workspace/[workspaceId]/w/[workflowId]/hooks/float', () => ({
26-
useFloatDrag: () => ({}),
27-
useFloatBoundarySync: () => {},
28-
useFloatResize: () => ({}),
29-
}))
3025

3126
let root: Root
3227
let container: HTMLDivElement

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

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import {
4949
import {
5050
useFloatBoundarySync,
5151
useFloatDrag,
52+
useFloatLayout,
5253
useFloatResize,
5354
} from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/float'
5455
import {
@@ -391,40 +392,27 @@ export function Chat() {
391392
const shouldShowConfigureStartInputsButton =
392393
Boolean(startBlockId) && missingStartReservedFields.length > 0
393394

394-
const isFloatingLayout = useCallback(() => {
395-
const element = preventZoomRef.current
396-
return element !== null && getComputedStyle(element).position === 'fixed'
397-
}, [preventZoomRef])
398-
399-
const updateDesktopPosition = useCallback(
400-
(position: { x: number; y: number }) => {
401-
if (isFloatingLayout()) setChatPosition(position)
402-
},
403-
[isFloatingLayout, setChatPosition]
404-
)
405-
406-
const updateDesktopDimensions = useCallback(
407-
(dimensions: { width: number; height: number }) => {
408-
if (isFloatingLayout()) setChatDimensions(dimensions)
409-
},
410-
[isFloatingLayout, setChatDimensions]
411-
)
395+
const { isFloatingLayout, updatePosition, updateDimensions } = useFloatLayout({
396+
ref: preventZoomRef,
397+
onPositionChange: setChatPosition,
398+
onDimensionsChange: setChatDimensions,
399+
})
412400

413-
const actualPosition = chatPosition ?? getChatPosition(null, chatWidth, chatHeight)
401+
const actualPosition = getChatPosition(chatPosition, chatWidth, chatHeight)
414402

415403
const { handleMouseDown } = useFloatDrag({
416404
position: actualPosition,
417405
width: chatWidth,
418406
height: chatHeight,
419-
onPositionChange: updateDesktopPosition,
407+
onPositionChange: updatePosition,
420408
})
421409

422410
useFloatBoundarySync({
423411
isOpen: isChatOpen && !isMobile,
424412
position: actualPosition,
425413
width: chatWidth,
426414
height: chatHeight,
427-
onPositionChange: updateDesktopPosition,
415+
onPositionChange: updatePosition,
428416
})
429417

430418
const {
@@ -436,8 +424,8 @@ export function Chat() {
436424
position: actualPosition,
437425
width: chatWidth,
438426
height: chatHeight,
439-
onPositionChange: updateDesktopPosition,
440-
onDimensionsChange: updateDesktopDimensions,
427+
onPositionChange: updatePosition,
428+
onDimensionsChange: updateDimensions,
441429
})
442430

443431
const workflowMessages = useMemo(() => {

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ import { useVariablesModalStore } from '@/stores/variables/modal'
9191
import { useVariablesStore } from '@/stores/variables/store'
9292
import { useWorkflowDiffStore } from '@/stores/workflow-diff/store'
9393
import { captureBaselineSnapshot } from '@/stores/workflow-diff/utils'
94+
import { useWorkflowSearchReplaceStore } from '@/stores/workflow-search-replace/store'
9495
import { getWorkflowWithValues } from '@/stores/workflows'
9596
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
9697
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
@@ -306,6 +307,9 @@ export const Panel = memo(function Panel() {
306307
}))
307308
)
308309

310+
const isSearchOpen = useWorkflowSearchReplaceStore((state) => state.isOpen)
311+
const hasCanvasOverlay = isChatOpen || isVariablesOpen || isSearchOpen
312+
309313
const currentWorkflow = activeWorkflowId ? workflows[activeWorkflowId] : null
310314
const workflowLocked = isWorkflowEffectivelyLocked(currentWorkflow, folders)
311315
const canMutateWorkflow = userPermissions.canEdit && !workflowLocked
@@ -736,7 +740,7 @@ export const Panel = memo(function Panel() {
736740
<div
737741
className={cn(
738742
'absolute top-3 right-3 z-[var(--z-dropdown)] @min-[960px]/workflow:hidden',
739-
isChatOpen && 'hidden'
743+
hasCanvasOverlay && 'hidden'
740744
)}
741745
>
742746
<Chip
@@ -761,7 +765,7 @@ export const Panel = memo(function Panel() {
761765
id='workflow-panel'
762766
className={cn(
763767
'panel-container @max-[960px]/workflow:absolute relative @max-[960px]/workflow:inset-0 @max-[960px]/workflow:z-[var(--z-dropdown)] @max-[960px]/workflow:w-full! shrink-0 overflow-hidden bg-[var(--bg)]',
764-
!isMobilePanelOpen && '@max-[960px]/workflow:hidden'
768+
(!isMobilePanelOpen || hasCanvasOverlay) && '@max-[960px]/workflow:hidden'
765769
)}
766770
aria-label='Workflow panel'
767771
>
@@ -802,7 +806,12 @@ export const Panel = memo(function Panel() {
802806
<Layout animate={isAutoLayouting} variant='clockwise' />
803807
Auto layout
804808
</DropdownMenuItem>
805-
<DropdownMenuItem onSelect={() => setVariablesOpen(!isVariablesOpen)}>
809+
<DropdownMenuItem
810+
onSelect={() => {
811+
setVariablesOpen(!isVariablesOpen)
812+
setIsMobilePanelOpen(false)
813+
}}
814+
>
806815
<VariableIcon />
807816
Variables
808817
</DropdownMenuItem>

‎apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/search-replace/components/replacement-controls/replacement-controls.tsx‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,21 +55,21 @@ export function ReplacementControls({
5555
/>
5656
)}
5757

58-
<div className='flex items-center justify-between gap-2'>
58+
<div className='flex @max-[960px]/workflow:flex-wrap items-center justify-between gap-2'>
5959
<span className='text-[var(--text-muted)] text-xs'>
6060
{eligibleCount} replaceable match{eligibleCount === 1 ? '' : 'es'}
6161
</span>
62-
<div className='flex gap-1.5'>
62+
<div className='@max-[960px]/workflow:ml-auto flex shrink-0 gap-1.5'>
6363
<Button
64-
className='h-8 text-xs'
64+
className='h-8 @max-[960px]/workflow:pointer-coarse:min-h-11 text-xs'
6565
variant='default'
6666
disabled={disabled || isApplying || !canReplaceActive}
6767
onClick={onReplaceActive}
6868
>
6969
Replace
7070
</Button>
7171
<Button
72-
className='h-8 text-xs'
72+
className='h-8 @max-[960px]/workflow:pointer-coarse:min-h-11 text-xs'
7373
variant='active'
7474
disabled={disabled || isApplying || !canReplaceAll}
7575
onClick={onReplaceAll}

0 commit comments

Comments
 (0)