clean up sub page nav button/link usage and various ui colors (#7641)

This commit is contained in:
Jonathan Brennan 2026-02-05 17:30:30 -06:00 committed by GitHub
parent 1bb6656dee
commit 068189f95e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 89 additions and 83 deletions

View file

@ -0,0 +1,32 @@
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
type SubPageNavigationLinkProps = {
dataCy?: string;
isActive: boolean;
onClick: () => void;
title: string;
};
export function SubPageNavigationLink({
dataCy,
isActive,
onClick,
title,
}: SubPageNavigationLinkProps) {
return (
<Button
data-cy={dataCy}
variant="ghost"
className={cn(
isActive
? 'text-neutral-12 bg-neutral-5 hover:bg-neutral-5 dark:bg-neutral-3 dark:hover:bg-neutral-3'
: 'text-neutral-11 hover:bg-transparent hover:underline',
'justify-start',
)}
onClick={onClick}
>
{title}
</Button>
);
}

View file

@ -101,7 +101,7 @@ export function SchemaExplorerUsageStats(props: {
<tr key={op.hash}>
<td className="px-2 pl-0 text-left">
<NextLink
className="text-neutral-2 hover:text-neutral-2 hover:underline hover:underline-offset-2"
className="text-orange-800 hover:text-orange-800 hover:underline hover:underline-offset-2 dark:text-orange-500 dark:hover:text-orange-500"
to="/$organizationSlug/$projectSlug/$targetSlug/insights/$operationName/$operationHash"
params={{
organizationSlug: props.organizationSlug,
@ -146,7 +146,7 @@ export function SchemaExplorerUsageStats(props: {
{usage.usedByClients.map(clientName => (
<li key={clientName} className="font-bold">
<NextLink
className="text-neutral-2 hover:text-neutral-2 hover:underline hover:underline-offset-2"
className="text-orange-800 hover:text-orange-800 hover:underline hover:underline-offset-2 dark:text-orange-500 dark:hover:text-orange-500"
to="/$organizationSlug/$projectSlug/$targetSlug/insights/client/$name"
params={{
organizationSlug: props.organizationSlug,

View file

@ -289,16 +289,25 @@ export function SchemaVariantFilter(props: {
return (
<TooltipProvider>
<Tabs defaultValue={props.variant}>
<TabsList>
<TabsList className="bg-neutral-5">
{variants.map(variant => (
<Tooltip key={variant.value}>
<TooltipTrigger asChild>
{props.variant === variant.value ? (
<div>
<TabsTrigger value={variant.value}>{variant.label}</TabsTrigger>
<TabsTrigger
className="dark:data-[state=active]:bg-neutral-7 data-[state=active]:text-neutral-12"
value={variant.value}
>
{variant.label}
</TabsTrigger>
</div>
) : (
<TabsTrigger value={variant.value} asChild>
<TabsTrigger
className="text-neutral-9 hover:text-neutral-11"
value={variant.value}
asChild
>
<Link
to={variant.pathname}
params={{

View file

@ -56,7 +56,7 @@ function SubgraphChip(props: {
service: props.text,
}}
style={{ backgroundColor: stringToHslColor(props.text) }}
className="my-[2px] ml-[6px] inline-block h-[22px] max-w-[100px] cursor-pointer items-center justify-between truncate rounded-[16px] py-0 pl-[8px] pr-[6px] text-[10px] font-normal normal-case leading-loose text-[#4f4f4f] drop-shadow-md"
className="my-[2px] ml-[6px] inline-block h-[22px] max-w-[100px] cursor-pointer items-center justify-between truncate rounded-[16px] py-0 pl-[8px] pr-[6px] text-[10px] font-normal normal-case leading-loose text-[#4f4f4f]"
>
{props.text}
<PackageIcon size={10} className="ml-1 inline-block" />

View file

@ -235,7 +235,7 @@ function ChangeItem(
<div>
<span className="text-neutral-10">{labelize(change.message)}</span>
{change.isSafeBasedOnUsage && (
<span className="cursor-pointer text-yellow-500">
<span className="cursor-pointer text-yellow-700 dark:text-yellow-500">
{' '}
<CheckIcon className="inline size-3" /> Safe based on usage data
</span>
@ -358,7 +358,7 @@ function ChangeItem(
<TableRow key={hash}>
<TableCell className="font-medium">
<Popover>
<PopoverTrigger className="text-neutral-2 hover:text-neutral-2 hover:underline hover:underline-offset-4">
<PopoverTrigger className="text-orange-800 hover:text-orange-800 hover:underline-offset-4 dark:text-orange-500 dark:hover:text-orange-500">
{hash.substring(0, 4)}_{name}
</PopoverTrigger>
<PopoverContent side="right">

View file

@ -1,16 +1,15 @@
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useQuery, UseQueryExecute } from 'urql';
import { OrganizationLayout, Page } from '@/components/layouts/organization';
import { SubPageNavigationLink } from '@/components/navigation/sub-page-navigation-link';
import { OrganizationInvitations } from '@/components/organization/members/invitations';
import { OrganizationMembers } from '@/components/organization/members/list';
import { OrganizationMemberRoles } from '@/components/organization/members/roles';
import { Button } from '@/components/ui/button';
import { Meta } from '@/components/ui/meta';
import { NavLayout, PageLayout, PageLayoutContent } from '@/components/ui/page-content-layout';
import { QueryError } from '@/components/ui/query-error';
import { FragmentType, graphql, useFragment } from '@/gql';
import { useRedirect } from '@/lib/access/common';
import { cn } from '@/lib/utils';
import { organizationMembersRoute } from '../router';
const OrganizationMembersPage_OrganizationFragment = graphql(`
@ -72,23 +71,14 @@ function PageContent(props: {
return (
<PageLayout>
<NavLayout>
{filteredSubPages.map(subPage => {
return (
<Button
key={subPage.key}
variant="ghost"
className={cn(
props.page === subPage.key
? 'bg-neutral-4 hover:bg-neutral-4 dark:bg-neutral-3 dark:hover:bg-neutral-3'
: 'hover:bg-transparent hover:underline',
'justify-start',
)}
onClick={() => props.onPageChange(subPage.key)}
>
{subPage.title}
</Button>
);
})}
{filteredSubPages.map(subPage => (
<SubPageNavigationLink
key={subPage.key}
isActive={props.page === subPage.key}
onClick={() => props.onPageChange(subPage.key)}
title={subPage.title}
/>
))}
</NavLayout>
<PageLayoutContent>
{props.page === 'list' ? (

View file

@ -4,6 +4,7 @@ import { useForm } from 'react-hook-form';
import { useMutation, useQuery } from 'urql';
import { z } from 'zod';
import { OrganizationLayout, Page } from '@/components/layouts/organization';
import { SubPageNavigationLink } from '@/components/navigation/sub-page-navigation-link';
import { AccessTokensSubPage } from '@/components/organization/settings/access-tokens/access-tokens-sub-page';
import { OIDCIntegrationSection } from '@/components/organization/settings/oidc-integration-section';
import { PersonalAccessTokensSubPage } from '@/components/organization/settings/personal-access-tokens/personal-access-tokens-sub-page';
@ -39,7 +40,6 @@ import { env } from '@/env/frontend';
import { FragmentType, graphql, useFragment } from '@/gql';
import { useRedirect } from '@/lib/access/common';
import { useToggle } from '@/lib/hooks';
import { cn } from '@/lib/utils';
import { zodResolver } from '@hookform/resolvers/zod';
import { useRouter } from '@tanstack/react-router';
@ -715,10 +715,9 @@ function SettingsPageContent(props: {
<NavLayout>
{subPages.map(subPage => {
return (
<Button
<SubPageNavigationLink
key={subPage.key}
data-cy={`target-settings-${subPage.key}-link`}
variant="ghost"
isActive={resolvedPage.key === subPage.key}
onClick={() => {
void router.navigate({
search: {
@ -726,15 +725,8 @@ function SettingsPageContent(props: {
},
});
}}
className={cn(
resolvedPage.key === subPage.key
? 'bg-neutral-3 hover:bg-neutral-3'
: 'hover:bg-transparent hover:underline',
'w-full justify-start text-left',
)}
>
{subPage.title}
</Button>
title={subPage.title}
/>
);
})}
</NavLayout>

View file

@ -4,6 +4,7 @@ import { useForm } from 'react-hook-form';
import { useMutation, useQuery } from 'urql';
import { z } from 'zod';
import { Page, ProjectLayout } from '@/components/layouts/project';
import { SubPageNavigationLink } from '@/components/navigation/sub-page-navigation-link';
import { PolicySettings } from '@/components/policy/policy-settings';
import { ProjectAccessTokensSubPage } from '@/components/project/settings/access-tokens/project-access-tokens-sub-page';
import { CompositionSettings } from '@/components/project/settings/composition';
@ -38,7 +39,6 @@ import { ProjectType } from '@/gql/graphql';
import { useRedirect } from '@/lib/access/common';
import { getDocsUrl } from '@/lib/docs-url';
import { useNotifications, useToggle } from '@/lib/hooks';
import { cn } from '@/lib/utils';
import { zodResolver } from '@hookform/resolvers/zod';
import { useRouter } from '@tanstack/react-router';
@ -589,9 +589,9 @@ function ProjectSettingsContent(props: {
<PageLayout>
<NavLayout>
{subPages.map(subPage => (
<Button
<SubPageNavigationLink
key={subPage.key}
variant="ghost"
isActive={resolvedPage.key === subPage.key}
onClick={() => {
void router.navigate({
search: {
@ -599,15 +599,8 @@ function ProjectSettingsContent(props: {
},
});
}}
className={cn(
resolvedPage.key === subPage.key
? 'bg-neutral-3 hover:bg-neutral-3'
: 'hover:bg-transparent hover:underline',
'w-full justify-start text-left',
)}
>
{subPage.title}
</Button>
title={subPage.title}
/>
))}
</NavLayout>
<PageLayoutContent>

View file

@ -480,7 +480,7 @@ function DefaultSchemaView(props: {
return (
<>
<Tabs value={selectedView} onValueChange={value => setSelectedView(value)}>
<TabsList className="bg-neutral-3 border-neutral-3 w-full justify-start rounded-none border-x border-b">
<TabsList className="bg-neutral-5 dark:bg-neutral-3 border-neutral-5 dark:border-neutral-3 w-full justify-start rounded-none border-x border-b">
{items.map(item => (
<TabsTrigger key={item.value} value={item.value} disabled={item.isDisabled}>
{item.icon}
@ -489,7 +489,7 @@ function DefaultSchemaView(props: {
))}
</TabsList>
</Tabs>
<div className="border-neutral-3 min-h-[850px] rounded-md rounded-t-none border border-t-0">
<div className="dark:border-neutral-3 border-neutral-5 grow rounded-md rounded-t-none border border-t-0">
{selectedView === 'details' && (
<div className="my-4 px-4">
{!schemaCheck.schemaPolicyWarnings?.edges?.length &&
@ -693,7 +693,7 @@ function ContractCheckView(props: {
))}
</TabsList>
</Tabs>
<div className="border-neutral-3 min-h-[850px] rounded-md rounded-t-none border border-t-0">
<div className="dark:border-neutral-3 border-neutral-5 grow rounded-md rounded-t-none border border-t-0">
{selectedView === 'details' && (
<div className="my-4 px-4">
{contractCheck.schemaCompositionErrors && (
@ -874,8 +874,11 @@ function SchemaChecksView(props: {
value={selectedItem}
onValueChange={value => setSelectedItem(value)}
>
<TabsList className="w-full justify-start rounded-b-none px-2 py-0">
<TabsTrigger value="default" className="mt-1 py-2 data-[state=active]:rounded-b-none">
<TabsList className="w-full justify-start rounded-b-none bg-transparent px-2 py-0">
<TabsTrigger
value="default"
className="data-[state=active]:bg-neutral-5 dark:data-[state=active]:bg-neutral-3 border-neutral-5 dark:border-neutral-3 mt-1 rounded-b-none border py-2"
>
<span>Default Graph</span>
<TooltipProvider>
<Tooltip>

View file

@ -147,7 +147,7 @@ const Navigation = (
<span className="overflow-hidden truncate">{edge.node.meta.author}</span>
</div>
) : null}
<div className="mb-1.5 mt-2.5 flex align-middle text-xs font-medium text-[#c4c4c4]">
<div className="text-neutral-10 mb-1.5 mt-2.5 flex align-middle text-xs font-medium">
<div
className={cn(
edge.node.__typename === 'FailedSchemaCheck' ? 'text-red-500' : null,

View file

@ -278,7 +278,7 @@ const ProposalsListPage = (props: {
</span>
<span className="text-neutral-10">{proposal.stage}</span>
</div>
<div className="mb-1.5 mt-2 flex flex-col gap-x-1 align-middle text-xs font-medium text-[#c4c4c4] md:flex-row">
<div className="text-neutral-10 mb-1.5 mt-2 flex flex-col gap-x-1 align-middle text-xs font-medium md:flex-row">
<div className="truncate">
proposed <TimeAgo date={proposal.updatedAt} />
</div>

View file

@ -7,6 +7,7 @@ import { useMutation, useQuery } from 'urql';
import * as Yup from 'yup';
import { z } from 'zod';
import { Page, TargetLayout } from '@/components/layouts/target';
import { SubPageNavigationLink } from '@/components/navigation/sub-page-navigation-link';
import { SchemaEditor } from '@/components/schema-editor';
import { CDNAccessTokens } from '@/components/target/settings/cdn-access-tokens';
import { CreateAccessTokenModal } from '@/components/target/settings/registry-access-token';
@ -53,7 +54,6 @@ import {
import { useRedirect } from '@/lib/access/common';
import { subDays } from '@/lib/date-time';
import { useToggle } from '@/lib/hooks';
import { cn } from '@/lib/utils';
import { zodResolver } from '@hookform/resolvers/zod';
import { RadioGroupIndicator } from '@radix-ui/react-radio-group';
import { Link, useRouter } from '@tanstack/react-router';
@ -1865,10 +1865,10 @@ function TargetSettingsContent(props: {
<NavLayout>
{subPages.map(subPage => {
return (
<Button
<SubPageNavigationLink
key={subPage.key}
data-cy={`target-settings-${subPage.key}-link`}
variant="ghost"
dataCy={`target-settings-${subPage.key}-link`}
isActive={resolvedPage.key === subPage.key}
onClick={() => {
void router.navigate({
search: {
@ -1876,15 +1876,8 @@ function TargetSettingsContent(props: {
},
});
}}
className={cn(
resolvedPage.key === subPage.key
? 'bg-neutral-3 hover:bg-neutral-3'
: 'hover:bg-transparent hover:underline',
'w-full justify-start text-left',
)}
>
{subPage.title}
</Button>
title={subPage.title}
/>
);
})}
</NavLayout>

View file

@ -1,5 +1,5 @@
import { useState } from 'react';
import { Button } from '@/components/ui/button';
import { SubPageNavigationLink } from '@/components/navigation/sub-page-navigation-link';
import { NavLayout, PageLayout, PageLayoutContent } from '@/components/ui/page-content-layout';
import type { Meta, StoryObj } from '@storybook/react';
@ -28,18 +28,12 @@ const Template: StoryObj<typeof PageLayout> = {
<NavLayout>
{subPages.map(subPage => {
return (
<Button
<SubPageNavigationLink
key={subPage.key}
variant="ghost"
isActive={page === subPage.key}
onClick={() => setPage(subPage.key)}
className={
page === subPage.key
? 'bg-neutral-3 hover:bg-neutral-3'
: 'hover:bg-transparent hover:underline'
}
>
{subPage.title}
</Button>
title={subPage.title}
/>
);
})}
</NavLayout>