Skip to content

Commit b8d65c5

Browse files
authored
Merge pull request #1001 from objectstack-ai/copilot/clean-up-action-buttons-layout
2 parents fedefab + 5ac3109 commit b8d65c5

4 files changed

Lines changed: 37 additions & 12 deletions

File tree

packages/components/src/renderers/action/action-bar.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import { ComponentRegistry } from '@object-ui/core';
3636
import type { ActionSchema, ActionLocation, ActionComponent } from '@object-ui/types';
3737
import { useCondition } from '@object-ui/react';
3838
import { cn } from '../../lib/utils';
39+
import { useIsMobile } from '../../hooks/use-mobile';
3940

4041
export interface ActionBarSchema {
4142
type: 'action:bar';
@@ -45,6 +46,8 @@ export interface ActionBarSchema {
4546
location?: ActionLocation;
4647
/** Maximum visible inline actions before overflow into "More" menu (default: 3) */
4748
maxVisible?: number;
49+
/** Maximum visible inline actions on mobile devices (default: 1). Desktop uses maxVisible instead. */
50+
mobileMaxVisible?: number;
4851
/** Visibility condition expression */
4952
visible?: string;
5053
/** Layout direction */
@@ -71,6 +74,7 @@ const ActionBarRenderer = forwardRef<HTMLDivElement, { schema: ActionBarSchema;
7174
} = props;
7275

7376
const isVisible = useCondition(schema.visible ? `\${${schema.visible}}` : undefined);
77+
const isMobile = useIsMobile();
7478

7579
// Filter actions by location
7680
const filteredActions = useMemo(() => {
@@ -82,7 +86,10 @@ const ActionBarRenderer = forwardRef<HTMLDivElement, { schema: ActionBarSchema;
8286
}, [schema.actions, schema.location]);
8387

8488
// Split into visible inline actions and overflow
85-
const maxVisible = schema.maxVisible ?? 3;
89+
// On mobile, show fewer actions inline (default: 1)
90+
const maxVisible = isMobile
91+
? (schema.mobileMaxVisible ?? 1)
92+
: (schema.maxVisible ?? 3);
8693
const { inlineActions, overflowActions } = useMemo(() => {
8794
if (filteredActions.length <= maxVisible) {
8895
return { inlineActions: filteredActions, overflowActions: [] as ActionSchema[] };

packages/layout/src/AppShell.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ export function AppShell({
136136
{sidebar}
137137
<SidebarInset>
138138
<header className="flex h-14 sm:h-16 shrink-0 items-center gap-2 border-b bg-background px-2 sm:px-4">
139-
<SidebarTrigger className="-ml-1" />
140-
<div className="w-px h-4 bg-border mx-1 sm:mx-2" />
139+
<SidebarTrigger className="-ml-1 hidden md:inline-flex" />
140+
<div className="w-px h-4 bg-border mx-1 sm:mx-2 hidden md:block" />
141141
{navbar}
142142
</header>
143143
<main className={cn("flex-1 min-w-0 overflow-auto p-3 sm:p-4 md:p-6", className)}>

packages/plugin-detail/src/DetailSection.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,9 @@ export const DetailSection: React.FC<DetailSectionProps> = ({
195195
className={cn(
196196
"grid gap-3 sm:gap-4",
197197
effectiveColumns === 1 ? "grid-cols-1" :
198-
effectiveColumns === 2 ? "grid-cols-1 md:grid-cols-2" :
199-
effectiveColumns === 3 ? "grid-cols-1 md:grid-cols-2 lg:grid-cols-3" :
200-
"grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
198+
effectiveColumns === 2 ? "grid-cols-1 sm:grid-cols-2" :
199+
effectiveColumns === 3 ? "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3" :
200+
"grid-cols-1 sm:grid-cols-2 lg:grid-cols-3"
201201
)}
202202
>
203203
{layoutFields.map(renderField)}

packages/plugin-detail/src/DetailView.tsx

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -469,15 +469,15 @@ export const DetailView: React.FC<DetailViewProps> = ({
469469
<SchemaRenderer key={index} schema={action} data={data} />
470470
))}
471471

472-
{/* Inline Edit Toggle */}
472+
{/* Inline Edit Toggle - hidden on mobile, accessible via more menu */}
473473
{inlineEdit && (
474474
<Tooltip>
475475
<TooltipTrigger asChild>
476476
<Button
477477
variant={isInlineEditing ? 'default' : 'outline'}
478478
size="sm"
479479
onClick={handleInlineEditToggle}
480-
className="gap-2"
480+
className="gap-2 hidden sm:inline-flex"
481481
>
482482
{isInlineEditing ? (
483483
<>
@@ -498,21 +498,21 @@ export const DetailView: React.FC<DetailViewProps> = ({
498498
</Tooltip>
499499
)}
500500

501-
{/* Share Button */}
501+
{/* Share Button - hidden on mobile, accessible via more menu */}
502502
<Tooltip>
503503
<TooltipTrigger asChild>
504-
<Button variant="outline" size="icon" onClick={handleShare}>
504+
<Button variant="outline" size="icon" onClick={handleShare} className="hidden sm:inline-flex">
505505
<Share2 className="h-4 w-4" />
506506
</Button>
507507
</TooltipTrigger>
508508
<TooltipContent>{t('detail.share')}</TooltipContent>
509509
</Tooltip>
510510

511-
{/* Edit Button */}
511+
{/* Edit Button - hidden on mobile, accessible via more menu */}
512512
{schema.showEdit && (
513513
<Tooltip>
514514
<TooltipTrigger asChild>
515-
<Button variant="default" onClick={handleEdit} className="gap-2">
515+
<Button variant="default" onClick={handleEdit} className="gap-2 hidden sm:inline-flex">
516516
<Edit className="h-4 w-4" />
517517
<span className="hidden sm:inline">{t('detail.edit')}</span>
518518
</Button>
@@ -534,6 +534,24 @@ export const DetailView: React.FC<DetailViewProps> = ({
534534
<TooltipContent>{t('detail.moreActions')}</TooltipContent>
535535
</Tooltip>
536536
<DropdownMenuContent align="end" className="w-[calc(100vw-2rem)] sm:w-48 max-h-[60vh] overflow-y-auto">
537+
{/* Mobile-only: Share, Edit, Inline Edit */}
538+
<DropdownMenuItem onClick={handleShare} className="sm:hidden">
539+
<Share2 className="h-4 w-4 mr-2" />
540+
{t('detail.share')}
541+
</DropdownMenuItem>
542+
{schema.showEdit && (
543+
<DropdownMenuItem onClick={handleEdit} className="sm:hidden">
544+
<Edit className="h-4 w-4 mr-2" />
545+
{t('detail.edit')}
546+
</DropdownMenuItem>
547+
)}
548+
{inlineEdit && (
549+
<DropdownMenuItem onClick={handleInlineEditToggle} className="sm:hidden">
550+
<Edit className="h-4 w-4 mr-2" />
551+
{isInlineEditing ? t('detail.save') : t('detail.editInline')}
552+
</DropdownMenuItem>
553+
)}
554+
<DropdownMenuSeparator className="sm:hidden" />
537555
<DropdownMenuItem onClick={handleDuplicate}>
538556
<Copy className="h-4 w-4 mr-2" />
539557
{t('detail.duplicate')}

0 commit comments

Comments
 (0)