From 0a13822234b385ed0e298b2498668c6eac1392e2 Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Thu, 9 Jan 2025 15:31:59 +0100 Subject: [PATCH 1/5] ccip overview card --- src/assets/role-icons/concepts-icon.svg | 7 + src/assets/role-icons/dapp-dev-icon.svg | 4 + src/assets/role-icons/frontend-dev-icon.svg | 4 + src/assets/role-icons/index.ts | 15 ++ src/assets/role-icons/quickstart-icon.svg | 5 + src/assets/role-icons/reference-icon.svg | 5 + src/assets/role-icons/token-dev-icon.svg | 5 + src/config/roles/ccip.ts | 107 +++++++++ src/config/roles/getRolesByProduct.ts | 7 + src/config/roles/types.ts | 20 ++ src/config/sidebar.ts | 4 + src/content/ccip/{index.mdx => about.mdx} | 3 +- .../landing/components/RoleCardGeneric.tsx | 54 +++++ .../landing/components/RoleCards.module.css | 208 ++++++++++++++++++ .../components/RoleCardsGeneric.module.css | 21 ++ .../landing/components/RoleCardsGeneric.tsx | 22 ++ src/layouts/DocsLayout.astro | 16 +- src/pages/ccip/index.astro | 39 +++- src/types/svg.d.ts | 4 + tsconfig.json | 3 +- 20 files changed, 541 insertions(+), 12 deletions(-) create mode 100644 src/assets/role-icons/concepts-icon.svg create mode 100644 src/assets/role-icons/dapp-dev-icon.svg create mode 100644 src/assets/role-icons/frontend-dev-icon.svg create mode 100644 src/assets/role-icons/index.ts create mode 100644 src/assets/role-icons/quickstart-icon.svg create mode 100644 src/assets/role-icons/reference-icon.svg create mode 100644 src/assets/role-icons/token-dev-icon.svg create mode 100644 src/config/roles/ccip.ts create mode 100644 src/config/roles/getRolesByProduct.ts create mode 100644 src/config/roles/types.ts rename src/content/ccip/{index.mdx => about.mdx} (96%) create mode 100644 src/features/landing/components/RoleCardGeneric.tsx create mode 100644 src/features/landing/components/RoleCards.module.css create mode 100644 src/features/landing/components/RoleCardsGeneric.module.css create mode 100644 src/features/landing/components/RoleCardsGeneric.tsx create mode 100644 src/types/svg.d.ts diff --git a/src/assets/role-icons/concepts-icon.svg b/src/assets/role-icons/concepts-icon.svg new file mode 100644 index 00000000000..8131ed57bbd --- /dev/null +++ b/src/assets/role-icons/concepts-icon.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/assets/role-icons/dapp-dev-icon.svg b/src/assets/role-icons/dapp-dev-icon.svg new file mode 100644 index 00000000000..f625e0b8365 --- /dev/null +++ b/src/assets/role-icons/dapp-dev-icon.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/assets/role-icons/frontend-dev-icon.svg b/src/assets/role-icons/frontend-dev-icon.svg new file mode 100644 index 00000000000..9453c0670e1 --- /dev/null +++ b/src/assets/role-icons/frontend-dev-icon.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/assets/role-icons/index.ts b/src/assets/role-icons/index.ts new file mode 100644 index 00000000000..17473a7bf2d --- /dev/null +++ b/src/assets/role-icons/index.ts @@ -0,0 +1,15 @@ +import conceptsIcon from "./concepts-icon.svg" +import dappDevIcon from "./dapp-dev-icon.svg" +import tokenDevIcon from "./token-dev-icon.svg" +import referenceIcon from "./reference-icon.svg" +import quickstartIcon from "./quickstart-icon.svg" +import frontendDevIcon from "./frontend-dev-icon.svg" + +export const roleIconMap: Record = { + concepts: conceptsIcon.src, + dappDev: dappDevIcon.src, + tokenDev: tokenDevIcon.src, + reference: referenceIcon.src, + quickstart: quickstartIcon.src, + frontendDev: frontendDevIcon.src, +} diff --git a/src/assets/role-icons/quickstart-icon.svg b/src/assets/role-icons/quickstart-icon.svg new file mode 100644 index 00000000000..2ed9327d1c7 --- /dev/null +++ b/src/assets/role-icons/quickstart-icon.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/assets/role-icons/reference-icon.svg b/src/assets/role-icons/reference-icon.svg new file mode 100644 index 00000000000..c2e9082f4ea --- /dev/null +++ b/src/assets/role-icons/reference-icon.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/assets/role-icons/token-dev-icon.svg b/src/assets/role-icons/token-dev-icon.svg new file mode 100644 index 00000000000..7550b1697cb --- /dev/null +++ b/src/assets/role-icons/token-dev-icon.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/config/roles/ccip.ts b/src/config/roles/ccip.ts new file mode 100644 index 00000000000..ae4dd67fe66 --- /dev/null +++ b/src/config/roles/ccip.ts @@ -0,0 +1,107 @@ +import type { ProductRoles } from "./types" + +export const ccipRoles: ProductRoles = { + productId: "ccip", + roles: [ + { + id: "overview", + title: "Concepts", + description: "Learn about CCIP and its core concepts", + iconType: "concepts", + links: [ + { type: "overview", title: "About CCIP", url: "/ccip/about" }, + { type: "concept", title: "Core Concepts", url: "/ccip/concepts" }, + { type: "concept", title: "Architecture", url: "/ccip/architecture" }, + { type: "concept", title: "Execution Latency", url: "/ccip/concepts/ccip-execution-latency" }, + { type: "concept", title: "Cross-Chain Tokens", url: "/ccip/concepts/cross-chain-tokens" }, + { type: "concept", title: "Manual Execution", url: "/ccip/concepts/manual-execution" }, + { type: "concept", title: "Billing", url: "/ccip/billing" }, + ], + }, + { + id: "getting-started", + title: "Get Started", + description: "Start building with CCIP", + iconType: "quickstart", + links: [ + { type: "get-started", title: "Getting Started Guide", url: "/ccip/getting-started" }, + { type: "guide", title: "Acquire Test Tokens", url: "/ccip/test-tokens" }, + { type: "guide", title: "Transfer Tokens from Contract", url: "/ccip/tutorials/transfer-tokens-from-contract" }, + { type: "guide", title: "Transfer Tokens (EOA)", url: "/ccip/tutorials/transfer-tokens-from-eoa" }, + { type: "guide", title: "Send Arbitrary Data", url: "/ccip/tutorials/send-arbitrary-data" }, + ], + }, + { + id: "token-dev", + title: "You are a Token Developer", + description: "Leverage the Cross-Chain Token (CCT) Standard to register and manage tokens on CCIP", + iconType: "tokenDev", + links: [ + { type: "concept", title: "Understanding Cross-Chain Tokens", url: "/ccip/concepts/cross-chain-tokens" }, + { type: "reference", title: "CCIP Directory", url: "/ccip/directory" }, + { type: "reference", title: "Service Responsibility", url: "/ccip/service-responsibility" }, + { type: "reference", title: "API Reference", url: "/ccip/api-reference" }, + { type: "reference", title: "Best Practices", url: "/ccip/best-practices" }, + { + type: "guide", + title: "Cross-Chain Token (CCT) guides", + url: "/ccip/tutorials/cross-chain-tokens", + }, + { type: "guide", title: "Transfer Tokens from Contract", url: "/ccip/tutorials/transfer-tokens-from-contract" }, + { type: "guide", title: "Transfer Tokens (EOA)", url: "/ccip/tutorials/transfer-tokens-from-eoa" }, + ], + }, + { + id: "dapp-dev", + title: "You are a dApp Developer", + description: "Build cross-chain applications with CCIP", + iconType: "dappDev", + links: [ + { type: "concept", title: "Manual Execution", url: "/ccip/concepts/manual-execution" }, + { type: "reference", title: "CCIP Directory", url: "/ccip/directory" }, + { type: "reference", title: "Service Responsibility", url: "/ccip/service-responsibility" }, + { type: "reference", title: "API Reference", url: "/ccip/api-reference" }, + { type: "reference", title: "Best Practices", url: "/ccip/best-practices" }, + { type: "guide", title: "Test CCIP Locally", url: "/ccip/tutorials/test-ccip-locally" }, + { type: "guide", title: "Transfer Tokens with Data", url: "/ccip/tutorials/programmable-token-transfers" }, + { + type: "guide", + title: "Transfer Tokens with Data (Defensive Programming)", + url: "/ccip/tutorials/programmable-token-transfers-defensive", + }, + { type: "guide", title: "Handle Receipts", url: "/ccip/tutorials/send-arbitrary-data-receipt-acknowledgment" }, + { type: "guide", title: "USDC Transfers", url: "/ccip/tutorials/usdc" }, + { type: "guide", title: "Manual Execution", url: "/ccip/tutorials/manual-execution" }, + { type: "guide", title: "Gas Limit Configuration", url: "/ccip/tutorials/ccipreceive-gaslimit" }, + ], + }, + { + id: "frontend-dev", + title: "You are a Frontend Developer", + description: "Build frontend applications that interact with CCIP", + iconType: "frontendDev", + links: [ + { type: "guide", title: "JavaScript SDK", url: "/ccip/ccip-javascript-sdk" }, + { type: "guide", title: "Off-chain Guides", url: "/ccip/tutorials/offchain" }, + { type: "reference", title: "API Reference", url: "/ccip/api-reference" }, + { type: "reference", title: "CCIP Directory", url: "/ccip/directory" }, + { type: "reference", title: "Best Practices", url: "/ccip/best-practices" }, + ], + }, + { + id: "reference", + title: "Reference", + description: "API documentation and technical details", + iconType: "reference", + links: [ + { type: "reference", title: "API Reference", url: "/ccip/api-reference" }, + { type: "guide", title: "JavaScript SDK", url: "/ccip/ccip-javascript-sdk" }, + { type: "reference", title: "CCIP Directory", url: "/ccip/directory" }, + { type: "reference", title: "Service Limits", url: "/ccip/service-limits" }, + { type: "reference", title: "Billing", url: "/ccip/billing" }, + { type: "reference", title: "Service Responsibility", url: "/ccip/service-responsibility" }, + { type: "reference", title: "Release Notes", url: "/ccip/release-notes" }, + ], + }, + ], +} diff --git a/src/config/roles/getRolesByProduct.ts b/src/config/roles/getRolesByProduct.ts new file mode 100644 index 00000000000..36ac249eb66 --- /dev/null +++ b/src/config/roles/getRolesByProduct.ts @@ -0,0 +1,7 @@ +import type { ProductRoles } from "./types" +import { ccipRoles } from "./ccip" + +export const PRODUCT_CONFIGS: Record = { + ccip: ccipRoles, + // Add other products here when they're ready for the role-based layout +} diff --git a/src/config/roles/types.ts b/src/config/roles/types.ts new file mode 100644 index 00000000000..8b318a6c302 --- /dev/null +++ b/src/config/roles/types.ts @@ -0,0 +1,20 @@ +export type LinkType = "overview" | "concept" | "get-started" | "guide" | "reference" + +export interface RoleLink { + type: LinkType + title: string + url: string +} + +export interface RoleConfig { + id: string + title: string + description: string + iconType: string + links: RoleLink[] +} + +export interface ProductRoles { + productId: string + roles: RoleConfig[] +} diff --git a/src/config/sidebar.ts b/src/config/sidebar.ts index 6b0a13ed1ac..0da19585e70 100644 --- a/src/config/sidebar.ts +++ b/src/config/sidebar.ts @@ -971,6 +971,10 @@ export const SIDEBAR: Partial> = { title: "Overview", url: "ccip", }, + { + title: "About CCIP", + url: "ccip/about", + }, { title: "Getting Started", url: "ccip/getting-started", diff --git a/src/content/ccip/index.mdx b/src/content/ccip/about.mdx similarity index 96% rename from src/content/ccip/index.mdx rename to src/content/ccip/about.mdx index 65bcfb9be31..cee7d7bd56f 100644 --- a/src/content/ccip/index.mdx +++ b/src/content/ccip/about.mdx @@ -2,7 +2,8 @@ section: ccip date: Last Modified title: "Chainlink CCIP" -isIndex: true +metadata: + description: "Chainlink CCIP is a secure blockchain interoperability protocol enabling cross-chain token transfers and messaging. Built with defense-in-depth security, it powers Web3 applications across multiple networks with industry-leading oracle infrastructure." whatsnext: { "Complete the Getting Started guide to learn the basics": "/ccip/getting-started", diff --git a/src/features/landing/components/RoleCardGeneric.tsx b/src/features/landing/components/RoleCardGeneric.tsx new file mode 100644 index 00000000000..9ed8e8a9d1a --- /dev/null +++ b/src/features/landing/components/RoleCardGeneric.tsx @@ -0,0 +1,54 @@ +import React from "react" +import type { RoleConfig } from "@config/roles/types" +import { roleIconMap } from "@assets/role-icons" +import styles from "./RoleCards.module.css" + +interface RoleCardGenericProps { + role: RoleConfig +} + +export const RoleCardGeneric = ({ role }: RoleCardGenericProps) => { + const { title, description, iconType, links } = role + + const groupedLinks = links.reduce((acc, link) => { + if (!acc[link.type]) { + acc[link.type] = [] + } + acc[link.type].push(link) + return acc + }, {} as Record) + + return ( +
+
+
+
+ {iconType && ( + + )} +
+

{title}

+
+ +

{description}

+ + +
+
+ ) +} diff --git a/src/features/landing/components/RoleCards.module.css b/src/features/landing/components/RoleCards.module.css new file mode 100644 index 00000000000..164010a6a48 --- /dev/null +++ b/src/features/landing/components/RoleCards.module.css @@ -0,0 +1,208 @@ +.rolesSection { + width: 100%; + max-width: var(--doc-content-width); + margin: 0 auto; + padding: var(--space-6x) var(--space-4x); +} + +.rolesContainer { + margin: 0 auto; + width: 100%; +} + +.cardGrid { + display: grid; + gap: var(--space-6x); + grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); + max-width: 1200px; + margin: 0 auto; + align-items: stretch; +} + +.card { + position: relative; + border-radius: 12px; + background: var(--color-background); + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + height: 100%; + border: 1px solid var(--Card-Border, #e4e8ed); + background-color: var(--color-background, #ffffff); +} + +.card:hover, +.card:focus-within { + transform: translateY(-2px); + box-shadow: 0 8px 12px rgba(26, 43, 107, 0.1); + background: var(--Blue-Blue-50, #eff6ff); +} + +.card:focus-within { + outline: 2px solid var(--color-primary); + outline-offset: 2px; +} + +.cardInner { + padding: var(--space-6x); + height: 100%; + display: flex; + flex-direction: column; + gap: var(--space-4x); +} + +.cardHeader { + display: flex; + align-items: flex-start; + gap: var(--space-4x); +} + +.iconWrapper { + flex-shrink: 0; + padding: var(--space-2x); + border-radius: 8px; + background: var(--color-background-secondary); + transition: transform 0.2s ease; +} + +.card:hover .iconWrapper { + transform: scale(1.05); +} + +.cardIcon { + width: var(--space-8x); + height: var(--space-8x); + display: block; +} + +.cardTitle { + font-size: var(--font-size-xl); + font-weight: 600; + color: var(--color-text-heading); + margin: 0; + line-height: 1.2; +} + +.cardDescription { + color: var(--color-text-secondary); + font-size: var(--font-size-base); + line-height: 1.6; + margin: 0; +} + +.linkGroups { + display: flex; + flex-direction: column; + gap: var(--space-6x); + margin-top: auto; +} + +.linkGroup { + display: flex; + flex-direction: column; + gap: var(--space-3x); +} + +.linkGroupTitle { + font-size: var(--font-size-sm); + font-weight: 600; + color: var(--color-text-secondary); + text-transform: capitalize; + margin: 0; + letter-spacing: 0.5px; +} + +.linkList { + list-style: none; + padding: 0; + margin: 0; + display: flex; + flex-direction: column; + gap: var(--space-2x); +} + +.link { + color: var(--blue-500); + text-decoration: none; + font-size: var(--font-size-base); + line-height: 1.4; + transition: all 0.2s ease; + display: inline-flex; + align-items: center; + padding: var(--space-1x) 0; + position: relative; + font-weight: 500; +} + +.linkText { + position: relative; +} + +.linkText::after { + content: ""; + position: absolute; + bottom: -2px; + left: 0; + width: 100%; + height: 1px; + background: currentColor; + transform: scaleX(0); + transform-origin: right; + transition: transform 0.3s ease; +} + +.link:hover .linkText::after, +.link:focus .linkText::after { + transform: scaleX(1); + transform-origin: left; +} + +.link:hover { + color: var(--blue-600); + text-decoration: underline; +} + +/* Responsive adjustments */ +@media (max-width: 1200px) { + .cardGrid { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (max-width: 768px) { + .rolesSection { + padding: var(--space-4x) var(--space-2x); + } + + .cardGrid { + grid-template-columns: 1fr; + gap: var(--space-4x); + } + + .cardInner { + padding: var(--space-4x); + } + + .cardTitle { + font-size: var(--font-size-lg); + } +} + +/* High contrast mode */ +@media (forced-colors: active) { + .card { + border: 2px solid CanvasText; + } + + .link:focus { + outline: 2px solid CanvasText; + } +} + +/* Reduced motion */ +@media (prefers-reduced-motion: reduce) { + .card, + .iconWrapper, + .link, + .linkText::after { + transition: none; + } +} diff --git a/src/features/landing/components/RoleCardsGeneric.module.css b/src/features/landing/components/RoleCardsGeneric.module.css new file mode 100644 index 00000000000..75dd5fd0dca --- /dev/null +++ b/src/features/landing/components/RoleCardsGeneric.module.css @@ -0,0 +1,21 @@ +.cardGrid { + display: grid; + gap: var(--space-6x); + width: 100%; +} + +/* Single column by default */ +@media (min-width: 640px) { + .cardGrid { + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: var(--space-4x); + } +} + +/* Two columns when there's enough space */ +@media (min-width: 1024px) { + .cardGrid { + grid-template-columns: repeat(2, 1fr); + gap: var(--space-6x); + } +} diff --git a/src/features/landing/components/RoleCardsGeneric.tsx b/src/features/landing/components/RoleCardsGeneric.tsx new file mode 100644 index 00000000000..07a6a92b294 --- /dev/null +++ b/src/features/landing/components/RoleCardsGeneric.tsx @@ -0,0 +1,22 @@ +import React from "react" +import type { RoleConfig } from "@config/roles/types" +import { RoleCardGeneric } from "./RoleCardGeneric" +import styles from "./RoleCards.module.css" + +interface RoleCardsGenericProps { + roles: RoleConfig[] +} + +export const RoleCardsGeneric = ({ roles }: RoleCardsGenericProps) => { + return ( +
+
+
+ {roles.map((role) => ( + + ))} +
+
+
+ ) +} diff --git a/src/layouts/DocsLayout.astro b/src/layouts/DocsLayout.astro index 3d119222496..94b7e2896f5 100644 --- a/src/layouts/DocsLayout.astro +++ b/src/layouts/DocsLayout.astro @@ -15,8 +15,10 @@ import { detectApiReference } from "@components/VersionSelector/utils/versions" interface Props { frontmatter: BaseFrontmatter headings?: MarkdownHeading[] + hideRightSidebar?: boolean + hideWhatsNext?: boolean } -const { frontmatter, headings } = Astro.props +const { frontmatter, headings, hideRightSidebar, hideWhatsNext } = Astro.props const titleHeading: MarkdownHeading = { text: frontmatter.title, @@ -62,11 +64,15 @@ const { isApiReference, product, isVersioned } = detectApiReference(currentPage) - {whatsNext && } + {whatsNext && !hideWhatsNext && } - + { + !hideRightSidebar && ( + + ) + } diff --git a/src/pages/ccip/index.astro b/src/pages/ccip/index.astro index 12f32f78397..b9395aadff8 100644 --- a/src/pages/ccip/index.astro +++ b/src/pages/ccip/index.astro @@ -1,10 +1,39 @@ --- import DocsLayout from "~/layouts/DocsLayout.astro" -import { getEntry } from "astro:content" -const entry = await getEntry("ccip", "index") -const { Content, headings } = await entry.render() +import { RoleCardsGeneric } from "~/features/landing/components/RoleCardsGeneric" +import { PRODUCT_CONFIGS } from "~/config/roles/getRolesByProduct" +import type { BaseFrontmatter } from "~/content/config" + +// Define frontmatter that was previously in index.mdx +const frontmatter: BaseFrontmatter = { + title: "Chainlink CCIP Documentation", + section: "ccip" as const, + metadata: { + description: + "Learn how to build cross-chain applications with Chainlink CCIP. Transfer tokens and/or data between blockchain networks securely and reliably.", + }, + isIndex: true, +} + +// Create headings array starting with the main title +const titleHeading = { + text: frontmatter.title, + slug: "overview", + depth: 1, +} + +const headings = [titleHeading] + +const productRoles = PRODUCT_CONFIGS.ccip --- - - + + {productRoles && } + + diff --git a/src/types/svg.d.ts b/src/types/svg.d.ts new file mode 100644 index 00000000000..aa39b450408 --- /dev/null +++ b/src/types/svg.d.ts @@ -0,0 +1,4 @@ +declare module "*.svg" { + const content: string + export default content +} diff --git a/tsconfig.json b/tsconfig.json index ef11db7bc8d..3f0b9029ae9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -30,7 +30,8 @@ "@utils": ["src/utils/"], "@utils/*": ["src/utils/*"], "@variables": ["src/config/markdown-variables.ts"], - "@abi": ["src/features/abi/index.ts"] + "@abi": ["src/features/abi/index.ts"], + "@assets/role-icons": ["src/assets/role-icons/index"] }, "strictNullChecks": true, "verbatimModuleSyntax": false From 0e8107113e6073b1d50ff049985a8589af21203d Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Thu, 9 Jan 2025 15:42:16 +0100 Subject: [PATCH 2/5] update --- .../landing/components/RoleCards.module.css | 45 ++++++++++++------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/src/features/landing/components/RoleCards.module.css b/src/features/landing/components/RoleCards.module.css index 164010a6a48..28b46dff843 100644 --- a/src/features/landing/components/RoleCards.module.css +++ b/src/features/landing/components/RoleCards.module.css @@ -16,42 +16,40 @@ grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); max-width: 1200px; margin: 0 auto; - align-items: stretch; + align-items: start; } .card { position: relative; border-radius: 12px; background: var(--color-background); - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); - height: 100%; + transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); + height: 520px; border: 1px solid var(--Card-Border, #e4e8ed); background-color: var(--color-background, #ffffff); + display: flex; } -.card:hover, -.card:focus-within { +.card:hover { transform: translateY(-2px); box-shadow: 0 8px 12px rgba(26, 43, 107, 0.1); background: var(--Blue-Blue-50, #eff6ff); } -.card:focus-within { - outline: 2px solid var(--color-primary); - outline-offset: 2px; -} - .cardInner { padding: var(--space-6x); - height: 100%; display: flex; flex-direction: column; - gap: var(--space-4x); + gap: var(--space-3x); + flex: 1; + width: 100%; + display: grid; + grid-template-rows: auto auto 1fr; } .cardHeader { display: flex; - align-items: flex-start; + align-items: center; gap: var(--space-4x); } @@ -61,6 +59,9 @@ border-radius: 8px; background: var(--color-background-secondary); transition: transform 0.2s ease; + display: flex; + align-items: center; + justify-content: center; } .card:hover .iconWrapper { @@ -70,7 +71,7 @@ .cardIcon { width: var(--space-8x); height: var(--space-8x); - display: block; + display: flex; } .cardTitle { @@ -79,6 +80,8 @@ color: var(--color-text-heading); margin: 0; line-height: 1.2; + display: flex; + align-items: center; } .cardDescription { @@ -86,19 +89,29 @@ font-size: var(--font-size-base); line-height: 1.6; margin: 0; + height: 4.8em; + overflow: hidden; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + text-overflow: ellipsis; } .linkGroups { display: flex; flex-direction: column; gap: var(--space-6x); - margin-top: auto; + margin-top: var(--space-6x); + overflow-y: auto; + @media (prefers-reduced-motion: no-preference) { + scroll-behavior: smooth; + } } .linkGroup { display: flex; flex-direction: column; - gap: var(--space-3x); + gap: var(--space-2x); } .linkGroupTitle { From 936dcc3b902b7ca90454cc9cc54b597fa9df4b69 Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Thu, 9 Jan 2025 15:55:09 +0100 Subject: [PATCH 3/5] update --- src/assets/role-icons/concepts-icon.svg | 8 ++--- src/assets/role-icons/dapp-dev-icon.svg | 4 ++- src/assets/role-icons/frontend-dev-icon.svg | 7 ++-- src/assets/role-icons/quickstart-icon.svg | 4 +-- src/assets/role-icons/reference-icon.svg | 6 ++-- src/assets/role-icons/token-dev-icon.svg | 39 +++++++++++++++++++-- 6 files changed, 53 insertions(+), 15 deletions(-) diff --git a/src/assets/role-icons/concepts-icon.svg b/src/assets/role-icons/concepts-icon.svg index 8131ed57bbd..5c6ed39319a 100644 --- a/src/assets/role-icons/concepts-icon.svg +++ b/src/assets/role-icons/concepts-icon.svg @@ -1,7 +1,7 @@ - - - - + + + + \ No newline at end of file diff --git a/src/assets/role-icons/dapp-dev-icon.svg b/src/assets/role-icons/dapp-dev-icon.svg index f625e0b8365..04dd64c232d 100644 --- a/src/assets/role-icons/dapp-dev-icon.svg +++ b/src/assets/role-icons/dapp-dev-icon.svg @@ -1,4 +1,6 @@ - + + + \ No newline at end of file diff --git a/src/assets/role-icons/frontend-dev-icon.svg b/src/assets/role-icons/frontend-dev-icon.svg index 9453c0670e1..39b17f4364f 100644 --- a/src/assets/role-icons/frontend-dev-icon.svg +++ b/src/assets/role-icons/frontend-dev-icon.svg @@ -1,4 +1,7 @@ + - - + + + + \ No newline at end of file diff --git a/src/assets/role-icons/quickstart-icon.svg b/src/assets/role-icons/quickstart-icon.svg index 2ed9327d1c7..6ee9745e22c 100644 --- a/src/assets/role-icons/quickstart-icon.svg +++ b/src/assets/role-icons/quickstart-icon.svg @@ -1,5 +1,5 @@ - - + + \ No newline at end of file diff --git a/src/assets/role-icons/reference-icon.svg b/src/assets/role-icons/reference-icon.svg index c2e9082f4ea..107c33cb1f9 100644 --- a/src/assets/role-icons/reference-icon.svg +++ b/src/assets/role-icons/reference-icon.svg @@ -1,5 +1,5 @@ - - - + + + \ No newline at end of file diff --git a/src/assets/role-icons/token-dev-icon.svg b/src/assets/role-icons/token-dev-icon.svg index 7550b1697cb..04e8230c835 100644 --- a/src/assets/role-icons/token-dev-icon.svg +++ b/src/assets/role-icons/token-dev-icon.svg @@ -1,5 +1,38 @@ - - - + + + + + + + + + + + + \ No newline at end of file From 3f60ec3ea90bbb273478fafb537eb50117e8f5a3 Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Thu, 9 Jan 2025 16:03:52 +0100 Subject: [PATCH 4/5] update --- src/assets/role-icons/token-dev-icon.svg | 3 +++ src/config/roles/ccip.ts | 23 +++++++++------- .../landing/components/RoleCardGeneric.tsx | 6 +++-- .../landing/components/RoleCards.module.css | 27 ++++++++++++++++++- .../landing/components/RoleCardsGeneric.tsx | 2 +- 5 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/assets/role-icons/token-dev-icon.svg b/src/assets/role-icons/token-dev-icon.svg index 04e8230c835..6a79aa8abfe 100644 --- a/src/assets/role-icons/token-dev-icon.svg +++ b/src/assets/role-icons/token-dev-icon.svg @@ -1,5 +1,7 @@ + + + \ No newline at end of file diff --git a/src/config/roles/ccip.ts b/src/config/roles/ccip.ts index ae4dd67fe66..657a26a5599 100644 --- a/src/config/roles/ccip.ts +++ b/src/config/roles/ccip.ts @@ -29,6 +29,8 @@ export const ccipRoles: ProductRoles = { { type: "guide", title: "Transfer Tokens from Contract", url: "/ccip/tutorials/transfer-tokens-from-contract" }, { type: "guide", title: "Transfer Tokens (EOA)", url: "/ccip/tutorials/transfer-tokens-from-eoa" }, { type: "guide", title: "Send Arbitrary Data", url: "/ccip/tutorials/send-arbitrary-data" }, + { type: "reference", title: "CCIP Directory", url: "/ccip/directory" }, + { type: "reference", title: "CCIP Explorer", url: "https://ccip.chain.link" }, ], }, { @@ -38,10 +40,6 @@ export const ccipRoles: ProductRoles = { iconType: "tokenDev", links: [ { type: "concept", title: "Understanding Cross-Chain Tokens", url: "/ccip/concepts/cross-chain-tokens" }, - { type: "reference", title: "CCIP Directory", url: "/ccip/directory" }, - { type: "reference", title: "Service Responsibility", url: "/ccip/service-responsibility" }, - { type: "reference", title: "API Reference", url: "/ccip/api-reference" }, - { type: "reference", title: "Best Practices", url: "/ccip/best-practices" }, { type: "guide", title: "Cross-Chain Token (CCT) guides", @@ -49,6 +47,10 @@ export const ccipRoles: ProductRoles = { }, { type: "guide", title: "Transfer Tokens from Contract", url: "/ccip/tutorials/transfer-tokens-from-contract" }, { type: "guide", title: "Transfer Tokens (EOA)", url: "/ccip/tutorials/transfer-tokens-from-eoa" }, + { type: "reference", title: "CCIP Directory", url: "/ccip/directory" }, + { type: "reference", title: "Service Responsibility", url: "/ccip/service-responsibility" }, + { type: "reference", title: "API Reference", url: "/ccip/api-reference" }, + { type: "reference", title: "Best Practices", url: "/ccip/best-practices" }, ], }, { @@ -58,10 +60,6 @@ export const ccipRoles: ProductRoles = { iconType: "dappDev", links: [ { type: "concept", title: "Manual Execution", url: "/ccip/concepts/manual-execution" }, - { type: "reference", title: "CCIP Directory", url: "/ccip/directory" }, - { type: "reference", title: "Service Responsibility", url: "/ccip/service-responsibility" }, - { type: "reference", title: "API Reference", url: "/ccip/api-reference" }, - { type: "reference", title: "Best Practices", url: "/ccip/best-practices" }, { type: "guide", title: "Test CCIP Locally", url: "/ccip/tutorials/test-ccip-locally" }, { type: "guide", title: "Transfer Tokens with Data", url: "/ccip/tutorials/programmable-token-transfers" }, { @@ -73,6 +71,11 @@ export const ccipRoles: ProductRoles = { { type: "guide", title: "USDC Transfers", url: "/ccip/tutorials/usdc" }, { type: "guide", title: "Manual Execution", url: "/ccip/tutorials/manual-execution" }, { type: "guide", title: "Gas Limit Configuration", url: "/ccip/tutorials/ccipreceive-gaslimit" }, + { type: "reference", title: "CCIP Directory", url: "/ccip/directory" }, + { type: "reference", title: "CCIP Explorer", url: "https://ccip.chain.link" }, + { type: "reference", title: "Service Responsibility", url: "/ccip/service-responsibility" }, + { type: "reference", title: "API Reference", url: "/ccip/api-reference" }, + { type: "reference", title: "Best Practices", url: "/ccip/best-practices" }, ], }, { @@ -84,6 +87,7 @@ export const ccipRoles: ProductRoles = { { type: "guide", title: "JavaScript SDK", url: "/ccip/ccip-javascript-sdk" }, { type: "guide", title: "Off-chain Guides", url: "/ccip/tutorials/offchain" }, { type: "reference", title: "API Reference", url: "/ccip/api-reference" }, + { type: "reference", title: "CCIP Explorer", url: "https://ccip.chain.link" }, { type: "reference", title: "CCIP Directory", url: "/ccip/directory" }, { type: "reference", title: "Best Practices", url: "/ccip/best-practices" }, ], @@ -94,9 +98,10 @@ export const ccipRoles: ProductRoles = { description: "API documentation and technical details", iconType: "reference", links: [ - { type: "reference", title: "API Reference", url: "/ccip/api-reference" }, { type: "guide", title: "JavaScript SDK", url: "/ccip/ccip-javascript-sdk" }, + { type: "reference", title: "API Reference", url: "/ccip/api-reference" }, { type: "reference", title: "CCIP Directory", url: "/ccip/directory" }, + { type: "reference", title: "CCIP Explorer", url: "https://ccip.chain.link" }, { type: "reference", title: "Service Limits", url: "/ccip/service-limits" }, { type: "reference", title: "Billing", url: "/ccip/billing" }, { type: "reference", title: "Service Responsibility", url: "/ccip/service-responsibility" }, diff --git a/src/features/landing/components/RoleCardGeneric.tsx b/src/features/landing/components/RoleCardGeneric.tsx index 9ed8e8a9d1a..14f55c4a8fe 100644 --- a/src/features/landing/components/RoleCardGeneric.tsx +++ b/src/features/landing/components/RoleCardGeneric.tsx @@ -19,7 +19,7 @@ export const RoleCardGeneric = ({ role }: RoleCardGenericProps) => { }, {} as Record) return ( -
+
@@ -27,7 +27,9 @@ export const RoleCardGeneric = ({ role }: RoleCardGenericProps) => { )}
-

{title}

+

+ {title} +

{description}

diff --git a/src/features/landing/components/RoleCards.module.css b/src/features/landing/components/RoleCards.module.css index 28b46dff843..609b161b2ea 100644 --- a/src/features/landing/components/RoleCards.module.css +++ b/src/features/landing/components/RoleCards.module.css @@ -24,7 +24,7 @@ border-radius: 12px; background: var(--color-background); transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); - height: 520px; + height: 480px; border: 1px solid var(--Card-Border, #e4e8ed); background-color: var(--color-background, #ffffff); display: flex; @@ -62,6 +62,8 @@ display: flex; align-items: center; justify-content: center; + width: 48px; + height: 48px; } .card:hover .iconWrapper { @@ -95,6 +97,7 @@ -webkit-line-clamp: 3; -webkit-box-orient: vertical; text-overflow: ellipsis; + opacity: 0.9; } .linkGroups { @@ -103,6 +106,28 @@ gap: var(--space-6x); margin-top: var(--space-6x); overflow-y: auto; + -webkit-overflow-scrolling: touch; + /* Customize scrollbar for modern browsers */ + scrollbar-width: thin; + scrollbar-color: var(--gray-200) transparent; + + /* Webkit scrollbar styling */ + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-track { + background: transparent; + } + + &::-webkit-scrollbar-thumb { + background-color: var(--gray-200); + border-radius: 3px; + } + + &::-webkit-scrollbar-thumb:hover { + background-color: var(--gray-300); + } @media (prefers-reduced-motion: no-preference) { scroll-behavior: smooth; } diff --git a/src/features/landing/components/RoleCardsGeneric.tsx b/src/features/landing/components/RoleCardsGeneric.tsx index 07a6a92b294..72f60c098a9 100644 --- a/src/features/landing/components/RoleCardsGeneric.tsx +++ b/src/features/landing/components/RoleCardsGeneric.tsx @@ -1,4 +1,4 @@ -import React from "react" +import React, { memo } from "react" import type { RoleConfig } from "@config/roles/types" import { RoleCardGeneric } from "./RoleCardGeneric" import styles from "./RoleCards.module.css" From 0841d707f143b52a45d015c47686d09e0ed96f03 Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Thu, 9 Jan 2025 16:38:17 +0100 Subject: [PATCH 5/5] update --- src/components/CCIP/Chain/Chain.astro | 36 +++++++++++-------- .../CCIP/Landing/ccip-landing.astro | 23 +++++++++--- src/components/CCIP/Token/Token.astro | 29 ++++++++------- .../landing/components/RoleCards.module.css | 1 + .../landing/components/RoleCardsGeneric.tsx | 1 - 5 files changed, 58 insertions(+), 32 deletions(-) diff --git a/src/components/CCIP/Chain/Chain.astro b/src/components/CCIP/Chain/Chain.astro index 512ff852cc7..7c5e63a0f69 100644 --- a/src/components/CCIP/Chain/Chain.astro +++ b/src/components/CCIP/Chain/Chain.astro @@ -1,6 +1,5 @@ --- import CcipLayout from "~/layouts/CcipLayout.astro" -import { getEntry } from "astro:content" import { Environment, getAllNetworkLanes, @@ -12,14 +11,28 @@ import { import ChainHero from "~/components/CCIP/ChainHero/ChainHero" import ChainTable from "~/components/CCIP/Tables/ChainTable" import { getTokenIconUrl } from "~/features/utils" -import Drawer from "../Drawer/Drawer" import ChainTokenGrid from "./ChainTokenGrid" +import { BaseFrontmatter } from "~/content/config" + +const { environment, network } = Astro.props + +// Define frontmatter and headings directly +const frontmatter: BaseFrontmatter = { + title: `CCIP Supported Networks - ${network.name}`, + section: "ccip" as const, + metadata: { + description: `View supported tokens and lanes for ${network.name} on Chainlink CCIP.`, + }, +} + +const headings = [ + { + depth: 1, + slug: "overview", + text: frontmatter.title, + }, +] -// TODO: Add type for network -const { environment, network } = Astro.props as { environment: Environment; network: any } - -const entry = await getEntry("ccip", "index") -const { headings } = await entry.render() const networks = getAllNetworks({ filter: environment }) const allTokens = getTokensOfChain({ @@ -46,14 +59,7 @@ const lanes = await getAllNetworkLanes({ const searchLanes = getSearchLanes({ environment }) --- - + { const searchLanes = getSearchLanes({ environment }) --- - +
diff --git a/src/components/CCIP/Token/Token.astro b/src/components/CCIP/Token/Token.astro index 9cde2a10ca3..daa30944c7e 100644 --- a/src/components/CCIP/Token/Token.astro +++ b/src/components/CCIP/Token/Token.astro @@ -1,6 +1,5 @@ --- import CcipLayout from "~/layouts/CcipLayout.astro" -import { getEntry } from "astro:content" import { getAllNetworks, getAllSupportedTokens, @@ -14,12 +13,25 @@ import { import ChainHero from "~/components/CCIP/ChainHero/ChainHero" import Table from "~/components/CCIP/Tables/TokenChainsTable" import { directoryToSupportedChain, getChainIcon, getExplorer, getTitle, getTokenIconUrl } from "~/features/utils" -import Drawer from "~/components/CCIP/Drawer/Drawer" const { token, logo, environment } = Astro.props as { token: string; logo: string; environment: Environment } -const entry = await getEntry("ccip", "index") -const { headings } = await entry.render() +const frontmatter = { + title: `CCIP Supported Tokens - ${token}`, + section: "ccip" as const, + metadata: { + description: `View supported blockchains and configurations for ${token} token on Chainlink CCIP.`, + }, +} + +const headings = [ + { + depth: 1, + slug: "overview", + text: frontmatter.title, + }, +] + const networks = getAllNetworks({ filter: environment }) const supportedTokens = getAllSupportedTokens({ @@ -56,14 +68,7 @@ const tokenLanes = getAllTokenLanes({ const searchLanes = getSearchLanes({ environment }) --- - +