From 390e7160d4ad84ad87c51cb4d2d2e7f0c531b7a1 Mon Sep 17 00:00:00 2001 From: Jamie Henson Date: Wed, 30 Apr 2025 16:48:00 +0100 Subject: [PATCH 1/2] chore: bump to ably-ui 16.2.0 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 8ddd0501fa..26b48d8f42 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "validate-llms-txt": "ts-node bin/validate-llms.txt.ts" }, "dependencies": { - "@ably/ui": "16.1.1", + "@ably/ui": "16.2.0", "@codesandbox/sandpack-react": "^2.20.0", "@codesandbox/sandpack-themes": "^2.0.21", "@mdx-js/react": "^2.3.0", diff --git a/yarn.lock b/yarn.lock index 058f17d8d9..dc21f30d02 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,10 +7,10 @@ resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== -"@ably/ui@16.1.1": - version "16.1.1" - resolved "https://registry.yarnpkg.com/@ably/ui/-/ui-16.1.1.tgz#bddfe9bb4df2ea06e981fa2901cda18cac63ca4b" - integrity sha512-GrsR/SDmeNg3HbRB3ThefIA2hzuiBvOT+1Xlq5JoIsxm+OKWEioKQuxu7aYtgpPgFP/9fOf2G97Jqnl7CaQKzg== +"@ably/ui@16.2.0": + version "16.2.0" + resolved "https://registry.yarnpkg.com/@ably/ui/-/ui-16.2.0.tgz#2469a89cb27a46f14d30af19cd955905d08e345a" + integrity sha512-i2/gfp+FME34eudF/521Y7EAE/05UD6at3viTuSW+FIkp6JJVfopiVFmc6ADsfuhk1z8BlzMvBjhp1HxtUV8ew== dependencies: "@radix-ui/react-accordion" "^1.2.1" "@radix-ui/react-navigation-menu" "^1.2.4" From a222e691bf0ef9370016e06d6b3a7d60266ab5ef Mon Sep 17 00:00:00 2001 From: Jamie Henson Date: Wed, 19 Mar 2025 11:18:49 +0000 Subject: [PATCH 2/2] feat: introduce support for MDX templating --- .prettierignore | 3 + content/chat/index.textile | 2 +- content/chat/rooms/messages.textile | 2 +- data/onCreatePage.ts | 54 +- gatsby-config.ts | 35 +- package.json | 4 +- src/components/Layout/Layout.tsx | 10 +- src/components/Layout/MDXWrapper.test.tsx | 154 + src/components/Layout/MDXWrapper.tsx | 99 + src/components/Layout/mdx/If.tsx | 20 + src/components/Layout/mdx/headers.ts | 68 + src/components/Markdown/MarkdownProvider.tsx | 13 +- .../block-component-maps/component-map.js | 7 +- src/contexts/layout-context.tsx | 28 +- yarn.lock | 4531 +++++++++-------- 15 files changed, 2924 insertions(+), 2106 deletions(-) create mode 100644 .prettierignore create mode 100644 src/components/Layout/MDXWrapper.test.tsx create mode 100644 src/components/Layout/MDXWrapper.tsx create mode 100644 src/components/Layout/mdx/If.tsx create mode 100644 src/components/Layout/mdx/headers.ts diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..cdd56bd501 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +# Ignore all mdx files in src/pages - we need to be able to render components on one line for inlining +src/pages/**/*.mdx +src/pages/**/*.md diff --git a/content/chat/index.textile b/content/chat/index.textile index 86d1ec266a..a81bf59772 100644 --- a/content/chat/index.textile +++ b/content/chat/index.textile @@ -40,4 +40,4 @@ h3(#reactions). Room reactions h2. Demo -Take a look at a "livestream basketball game":https://ably-livestream-chat-demo.vercel.app with some simulated users chatting built using the Chat SDK. The "source code":https://github.com/ably/ably-chat-js/tree/main/demo is available in GitHub. +Take a look at a "livestream basketball game":https://ably-livestream-chat-demo.vercel.app with some simulated users chatting built using the Chat SDK. The "source code":https://github.com/ably/ably-chat-js/tree/main/demo is available in GitHub. \ No newline at end of file diff --git a/content/chat/rooms/messages.textile b/content/chat/rooms/messages.textile index f4a1092bd0..fe2dafbc73 100644 --- a/content/chat/rooms/messages.textile +++ b/content/chat/rooms/messages.textile @@ -573,4 +573,4 @@ Applying an action to a message produces a new version, which is uniquely identi The @Message@ object also has convenience methods "@isOlderVersionOf@":https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#isolderversionof, "@isNewerVersionOf@":https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#isnewerversionof and "@isSameVersionAs@":https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#issameversionas which provide the same comparison. -Update and Delete events provide the full message payload, so may be used to replace the entire earlier version of the message. +Update and Delete events provide the full message payload, so may be used to replace the entire earlier version of the message. \ No newline at end of file diff --git a/data/onCreatePage.ts b/data/onCreatePage.ts index 2d959cfca4..f28a0882c0 100644 --- a/data/onCreatePage.ts +++ b/data/onCreatePage.ts @@ -1,7 +1,11 @@ import { GatsbyNode } from 'gatsby'; +import path from 'path'; +import fs from 'fs'; export type LayoutOptions = { sidebar: boolean; searchBar: boolean; template: string }; +const mdxWrapper = path.resolve('src/components/Layout/MDXWrapper.tsx'); + const pageLayoutOptions: Record = { '/docs': { sidebar: false, searchBar: false, template: 'index' }, '/docs/api/control-api': { sidebar: false, searchBar: true, template: 'control-api' }, @@ -11,17 +15,49 @@ const pageLayoutOptions: Record = { '/docs/404': { sidebar: false, searchBar: false, template: '404' }, }; -export const onCreatePage: GatsbyNode['onCreatePage'] = ({ page, actions }) => { - const { createPage } = actions; +// Function to extract code element classes from an MDX file +const extractCodeLanguages = async (filePath: string): Promise> => { + try { + // Check if the file exists + if (!fs.existsSync(filePath)) { + return new Set(); + } - const pathOptions = Object.entries(pageLayoutOptions).find(([path]) => page.path === path); + // Read the file content + const fileContent = fs.readFileSync(filePath, 'utf8'); - if (pathOptions) { - page.context = { - ...page.context, - layout: pathOptions[1], - }; + // Find all instances of code blocks with language specifiers (```language) + const codeBlockRegex = /```(\w+)/g; + let match; + const languages = new Set(); + + while ((match = codeBlockRegex.exec(fileContent)) !== null) { + if (match[1] && match[1].trim()) { + languages.add(match[1].trim()); + } + } + return languages; + } catch (error) { + console.error(`Error extracting code element classes from ${filePath}:`, error); + return new Set(); + } +}; + +export const onCreatePage: GatsbyNode['onCreatePage'] = async ({ page, actions }) => { + const { createPage } = actions; + const pathOptions = Object.entries(pageLayoutOptions).find(([path]) => page.path === path); + const isMDX = page.component.endsWith('.mdx'); + const detectedLanguages = isMDX ? await extractCodeLanguages(page.component) : new Set(); - createPage(page); + if (pathOptions || isMDX) { + createPage({ + ...page, + context: { + ...page.context, + layout: pathOptions ? pathOptions[1] : { sidebar: true, searchBar: true, template: 'base' }, + ...(isMDX ? { languages: Array.from(detectedLanguages) } : {}), + }, + component: isMDX ? `${mdxWrapper}?__contentFilePath=${page.component}` : page.component, + }); } }; diff --git a/gatsby-config.ts b/gatsby-config.ts index a871300225..8d826e8b12 100644 --- a/gatsby-config.ts +++ b/gatsby-config.ts @@ -1,4 +1,5 @@ import dotenv from 'dotenv'; +import remarkGfm from 'remark-gfm'; dotenv.config({ path: `.env.${process.env.NODE_ENV}`, @@ -38,6 +39,8 @@ export const siteMetadata = { export const graphqlTypegen = true; +const headerLinkIcon = ``; + export const plugins = [ 'gatsby-plugin-postcss', 'gatsby-plugin-image', @@ -51,7 +54,37 @@ export const plugins = [ 'how-tos': `${__dirname}/how-tos`, }, }, - 'gatsby-plugin-mdx', + { + resolve: 'gatsby-plugin-mdx', + options: { + gatsbyRemarkPlugins: [ + { + resolve: `gatsby-remark-autolink-headers`, + options: { + offsetY: `100`, + icon: headerLinkIcon, + className: `gatsby-copyable-header`, + removeAccents: true, + isIconAfterHeader: true, + elements: [`h2`, `h3`], + }, + }, + ], + mdxOptions: { + remarkPlugins: [ + // Add GitHub Flavored Markdown (GFM) support + remarkGfm, + ], + }, + }, + }, + { + resolve: `gatsby-source-filesystem`, + options: { + name: `pages`, + path: `${__dirname}/src/pages`, + }, + }, // Images { resolve: 'gatsby-source-filesystem', diff --git a/package.json b/package.json index 26b48d8f42..e2c8ca7e66 100644 --- a/package.json +++ b/package.json @@ -59,11 +59,12 @@ "gatsby-plugin-image": "^3.3.0", "gatsby-plugin-layout": "^4.14.0", "gatsby-plugin-manifest": "^5.3.0", - "gatsby-plugin-mdx": "^5.12.0", + "gatsby-plugin-mdx": "^5.14.0", "gatsby-plugin-react-helmet": "^6.3.0", "gatsby-plugin-root-import": "^2.0.9", "gatsby-plugin-sharp": "^5.8.1", "gatsby-plugin-sitemap": "^6.12.1", + "gatsby-remark-autolink-headers": "^6.14.0", "gatsby-source-filesystem": "^5.12.0", "gatsby-transformer-remark": "^6.12.0", "gatsby-transformer-sharp": "^5.3.0", @@ -81,6 +82,7 @@ "react-helmet": "^6.1.0", "react-medium-image-zoom": "^5.1.2", "react-select": "^5.7.0", + "remark-gfm": "^1.0.0", "textile-js": "^2.1.1", "turndown": "^7.1.1", "typescript": "^4.6.3", diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index 7d63075dc6..81b06a0597 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -12,8 +12,12 @@ import Header from './Header'; import LeftSidebar from './LeftSidebar'; import RightSidebar from './RightSidebar'; -type PageContextType = { +export type PageContextType = { layout: LayoutOptions; + languages?: string[]; + frontmatter?: { + title: string; + }; }; type LayoutProps = PageProps; @@ -26,7 +30,7 @@ const Layout: React.FC = ({ children, pageContext }) => {
{sidebar ? : null} - + {sidebar ? : null} {children}