Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Focus visible style refinements #1577

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7f3994b
reduces the thickness of the focus-visible
samejr Dec 18, 2024
7020df3
More subtle Input style
samejr Dec 18, 2024
dc2e063
Updates focus-visible styles for the SimpleSelect
samejr Dec 18, 2024
b87bb11
Tables tab through rows and action cells only
samejr Dec 18, 2024
5dc8d7f
Refined focus visible style
samejr Dec 18, 2024
a1c37d6
Adds the custom focus visible to the TextLink
samejr Dec 18, 2024
687ead4
Moves the onClick handling to the table row rather than the cell
samejr Dec 18, 2024
149ee94
Merge branch 'main' into focus-visible-style-refinments
samejr Dec 19, 2024
758a96d
Makes table row heights consistent
samejr Dec 19, 2024
8fd2948
Adds gap between task search bar and button
samejr Dec 19, 2024
1daafa3
Prevents long tag values from wrapping
samejr Dec 19, 2024
9f577c7
Removes unnecessary rows from table header
samejr Dec 23, 2024
6028ef3
Added gap between search and filters
samejr Dec 23, 2024
f97c60d
Fixes the schedules table pagination staying fixed to the bottom of t…
samejr Dec 23, 2024
3b0e6d4
Removed more unnecessary header table rows to prevent them being sele…
samejr Dec 23, 2024
4ab3f3c
Removed isSelected styles (not working)
samejr Dec 23, 2024
f9caa9f
Added <tr> back to the main Table compontent
samejr Dec 31, 2024
b239474
Table row handles modifier keys
samejr Jan 3, 2025
8a814d4
Adds to={path} to the TableRow only
samejr Jan 3, 2025
f2bdc64
Revert "Adds to={path} to the TableRow only"
samejr Jan 4, 2025
47a560b
Revert "Table row handles modifier keys"
samejr Jan 4, 2025
8ad7443
Table reverted to use linked cells rather than rows
samejr Jan 4, 2025
796e0d3
Set the tab index of a cell and style the table row when tabbed
samejr Jan 4, 2025
17302b8
Tabbed row style applied to the sticky cells
samejr Jan 4, 2025
9edd0e2
Adds isTabbableCell to each table
samejr Jan 4, 2025
5b11f5c
Improves the spcificity of the row highlighting
samejr Jan 4, 2025
2219abc
Reduces the height of the task rows to match the other tables
samejr Jan 4, 2025
ab32e4d
Adds tab styles to fill in row dividers top and bottom
samejr Jan 5, 2025
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
10 changes: 5 additions & 5 deletions apps/webapp/app/components/primitives/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { cn } from "~/utils/cn";
import { Icon, RenderIcon } from "./Icon";

const containerBase =
"has-[:focus-visible]:outline-none has-[:focus-visible]:ring-1 has-[:focus-visible]:ring-text-link has-[:focus-visible]:ring-offset-0 has-[:focus]:border-ring has-[:focus]:outline-none has-[:focus]:ring-2 has-[:focus]:ring-ring has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50 ring-offset-background transition cursor-text";
"has-[:focus-visible]:outline-none has-[:focus-visible]:ring-1 has-[:focus-visible]:ring-charcoal-650 has-[:focus-visible]:ring-offset-0 has-[:focus]:border-ring has-[:focus]:outline-none has-[:focus]:ring-1 has-[:focus]:ring-ring has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50 ring-offset-background transition cursor-text";

const inputBase =
"h-full w-full text-text-bright bg-transparent file:border-0 file:bg-transparent file:text-base file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-0 disabled:cursor-not-allowed outline-none ring-0 border-none";
Expand All @@ -17,27 +17,27 @@ const variants = {
container:
"px-1 w-full h-10 rounded-[3px] border border-charcoal-800 bg-charcoal-750 hover:border-charcoal-600 hover:bg-charcoal-650",
input: "px-2 text-sm",
iconSize: "h-4 w-4 ml-1",
iconSize: "size-4 ml-1",
shortcut: "mr-1 min-w-[22px] rounded-sm py-[3px] px-[5px] text-[0.6rem] select-none",
},
medium: {
container:
"px-1 h-8 w-full rounded border border-charcoal-800 bg-charcoal-750 hover:border-charcoal-600 hover:bg-charcoal-650",
input: "px-1.5 rounded text-sm",
iconSize: "h-4 w-4 ml-0.5",
iconSize: "size-4 ml-0.5",
shortcut: "min-w-[22px] rounded-sm py-[3px] px-[5px] text-[0.6rem]",
},
small: {
container:
"px-1 h-6 w-full rounded border border-charcoal-800 bg-charcoal-750 hover:border-charcoal-600 hover:bg-charcoal-650",
input: "px-1 rounded text-xs",
iconSize: "h-3 w-3 ml-0.5",
iconSize: "size-3 ml-0.5",
shortcut: "min-w-[22px] rounded-[2px] py-px px-[3px] text-[0.5rem]",
},
tertiary: {
container: "px-1 h-6 w-full rounded hover:bg-charcoal-750",
input: "px-1 rounded text-xs",
iconSize: "h-3 w-3 ml-0.5",
iconSize: "size-3 ml-0.5",
shortcut: "min-w-[22px] rounded-[2px] py-px px-[3px] text-[0.5rem]",
},
};
Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/app/components/primitives/SimpleSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const SelectTrigger = React.forwardRef<
<SelectPrimitive.Trigger
ref={ref}
className={cn(
"ring-offset-background focus-visible:ring-ring group flex items-center justify-between gap-x-1 rounded text-text-dimmed transition placeholder:text-text-dimmed hover:text-text-bright focus-visible:bg-tertiary focus-visible:text-text-bright focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50",
"ring-offset-background group flex items-center justify-between gap-x-1 rounded text-text-dimmed transition placeholder:text-text-dimmed hover:text-text-bright focus-visible:focus-custom disabled:cursor-not-allowed disabled:opacity-50",
width === "full" ? "w-full" : "w-min",
sizeClassName,
className
Expand Down
79 changes: 46 additions & 33 deletions apps/webapp/app/components/primitives/Table.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ChevronRightIcon } from "@heroicons/react/24/solid";
import { Link } from "@remix-run/react";
import { ReactNode, forwardRef, useState } from "react";
import { useNavigate } from "@remix-run/react";
import React, { ReactNode, forwardRef, useState } from "react";
import { cn } from "~/utils/cn";
import { Popover, PopoverContent, PopoverVerticalEllipseTrigger } from "./Popover";
import { InfoIconTooltip } from "./Tooltip";
Expand Down Expand Up @@ -44,6 +44,7 @@ export const TableHeader = forwardRef<HTMLTableSectionElement, TableHeaderProps>
"sticky top-0 z-10 bg-background-dimmed after:absolute after:bottom-0 after:left-0 after:right-0 after:h-px after:bg-grid-bright",
className
)}
tabIndex={-1}
>
{children}
</thead>
Expand Down Expand Up @@ -71,15 +72,49 @@ type TableRowProps = {
children: ReactNode;
disabled?: boolean;
isSelected?: boolean;
to?: string;
onClick?: (event: React.KeyboardEvent | React.MouseEvent) => void;
};

export const TableRow = forwardRef<HTMLTableRowElement, TableRowProps>(
({ className, disabled, isSelected, children }, ref) => {
({ className, disabled, isSelected, children, to, onClick }, ref) => {
const navigate = useNavigate();

const handleInteraction = (event: React.KeyboardEvent | React.MouseEvent) => {
if ((event.target as HTMLElement).closest('button, a, [role="button"]')) {
return;
}

const firstCellWithTo = React.Children.toArray(children).find((child) => {
if (React.isValidElement(child) && child.type === TableCell) {
return child.props.to;
}
return false;
}) as React.ReactElement | undefined;

if (firstCellWithTo?.props.to) {
navigate(firstCellWithTo.props.to);
} else if (onClick) {
onClick(event);
}
};

const handleKeyDown = (event: React.KeyboardEvent) => {
if (event.key === "Enter") {
event.preventDefault();
event.stopPropagation();
handleInteraction(event);
}
};

return (
<tr
ref={ref}
tabIndex={disabled ? -1 : 0}
onClick={handleInteraction}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this break CMD+clicking on cells?

onKeyDown={handleKeyDown}
className={cn(
"group/table-row relative w-full after:absolute after:bottom-0 after:left-3 after:right-0 after:h-px after:bg-grid-dimmed",
"group/table-row relative w-full cursor-pointer outline-none after:absolute after:bottom-0 after:left-3 after:right-0 after:h-px after:bg-grid-dimmed focus-visible:bg-background-bright",
disabled && "opacity-50",
isSelected && isSelectedStyle,
className
Expand Down Expand Up @@ -125,6 +160,7 @@ export const TableHeaderCell = forwardRef<HTMLTableCellElement, TableHeaderCellP
className
)}
colSpan={colSpan}
tabIndex={-1}
>
{hiddenLabel ? (
<span className="sr-only">{children}</span>
Expand Down Expand Up @@ -153,7 +189,7 @@ type TableCellProps = TableCellBasicProps & {

const rowHoverStyles = {
default:
"group-hover/table-row:bg-charcoal-800 group-hover/table-row:before:absolute group-hover/table-row:before:bg-charcoal-750 group-hover/table-row:before:top-[-1px] group-hover/table-row:before:left-0 group-hover/table-row:before:h-px group-hover/table-row:before:w-3 group-hover/table-row:after:absolute group-hover/table-row:after:bg-charcoal-750 group-hover/table-row:after:bottom-0 group-hover/table-row:after:left-0 group-hover/table-row:after:h-px group-hover/table-row:after:w-3",
"group-hover/table-row:bg-charcoal-800 group-focus-visible/table-row:bg-background-bright group-hover/table-row:before:absolute group-hover/table-row:before:bg-charcoal-750 group-hover/table-row:before:top-[-1px] group-hover/table-row:before:left-0 group-hover/table-row:before:h-px group-hover/table-row:before:w-3 group-hover/table-row:after:absolute group-hover/table-row:after:bg-charcoal-750 group-hover/table-row:after:bottom-0 group-hover/table-row:after:left-0 group-hover/table-row:after:h-px group-hover/table-row:after:w-3",
dimmed:
"group-hover/table-row:bg-charcoal-850 group-hover/table-row:before:absolute group-hover/table-row:before:bg-charcoal-800 group-hover/table-row:before:top-[-1px] group-hover/table-row:before:left-0 group-hover/table-row:before:h-px group-hover/table-row:before:w-3 group-hover/table-row:after:absolute group-hover/table-row:after:bg-charcoal-800 group-hover/table-row:after:bottom-0 group-hover/table-row:after:left-0 group-hover/table-row:after:h-px group-hover/table-row:after:w-3",
bright:
Expand All @@ -173,8 +209,6 @@ export const TableCell = forwardRef<HTMLTableCellElement, TableCellProps>(
alignment = "left",
children,
colSpan,
to,
onClick,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you remove these from TableCellProps do you get errors when you run pnpm run typecheck --filter webapp. My bet is you do

hasAction = false,
isSticky = false,
rowHoverStyle = "default",
Expand All @@ -192,40 +226,22 @@ export const TableCell = forwardRef<HTMLTableCellElement, TableCellProps>(
break;
}

const flexClasses = cn(
"flex w-full whitespace-nowrap px-3 py-3 text-xs text-text-dimmed",
alignment === "left"
? "justify-start text-left"
: alignment === "center"
? "justify-center text-center"
: "justify-end text-right"
);

return (
<td
ref={ref}
className={cn(
"text-xs text-charcoal-400",
to || onClick || hasAction ? "cursor-pointer" : "px-3 py-3 align-middle",
!to && !onClick && alignmentClassName,
hasAction ? "cursor-pointer" : "h-10 min-h-10 px-3 align-middle",
alignmentClassName,
actionClassName,
isSticky && stickyStyles,
isSelected && isSelectedStyle,
!isSelected && rowHoverStyles[rowHoverStyle],
className
)}
colSpan={colSpan}
>
{to ? (
<Link to={to} className={cn("focus-custom", flexClasses, actionClassName)}>
{children}
</Link>
) : onClick ? (
<button onClick={onClick} className={cn("focus-custom", flexClasses, actionClassName)}>
{children}
</button>
) : (
<>{children}</>
)}
{children}
</td>
);
}
Expand Down Expand Up @@ -297,10 +313,7 @@ export const TableCellMenu = forwardRef<
<div className="relative h-full p-1">
<div
className={cn(
"absolute right-0 top-1/2 mr-1 flex -translate-y-1/2 items-center justify-end gap-0.5 rounded-[0.25rem] bg-background-dimmed p-0.5 group-hover/table-row:bg-background-bright group-hover/table-row:ring-1 group-hover/table-row:ring-grid-bright",
isSelected && isSelectedStyle,
isSelected &&
"group-hover/table-row:bg-charcoal-750 group-hover/table-row:ring-charcoal-600/50"
"absolute right-0 top-1/2 mr-1 flex -translate-y-1/2 items-center justify-end gap-0.5 rounded-[0.25rem] bg-background-dimmed p-0.5 group-hover/table-row:bg-background-bright group-hover/table-row:ring-1 group-hover/table-row:ring-grid-bright"
)}
>
{/* Hidden buttons that show on hover */}
Expand Down
8 changes: 4 additions & 4 deletions apps/webapp/app/components/primitives/TextLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { cn } from "~/utils/cn";

const variations = {
primary:
"text-indigo-500 transition hover:text-indigo-400 inline-flex gap-0.5 items-center group",
"text-indigo-500 transition hover:text-indigo-400 inline-flex gap-0.5 items-center group focus-visible:focus-custom",
secondary:
"text-text-dimmed transition underline underline-offset-2 decoration-dimmed/50 hover:decoration-dimmed inline-flex gap-0.5 items-center group",
"text-text-dimmed transition underline underline-offset-2 decoration-dimmed/50 hover:decoration-dimmed inline-flex gap-0.5 items-center group focus-visible:focus-custom",
} as const;

type TextLinkProps = {
Expand Down Expand Up @@ -34,14 +34,14 @@ export function TextLink({
<Link to={to} className={cn(classes, className)} {...props}>
{children}{" "}
{trailingIcon && (
<NamedIcon name={trailingIcon} className={cn("h-4 w-4", trailingIconClassName)} />
<NamedIcon name={trailingIcon} className={cn("size-4", trailingIconClassName)} />
)}
</Link>
) : href ? (
<a href={href} className={cn(classes, className)} {...props}>
{children}{" "}
{trailingIcon && (
<NamedIcon name={trailingIcon} className={cn("h-4 w-4", trailingIconClassName)} />
<NamedIcon name={trailingIcon} className={cn("size-4", trailingIconClassName)} />
)}
</a>
) : (
Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/app/components/runs/v3/RunTag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function RunTag({ tag }: { tag: string }) {
<span className="flex items-center border-y border-r border-charcoal-700 bg-charcoal-800 pr-1.5 text-text-dimmed">
{tagResult.key}
</span>
<span className="flex items-center rounded-r-sm border-y border-r border-charcoal-700 bg-charcoal-750 px-1.5 text-text-dimmed">
<span className="flex items-center whitespace-nowrap rounded-r-sm border-y border-r border-charcoal-700 bg-charcoal-750 px-1.5 text-text-dimmed">
{tagResult.value}
</span>
</span>
Expand Down
4 changes: 2 additions & 2 deletions apps/webapp/app/components/runs/v3/ScheduleFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export function ScheduleFilters({ possibleEnvironments, possibleTasks }: Schedul
}, []);

return (
<div className="flex w-full flex-row">
<div className="flex w-full">
<Input
name="search"
placeholder="Search schedule id, external id, deduplication id or CRON pattern"
Expand All @@ -103,7 +103,7 @@ export function ScheduleFilters({ possibleEnvironments, possibleTasks }: Schedul
defaultValue={search}
onChange={(e) => handleSearchChange(e.target.value)}
/>
<SelectGroup>
<SelectGroup className="ml-2">
<Select name="type" value={type ?? "ALL"} onValueChange={handleTypeChange}>
<SelectTrigger size="minimal" width="full">
<SelectValue placeholder={"Select type"} className="ml-2 whitespace-nowrap p-0" />
Expand Down
Loading