Skip to content

Commit bf468e2

Browse files
committed
Improve styles
1 parent b245d89 commit bf468e2

File tree

8 files changed

+226
-159
lines changed

8 files changed

+226
-159
lines changed

src/app/(main)/resources/[category]/blog-posts-section.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export function BlogPostsSection({
2828
readAllLabel = "Read all GraphQL stories",
2929
}: BlogPostsSectionProps) {
3030
return (
31-
<section className="flex flex-col gap-10 lg:gap-16">
31+
<section className="gql-container gql-section flex flex-col gap-10 lg:gap-16">
3232
<header className="flex flex-col gap-6 lg:flex-row lg:items-end lg:justify-between">
3333
<div className="flex flex-col gap-3">
3434
<Eyebrow>Blog posts</Eyebrow>
14.3 KB
Loading

src/app/(main)/resources/[category]/category-tools-libraries-section.tsx

Lines changed: 81 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ import { glob } from "node:fs/promises"
33
import { readFile } from "node:fs/promises"
44
import matter from "gray-matter"
55

6-
import { clsx } from "clsx"
76
import { Button } from "@/app/conf/_design-system/button"
7+
import blurCorner from "./blur-corner.webp"
88
import { Eyebrow } from "@/_design-system/eyebrow"
99
import slugMap from "@/code/slug-map.json"
1010
import { type Topic } from "@/resources/types"
11+
import { StripesDecoration } from "@/app/conf/_design-system/stripes-decoration"
1112

1213
interface LibraryEntry {
1314
name: string
@@ -78,78 +79,93 @@ export async function CategoryToolsLibrariesSection({
7879
)
7980
.slice(0, 20),
8081
}))
81-
.sort((a, b) => a.name.localeCompare(b.name, "en", { sensitivity: "base" }))
82+
.sort((a, b) => b.items.length - a.items.length)
8283

8384
if (grouped.length === 0) {
8485
return null
8586
}
8687

87-
const desktopLayoutClass =
88-
grouped.length > 2 ? "lg:grid lg:grid-cols-1 lg:gap-6" : "lg:grid lg:grid-cols-2 lg:gap-6"
89-
9088
return (
91-
<section
92-
id="tools-and-libraries"
93-
className="flex flex-col gap-8 border border-sec-base bg-sec-lighter p-6 dark:border-sec-darker dark:bg-sec-darker/15 lg:gap-10 lg:p-10"
94-
>
95-
<div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
96-
<div className="flex flex-col gap-3">
97-
<Eyebrow className="!text-sec-darker dark:!text-sec-light">
98-
key tools & libraries
99-
</Eyebrow>
100-
<h2 className="typography-h3 text-pretty">
101-
Build GraphQL with tools and libraries
102-
</h2>
103-
<p className="typography-body-md text-neu-800">
104-
Explore language and platform tooling to ship production-ready
105-
graphs.
106-
</p>
107-
</div>
108-
<Button href="/code" variant="tertiary" className="w-fit">
109-
See all Tools & Libraries
110-
</Button>
111-
</div>
112-
113-
<div
114-
className={clsx(
115-
"flex gap-4 overflow-x-auto pb-2 lg:overflow-visible",
116-
desktopLayoutClass,
117-
)}
89+
<div className="relative bg-neu-100 dark:bg-neu-50/25">
90+
<Stripes />
91+
<section
92+
id="tools-and-libraries"
93+
className="gql-container gql-section relative flex flex-col gap-8 overflow-hidden"
11894
>
119-
{grouped.map(group => (
120-
<div
121-
key={group.id}
122-
className="min-w-[280px] shrink-0 border border-neu-200 bg-neu-0 shadow-[0_1px_0_#E5E7EB] dark:border-neu-100 dark:bg-neu-0/60 lg:min-w-0"
123-
>
124-
<div className="flex items-center gap-3 border-b border-neu-200 px-4 py-3 text-neu-900 dark:border-neu-100">
125-
<span className="font-mono text-sm uppercase text-neu-700">
95+
<div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
96+
<div className="flex flex-col gap-3">
97+
<Eyebrow className="!text-pri-base dark:!text-pri-light">
98+
key tools & libraries
99+
</Eyebrow>
100+
<h2 className="typography-h3 text-pretty">
101+
Build GraphQL with tools and libraries
102+
</h2>
103+
<p className="typography-body-md text-neu-700 dark:text-neu-100">
104+
Explore language and platform tooling to ship production-ready
105+
graphs.
106+
</p>
107+
</div>
108+
<Button href="/code" variant="primary" className="w-fit">
109+
See all Tools & Libraries
110+
</Button>
111+
</div>
112+
113+
<div className="flex flex-wrap gap-4 pb-2 lg:overflow-visible">
114+
{grouped.map(group => (
115+
<div
116+
key={group.id}
117+
className="min-w-[480px] shrink-0 grow border border-neu-200 bg-neu-50 dark:bg-neu-50/50 lg:w-1/3 lg:min-w-0"
118+
>
119+
<div className="typography-body-lg flex items-center gap-3 border-b border-inherit bg-neu-50 px-4 py-3 text-neu-900">
120+
{/* todo: we should have an icon here */}
126121
{group.name}
127-
</span>
128-
</div>
129-
<ul className="divide-y divide-neu-200 dark:divide-neu-100">
130-
{group.items.map(item => (
131-
<li key={`${group.id}-${item.name}`}>
132-
{item.href ? (
133-
<a
134-
href={item.href}
135-
className="flex items-center justify-between px-4 py-3 text-neu-900 transition-colors hover:bg-neu-50 dark:hover:bg-neu-50/50"
136-
>
137-
<span>{item.name}</span>
138-
<span aria-hidden className="text-neu-500">
139-
122+
</div>
123+
<ul className="divide-y divide-neu-200 dark:divide-neu-100">
124+
{group.items.map(item => (
125+
<li key={`${group.id}-${item.name}`}>
126+
{item.href ? (
127+
<a
128+
href={item.href}
129+
className="flex items-center justify-between bg-neu-0/40 px-4 py-3 text-neu-900 transition-colors hover:bg-neu-0 hover:duration-0"
130+
>
131+
{item.name}
132+
</a>
133+
) : (
134+
<span className="flex items-center justify-between bg-neu-50 px-4 py-3 text-neu-900">
135+
{item.name}
140136
</span>
141-
</a>
142-
) : (
143-
<span className="flex items-center justify-between px-4 py-3 text-neu-900">
144-
<span>{item.name}</span>
145-
</span>
146-
)}
147-
</li>
148-
))}
149-
</ul>
150-
</div>
151-
))}
152-
</div>
153-
</section>
137+
)}
138+
</li>
139+
))}
140+
</ul>
141+
</div>
142+
))}
143+
</div>
144+
</section>
145+
</div>
146+
)
147+
}
148+
149+
function Stripes() {
150+
return (
151+
<div
152+
className="pointer-events-none absolute inset-x-0 top-0 h-[542px]"
153+
style={{
154+
maskImage: `url(${blurCorner.src})`,
155+
WebkitMaskImage: `url(${blurCorner.src})`,
156+
maskSize: "62% 62%",
157+
WebkitMaskSize: "62% 62%",
158+
maskPosition: "top right",
159+
WebkitMaskPosition: "top right",
160+
maskRepeat: "no-repeat",
161+
WebkitMaskRepeat: "no-repeat",
162+
}}
163+
>
164+
<StripesDecoration
165+
evenClassName="bg-[linear-gradient(90deg,hsl(var(--color-pri-lighter))_0_12px,hsl(var(--color-pri-light))_12px_24px)] dark:bg-[linear-gradient(90deg,hsl(var(--color-sec-dark)/0.22)_0_12px,hsl(var(--color-sec-base)/0.22)_12px_24px)]"
166+
oddClassName="bg-[linear-gradient(90deg,hsl(var(--color-pri-light))_0_12px,hsl(var(--color-pri-base)/0)_12px_24px)] dark:bg-[linear-gradient(90deg,hsl(var(--color-sec-base)/0.14)_0_12px,hsl(var(--color-sec-light)/0.14)_12px_24px)]"
167+
angle="-90deg"
168+
/>
169+
</div>
154170
)
155171
}

src/app/(main)/resources/[category]/page.tsx

Lines changed: 16 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ const sectionKindNames: Record<Kind, string> = {
2424
blog: "Blog posts",
2525
"tools-and-libraries": "Tools & Libraries",
2626
guide: "Guides",
27+
book: "Books",
28+
"blog-or-newsletter": "Blogs & Newsletters",
2729
}
2830

2931
// TODO: I'd prefer to have this in JSX over "JSON" objects
@@ -93,23 +95,13 @@ export default async function CategoryPage({ params }: { params: PageParams }) {
9395
/>
9496
</ResourcesHero>
9597

96-
<div className="gql-container gql-section pb-16 pt-12 lg:pb-24 lg:pt-20">
97-
{grouped.length === 0 ? (
98-
<p className="typography-body-md text-neu-700">
99-
No resources available for this category yet. Check back soon.
100-
</p>
101-
) : (
102-
<div className="flex flex-col gap-12 lg:gap-16">
103-
{grouped.map(section => (
104-
<CategorySection
105-
key={section.kind}
106-
section={section}
107-
category={category}
108-
/>
109-
))}
110-
</div>
111-
)}
112-
</div>
98+
{grouped.map(section => (
99+
<CategorySection
100+
key={section.kind}
101+
section={section}
102+
category={category}
103+
/>
104+
))}
113105
</main>
114106
)
115107
}
@@ -175,7 +167,7 @@ function CategorySection({
175167
return (
176168
<section
177169
id={sectionKindNames[section.kind].toLowerCase().replace(/ /g, "-")}
178-
className="flex flex-col gap-6"
170+
className="gql-container gql-section flex flex-col gap-6"
179171
>
180172
<header className="flex items-center justify-between gap-4">
181173
<div className="flex flex-col gap-3">
@@ -192,42 +184,15 @@ function CategorySection({
192184
<ul className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
193185
{section.resources.map(resource => (
194186
<li key={resource.url}>
195-
<ResourceCard resource={resource} />
187+
<ResourceHubCard
188+
href={resource.url}
189+
title={resource.title}
190+
author={resource.author}
191+
tags={resource.tags}
192+
/>
196193
</li>
197194
))}
198195
</ul>
199196
</section>
200197
)
201198
}
202-
203-
const tagColors: Partial<Record<Topic, string>> = {
204-
frontend: "hsl(var(--color-pri-base))",
205-
backend: "hsl(var(--color-sec-base))",
206-
federation: "hsl(var(--color-ter-base))",
207-
"schema-design": "hsl(var(--color-qua-base))",
208-
"api-platform-and-gateways": "hsl(var(--color-qui-base))",
209-
"developer-experience": "hsl(var(--color-sen-base))",
210-
security: "hsl(var(--color-oct-base))",
211-
ai: "hsl(var(--color-non-base))",
212-
monitoring: "hsl(var(--color-dec-base))",
213-
tools: "hsl(var(--color-ele-base))",
214-
}
215-
216-
function ResourceCard({ resource }: { resource: ResourceMetadata }) {
217-
218-
const tags = resource.tags
219-
.map(tag => ({
220-
label: tag,
221-
color: "hsl(var(--color-neu-500))",
222-
}))
223-
.filter(tag => tag.label !== "video")
224-
225-
return (
226-
<ResourceHubCard
227-
href={resource.url}
228-
title={resource.title}
229-
author={resource.author}
230-
tags={tags}
231-
/>
232-
)
233-
}

src/app/(main)/resources/reading-resources-section.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,15 @@ export function ReadingResourcesSection() {
4949
)
5050
}
5151

52-
interface ReadingLinkProps {
52+
function ReadingLink({
53+
href,
54+
icon,
55+
label,
56+
}: {
5357
href: string
5458
icon: React.ReactNode
5559
label: string
56-
}
57-
58-
function ReadingLink({ href, icon, label }: ReadingLinkProps) {
60+
}) {
5961
return (
6062
<Link
6163
href={href}

src/app/(main)/resources/reading/reading-page.tsx

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { clsx } from "clsx"
66

77
import { ResourcesHero } from "../resources-hero"
88
import { Eyebrow } from "@/_design-system/eyebrow"
9-
import { ResourceHubCard } from "../resource-hub-card"
9+
import { ReadingResourcesCard } from "./reading-resources-card"
1010
import { readResources } from "@/resources/data"
1111
import { topics, type ResourceMetadata, type Topic } from "@/resources/types"
1212

@@ -118,13 +118,6 @@ function uniqueByTitle(resources: ResourceMetadata[]) {
118118
})
119119
}
120120

121-
function formatTags(resource: ResourceMetadata) {
122-
return resource.tags.map(tag => ({
123-
label: tag,
124-
color: "hsl(var(--color-neu-500))",
125-
}))
126-
}
127-
128121
export async function ReadingLibraryPage({ variant }: { variant: Variant }) {
129122
const config = variants[variant]
130123
if (!config) return notFound()
@@ -197,12 +190,7 @@ export async function ReadingLibraryPage({ variant }: { variant: Variant }) {
197190
<ul className="mt-10 grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
198191
{filtered.map(resource => (
199192
<li key={resource.url}>
200-
<ResourceHubCard
201-
href={resource.url}
202-
title={resource.title}
203-
author={resource.author}
204-
tags={formatTags(resource)}
205-
/>
193+
<ReadingResourcesCard resource={resource} />
206194
</li>
207195
))}
208196
</ul>

0 commit comments

Comments
 (0)