feat: refine workbench chrome (#761)
* docs: define product and design direction * style: establish restrained workbench primitives * refactor: declutter board and task topbars * style: align dockview panel chrome * fix: align task topbar vcs control sizing * refactor: surface integrations navigation * fix: repair integrations and task creation workflow * refactor: include linear in integrations navigation * style: restore familiar workbench tones * fix: add dockview tab breathing room * fix: show configured integration shortcuts * fix: hover open integrations menu * fix: stabilize integrations hover menu * fix: align home and dockview topbars * fix: normalize home topbar controls * fix: compact home topbar height * fix: simplify home chrome and split buttons * fix: move integrations to left chrome * fix: restore home stats shortcut * fix: add dockview tab breathing room * fix: border home stats button * fix: streamline dockview topbar actions * fix: align task split button seam * fix: address review feedback * fix: restore topbar e2e affordances * fix: stabilize workflow e2e isolation * fix: add task topbar action overflow * fix: address PR review feedback
This commit is contained in:
@@ -4,11 +4,17 @@ import { cn } from "@kandev/ui/lib/utils";
|
||||
/**
|
||||
* Reusable dockview panel layout primitives.
|
||||
*
|
||||
* PanelRoot – outermost wrapper, fills the dockview content area
|
||||
* PanelBody – scrollable (or non-scrollable) content region
|
||||
* PanelToolbar – fixed strip at the top/bottom of a panel
|
||||
* PanelRoot - outermost wrapper, fills the dockview content area
|
||||
* PanelBody - scrollable (or non-scrollable) content region
|
||||
* PanelToolbar - fixed header strip for panel actions
|
||||
*/
|
||||
|
||||
const PANEL_ROOT_CLASS = "h-full min-h-0 flex flex-col bg-card text-card-foreground";
|
||||
const PANEL_BAR_CLASS =
|
||||
"flex items-center gap-1.5 h-[30px] px-2.5 shrink-0 border-border/80 bg-card/95 text-xs text-foreground";
|
||||
const PANEL_ACTION_CURSOR_CLASS =
|
||||
"[&_button:not(:disabled)]:cursor-pointer [&_[role=button]:not([aria-disabled=true])]:cursor-pointer";
|
||||
|
||||
type PanelRootProps = HTMLAttributes<HTMLDivElement> & {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
@@ -20,7 +26,7 @@ export const PanelRoot = forwardRef<HTMLDivElement, PanelRootProps>(function Pan
|
||||
ref,
|
||||
) {
|
||||
return (
|
||||
<div ref={ref} className={cn("h-full flex flex-col min-h-0", className)} {...rest}>
|
||||
<div ref={ref} className={cn(PANEL_ROOT_CLASS, className)} {...rest}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
@@ -29,7 +35,7 @@ export const PanelRoot = forwardRef<HTMLDivElement, PanelRootProps>(function Pan
|
||||
type PanelBodyProps = Omit<HTMLAttributes<HTMLDivElement>, "className"> & {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
/** Add default p-3 padding. Default true. */
|
||||
/** Add default p-2.5 padding. Default true. */
|
||||
padding?: boolean;
|
||||
/** Enable overflow scrolling. Default true. */
|
||||
scroll?: boolean;
|
||||
@@ -44,9 +50,9 @@ export const PanelBody = forwardRef<HTMLDivElement, PanelBodyProps>(function Pan
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex-1 min-h-0 bg-card",
|
||||
"flex-1 min-h-0 bg-card text-card-foreground",
|
||||
scroll && "overflow-auto",
|
||||
padding && "p-3",
|
||||
padding && "p-2.5",
|
||||
className,
|
||||
)}
|
||||
{...rest}
|
||||
@@ -61,20 +67,25 @@ type PanelToolbarProps = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
/** Fixed toolbar strip. Doesn't scroll with content. */
|
||||
export function PanelToolbar({ children, className }: PanelToolbarProps) {
|
||||
type PanelBarProps = {
|
||||
children?: ReactNode;
|
||||
className?: string;
|
||||
borderClassName: "border-b" | "border-t";
|
||||
};
|
||||
|
||||
function PanelBar({ children, className, borderClassName }: PanelBarProps) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center gap-2 px-3 py-1.5 border-b border-border shrink-0",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<div className={cn(PANEL_BAR_CLASS, PANEL_ACTION_CURSOR_CLASS, borderClassName, className)}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/** Fixed header toolbar strip. Doesn't scroll with content. */
|
||||
export function PanelToolbar({ children, className }: PanelToolbarProps) {
|
||||
return <PanelHeaderBar className={className}>{children}</PanelHeaderBar>;
|
||||
}
|
||||
|
||||
type PanelHeaderBarProps = {
|
||||
children?: ReactNode;
|
||||
className?: string;
|
||||
@@ -83,14 +94,9 @@ type PanelHeaderBarProps = {
|
||||
/** Fixed-height panel header bar. Renders children directly. */
|
||||
export function PanelHeaderBar({ children, className }: PanelHeaderBarProps) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center gap-2 px-3 h-[30px] border-b border-border shrink-0 bg-card",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<PanelBar borderClassName="border-b" className={className}>
|
||||
{children}
|
||||
</div>
|
||||
</PanelBar>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -104,9 +110,9 @@ type PanelHeaderBarSplitProps = {
|
||||
export function PanelHeaderBarSplit({ left, right, className }: PanelHeaderBarSplitProps) {
|
||||
return (
|
||||
<PanelHeaderBar className={className}>
|
||||
<div className="flex items-center gap-1.5 min-w-0">{left}</div>
|
||||
<div className="flex items-center gap-1.5 min-w-0 overflow-hidden">{left}</div>
|
||||
<div className="flex-1" />
|
||||
<div className="flex items-center gap-1.5 min-w-0">{right}</div>
|
||||
<div className="flex items-center gap-1.5 min-w-0 overflow-hidden">{right}</div>
|
||||
</PanelHeaderBar>
|
||||
);
|
||||
}
|
||||
@@ -114,13 +120,8 @@ export function PanelHeaderBarSplit({ left, right, className }: PanelHeaderBarSp
|
||||
/** Fixed-height panel footer bar with border-t. Mirrors PanelHeaderBar but anchors to the bottom. */
|
||||
export function PanelFooterBar({ children, className }: PanelHeaderBarProps) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center gap-2 px-3 h-[30px] border-t border-border shrink-0 bg-card",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<PanelBar borderClassName="border-t" className={className}>
|
||||
{children}
|
||||
</div>
|
||||
</PanelBar>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user