diff --git a/src/components/Callout.astro b/src/components/Callout.astro index aff84f81e..b48dfb414 100644 --- a/src/components/Callout.astro +++ b/src/components/Callout.astro @@ -58,6 +58,12 @@ if (Astro.slots.has("default")) { --- - - - +
+ + + +
diff --git a/src/components/LeftSidebar/Navigation.astro b/src/components/LeftSidebar/Navigation.astro index 7020bade9..5ee36dd09 100644 --- a/src/components/LeftSidebar/Navigation.astro +++ b/src/components/LeftSidebar/Navigation.astro @@ -2,12 +2,12 @@ import classNames from "classnames"; import { getLanguageFromURL } from "@i18n/locales"; -import type { getNavigationEntries } from "src/utils/helpers/navigation/getNavigationEntries"; - import NavigationItem from "./NavigationItem"; +import type { NavigationData } from "src/utils/helpers/navigation/types"; + interface NavigationProps { - navigationEntries: ReturnType; + navigationEntries: NavigationData["languageTree"]; } const { navigationEntries } = Astro.props as NavigationProps; diff --git a/src/components/PageBreadcrumbs/PageBreadcrumbs.astro b/src/components/PageBreadcrumbs/PageBreadcrumbs.astro new file mode 100644 index 000000000..8a3b3d21c --- /dev/null +++ b/src/components/PageBreadcrumbs/PageBreadcrumbs.astro @@ -0,0 +1,45 @@ +--- +import classNames from "classnames"; + +import type { NavigationData } from "src/utils/helpers/navigation/types"; + +import "./breadcrumbs.css"; + +interface BreadcrumbsProps { + breadcrumbs: NavigationData["breadcrumbs"]; +} + +const { breadcrumbs } = Astro.props as BreadcrumbsProps; +const currentPage = Astro.url.pathname; +const currentPageMatch = currentPage.endsWith("/") + ? currentPage.slice(1, -1) + : currentPage.slice(1); +--- + +
+ +
diff --git a/src/components/PageBreadcrumbs/breadcrumbs.css b/src/components/PageBreadcrumbs/breadcrumbs.css new file mode 100644 index 000000000..7a7884b44 --- /dev/null +++ b/src/components/PageBreadcrumbs/breadcrumbs.css @@ -0,0 +1,8 @@ +.breadcrumbs-item::after { + content: "•"; + font-weight: 500; + position: absolute; + top: -5px; + right: -16px; + font-size: 20px; +} diff --git a/src/components/PageContent/PageContent.astro b/src/components/PageContent/PageContent.astro index 7d4ed5cc4..5bb2d2b4a 100644 --- a/src/components/PageContent/PageContent.astro +++ b/src/components/PageContent/PageContent.astro @@ -1,18 +1,16 @@ --- import type { MarkdownHeading } from "astro"; -import MoreMenu from "../RightSidebar/MoreMenu.astro"; import TableOfContents from "../RightSidebar/TableOfContents"; type Props = { title: string; headings: MarkdownHeading[]; - githubEditUrl: string; }; -const { title, headings, githubEditUrl } = Astro.props; +const { title, headings } = Astro.props; --- -
+

{title}

-
diff --git a/src/components/RightSidebar/MoreMenu.astro b/src/components/RightSidebar/MoreMenu.astro deleted file mode 100644 index a8a1b9ce2..000000000 --- a/src/components/RightSidebar/MoreMenu.astro +++ /dev/null @@ -1,75 +0,0 @@ ---- -import { COMMUNITY_INVITE_URL } from "../../consts"; - -type Props = { - editHref: string; -}; - -const { editHref } = Astro.props; -const showMoreSection = Boolean(COMMUNITY_INVITE_URL); ---- - -{showMoreSection &&

More

} - - - diff --git a/src/components/RightSidebar/RightSidebar.astro b/src/components/RightSidebar/RightSidebar.astro index 95e0c6623..243a75c8f 100644 --- a/src/components/RightSidebar/RightSidebar.astro +++ b/src/components/RightSidebar/RightSidebar.astro @@ -1,19 +1,16 @@ --- import type { MarkdownHeading } from "astro"; import TableOfContents from "./TableOfContents"; -import MoreMenu from "./MoreMenu.astro"; type Props = { headings: MarkdownHeading[]; - githubEditUrl: string; }; -const { headings, githubEditUrl } = Astro.props; +const { headings } = Astro.props; --- diff --git a/src/components/RightSidebar/TableOfContents.tsx b/src/components/RightSidebar/TableOfContents.tsx index df53fc25b..6064ed488 100644 --- a/src/components/RightSidebar/TableOfContents.tsx +++ b/src/components/RightSidebar/TableOfContents.tsx @@ -1,4 +1,3 @@ -/** @jsxImportSource react */ import type { MarkdownHeading } from "astro"; import type { FC } from "react"; import { unescape } from "html-escaper"; @@ -100,7 +99,9 @@ const TableOfContents: FC<{ headings: MarkdownHeading[] }> = ({ .map((heading) => (
  • diff --git a/src/components/atlas/BuildTabs.tsx b/src/components/atlas/BuildTabs.tsx index f58114f83..b02b94c49 100644 --- a/src/components/atlas/BuildTabs.tsx +++ b/src/components/atlas/BuildTabs.tsx @@ -64,14 +64,14 @@ const BuildTabs: FC<{ }, []); return ( - <> +
    handleTabChange(id, currentTabs.isTabsHaveSync)} /> {content} - +
    ); }; diff --git a/src/layouts/MainLayout.astro b/src/layouts/MainLayout.astro index 2ef5cb343..f2bae06d5 100644 --- a/src/layouts/MainLayout.astro +++ b/src/layouts/MainLayout.astro @@ -1,11 +1,13 @@ --- import type { MarkdownHeading } from "astro"; import type { CollectionEntry } from "astro:content"; + import HeadCommon from "../components/HeadCommon.astro"; import HeadSEO from "../components/HeadSEO.astro"; import PageContent from "../components/PageContent/PageContent.astro"; +import PageBreadcrumbs from "@components/PageBreadcrumbs/PageBreadcrumbs.astro"; import Navigation from "../components/LeftSidebar/Navigation.astro"; -import { GITHUB_EDIT_URL, SITE } from "../consts"; +import { SITE } from "../consts"; import { getNavigationEntries } from "src/utils/helpers/navigation/getNavigationEntries"; import SidebarHeader from "@components/LeftSidebar/SidebarHeader/SidebarHeader.astro"; import SidebarSearch from "@components/LeftSidebar/SidebarSearch/SidebarSearch.astro"; @@ -23,11 +25,8 @@ type Props = CollectionEntry<"docs">["data"] & { const pages = await Astro.glob("../content/docs/**/*.mdx"); const currentPage = Astro.url.pathname; const navigationEntries = getNavigationEntries(pages, currentPage); - const { headings, ...data } = Astro.props; const canonicalURL = new URL(Astro.url.pathname, Astro.site); -const currentFile = `src/content/docs${currentPage.replace(/\/$/, "")}.md`; -const githubEditUrl = `${GITHUB_EDIT_URL}/${currentFile}`; const currentLang = getLanguageFromURL(currentPage); const homeUrl = `${Astro.url.origin}/${currentLang}`; --- @@ -54,7 +53,7 @@ const homeUrl = `${Astro.url.origin}/${currentLang}`; {/* Search input */} - +
    - + +
    diff --git a/src/styles/index.css b/src/styles/index.css index 4a15ae4e7..bf3b05fc4 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -96,27 +96,27 @@ h2 { } h1 { - font-size: 3.25rem; - font-weight: 800; + @apply text-heading-1; } h2 { - font-size: 2.5rem; + @apply text-heading-2; } h3 { - font-size: 1.75rem; + @apply text-heading-3; } h4 { - font-size: 1.3rem; + @apply text-heading-4; } h5 { - font-size: 1rem; + @apply text-heading-5; } -p { +article p { + @apply mb-4; line-height: 1.65em; } @@ -126,7 +126,7 @@ p { p, .content ul { - color: var(--theme-text-light); + @apply text-black; } small, @@ -135,8 +135,9 @@ small, } .article-main a { - color: var(--theme-text-accent); - font-weight: 400; + @apply text-base; + @apply text-link-active; + font-weight: 450; text-underline-offset: 0.08em; align-items: center; gap: 0.5rem; @@ -166,6 +167,39 @@ article > section nav :is(ul, ol) { padding-left: inherit; } +article ol { + list-style: none; + & li { + position: relative; + } +} + +article ol li::before { + content: counter(list-item); + font-size: 15px; + font-weight: 600; + line-height: 20px; + position: absolute; + top: 2px; + left: -14px; +} + +article ul { + list-style: none; + & li { + position: relative; + } +} + +article ul li:not(#tabs-container li)::before { + content: "•"; + font-weight: 500; + position: absolute; + top: -5px; + left: -14px; + font-size: 20px; +} + article > section nav { margin-top: 1rem; margin-bottom: 2rem; @@ -219,6 +253,10 @@ strong { /* Supporting Content */ +article .expressive-code { + @apply mb-7; +} + code { --border-radius: 3px; --padding-block: 0.2rem; diff --git a/src/utils/helpers/navigation/getAllLanguageCategories.ts b/src/utils/helpers/navigation/getAllLanguageCategories.ts index f21d51b0f..e05bbd15f 100644 --- a/src/utils/helpers/navigation/getAllLanguageCategories.ts +++ b/src/utils/helpers/navigation/getAllLanguageCategories.ts @@ -1,7 +1,7 @@ import { KNOWN_LANGUAGE_CODES } from "@i18n/locales"; import { CONTENT_PATH } from "src/consts"; -import type { CategoryEntry, NavigationEntry } from "./types"; +import type { CategoryEntry, NavigationData, NavigationEntry } from "./types"; const getParentId = (url: string) => { const parts = url.split("/"); @@ -34,7 +34,8 @@ export const getAllCategoriesUnderLanguages = ( data: NavigationEntry[], currentPage: string ) => { - const obj: { [key: string]: CategoryEntry } = {}; + const categories: { [key: string]: CategoryEntry } = {}; + const breadcrumbs: NavigationData["breadcrumbs"] = []; KNOWN_LANGUAGE_CODES.forEach((languageKey) => { data.forEach((item) => { @@ -52,8 +53,8 @@ export const getAllCategoriesUnderLanguages = ( const usedTitle = sidebarLabel || categoryTitle || title; // creating language object - if (!obj[languageKey]) { - obj[languageKey] = { + if (!categories[languageKey]) { + categories[languageKey] = { children: [], position, title: usedTitle, @@ -71,7 +72,7 @@ export const getAllCategoriesUnderLanguages = ( if (url.includes(`${CONTENT_PATH}/${languageKey}`) && usedTitle) { const isTopCategory = path === `${CONTENT_PATH}/${languageKey}/index`; - obj[languageKey].children?.push({ + categories[languageKey].children?.push({ ...item, children: [], position, @@ -95,21 +96,41 @@ export const getAllCategoriesUnderLanguages = ( return result; }, [] as string[]); - obj[languageKey].children = obj[languageKey].children.map((child) => { - let isCollapsed = false; - - parts.forEach((part) => { - if (child.path?.endsWith(part + "/index")) { - isCollapsed = true; - } - }); + categories[languageKey].children = categories[languageKey].children.map( + (child) => { + let isCollapsed = false; + + parts.forEach((part) => { + if ( + child.path?.endsWith(part + "/index") || + child.path?.endsWith(part) + ) { + isCollapsed = true; + breadcrumbs.unshift({ + title: child.title, + url: child.slug, + level: child.level, + }); + } + }); - return { - ...child, - collapsed: isCollapsed, - }; - }); + return { + ...child, + collapsed: isCollapsed, + }; + } + ); }); - return obj; + // need to sort breadcrumbs by level to make sure that the hierarchy is correct + const sortedBreadcrumbs = breadcrumbs.sort((a, b) => + a.level > b.level ? 1 : -1 + ); + // need to filter breadcrumbs from clones + const breadcrumbsUnique = sortedBreadcrumbs.filter( + (breadcrumb, index, arr) => + arr.findIndex((element) => element.url === breadcrumb.url) === index + ); + + return { categories, breadcrumbs: breadcrumbsUnique }; }; diff --git a/src/utils/helpers/navigation/getNavigationEntries.ts b/src/utils/helpers/navigation/getNavigationEntries.ts index 17f902836..dacfcbf41 100644 --- a/src/utils/helpers/navigation/getNavigationEntries.ts +++ b/src/utils/helpers/navigation/getNavigationEntries.ts @@ -5,7 +5,7 @@ import { KNOWN_LANGUAGE_CODES } from "@i18n/locales"; import { getNavigationTree } from "./getNavigationTree"; import { getAllCategoriesUnderLanguages } from "./getAllLanguageCategories"; -import type { CategoryEntry, NavigationEntry } from "./types"; +import type { CategoryEntry, NavigationData, NavigationEntry } from "./types"; const getLastPath = (value: string) => { return value?.replace(/\/[\w\d\-\.]*$/, ""); @@ -14,7 +14,7 @@ const getLastPath = (value: string) => { export const getNavigationEntries = ( pages: MDXInstance>[], currentPage: string -) => { +): NavigationData => { // getting data for the pages const pagesData = pages.map((page) => ({ ...page.frontmatter, @@ -22,7 +22,7 @@ export const getNavigationEntries = ( url: page.url ? getLastPath(page.url) : "", })); - const categories = getAllCategoriesUnderLanguages( + const { categories, breadcrumbs } = getAllCategoriesUnderLanguages( pagesData as NavigationEntry[], currentPage ); @@ -40,5 +40,5 @@ export const getNavigationEntries = ( return acc; }, {} as { [key: string]: CategoryEntry }); - return languageTree; + return { languageTree, breadcrumbs }; }; diff --git a/src/utils/helpers/navigation/types.ts b/src/utils/helpers/navigation/types.ts index 937f76942..ac9f45bdb 100644 --- a/src/utils/helpers/navigation/types.ts +++ b/src/utils/helpers/navigation/types.ts @@ -24,3 +24,12 @@ export interface NavigationEntry { export interface GroupedNavigationItems { [langKey: string]: { [categoryKey: string]: CategoryEntry }; } + +export interface NavigationData { + languageTree: { [key: string]: CategoryEntry }; + breadcrumbs: { + title: string; + url: string; + level: number; + }[]; +} diff --git a/tailwind.config.cjs b/tailwind.config.cjs index bdfd1915a..2cf6f0532 100644 --- a/tailwind.config.cjs +++ b/tailwind.config.cjs @@ -23,41 +23,48 @@ module.exports = { xxxl: "2200px", // => @media (min-width: 1280px) { ... } }, - extend: {}, fontFamily: { body: ["ttnormspro, Helvetica, sans-serif"], sans: ["Droid Sans Mono, monospace"], }, - backgroundColor: (theme) => ({ - ...theme("colors"), - success: "#d4f8f2", - primary: "#ddebf9", - neutral: "#eceef4", - negative: "#ffe8ee", - warning: "#f9ebd6", - secondary: "#F9FAFC", - }), - textColor: (theme) => ({ - ...theme("colors"), - secondary: "#565C78", - }), - colors: { - "link-active": "#0B58FE", - white: "#FFFFFF", - "icon-neutral": "#6E7492", - headers: { - success: "#04585c", - primary: "#0c2663", - neutral: "#21253a", - negative: "#660835", - warning: "#664b29", + + extend: { + backgroundColor: { + success: "#d4f8f2", + primary: "#ddebf9", + neutral: "#eceef4", + negative: "#ffe8ee", + warning: "#f9ebd6", + secondary: "#F9FAFC", + }, + colors: { + "link-active": "#0B58FE", + white: "#FFFFFF", + "icon-neutral": "#6E7492", + headers: { + success: "#04585c", + primary: "#0c2663", + neutral: "#21253a", + negative: "#660835", + warning: "#664b29", + }, + icons: { + success: "rgb(6, 166, 147);", + primary: "rgb(31, 81, 217)", + neutral: "rgb(86, 92, 120)", + negative: "rgb(203, 55, 99)", + warning: "rgb(193, 134, 47)", + }, + }, + textColor: { + secondary: "#565C78", }, - icons: { - success: "rgb(6, 166, 147);", - primary: "rgb(31, 81, 217)", - neutral: "rgb(86, 92, 120)", - negative: "rgb(203, 55, 99)", - warning: "rgb(193, 134, 47)", + fontSize: { + "heading-1": ["45px", { lineHeight: "49px" }], + "heading-2": ["33px", { lineHeight: "37px" }], + "heading-3": ["25px", { lineHeight: "29.5px" }], + "heading-4": ["22px", { lineHeight: "25.5px" }], + "heading-5": ["16px", { lineHeight: "20px" }], }, }, },