From 492c1991936972a5f269524299388b3372c0f2bb Mon Sep 17 00:00:00 2001 From: David Moore Date: Wed, 2 Oct 2024 16:16:59 +1000 Subject: [PATCH 001/124] docs v2 --- .gitignore | 9 +- .husky/pre-commit | 1 + .spellcheckerrc.yml | 2 +- components.json | 13 +- contentlayer.config.ts | 71 + cypress.config.ts | 11 - cypress/e2e/broken-links.cy.ts | 11 +- .../getting-started/installation.mdx | 14 +- {src/pages => docs}/index.mdx | 110 +- lint-staged.config.mjs | 9 + mdx-components.tsx | 10 + next-env.d.ts | 11 +- next-sitemap.config.js | 5 - next.config.mjs | 51 +- package.json | 190 +- postcss.config.js | 3 - prettier.config.js | 3 +- public/images/open_graph.png | Bin 396941 -> 81658 bytes src/actions/sendFeedback.ts | 41 + src/app/(sitemaps)/sitemap-0.xml/route.ts | 46 + src/app/(sitemaps)/sitemap.xml/route.ts | 30 + src/app/Fathom.tsx | 50 + src/app/[[...slug]]/layout.tsx | 63 + src/app/[[...slug]]/page.tsx | 82 + src/app/apple-icon.png | Bin 0 -> 3679 bytes {public => src/app}/favicon.ico | Bin src/app/layout.tsx | 76 + src/app/not-found.tsx | 25 + src/app/og/route.tsx | 113 + src/app/providers.tsx | 38 + src/app/robots.ts | 23 + src/components/BoxGrid.tsx | 68 - src/components/Breadcrumbs.tsx | 58 + src/components/BuildingBlocks.tsx | 97 - src/components/Button.tsx | 52 +- src/components/Code.tsx | 371 - src/components/Community.tsx | 132 - src/components/Concepts.tsx | 105 - src/components/DifferencesGrid.tsx | 126 - src/components/Feedback.tsx | 106 + src/components/FeedbackForm.tsx | 121 +- src/components/Footer.tsx | 228 +- src/components/GettingStarted.tsx | 95 - src/components/GitHubStarCount.tsx | 71 + src/components/GridPattern.tsx | 18 +- src/components/Guides.tsx | 54 + src/components/GuidesGrid.tsx | 183 - src/components/Header.tsx | 120 - src/components/Heading.tsx | 113 - src/components/HeroPattern.tsx | 6 +- src/components/HomeHeader.tsx | 8 +- src/components/InstallNitric.tsx | 38 - .../InstallNitric/InstallNitric.tsx | 24 + .../InstallNitricTabs.client.tsx | 45 + src/components/InstallNitric/OSContext.tsx | 52 + src/components/InstallNitric/index.ts | 1 + src/components/Layout.tsx | 99 - src/components/Libraries.tsx | 4 +- src/components/Logo.tsx | 5 +- src/components/MDXContent.tsx | 31 + src/components/MobileNavigation.tsx | 132 - src/components/ModeToggle.tsx | 36 - src/components/Navigation.tsx | 395 - src/components/NitricLogo.tsx | 62 - src/components/NitricWhiteLogo.tsx | 62 - src/components/Prose.tsx | 24 +- src/components/Providers.tsx | 111 - src/components/ResourcePattern.tsx | 28 - src/components/Resources.tsx | 186 + src/components/SectionProvider.tsx | 127 - src/components/ShowIfLang.tsx | 24 + src/components/Spinner.tsx | 32 - src/components/Tabs.tsx | 0 src/components/Tag.tsx | 27 +- src/components/ThemeToggle.tsx | 44 + src/components/VersionSelect.tsx | 75 - src/components/code/Code.tsx | 23 + src/components/code/CodeContainer.tsx | 18 + src/components/code/CodeSwitcher.tsx | 29 + src/components/code/CodeSwitcherSelect.tsx | 96 + src/components/code/CodeWithTabs.tsx | 54 + src/components/code/CopyButton.tsx | 68 + src/components/code/ImportCode.tsx | 27 + src/components/code/Pre.tsx | 70 + src/components/code/annotations/callout.tsx | 38 + src/components/code/annotations/classname.tsx | 11 + src/components/code/annotations/collapse.tsx | 67 + src/components/code/annotations/fold.tsx | 20 + .../annotations/token-transitions.client.tsx | 50 + .../code/annotations/token-transitions.tsx | 12 + src/components/code/theme.ts | 6530 ++++++++++++++ src/components/icons/BellIcon.tsx | 2 +- src/components/icons/BoltIcon.tsx | 2 +- src/components/icons/BookIcon.tsx | 2 +- src/components/icons/CalendarIcon.tsx | 2 +- src/components/icons/CartIcon.tsx | 2 +- src/components/icons/ChatBubbleIcon.tsx | 2 +- src/components/icons/CheckIcon.tsx | 2 +- src/components/icons/ChevronRightLeftIcon.tsx | 4 +- src/components/icons/ClipboardIcon.tsx | 2 +- src/components/icons/CogIcon.tsx | 2 +- src/components/icons/CopyIcon.tsx | 2 +- src/components/icons/DocumentIcon.tsx | 2 +- src/components/icons/EnvelopeIcon.tsx | 2 +- src/components/icons/FaceSmileIcon.tsx | 2 +- src/components/icons/FolderIcon.tsx | 2 +- src/components/icons/GitHubIcon.tsx | 2 +- src/components/icons/LinkIcon.tsx | 2 +- src/components/icons/ListIcon.tsx | 2 +- src/components/icons/MagnifyingGlassIcon.tsx | 4 +- src/components/icons/MapPinIcon.tsx | 2 +- src/components/icons/PackageIcon.tsx | 2 +- src/components/icons/PaperAirplaneIcon.tsx | 4 +- src/components/icons/PaperClipIcon.tsx | 2 +- src/components/icons/ShapesIcon.tsx | 2 +- src/components/icons/ShirtIcon.tsx | 2 +- src/components/icons/SquaresPlusIcon.tsx | 2 +- src/components/icons/TagIcon.tsx | 2 +- src/components/icons/UserIcon.tsx | 2 +- src/components/icons/UsersIcon.tsx | 2 +- src/components/layout/BaseLayout.tsx | 28 + src/components/layout/DocToC.tsx | 72 + src/components/layout/DocTracingBeam.tsx | 101 + src/components/layout/Header.tsx | 115 + src/components/{ => layout}/Search.tsx | 26 +- src/components/mdx.tsx | 168 +- src/components/nav/CollapsibleNavItem.tsx | 88 + src/components/nav/MobileNavigation.tsx | 148 + src/components/nav/NavLink.tsx | 59 + src/components/nav/Navigation.tsx | 37 + src/components/nav/NavigationGroup.tsx | 49 + src/components/ui/accordion.tsx | 57 + src/components/ui/avatar.tsx | 50 + src/components/ui/badge.tsx | 8 +- src/components/ui/breadcrumb.tsx | 115 + src/components/ui/button.tsx | 63 + src/components/ui/collapsible.tsx | 11 + src/components/ui/dialog.tsx | 123 + src/components/ui/heading.tsx | 40 + src/components/ui/input.tsx | 25 + src/components/ui/label.tsx | 26 + src/components/ui/navigation-menu.tsx | 128 + src/components/ui/pagination.tsx | 145 + src/components/ui/radio-group.tsx | 44 + src/components/ui/scroll-area.tsx | 48 + src/components/ui/select.tsx | 36 +- src/components/ui/separator.tsx | 31 + src/components/ui/subheading.tsx | 19 + src/components/ui/table.tsx | 120 + src/components/ui/tabs.tsx | 55 + src/config/index.ts | 273 + src/config/reference/dart.ts | 251 + src/config/reference/go.ts | 240 + src/config/reference/node.ts | 260 + src/config/reference/python.ts | 215 + src/config/types.ts | 16 + src/hooks/useLang.ts | 94 + src/images/logos/go copy.svg | 14 + src/images/logos/node copy.svg | 4 + src/images/logos/php copy.svg | 10 + src/images/logos/python copy.svg | 13 + src/images/logos/ruby copy.svg | 4 + src/lib/constants.ts | 34 + src/lib/getNavInfo.ts | 53 + src/lib/hooks/use-versions.ts | 42 - src/lib/remToPx.ts | 4 +- src/lib/utils.ts | 2 +- src/mdx/mdx-options.mjs | 16 + src/mdx/recma.mjs | 18 +- src/mdx/rehype.mjs | 95 +- src/mdx/remark-toc-headings.mjs | 41 + src/mdx/remark.mjs | 3 +- src/mdx/search.mjs | 27 +- src/pages/_app.tsx | 116 - src/pages/_document.tsx | 50 - src/pages/api/feedback.ts | 56 - src/pages/api/og.tsx | 115 - src/styles/docsearch.css | 56 +- src/styles/tailwind.css | 164 +- tailwind.config.js | 191 - tailwind.config.ts | 214 + tsconfig.json | 38 +- types.d.ts | 11 + typography.js | 357 - typography.ts | 307 + yarn.lock | 7812 +++++++++++------ 186 files changed, 18128 insertions(+), 7207 deletions(-) create mode 100644 .husky/pre-commit create mode 100644 contentlayer.config.ts delete mode 100644 cypress.config.ts rename {src/pages => docs}/getting-started/installation.mdx (88%) rename {src/pages => docs}/index.mdx (79%) create mode 100644 lint-staged.config.mjs create mode 100644 mdx-components.tsx delete mode 100644 next-sitemap.config.js create mode 100644 src/actions/sendFeedback.ts create mode 100644 src/app/(sitemaps)/sitemap-0.xml/route.ts create mode 100644 src/app/(sitemaps)/sitemap.xml/route.ts create mode 100644 src/app/Fathom.tsx create mode 100644 src/app/[[...slug]]/layout.tsx create mode 100644 src/app/[[...slug]]/page.tsx create mode 100644 src/app/apple-icon.png rename {public => src/app}/favicon.ico (100%) create mode 100644 src/app/layout.tsx create mode 100644 src/app/not-found.tsx create mode 100644 src/app/og/route.tsx create mode 100644 src/app/providers.tsx create mode 100644 src/app/robots.ts delete mode 100644 src/components/BoxGrid.tsx create mode 100644 src/components/Breadcrumbs.tsx delete mode 100644 src/components/BuildingBlocks.tsx delete mode 100644 src/components/Code.tsx delete mode 100644 src/components/Community.tsx delete mode 100644 src/components/Concepts.tsx delete mode 100644 src/components/DifferencesGrid.tsx create mode 100644 src/components/Feedback.tsx delete mode 100644 src/components/GettingStarted.tsx create mode 100644 src/components/GitHubStarCount.tsx create mode 100644 src/components/Guides.tsx delete mode 100644 src/components/GuidesGrid.tsx delete mode 100644 src/components/Header.tsx delete mode 100644 src/components/Heading.tsx delete mode 100644 src/components/InstallNitric.tsx create mode 100644 src/components/InstallNitric/InstallNitric.tsx create mode 100644 src/components/InstallNitric/InstallNitricTabs.client.tsx create mode 100644 src/components/InstallNitric/OSContext.tsx create mode 100644 src/components/InstallNitric/index.ts delete mode 100644 src/components/Layout.tsx create mode 100644 src/components/MDXContent.tsx delete mode 100644 src/components/MobileNavigation.tsx delete mode 100644 src/components/ModeToggle.tsx delete mode 100644 src/components/Navigation.tsx delete mode 100644 src/components/NitricLogo.tsx delete mode 100644 src/components/NitricWhiteLogo.tsx delete mode 100644 src/components/Providers.tsx delete mode 100644 src/components/ResourcePattern.tsx create mode 100644 src/components/Resources.tsx delete mode 100644 src/components/SectionProvider.tsx create mode 100644 src/components/ShowIfLang.tsx delete mode 100644 src/components/Spinner.tsx delete mode 100644 src/components/Tabs.tsx create mode 100644 src/components/ThemeToggle.tsx delete mode 100644 src/components/VersionSelect.tsx create mode 100644 src/components/code/Code.tsx create mode 100644 src/components/code/CodeContainer.tsx create mode 100644 src/components/code/CodeSwitcher.tsx create mode 100644 src/components/code/CodeSwitcherSelect.tsx create mode 100644 src/components/code/CodeWithTabs.tsx create mode 100644 src/components/code/CopyButton.tsx create mode 100644 src/components/code/ImportCode.tsx create mode 100644 src/components/code/Pre.tsx create mode 100644 src/components/code/annotations/callout.tsx create mode 100644 src/components/code/annotations/classname.tsx create mode 100644 src/components/code/annotations/collapse.tsx create mode 100644 src/components/code/annotations/fold.tsx create mode 100644 src/components/code/annotations/token-transitions.client.tsx create mode 100644 src/components/code/annotations/token-transitions.tsx create mode 100644 src/components/code/theme.ts create mode 100644 src/components/layout/BaseLayout.tsx create mode 100644 src/components/layout/DocToC.tsx create mode 100644 src/components/layout/DocTracingBeam.tsx create mode 100644 src/components/layout/Header.tsx rename src/components/{ => layout}/Search.tsx (78%) create mode 100644 src/components/nav/CollapsibleNavItem.tsx create mode 100644 src/components/nav/MobileNavigation.tsx create mode 100644 src/components/nav/NavLink.tsx create mode 100644 src/components/nav/Navigation.tsx create mode 100644 src/components/nav/NavigationGroup.tsx create mode 100644 src/components/ui/accordion.tsx create mode 100644 src/components/ui/avatar.tsx create mode 100644 src/components/ui/breadcrumb.tsx create mode 100644 src/components/ui/button.tsx create mode 100644 src/components/ui/collapsible.tsx create mode 100644 src/components/ui/dialog.tsx create mode 100644 src/components/ui/heading.tsx create mode 100644 src/components/ui/input.tsx create mode 100644 src/components/ui/label.tsx create mode 100644 src/components/ui/navigation-menu.tsx create mode 100644 src/components/ui/pagination.tsx create mode 100644 src/components/ui/radio-group.tsx create mode 100644 src/components/ui/scroll-area.tsx create mode 100644 src/components/ui/separator.tsx create mode 100644 src/components/ui/subheading.tsx create mode 100644 src/components/ui/table.tsx create mode 100644 src/components/ui/tabs.tsx create mode 100644 src/config/index.ts create mode 100644 src/config/reference/dart.ts create mode 100644 src/config/reference/go.ts create mode 100644 src/config/reference/node.ts create mode 100644 src/config/reference/python.ts create mode 100644 src/config/types.ts create mode 100644 src/hooks/useLang.ts create mode 100644 src/images/logos/go copy.svg create mode 100644 src/images/logos/node copy.svg create mode 100644 src/images/logos/php copy.svg create mode 100644 src/images/logos/python copy.svg create mode 100644 src/images/logos/ruby copy.svg create mode 100644 src/lib/constants.ts create mode 100644 src/lib/getNavInfo.ts delete mode 100644 src/lib/hooks/use-versions.ts create mode 100644 src/mdx/mdx-options.mjs create mode 100644 src/mdx/remark-toc-headings.mjs delete mode 100644 src/pages/_app.tsx delete mode 100644 src/pages/_document.tsx delete mode 100644 src/pages/api/feedback.ts delete mode 100644 src/pages/api/og.tsx delete mode 100644 tailwind.config.js create mode 100644 tailwind.config.ts create mode 100644 types.d.ts delete mode 100644 typography.js create mode 100644 typography.ts diff --git a/.gitignore b/.gitignore index 55175ef86..60e8169f0 100644 --- a/.gitignore +++ b/.gitignore @@ -23,10 +23,17 @@ npm-debug.log* yarn-debug.log* yarn-error.log* -.pnpm-debug.log* # local env files .env*.local # vercel .vercel + +# typescript +*.tsbuildinfo +next-env.d.ts + +.contentlayer + +old diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 000000000..372362317 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +yarn lint-staged diff --git a/.spellcheckerrc.yml b/.spellcheckerrc.yml index 38ec9f4ac..0ec37d44e 100644 --- a/.spellcheckerrc.yml +++ b/.spellcheckerrc.yml @@ -1,5 +1,5 @@ files: - - 'src/pages/**/*.{md,mdx}' + - 'docs/**/*.{md,mdx}' dictionaries: - dictionary.txt quiet: true diff --git a/components.json b/components.json index f4668fca4..ff2d0f1df 100644 --- a/components.json +++ b/components.json @@ -1,17 +1,20 @@ { "$schema": "https://ui.shadcn.com/schema.json", - "style": "default", - "rsc": false, + "style": "new-york", + "rsc": true, "tsx": true, "tailwind": { - "config": "tailwind.config.js", + "config": "tailwind.config.ts", "css": "src/styles/tailwind.css", - "baseColor": "slate", + "baseColor": "zinc", "cssVariables": true, "prefix": "" }, "aliases": { "components": "@/components", - "utils": "@/lib/utils" + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" } } diff --git a/contentlayer.config.ts b/contentlayer.config.ts new file mode 100644 index 000000000..cb2fbbe9e --- /dev/null +++ b/contentlayer.config.ts @@ -0,0 +1,71 @@ +import { defineDocumentType, makeSource } from 'contentlayer2/source-files' +import { extractTocHeadings } from './src/mdx/remark-toc-headings.mjs' +import { title } from 'radash' +import path from 'path' +import fs from 'fs' + +const contentDirPath = 'docs' + +const branch = process.env.NEXT_PUBLIC_GITHUB_BRANCH || 'main' + +const Doc = defineDocumentType(() => ({ + name: 'Doc', + filePathPattern: '**/*.mdx', + fields: { + title: { + type: 'string', + description: 'The meta title of the doc', + }, + nav_title: { + type: 'string', + description: 'The title of the doc in the navigation', + }, + description: { + type: 'string', + description: 'The description of the doc', + }, + image: { + type: 'string', + description: 'The image of the doc', + }, + image_alt: { + type: 'string', + description: 'The image alt of the doc', + }, + disable_edit: { + type: 'boolean', + description: 'Disable the github edit button', + }, + }, + computedFields: { + slug: { + type: 'string', + resolve: (doc) => doc._raw.flattenedPath, + }, + toc: { type: 'json', resolve: (doc) => extractTocHeadings(doc.body.raw) }, + editUrl: { + type: 'string', + resolve: (doc) => + `https://github.com/nitrictech/docs/edit/${branch}/docs/${doc._raw.sourceFilePath}`, + }, + lastModified: { + type: 'date', + resolve: (doc) => { + // Get the full path to the markdown file + const filePath = path.join( + process.cwd(), + contentDirPath, + doc._raw.sourceFilePath, + ) + // Extract and return the last modified date + const stats = fs.statSync(filePath) + return stats.mtime // This is the last modified date + }, + }, + }, +})) + +export default makeSource({ + contentDirPath, + documentTypes: [Doc], +}) diff --git a/cypress.config.ts b/cypress.config.ts deleted file mode 100644 index f343d4a3c..000000000 --- a/cypress.config.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { defineConfig } from 'cypress' - -export default defineConfig({ - e2e: { - baseUrl: 'http://localhost:3000', - setupNodeEvents(on, config) { - // require("cypress-fail-fast/plugin")(on, config); - return config - }, - }, -}) diff --git a/cypress/e2e/broken-links.cy.ts b/cypress/e2e/broken-links.cy.ts index 2ef8f3e21..cb7f91092 100644 --- a/cypress/e2e/broken-links.cy.ts +++ b/cypress/e2e/broken-links.cy.ts @@ -33,7 +33,7 @@ const isExternalUrl = (url: string) => { return !url.includes('localhost') } -const req = (url: string, retryCount = 0) => { +const req = (url: string, retryCount = 0): any => { return cy .request({ url, @@ -71,7 +71,8 @@ describe('Broken links test suite', () => { (link.getAttribute('href') && link.getAttribute('href')?.includes(l)) || //@ts-ignore - (link.getAttribute('src') && link.getAttribute('src').includes(l)) + (link.getAttribute('src') && + link.getAttribute('src').includes(l)), ) }) .each((link) => { @@ -90,7 +91,7 @@ describe('Broken links test suite', () => { let acceptableCodes = CORRECT_CODES if (REDIRECT_CODES.includes(res.status) && !isExternalUrl(url)) { assert.fail( - `${url} returned ${res.status} to ${res.headers['location']}` + `${url} returned ${res.status} to ${res.headers['location']}`, ) } else { acceptableCodes = [ @@ -106,7 +107,7 @@ describe('Broken links test suite', () => { expect(res.status).oneOf( acceptableCodes, - `${url} returned ${res.status}` + `${url} returned ${res.status}`, ) }) } @@ -129,7 +130,7 @@ describe('Current links test suite', () => { ? '/docs' : `/docs${p.loc .substring(PROD_BASE_URL.length, p.loc.length) - .replace('/_index', '')}` + .replace('/_index', '')}`, ) }) }) diff --git a/src/pages/getting-started/installation.mdx b/docs/getting-started/installation.mdx similarity index 88% rename from src/pages/getting-started/installation.mdx rename to docs/getting-started/installation.mdx index 7bf7bf77d..413a1abc5 100644 --- a/src/pages/getting-started/installation.mdx +++ b/docs/getting-started/installation.mdx @@ -1,5 +1,3 @@ -import { InstallNitric } from '@/components/InstallNitric' - export const description = 'Basic installation instructions for the Nitric Framework' @@ -26,16 +24,16 @@ Please follow these links to the official installation steps for each. -```bash {{ title: 'macOS' }} +```bash !!tabs macOS brew install nitrictech/tap/nitric ``` -```bash {{ title: 'Windows' }} +```bash !!tabs Windows scoop bucket add nitric https://github.com/nitrictech/scoop-bucket.git scoop install nitric ``` -```bash {{ title: 'Linux' }} +```bash !!tabs Linux curl -L "https://nitric.io/install?version=latest" | bash ``` @@ -49,15 +47,15 @@ Alternatively, you can download pre-compiled binaries from the [releases](https: -```bash {{ title: 'macOS' }} +```bash !!tabs macOS brew upgrade nitric ``` -```bash {{ title: 'Windows' }} +```bash !!tabs Windows scoop update nitric ``` -```bash {{ title: 'Linux' }} +```bash !!tabs Linux curl -L "https://nitric.io/install?version=latest" | bash ``` diff --git a/src/pages/index.mdx b/docs/index.mdx similarity index 79% rename from src/pages/index.mdx rename to docs/index.mdx index 6a78076a1..97adce7c6 100644 --- a/src/pages/index.mdx +++ b/docs/index.mdx @@ -1,11 +1,7 @@ -import { HomeHeader } from '@/components/HomeHeader' -import { InstallNitric } from '@/components/InstallNitric' -import { Libraries } from '@/components/Libraries' - -export const description = - 'Documentation for the Nitric cloud application framework.' - -export const disableEditGithub = true +--- +title: Nitric Docs +description: Build cloud backends that run anywhere, fast. +--- + -```javascript {{ label:"services/example.js" }} +```javascript !! services/example.js import { bucket } from '@nitric/sdk' const profiles = bucket('profiles').allow('read', 'write', 'delete') ``` -```python {{ label:"services/example.py" }} +```python !! services/example.py from nitric.resources import bucket from nitric.application import Nitric @@ -66,7 +62,7 @@ profiles = bucket('profiles').allow('read', 'write', 'delete') Nitric.run() ``` -```go {{ label:"services/example/main.go" }} +```go !! services/example/main.go import ( "fmt" @@ -82,7 +78,7 @@ func main() { } ``` -```dart {{ label:"services/example.dart" }} +```dart !! services/example.dart import 'package:nitric_sdk/nitric.dart'; void main() { @@ -94,7 +90,7 @@ void main() { } ``` - + Nitric collects everything your services request. When you deploy, the deployment plugin you choose creates the resources and services, then links them all together. @@ -104,8 +100,6 @@ Nitric collects everything your services request. When you deploy, the deploymen [Concepts](/concepts/introduction) section. ---- - ## Deployment Plugins (Providers) Nitric is designed to be independent of any platform, so you can run your apps anywhere. You can deploy to AWS, Azure, GCP, your own Kubernetes cluster or a single server. You could even deploy to multiple clouds at once. @@ -114,39 +108,39 @@ Are the differences between a bucket on AWS and a bucket on Azure important to m Nitric abstracts away API layer differences, so you can focus on your app. The part that makes that possible is a plugin, we call a **Provider**. - + -```yaml {{ label:"nitric.prod.yaml", title: "AWS Pulumi" }} +```yaml !!tabs AWS Pulumi provider: nitric/aws@1.1.1 region: us-east-1 ``` -```yaml {{ label:"nitric.prod.yaml", title: "Azure Pulumi" }} +```yaml !!tabs Azure Pulumi provider: nitric/azure@1.1.1 region: East US ``` -```yaml {{ label:"nitric.prod.yaml", title: "Google Pulumi" }} +```yaml !!tabs Google Pulumi provider: nitric/gcp@1.1.1 region: us-east1 ``` -```yaml {{ label:"nitric.prod.yaml", title: "AWS Terraform" }} +```yaml !!tabs AWS Terraform provider: nitric/awstf@1.1.1 region: us-east-1 ``` -```yaml {{ label:"nitric.prod.yaml", title: "Google Terraform" }} +```yaml !!tabs Google Terraform provider: nitric/gcptf@1.1.1 region: us-east1 ``` -```yaml {{ label:"nitric.prod.yaml", title: "Custom" }} +```yaml !!tabs Custom # Build your own provider to deploy anywhere you like. provider: custom/on-prem@1.0.0 ``` - + We have several providers built-in with IaC from [Pulumi](https://www.pulumi.com/) or [Terraform](https://www.terraform.io/), but you can build your own with any tools you prefer and **deploy anywhere**. @@ -167,9 +161,9 @@ Nitric uses this to find your services, then it turns each service into a contai So, a project structure might look something like this: - + -```plaintext {{ title:"JavaScript" }} +```bash !!tabs JavaScript example/ ├── nitric.yaml ├── services/ @@ -178,7 +172,7 @@ example/ └── package.json ``` -```plaintext {{ title:"Python" }} +```bash !!tabs Python example/ ├── nitric.yaml ├── services/ @@ -187,7 +181,7 @@ example/ └── Pipfile ``` -```plaintext {{ title:"Go" }} +```bash !!tabs Go example/ ├── nitric.yaml ├── services/ @@ -199,7 +193,7 @@ example/ └── go.mod ``` -```plaintext {{ title:"Dart" }} +```bash !!tabs Dart example/ ├── nitric.yaml ├── services/ @@ -208,7 +202,7 @@ example/ └── pubspec.yaml ``` - + --- @@ -218,16 +212,16 @@ Nitric has a CLI to help you create, manage, run and deploy your projects. We re -```bash {{ title: 'macOS' }} +```bash !!tabs macOS brew install nitrictech/tap/nitric ``` -```bash {{ title: 'Windows' }} +```bash !!tabs Windows scoop bucket add nitric https://github.com/nitrictech/scoop-bucket.git scoop install nitric ``` -```bash {{ title: 'Linux' }} +```bash !!tabs Linux curl -L "https://nitric.io/install?version=latest" | bash ``` @@ -320,9 +314,9 @@ Here are some ways you can extend or escape Nitric. If you need to access a service in a way Nitric doesn't support, you can always use the provider's SDK directly. Code like this will always work: - + -```javascript +```javascript !! // Import the AWS SDK import { S3Client } from '@aws-sdk/client-s3' @@ -331,7 +325,7 @@ const s3 = new S3Client({ region: 'us-east-1' }) const { Contents } = await s3.listObjectsV2({ Bucket: 'my-bucket' }) ``` -```python +```python !! # Import the boto3 (AWS) SDK from boto3 import client @@ -340,7 +334,7 @@ s3 = client('s3', region_name='us-east-1') response = s3.list_objects_v2(Bucket='my-bucket') ``` -```go +```go !! import ( "context" // Import the AWS SDK @@ -357,7 +351,7 @@ output, _ := client.ListObjectsV2(context.TODO(), &s3.ListObjectsV2Input{ }) ``` -```dart +```dart !! // Import the AWS SDK import 'package:aws_s3/aws_s3.dart'; @@ -367,29 +361,37 @@ final response = await s3.listObjectsV2(Bucket: 'my-bucket'); print(response.contents); ``` - + -### Overriding +### Manual Install -If you need to change how Nitric deploys a resources or how it interacts with a service at runtime, you can [extend or modify a provider](/reference/providers/custom/extend-standard-provider). +Alternatively, you can download pre-compiled binaries from the [releases](https://github.com/nitrictech/cli/releases) page and install them manually. - - For example, here's a [project that swaps SNS for - EventBridge](https://github.com/jyecusch/iac-ifc-comparison) on AWS. - +## Update to the latest version -### Full Customization + -If you need to deploy to a new platform or new set of services that Nitric doesn't support, you can [build your own provider](/reference/providers/custom/building-custom-provider). This is a bit more advanced, but it's the ultimate escape hatch. +```bash !!tabs macOS +brew upgrade nitric +``` -The included providers are written in Go and built using Terraform or Pulumi, but you can use any language or tool you like. +```bash !!tabs Windows +scoop update nitric +``` -### Additional Resources +```bash !!tabs Linux +curl -L "https://nitric.io/install?version=latest" | bash +``` -If you need to use a service/resource that Nitric doesn't support, you do that like you always would. Nitric doesn't get in the way of you using the cloud, it just makes it easier. + ---- +You can easily check which version you're on by running `nitric version`. + +## Release notes + +You can view the CLI release notes on our [CLI GitHub Releases page](https://github.com/nitrictech/cli/releases). -## What now? +## What's next -If you're still not sure what to make of Nitric, maybe start with the [Concepts](/concepts/introduction) section, otherwise the best way to learn is to dive into the [Guides](/guides) and start building your first project. +- Checkout out our [concepts](/concepts/introduction) page for a quick overview of Nitric. +- Start building with our [quickstart guide](./quickstart). diff --git a/lint-staged.config.mjs b/lint-staged.config.mjs new file mode 100644 index 000000000..682c0c85d --- /dev/null +++ b/lint-staged.config.mjs @@ -0,0 +1,9 @@ +export default { + '*.{js,jsx,mjs,ts,tsx,mts}': [ + 'prettier --with-node-modules --ignore-path .prettierignore --write', + 'eslint --fix', + ], + '*.{json,md,mdx,css,html,yml,yaml,scss}': [ + 'prettier --with-node-modules --ignore-path .prettierignore --write', + ], +} diff --git a/mdx-components.tsx b/mdx-components.tsx new file mode 100644 index 000000000..906c1ddde --- /dev/null +++ b/mdx-components.tsx @@ -0,0 +1,10 @@ +import { type MDXComponents } from 'mdx/types' + +import * as mdxComponents from '@/components/mdx' + +export function useMDXComponents(components: MDXComponents) { + return { + ...components, + ...mdxComponents, + } +} diff --git a/next-env.d.ts b/next-env.d.ts index 62b8a52d3..725dd6f24 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -1,5 +1,6 @@ -/// -/// - -// NOTE: This file should not be edited -// see https://nextjs.org/docs/basic-features/typescript for more information. +/// +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. diff --git a/next-sitemap.config.js b/next-sitemap.config.js deleted file mode 100644 index f203557fc..000000000 --- a/next-sitemap.config.js +++ /dev/null @@ -1,5 +0,0 @@ -/** @type {import('next-sitemap').IConfig} */ -module.exports = { - siteUrl: process.env.SITE_URL || 'https://nitric.io/docs', - generateRobotsTxt: process.env.NEXT_PUBLIC_VERCEL_ENV === 'production', -} diff --git a/next.config.mjs b/next.config.mjs index d73b16681..7bcadabd0 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,25 +1,36 @@ import nextMDX from '@next/mdx' -import withSearch from './src/mdx/search.mjs' -import { remarkPlugins } from './src/mdx/remark.mjs' -import { rehypePlugins } from './src/mdx/rehype.mjs' -import { recmaPlugins } from './src/mdx/recma.mjs' +import { createContentlayerPlugin } from 'next-contentlayer2' +import { mdxOptions } from './src/mdx/mdx-options.mjs' +import path from 'path' const withMDX = nextMDX({ - options: { - remarkPlugins, - rehypePlugins, - recmaPlugins, - providerImportSource: '@mdx-js/react', - }, + options: mdxOptions, }) +const isProd = process.env.NEXT_PUBLIC_VERCEL_ENV === 'production' + /** @type {import('next').NextConfig} */ const nextConfig = { basePath: '/docs', - reactStrictMode: true, pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'mdx'], + experimental: { + outputFileTracingIncludes: { + '/**/*': ['./src/app/**/*.mdx'], + }, + }, images: { - domains: ['github.com', 'raw.githubusercontent.com'], + remotePatterns: [ + { + protocol: 'https', + hostname: 'github.com', + port: '', + }, + { + protocol: 'https', + hostname: 'raw.githubusercontent.com', + port: '', + }, + ], }, async redirects() { return [ @@ -69,7 +80,7 @@ const nextConfig = { source: source, destination: `/docs/guides/nodejs${source.replace( /^(\/docs\/guides\/|\/docs\/)/, - '/' + '/', )}`, basePath: false, permanent: true, @@ -85,7 +96,7 @@ const nextConfig = { source: source, destination: `/docs/getting-started${source.replace( /^(\/docs\/guides\/|\/docs\/)/, - '/' + '/', )}`, basePath: false, permanent: true, @@ -95,11 +106,11 @@ const nextConfig = { source: source, destination: `/docs/guides/python${source.replace( /^(\/docs\/guides\/|\/docs\/)/, - '/' + '/', )}`, basePath: false, permanent: true, - }) + }), ), { source: '/docs/comparison/:slug', @@ -277,7 +288,7 @@ const nextConfig = { source: source, destination: `/docs/${source.replace( /^(\/docs\/guides\/|\/docs\/)/, - '' + '', )}`, basePath: false, permanent: true, @@ -363,4 +374,8 @@ const nextConfig = { }, } -export default withSearch(withMDX(nextConfig)) +const withContentlayer = createContentlayerPlugin({ + configPath: path.resolve(process.cwd(), './contentlayer.config.ts'), +}) + +export default withContentlayer(withMDX(nextConfig)) diff --git a/package.json b/package.json index 8acfb9219..279e8209d 100644 --- a/package.json +++ b/package.json @@ -1,94 +1,96 @@ -{ - "name": "nitric-docs", - "version": "0.1.0", - "scripts": { - "postinstall": "prisma generate && node scripts/collect-assets", - "dev": "next dev", - "build": "next build", - "postbuild": "next-sitemap", - "start": "next start", - "lint": "next lint", - "test:spellcheck": "spellchecker", - "format:check": "prettier --check src", - "format:fix": "prettier --write src", - "prepare": "husky install", - "cypress": "cypress open", - "cypress:headless": "cypress run", - "e2e:headless": "start-server-and-test start http://localhost:3000 cypress:headless" - }, - "browserslist": "defaults, not ie <= 11", - "dependencies": { - "@algolia/autocomplete-core": "^1.7.3", - "@docsearch/react": "^3.4.0", - "@headlessui/react": "^1.7.13", - "@heroicons/react": "^2.0.18", - "@mdx-js/loader": "^2.1.5", - "@mdx-js/react": "^2.1.5", - "@next/mdx": "^13.0.3", - "@prisma/client": "^4.16.0", - "@radix-ui/react-select": "^2.0.0", - "@sindresorhus/slugify": "^2.1.1", - "@tailwindcss/typography": "^0.5.8", - "acorn": "^8.8.1", - "autoprefixer": "^10.4.7", - "class-variance-authority": "^0.7.0", - "clsx": "^2.1.0", - "fast-glob": "^3.2.12", - "fathom-client": "^3.5.0", - "flexsearch": "^0.7.31", - "focus-visible": "^5.2.0", - "framer-motion": "7.8.1", - "lucide-react": "^0.330.0", - "mdast-util-to-string": "^3.2.0", - "mdx-annotations": "^0.1.1", - "next": "13.4.4", - "postcss-focus-visible": "^6.0.4", - "radash": "^12.1.0", - "react": "18.2.0", - "react-dom": "18.2.0", - "react-highlight-words": "^0.20.0", - "react-icons": "^4.9.0", - "recma-nextjs-static-props": "^1.0.0", - "rehype-mdx-title": "^2.0.0", - "remark": "^14.0.2", - "remark-code-import": "^1.2.0", - "remark-gfm": "^3.0.1", - "remark-mdx": "^2.3.0", - "shiki": "^1.10.1", - "simple-functional-loader": "^1.2.1", - "tailwind-merge": "^2.2.1", - "tailwindcss": "^3.3.0", - "tailwindcss-animate": "^1.0.7", - "unist-util-filter": "^4.0.1", - "unist-util-visit": "^4.1.1", - "zustand": "^4.3.2" - }, - "devDependencies": { - "@types/node": "20.2.5", - "@types/react": "^18.2.8", - "@types/react-dom": "^18.2.4", - "cypress": "^12.17.4", - "cypress-axe": "^1.4.0", - "cypress-fail-fast": "^7.0.1", - "eslint": "8.26.0", - "eslint-config-next": "13.0.2", - "fast-xml-parser": "^4.2.4", - "husky": "^7.0.1", - "lint-staged": "^11.0.1", - "next-sitemap": "^4.1.3", - "prettier": "^2.8.7", - "prettier-plugin-tailwindcss": "^0.2.6", - "prisma": "^4.16.0", - "spellchecker-cli": "^4.8.1", - "start-server-and-test": "^2.0.0", - "typescript": "5.1.3" - }, - "lint-staged": { - "./src/**/*.{mdx,md}": "yarn format:fix" - }, - "husky": { - "hooks": { - "pre-commit": "lint-staged" - } - } -} +{ + "name": "nitric-docs-v2", + "version": "0.1.0", + "private": true, + "scripts": { + "postinstall": "husky && prisma generate && node scripts/collect-assets", + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint", + "test:spellcheck": "spellchecker", + "format:check": "prettier --check src", + "format:fix": "prettier --write src", + "cypress": "cypress open", + "lint-staged": "lint-staged" + }, + "browserslist": "defaults, not ie <= 11", + "dependencies": { + "@algolia/autocomplete-core": "^1.7.3", + "@docsearch/react": "^3.6.1", + "@headlessui/react": "^2.1.0", + "@headlessui/tailwindcss": "^0.2.0", + "@heroicons/react": "^2.1.5", + "@mdx-js/loader": "^3.0.0", + "@mdx-js/react": "^3.0.0", + "@next/mdx": "^14.0.4", + "@prisma/client": "^5.20.0", + "@radix-ui/react-accordion": "^1.2.0", + "@radix-ui/react-avatar": "^1.1.0", + "@radix-ui/react-collapsible": "^1.1.0", + "@radix-ui/react-dialog": "^1.1.1", + "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-label": "^2.1.0", + "@radix-ui/react-navigation-menu": "^1.2.0", + "@radix-ui/react-radio-group": "^1.2.0", + "@radix-ui/react-scroll-area": "^1.1.0", + "@radix-ui/react-select": "^2.1.1", + "@radix-ui/react-separator": "^1.1.0", + "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-tabs": "^1.1.0", + "@sindresorhus/slugify": "^2.1.1", + "@tailwindcss/typography": "^0.5.10", + "@types/mdx": "^2.0.8", + "@types/node": "^20.10.8", + "@types/react": "^18.2.47", + "@types/react-dom": "^18.2.18", + "@types/react-highlight-words": "^0.16.4", + "acorn": "^8.8.1", + "autoprefixer": "^10.4.7", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "codehike": "^1.0.1", + "contentlayer2": "^0.5.1", + "fathom-client": "^3.7.2", + "framer-motion": "^10.18.0", + "hast-util-from-html-isomorphic": "^2.0.0", + "lucide-react": "^0.445.0", + "mdast-util-to-string": "^4.0.0", + "mdx-annotations": "^0.1.1", + "next": "^14.2.13", + "next-contentlayer2": "^0.5.1", + "next-themes": "^0.3.0", + "radash": "^12.1.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-highlight-words": "^0.20.0", + "react-icons": "^5.3.0", + "rehype-autolink-headings": "^7.1.0", + "remark": "^15.0.1", + "remark-gfm": "^4.0.0", + "remark-mdx": "^3.0.0", + "simple-functional-loader": "^1.2.1", + "slugify": "^1.6.6", + "tailwind-merge": "^2.5.2", + "tailwindcss": "^3.4.1", + "tailwindcss-animate": "^1.0.7", + "typescript": "^5.3.3", + "unist-util-filter": "^5.0.1", + "unist-util-visit": "^5.0.0", + "zustand": "^4.3.2" + }, + "devDependencies": { + "cypress": "^13.15.0", + "cypress-axe": "^1.5.0", + "eslint": "^8.56.0", + "eslint-config-next": "^14.0.4", + "fast-xml-parser": "^4.5.0", + "husky": "^9.1.6", + "lint-staged": "^15.2.10", + "prettier": "^3.3.2", + "prettier-plugin-tailwindcss": "^0.6.5", + "prisma": "^5.20.0", + "sharp": "0.33.1", + "spellchecker-cli": "^6.2.0" + } +} diff --git a/postcss.config.js b/postcss.config.js index 6573c2532..33ad091d2 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,9 +1,6 @@ module.exports = { plugins: { tailwindcss: {}, - 'postcss-focus-visible': { - replaceWith: '[data-focus-visible-added]', - }, autoprefixer: {}, }, } diff --git a/prettier.config.js b/prettier.config.js index 35bb2b2a6..6b16840e2 100644 --- a/prettier.config.js +++ b/prettier.config.js @@ -1,5 +1,6 @@ +/** @type {import('prettier').Options} */ module.exports = { singleQuote: true, semi: false, - plugins: [require('prettier-plugin-tailwindcss')], + plugins: ['prettier-plugin-tailwindcss'], } diff --git a/public/images/open_graph.png b/public/images/open_graph.png index 064cf0462d1fa96047e1bf99fecacb8e3118f865..628b99aa11da090627eadf81f70c9e78c63e2c3d 100644 GIT binary patch literal 81658 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 literal 396941 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∈?;A{Rv6@s{^ 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 + ) +} diff --git a/src/app/[[...slug]]/page.tsx b/src/app/[[...slug]]/page.tsx new file mode 100644 index 000000000..c0f19d03a --- /dev/null +++ b/src/app/[[...slug]]/page.tsx @@ -0,0 +1,82 @@ +import { notFound } from 'next/navigation' +import MDXContent from '@/components/MDXContent' +import { Metadata } from 'next/types' +import { BASE_URL } from '@/lib/constants' +import { allDocs } from '@/content' +import { getNavInfo } from '@/lib/getNavInfo' +import { title } from 'radash' +import { OpenGraph } from 'next/dist/lib/metadata/types/opengraph-types' + +export async function generateMetadata({ + params, +}: { + params: { slug: string[] } +}): Promise { + const slug = params.slug ? decodeURI(params.slug.join('/')) : '' + const doc = allDocs.find((p) => p.slug === slug) + + if (!doc) { + return + } + + const { navItem } = getNavInfo(doc) + + let seoTitle = doc.slug + ? `${title(doc.slug.split('/')[0])}: ${navItem?.title}` + : 'Welcome to Nitric Docs' + + if (navItem && navItem.breadcrumbParentItem?.title) { + seoTitle = `${navItem.breadcrumbParentItem.title}: ${navItem.title}` + } + + const openGraph: OpenGraph = { + siteName: 'Nitric Docs', + locale: 'en_US', + url: `${BASE_URL}/docs/${doc.slug}`, + images: [ + { + url: `${BASE_URL}/docs/og?title=${encodeURIComponent(doc.title || 'Nitric Docs')}&description=${encodeURIComponent(doc.description || '')}`, + alt: 'Nitric Docs', + }, + ], + } + + if (doc.image && doc.image_alt) { + openGraph.images = [ + { + url: doc.image, + alt: doc.image_alt, + }, + ] + } + + return { + title: seoTitle, + description: doc.description, + openGraph, + twitter: { + card: 'summary_large_image', + }, + alternates: { + canonical: `${BASE_URL}/docs/${doc.slug}`, + }, + } +} + +export const generateStaticParams = async () => { + return allDocs.map((p) => ({ + slug: p.slug.split('/').map((name) => decodeURI(name)), + })) +} + +export default function Page({ params }: { params: { slug: string[] } }) { + const slug = params.slug ? decodeURI(params.slug.join('/')) : '' + + const doc = allDocs.find((p) => p.slug === slug) + + if (!doc) { + return notFound() + } + + return +} diff --git a/src/app/apple-icon.png b/src/app/apple-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e3c168a3afdda07c16c26dda8b6dcb5fb79da89a GIT binary patch literal 3679 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 + {/* group/body is used by ShowIfLang */} + + + + {children} + + + + ) +} diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx new file mode 100644 index 000000000..98d93b0c1 --- /dev/null +++ b/src/app/not-found.tsx @@ -0,0 +1,25 @@ +import { HeroPattern } from '@/components/HeroPattern' +import { Button } from '@/components/ui/button' +import Link from 'next/link' + +export default function NotFound() { + return ( + <> + +
+

+ 404 +

+

+ Page not found +

+

+ Sorry, we couldn’t find the page you’re looking for. +

+ +
+ + ) +} diff --git a/src/app/og/route.tsx b/src/app/og/route.tsx new file mode 100644 index 000000000..dd4e77714 --- /dev/null +++ b/src/app/og/route.tsx @@ -0,0 +1,113 @@ +import { BASE_URL } from '@/lib/constants' +import { ImageResponse } from 'next/og' +import { NextRequest } from 'next/server' + +export const runtime = 'edge' + +const size = { + width: 1200, + height: 630, +} + +// Image generation +export async function GET(req: NextRequest) { + const { searchParams } = req.nextUrl + // ?title= + const hasTitle = searchParams.has('title') + const title = hasTitle + ? searchParams.get('title')?.slice(0, 100) + : 'Nitric Docs' + + const hasDescription = searchParams.has('description') + + const description = hasDescription + ? searchParams.get('description')?.slice(0, 100) + : 'Docs for the Nitric cloud application framework.' + + const imageBaseUrl = req.headers.get('host')?.startsWith('localhost') + ? `http://${req.headers.get('host')}` + : `https://${req.headers.get('host')}` + + // Font + const soraBold = fetch( + new URL('../../assets/Sora-Bold.ttf', import.meta.url), + ).then((res) => res.arrayBuffer()) + + return new ImageResponse( + ( + // ImageResponse JSX element + <div + style={{ + backgroundColor: '#121118', + backgroundSize: '150px 150px', + height: '100%', + width: '100%', + display: 'flex', + textAlign: 'center', + alignItems: 'center', + justifyContent: 'center', + flexDirection: 'column', + flexWrap: 'nowrap', + position: 'relative', + }} + > + <div + style={{ + display: 'flex', + alignItems: 'center', + alignContent: 'center', + justifyContent: 'center', + justifyItems: 'center', + }} + > + {/* eslint-disable-next-line @next/next/no-img-element */} + <img alt="Nitric" src={`${BASE_URL}/docs/images/open_graph.png`} /> + </div> + <div + style={{ + width: '500px', + display: 'flex', + flexDirection: 'column', + gap: 10, + left: '79px', + top: '230px', + bottom: '156px', + position: 'absolute', + color: 'white', + fontSize: '50px', + fontFamily: 'Sora', + lineHeight: '120%', + fontWeight: 700, + textAlign: 'left', + }} + > + {title} + <div + style={{ + color: '#A1A1AA', + fontSize: '28px', + fontWeight: 500, + }} + > + {description} + </div> + </div> + <br /> + </div> + ), + // ImageResponse options + { + // For convenience, we can re-use the exported opengraph-image + // size config to also set the ImageResponse's width and height. + ...size, + fonts: [ + { + name: 'Sora', + data: await soraBold, + style: 'normal', + weight: 600, + }, + ], + }, + ) +} diff --git a/src/app/providers.tsx b/src/app/providers.tsx new file mode 100644 index 000000000..9ccc150ae --- /dev/null +++ b/src/app/providers.tsx @@ -0,0 +1,38 @@ +'use client' + +import { useEffect } from 'react' +import { ThemeProvider, useTheme } from 'next-themes' +import { OSProvider } from '@/components/InstallNitric/OSContext' + +function ThemeWatcher() { + let { resolvedTheme, setTheme } = useTheme() + + useEffect(() => { + let media = window.matchMedia('(prefers-color-scheme: dark)') + + function onMediaChange() { + let systemTheme = media.matches ? 'dark' : 'light' + if (resolvedTheme === systemTheme) { + setTheme('system') + } + } + + onMediaChange() + media.addEventListener('change', onMediaChange) + + return () => { + media.removeEventListener('change', onMediaChange) + } + }, [resolvedTheme, setTheme]) + + return null +} + +export function Providers({ children }: { children: React.ReactNode }) { + return ( + <ThemeProvider attribute="class" disableTransitionOnChange> + <ThemeWatcher /> + <OSProvider>{children}</OSProvider> + </ThemeProvider> + ) +} diff --git a/src/app/robots.ts b/src/app/robots.ts new file mode 100644 index 000000000..7c00dc7b7 --- /dev/null +++ b/src/app/robots.ts @@ -0,0 +1,23 @@ +import type { MetadataRoute } from 'next' + +export default function robots(): MetadataRoute.Robots { + // staging robots.txt + if (process.env.NEXT_PUBLIC_VERCEL_ENV !== 'production') { + return { + rules: { + userAgent: '*', + disallow: '/', + }, + } + } + + // production robots.txt + return { + rules: { + userAgent: '*', + allow: '/', + }, + host: 'https://nitric.io/docs', + sitemap: 'https://nitric.io/docs/sitemap.xml', + } +} diff --git a/src/components/BoxGrid.tsx b/src/components/BoxGrid.tsx deleted file mode 100644 index 73d4db0b8..000000000 --- a/src/components/BoxGrid.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import Link from 'next/link' -import { motion, useMotionTemplate, useMotionValue } from 'framer-motion' - -import { GridPattern } from '@/components/GridPattern' -import { Heading } from '@/components/Heading' -import clsx from 'clsx' -import { ResourcePattern } from './ResourcePattern' - -function ResourceIcon({ icon: Icon }) { - return ( - <div className="flex h-7 w-7 items-center justify-center rounded-full bg-gray-800/5 ring-1 ring-zinc-900/25 backdrop-blur-[2px] transition duration-300 group-hover:bg-white/50 group-hover:ring-zinc-900/25 dark:bg-white/7.5 dark:ring-white/15 dark:group-hover:bg-primary-300/10 dark:group-hover:ring-primary-400"> - <Icon className="h-5 w-5 fill-zinc-700/10 stroke-zinc-700 transition-colors duration-300 group-hover:stroke-zinc-900 dark:fill-white/10 dark:stroke-zinc-400 dark:group-hover:fill-primary-300/10 dark:group-hover:stroke-primary-400" /> - </div> - ) -} - -function Block({ block }) { - let mouseX = useMotionValue(0) - let mouseY = useMotionValue(0) - - function onMouseMove({ currentTarget, clientX, clientY }) { - let { left, top } = currentTarget.getBoundingClientRect() - mouseX.set(clientX - left) - mouseY.set(clientY - top) - } - - return ( - <div - key={block.href} - onMouseMove={onMouseMove} - className="group relative flex rounded-2xl bg-zinc-50 transition-shadow hover:shadow-md hover:shadow-zinc-900/5 dark:bg-white/2.5 dark:hover:shadow-black/5" - > - <ResourcePattern {...block.pattern} mouseX={mouseX} mouseY={mouseY} /> - <div className="absolute inset-0 rounded-2xl ring-1 ring-inset ring-zinc-900/7.5 group-hover:ring-zinc-900/10 dark:ring-white/10 dark:group-hover:ring-white/20" /> - <div className="relative w-full rounded-2xl p-8"> - <div - className={clsx( - 'flex items-center gap-2.5', - block.description && 'mb-4' - )} - > - {block.icon && <ResourceIcon icon={block.icon} />} - <h3 className="text-sm font-semibold leading-7 text-zinc-900 dark:text-white"> - <Link href={block.href}> - <span className="absolute inset-0 rounded-2xl" /> - {block.name} - </Link> - </h3> - </div> - {block.description && ( - <p className="mt-1 text-sm text-zinc-600 dark:text-zinc-400"> - {block.description} - </p> - )} - </div> - </div> - ) -} - -export function BoxGrid({ boxes }) { - return ( - <div className="not-prose mt-4 grid grid-cols-1 gap-8 border-t border-zinc-900/5 pt-10 dark:border-white/5 sm:grid-cols-2 xl:grid-cols-3"> - {boxes.map((box) => ( - <Block key={box.href} block={box} /> - ))} - </div> - ) -} diff --git a/src/components/Breadcrumbs.tsx b/src/components/Breadcrumbs.tsx new file mode 100644 index 000000000..f458c2925 --- /dev/null +++ b/src/components/Breadcrumbs.tsx @@ -0,0 +1,58 @@ +import React from 'react' +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, +} from './ui/breadcrumb' +import { Doc } from '@/content' +import { getNavInfo } from '@/lib/getNavInfo' +import Link from 'next/link' + +interface Props { + doc: Doc + className?: string +} + +const Breadcrumbs: React.FC<Props> = ({ doc, className }) => { + // Implement your component logic here + + const docs = doc.slug.split('/') + + const navInfo = getNavInfo(doc) + + if ( + docs.length === 1 || + !navInfo || + !navInfo.navItem?.breadcrumbParentItem || + navInfo.navItem.breadcrumbRoot + ) { + return null + } + + const { breadcrumbParentItem } = navInfo.navItem + + return ( + <Breadcrumb className={className}> + <BreadcrumbList> + {'href' in breadcrumbParentItem ? ( + <BreadcrumbItem> + <BreadcrumbLink asChild> + <Link href={breadcrumbParentItem.href}> + {breadcrumbParentItem.title} + </Link> + </BreadcrumbLink> + </BreadcrumbItem> + ) : null} + <BreadcrumbSeparator /> + <BreadcrumbItem> + <BreadcrumbPage>{navInfo.navItem.title}</BreadcrumbPage> + </BreadcrumbItem> + </BreadcrumbList> + </Breadcrumb> + ) +} + +export default Breadcrumbs diff --git a/src/components/BuildingBlocks.tsx b/src/components/BuildingBlocks.tsx deleted file mode 100644 index 9234f6636..000000000 --- a/src/components/BuildingBlocks.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import { Heading } from '@/components/Heading' -import { - ArchiveBoxIcon, - CircleStackIcon, - ClockIcon, - GlobeAltIcon, - LockClosedIcon, - MegaphoneIcon, -} from '@heroicons/react/24/outline' -import { BoxGrid } from './BoxGrid' - -const buildingBlocks = [ - { - href: '/apis', - name: 'APIs', - description: - 'Create powerful APIs with easy to setup routes, middleware and security.', - icon: GlobeAltIcon, - pattern: { - y: 16, - squares: [ - [0, 1], - [1, 3], - ], - }, - }, - { - href: '/keyvalue', - name: 'Key Value Stores', - description: - 'A built-in key value store to quickly store and retrieve unstructured data.', - icon: ArchiveBoxIcon, - pattern: { - y: -6, - squares: [ - [-1, 2], - [1, 3], - ], - }, - }, - { - href: '/schedules', - name: 'Schedules', - description: - 'Schedule actions easily using either simple rate expressions or cron.', - icon: ClockIcon, - pattern: { - y: 32, - squares: [ - [0, 2], - [1, 4], - ], - }, - }, - { - href: '/storage', - name: 'Storage', - description: 'Store and retrieve BLOB data effortlessly.', - icon: CircleStackIcon, - pattern: { - y: 22, - squares: [[0, 1]], - }, - }, - { - href: '/messaging', - name: 'Messages', - description: - 'Use Topics and Queues to create event-driven distributed applications', - icon: MegaphoneIcon, - pattern: { - y: 22, - squares: [[0, 1]], - }, - }, - { - href: '/secrets', - name: 'Secrets', - description: 'Securely store and retrieve secrets.', - icon: LockClosedIcon, - pattern: { - y: 22, - squares: [[1, 3]], - }, - }, -] - -export function BuildingBlocks() { - return ( - <div className="my-16 xl:max-w-none"> - <Heading level={2} id="building-blocks"> - Building Blocks - </Heading> - <BoxGrid boxes={buildingBlocks} /> - </div> - ) -} diff --git a/src/components/Button.tsx b/src/components/Button.tsx index f1e037d4d..556e2f423 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -1,8 +1,7 @@ import Link from 'next/link' import clsx from 'clsx' -import { AnchorHTMLAttributes, ButtonHTMLAttributes } from 'react' -function ArrowIcon(props) { +function ArrowIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}> <path @@ -17,34 +16,35 @@ function ArrowIcon(props) { const variantStyles = { primary: - 'rounded-full bg-gray-800 py-1 px-3 text-white hover:bg-zinc-700 dark:bg-primary-400/10 dark:text-primary-200 dark:ring-1 dark:ring-inset dark:ring-primary-400/20 dark:hover:bg-primary-400/10 dark:hover:text-primary-100 dark:hover:ring-primary-300', + 'rounded-full bg-zinc-900 py-1 px-3 text-white hover:bg-zinc-700 dark:bg-emerald-400/10 dark:text-emerald-400 dark:ring-1 dark:ring-inset dark:ring-emerald-400/20 dark:hover:bg-emerald-400/10 dark:hover:text-emerald-300 dark:hover:ring-emerald-300', secondary: 'rounded-full bg-zinc-100 py-1 px-3 text-zinc-900 hover:bg-zinc-200 dark:bg-zinc-800/40 dark:text-zinc-400 dark:ring-1 dark:ring-inset dark:ring-zinc-800 dark:hover:bg-zinc-800 dark:hover:text-zinc-300', filled: - 'rounded-full bg-gray-800 py-1 px-3 text-white hover:bg-zinc-700 dark:bg-primary-500 dark:text-white dark:hover:bg-primary-400', + 'rounded-full bg-zinc-900 py-1 px-3 text-white hover:bg-zinc-700 dark:bg-emerald-500 dark:text-white dark:hover:bg-emerald-400', outline: - 'rounded-full py-1 px-3 text-zinc-700 ring-1 ring-inset ring-zinc-900/10 hover:bg-gray-800/2.5 hover:text-zinc-900 dark:text-zinc-400 dark:ring-white/10 dark:hover:bg-white/5 dark:hover:text-white', - text: 'text-primary-500 hover:text-black dark:text-primary-300 dark:hover:text-white', + 'rounded-full py-1 px-3 text-zinc-700 ring-1 ring-inset ring-zinc-900/10 hover:bg-zinc-900/2.5 hover:text-zinc-900 dark:text-zinc-400 dark:ring-white/10 dark:hover:bg-white/5 dark:hover:text-white', + text: 'text-emerald-500 hover:text-emerald-600 dark:text-emerald-400 dark:hover:text-emerald-500', } -export type ButtonProps = { +type ButtonProps = { variant?: keyof typeof variantStyles - className?: string arrow?: 'left' | 'right' -} & ButtonHTMLAttributes<HTMLButtonElement> & - AnchorHTMLAttributes<HTMLAnchorElement> +} & ( + | React.ComponentPropsWithoutRef<typeof Link> + | (React.ComponentPropsWithoutRef<'button'> & { href?: undefined }) +) -export const Button: React.FC<ButtonProps> = ({ +export function Button({ variant = 'primary', className, children, arrow, ...props -}) => { +}: ButtonProps) { className = clsx( 'inline-flex gap-0.5 justify-center overflow-hidden text-sm font-medium transition', variantStyles[variant], - className + className, ) let arrowIcon = ( @@ -53,22 +53,30 @@ export const Button: React.FC<ButtonProps> = ({ 'mt-0.5 h-5 w-5', variant === 'text' && 'relative top-px', arrow === 'left' && '-ml-1 rotate-180', - arrow === 'right' && '-mr-1' + arrow === 'right' && '-mr-1', )} /> ) - return props.href ? ( - <Link className={className} href={props.href} {...props}> + let inner = ( + <> {arrow === 'left' && arrowIcon} {children} {arrow === 'right' && arrowIcon} + </> + ) + + if (typeof props.href === 'undefined') { + return ( + <button className={className} {...props}> + {inner} + </button> + ) + } + + return ( + <Link className={className} {...props}> + {inner} </Link> - ) : ( - <button className={className} {...props}> - {arrow === 'left' && arrowIcon} - {children} - {arrow === 'right' && arrowIcon} - </button> ) } diff --git a/src/components/Code.tsx b/src/components/Code.tsx deleted file mode 100644 index f17c3d0e9..000000000 --- a/src/components/Code.tsx +++ /dev/null @@ -1,371 +0,0 @@ -// @ts-nocheck - -import { - Children, - createContext, - useContext, - useEffect, - useRef, - useState, -} from 'react' -import { Tab } from '@headlessui/react' -import clsx from 'clsx' -import { create } from 'zustand' - -import { Tag } from '@/components/Tag' - -const languageNames = { - js: 'JavaScript', - ts: 'TypeScript', - javascript: 'JavaScript', - typescript: 'TypeScript', - php: 'PHP', - python: 'Python', - ruby: 'Ruby', - go: 'Go', - java: 'Java', - csharp: 'C#', - kotlin: 'Kotlin', - dart: 'Dart', -} - -const copyToClipboard = (str: string, callback = () => {}) => { - const focused = window.document.hasFocus() - if (focused) { - window.navigator?.clipboard?.writeText(str).then(() => { - callback() - }) - } else { - console.warn('Unable to copy to clipboard') - } -} - -function getPanelTitle({ title, language }) { - return title ?? languageNames[language] ?? 'Code' -} - -function ClipboardIcon(props) { - return ( - <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> - <path - strokeWidth="0" - d="M5.5 13.5v-5a2 2 0 0 1 2-2l.447-.894A2 2 0 0 1 9.737 4.5h.527a2 2 0 0 1 1.789 1.106l.447.894a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-5a2 2 0 0 1-2-2Z" - /> - <path - fill="none" - strokeLinejoin="round" - d="M12.5 6.5a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-5a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2m5 0-.447-.894a2 2 0 0 0-1.79-1.106h-.527a2 2 0 0 0-1.789 1.106L7.5 6.5m5 0-1 1h-3l-1-1" - /> - </svg> - ) -} - -function CopyButton({ code }) { - let [copyCount, setCopyCount] = useState(0) - let copied = copyCount > 0 - - useEffect(() => { - if (copyCount > 0) { - let timeout = setTimeout(() => setCopyCount(0), 1000) - return () => { - clearTimeout(timeout) - } - } - }, [copyCount]) - - return ( - <button - type="button" - className={clsx( - 'group/button absolute right-4 top-3.5 overflow-hidden rounded-full py-1 pl-2 pr-3 text-2xs font-medium opacity-0 backdrop-blur transition focus:opacity-100 group-hover:opacity-100', - copied - ? 'bg-primary-400/10 ring-1 ring-inset ring-primary-400/20' - : 'bg-white/5 hover:bg-white/7.5 dark:bg-white/2.5 dark:hover:bg-white/5' - )} - onClick={() => { - copyToClipboard(code.trim(), () => { - setCopyCount((count) => count + 1) - }) - }} - > - <span - aria-hidden={copied} - className={clsx( - 'pointer-events-none flex items-center gap-0.5 text-zinc-400 transition duration-300', - copied && '-translate-y-1.5 opacity-0' - )} - > - <ClipboardIcon className="h-5 w-5 fill-zinc-500/20 stroke-zinc-500 transition-colors group-hover/button:stroke-zinc-400" /> - Copy - </span> - <span - aria-hidden={!copied} - className={clsx( - 'pointer-events-none absolute inset-0 flex items-center justify-center text-primary-300 transition duration-300', - !copied && 'translate-y-1.5 opacity-0' - )} - > - Copied! - </span> - </button> - ) -} - -function CodePanelHeader({ tag, label }) { - if (!tag && !label) { - return null - } - - return ( - <div className="flex h-9 items-center gap-2 border-y border-b-white/7.5 border-t-transparent bg-gray-800 bg-white/2.5 px-4 dark:border-b-white/5 dark:bg-white/1"> - {tag && ( - <div className="dark flex"> - <Tag variant="small">{tag}</Tag> - </div> - )} - {tag && label && ( - <span className="h-0.5 w-0.5 rounded-full bg-zinc-500" /> - )} - {label && ( - <span - className="font-mono text-xs text-zinc-400" - dangerouslySetInnerHTML={{ __html: label }} - /> - )} - </div> - ) -} - -function CodePanel({ tag, label, code, compare, children }) { - let child = Children.only(children) - - if (compare) { - return child - } - - return ( - <div className="code-panel group dark:bg-white/2.5"> - <CodePanelHeader - tag={child.props.tag ?? tag} - label={child.props.label ?? label} - /> - <div className="relative"> - <pre className="overflow-x-auto p-4 text-xs text-white">{children}</pre> - <CopyButton code={child.props.code ?? code} /> - </div> - </div> - ) -} - -function CodeGroupHeader({ title, children, selectedIndex }) { - let hasTabs = Children.count(children) > 1 - - if (!title && !hasTabs) { - return null - } - - return ( - <div className="flex min-h-[calc(theme(spacing.12)+1px)] flex-wrap items-start gap-x-4 border-b border-zinc-700 bg-zinc-800 px-4 dark:border-zinc-800 dark:bg-transparent"> - {title && ( - <h3 className="mr-auto pt-3 text-xs font-semibold text-white"> - {title} - </h3> - )} - {hasTabs && ( - <Tab.List className="-mb-px flex gap-4 text-xs font-medium"> - {Children.map(children, (child, childIndex) => ( - <Tab - className={clsx( - 'border-b py-3 transition focus:[&:not(:focus-visible)]:outline-none', - childIndex === selectedIndex - ? 'border-primary-400 text-primary-200' - : 'border-transparent text-zinc-400 hover:text-zinc-300' - )} - > - {getPanelTitle(child.props)} - </Tab> - ))} - </Tab.List> - )} - </div> - ) -} - -function CodeGroupPanels({ children, ...props }) { - let hasTabs = Children.count(children) > 1 - - if (hasTabs) { - return ( - <Tab.Panels> - {Children.map(children, (child) => ( - <Tab.Panel> - <CodePanel {...props}>{child}</CodePanel> - </Tab.Panel> - ))} - </Tab.Panels> - ) - } - - return <CodePanel {...props}>{children}</CodePanel> -} - -function usePreventLayoutShift() { - let positionRef = useRef() - let rafRef = useRef() - - useEffect(() => { - return () => { - window.cancelAnimationFrame(rafRef.current) - } - }, []) - - return { - positionRef, - preventLayoutShift(callback) { - let initialTop = positionRef.current.getBoundingClientRect().top - - callback() - - rafRef.current = window.requestAnimationFrame(() => { - let newTop = positionRef.current.getBoundingClientRect().top - window.scrollBy(0, newTop - initialTop) - }) - }, - } -} - -const usePreferredLanguageStore = create((set) => ({ - preferredLanguages: [], - addPreferredLanguage: (language) => - set((state) => ({ - preferredLanguages: [ - ...state.preferredLanguages.filter( - (preferredLanguage) => preferredLanguage !== language - ), - language, - ], - })), - defaultInitialized: false, - setDefaultInitialized: (value) => - set((state) => ({ ...state, defaultInitialized: value })), -})) - -function useTabGroupProps(availableLanguages, defaultIndex) { - let { - preferredLanguages, - addPreferredLanguage, - defaultInitialized, - setDefaultInitialized, - } = usePreferredLanguageStore() - let [selectedIndex, setSelectedIndex] = useState(0) - let activeLanguage = - typeof defaultIndex !== 'undefined' && !defaultInitialized - ? availableLanguages[defaultIndex] - : [...availableLanguages].sort( - (a, z) => - preferredLanguages.indexOf(z) - preferredLanguages.indexOf(a) - )[0] - let languageIndex = availableLanguages.indexOf(activeLanguage) - let newSelectedIndex = languageIndex === -1 ? selectedIndex : languageIndex - - if (newSelectedIndex !== selectedIndex) { - setSelectedIndex(newSelectedIndex) - } - - let { positionRef, preventLayoutShift } = usePreventLayoutShift() - - return { - as: 'div', - ref: positionRef, - selectedIndex, - onChange: (newSelectedIndex) => { - if (typeof defaultIndex !== 'undefined' && !defaultInitialized) { - setDefaultInitialized(true) - } - - preventLayoutShift(() => - addPreferredLanguage(availableLanguages[newSelectedIndex]) - ) - }, - } -} - -export const CodeGroupContext = createContext(false) - -export function CodeGroup({ - children, - title, - compare, - defaultIndex, - ...props -}) { - let languages = Children.map(children, (child) => getPanelTitle(child.props)) - let tabGroupProps = useTabGroupProps(languages, defaultIndex) - let hasTabs = Children.count(children) > 1 - let Container = hasTabs ? Tab.Group : 'div' - let containerProps = hasTabs ? tabGroupProps : {} - let headerProps = hasTabs - ? { selectedIndex: tabGroupProps.selectedIndex } - : {} - - if (compare) { - const groups = {} - - Children.forEach(children, (child) => { - if (child.props.title) { - groups[child.props.title] = [ - ...(groups[child.props.title] || []), - child, - ] - } - }) - - return ( - <div className="gap-4 md:grid md:grid-cols-2"> - {Object.entries(groups).map(([key, value]) => ( - <div key={key}> - {value.map((child, i) => ( - <CodePanel key={i} {...props} compare={compare}> - {child} - </CodePanel> - ))} - </div> - ))} - </div> - ) - } - - return ( - <CodeGroupContext.Provider value={true}> - <Container - {...containerProps} - className="not-prose my-6 overflow-hidden rounded-2xl bg-gray-700 shadow-md dark:bg-gray-800 dark:ring-1 dark:ring-white/10" - > - <CodeGroupHeader title={title} {...headerProps}> - {children} - </CodeGroupHeader> - <CodeGroupPanels {...props}>{children}</CodeGroupPanels> - </Container> - </CodeGroupContext.Provider> - ) -} - -export function Code({ children, ...props }) { - let isGrouped = useContext(CodeGroupContext) - - if (isGrouped) { - return <code {...props} dangerouslySetInnerHTML={{ __html: children }} /> - } - - return <code {...props}>{children}</code> -} - -export function Pre({ children, ...props }) { - let isGrouped = useContext(CodeGroupContext) - - if (isGrouped) { - return children - } - - return <CodeGroup {...props}>{children}</CodeGroup> -} diff --git a/src/components/Community.tsx b/src/components/Community.tsx deleted file mode 100644 index 5c2951f8a..000000000 --- a/src/components/Community.tsx +++ /dev/null @@ -1,132 +0,0 @@ -import Link from 'next/link' -import { motion, useMotionTemplate, useMotionValue } from 'framer-motion' - -import { GridPattern } from '@/components/GridPattern' -import { Heading } from '@/components/Heading' -import { StarIcon } from '@heroicons/react/24/solid' -import Image from 'next/image' -import { cn } from '@/lib/utils' -import { ChatBubbleLeftIcon } from '@heroicons/react/24/outline' -import { FaDiscord } from 'react-icons/fa' -import logoX from '@/images/logos/x.svg' -import { ResourcePattern } from './ResourcePattern' - -const items = [ - { - href: 'https://nitric.io/chat', - name: 'Join our Discord Server', - description: - 'The help forum is a great place to get help with any questions about Nitric.', - icon: FaDiscord, - iconClassName: 'text-[#5865F2]', - pattern: { - y: 16, - squares: [ - [0, 1], - [1, 3], - ], - }, - }, - { - href: 'https://x.com/nitric_io', - name: 'Follow us on X (Twitter)', - description: 'Follow us on X (Twitter) to get the latest updates and news.', - logo: logoX, - pattern: { - y: -6, - squares: [ - [-1, 2], - [1, 3], - ], - }, - }, - { - href: 'https://calendly.com/d/2hs-96w-9gd/nitric-demo-30-min', - name: 'Book a Chat', - description: - 'Arrange a chat with one of our team. We can help answer questions and give 1-on-1 help.', - icon: ChatBubbleLeftIcon, - iconClassName: 'text-secondary-light', - pattern: { - y: -6, - squares: [ - [-1, 2], - [1, 3], - ], - }, - }, - { - href: 'https://github.com/nitrictech/nitric', - name: 'Give us a star on GitHub', - description: 'Show your support with a Star at nitrictech/nitric.', - icon: StarIcon, - iconClassName: 'text-amber-500', - pattern: { - y: -6, - squares: [ - [-1, 2], - [1, 3], - ], - }, - }, -] - -function Asset({ block }) { - let mouseX = useMotionValue(0) - let mouseY = useMotionValue(0) - - function onMouseMove({ currentTarget, clientX, clientY }) { - let { left, top } = currentTarget.getBoundingClientRect() - mouseX.set(clientX - left) - mouseY.set(clientY - top) - } - - return ( - <div - key={block.href} - onMouseMove={onMouseMove} - className="group relative flex rounded-2xl bg-zinc-50 transition-shadow hover:shadow-md hover:shadow-zinc-900/5 dark:bg-white/2.5 dark:hover:shadow-black/5" - > - <ResourcePattern {...block.pattern} mouseX={mouseX} mouseY={mouseY} /> - <div className="absolute inset-0 rounded-2xl ring-1 ring-inset ring-zinc-900/7.5 group-hover:ring-zinc-900/10 dark:ring-white/10 dark:group-hover:ring-white/20" /> - <div className="relative rounded-2xl p-8"> - <div className="flex flex-col gap-2.5"> - {block.icon ? ( - <block.icon className={cn('h-6 w-6', block.iconClassName)} /> - ) : ( - <Image - src={block.logo} - alt={block.name + ' Logo'} - className={`h-6 w-6`} - unoptimized - /> - )} - <h3 className="text-lg font-semibold leading-7 text-zinc-900 dark:text-white"> - <Link href={block.href} target="_blank"> - <span className="absolute inset-0 rounded-2xl" /> - {block.name} - </Link> - </h3> - </div> - <p className="mt-1 text-sm text-zinc-600 dark:text-zinc-400"> - {block.description} - </p> - </div> - </div> - ) -} - -export function Community() { - return ( - <div className="my-16 xl:max-w-none"> - <Heading level={2} id="community"> - Join the community - </Heading> - <div className="not-prose mt-4 grid grid-cols-1 gap-8 border-t border-zinc-900/5 pt-10 dark:border-white/5 sm:grid-cols-2"> - {items.map((block) => ( - <Asset key={block.href} block={block} /> - ))} - </div> - </div> - ) -} diff --git a/src/components/Concepts.tsx b/src/components/Concepts.tsx deleted file mode 100644 index 0c29724a6..000000000 --- a/src/components/Concepts.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import Link from 'next/link' -import { useMotionValue } from 'framer-motion' - -import { Heading } from '@/components/Heading' -import { - MagnifyingGlassIcon, - Square3Stack3DIcon, -} from '@heroicons/react/24/outline' - -import { cn } from '@/lib/utils' -import { ResourcePattern } from './ResourcePattern' - -const items = [ - { - href: '/concepts/how-nitric-works', - name: 'How Nitric works', - description: - 'Learn about the components of Nitric and how it works for development and deployment.', - icon: Square3Stack3DIcon, - pattern: { - y: 16, - squares: [ - [0, 1], - [1, 3], - ], - }, - }, - { - href: '/concepts/comparison', - name: 'Comparison with other tools', - description: 'See how Nitric differs and fits alongside other solutions.', - icon: MagnifyingGlassIcon, - pattern: { - y: -6, - squares: [ - [-1, 2], - [1, 3], - ], - }, - }, -] - -function Block({ block }) { - let mouseX = useMotionValue(0) - let mouseY = useMotionValue(0) - - function onMouseMove({ currentTarget, clientX, clientY }) { - let { left, top } = currentTarget.getBoundingClientRect() - mouseX.set(clientX - left) - mouseY.set(clientY - top) - } - - return ( - <div - key={block.href} - onMouseMove={onMouseMove} - className={ - 'group relative flex rounded-2xl bg-zinc-50 transition-shadow hover:shadow-md hover:shadow-zinc-900/5 dark:bg-white/2.5 dark:hover:shadow-black/5' - } - > - <ResourcePattern {...block.pattern} mouseX={mouseX} mouseY={mouseY} /> - <div className="absolute inset-0 rounded-2xl ring-1 ring-inset ring-zinc-900/7.5 group-hover:ring-zinc-900/10 dark:ring-white/10 dark:group-hover:ring-white/20" /> - <div className="relative w-full rounded-2xl p-8"> - <div - className={cn( - 'flex items-center gap-2.5', - block.description && 'mb-4' - )} - > - {block.icon && ( - <block.icon - className={cn('h-6 w-6 text-primary-light', block.iconClassName)} - /> - )} - <h3 className="text-lg font-semibold leading-7 text-zinc-900 dark:text-white"> - <Link href={block.href}> - <span className="absolute inset-0 rounded-2xl" /> - {block.name} - </Link> - </h3> - </div> - {block.description && ( - <p className="mt-1 text-sm text-zinc-600 dark:text-zinc-400"> - {block.description} - </p> - )} - </div> - </div> - ) -} - -export function Concepts() { - return ( - <div className="my-16 xl:max-w-none"> - <Heading level={2} id="concepts"> - Concepts - </Heading> - <div className="not-prose mt-4 grid grid-cols-1 gap-8 border-t border-zinc-900/5 pt-10 dark:border-white/5 sm:grid-cols-2"> - {items.map((block) => ( - <Block key={block.href} block={block} /> - ))} - </div> - </div> - ) -} diff --git a/src/components/DifferencesGrid.tsx b/src/components/DifferencesGrid.tsx deleted file mode 100644 index 99772b6de..000000000 --- a/src/components/DifferencesGrid.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import { BoxGrid } from './BoxGrid' -import { Heading } from './Heading' - -const assets = [ - { - href: '/concepts/comparison/aws-cdk', - name: 'AWS CDK', - pattern: { - y: 16, - squares: [ - [0, 1], - [1, 3], - ], - }, - }, - { - href: '/concepts/comparison/aws-sam', - name: 'AWS SAM', - pattern: { - y: 16, - squares: [ - [0, 1], - [1, 3], - ], - }, - }, - { - href: '/concepts/comparison/gcp-deployment-manager', - name: 'Google Cloud Deployment Manager', - pattern: { - y: 16, - squares: [ - [0, 1], - [1, 3], - ], - }, - }, - { - href: '/concepts/comparison/bicep', - name: 'Azure Resource Manager', - pattern: { - y: 16, - squares: [ - [0, 1], - [1, 3], - ], - }, - }, - { - href: '/concepts/comparison/pulumi', - name: 'Pulumi', - pattern: { - y: 16, - squares: [ - [0, 1], - [1, 3], - ], - }, - }, - { - href: '/concepts/comparison/terraform', - name: 'Terraform', - pattern: { - y: 16, - squares: [ - [0, 1], - [1, 3], - ], - }, - }, - { - href: '/concepts/comparison/sst', - name: 'SST', - pattern: { - y: 16, - squares: [ - [0, 1], - [1, 3], - ], - }, - }, - { - href: '/concepts/comparison/encore', - name: 'Encore', - pattern: { - y: 16, - squares: [ - [0, 1], - [1, 3], - ], - }, - }, - { - href: '/concepts/comparison/winglang', - name: 'Wing', - pattern: { - y: 16, - squares: [ - [0, 1], - [1, 3], - ], - }, - }, - { - href: '/concepts/comparison/ampt', - name: 'Ampt', - pattern: { - y: 16, - squares: [ - [0, 1], - [1, 3], - ], - }, - }, -] - -export function DifferencesGrid() { - return ( - <div className="my-16 xl:max-w-none"> - <Heading level={2} id="differences"> - Differences From Other Solutions - </Heading> - <BoxGrid boxes={assets} /> - </div> - ) -} diff --git a/src/components/Feedback.tsx b/src/components/Feedback.tsx new file mode 100644 index 000000000..8918bb879 --- /dev/null +++ b/src/components/Feedback.tsx @@ -0,0 +1,106 @@ +'use client' + +import { forwardRef, useState } from 'react' +import { Transition } from '@headlessui/react' +import clsx from 'clsx' + +function CheckIcon(props: React.ComponentPropsWithoutRef<'svg'>) { + return ( + <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> + <circle cx="10" cy="10" r="10" strokeWidth="0" /> + <path + fill="none" + strokeLinecap="round" + strokeLinejoin="round" + strokeWidth="1.5" + d="m6.75 10.813 2.438 2.437c1.218-4.469 4.062-6.5 4.062-6.5" + /> + </svg> + ) +} + +function FeedbackButton( + props: Omit<React.ComponentPropsWithoutRef<'button'>, 'type' | 'className'>, +) { + return ( + <button + type="submit" + className="px-3 text-sm font-medium text-zinc-600 transition hover:bg-zinc-900/2.5 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-white/5 dark:hover:text-white" + {...props} + /> + ) +} + +const FeedbackForm = forwardRef< + React.ElementRef<'form'>, + React.ComponentPropsWithoutRef<'form'> +>(function FeedbackForm({ onSubmit, className, ...props }, ref) { + return ( + <form + {...props} + ref={ref} + onSubmit={onSubmit} + className={clsx( + className, + 'absolute inset-0 flex items-center justify-center gap-6 md:justify-start', + )} + > + <p className="text-sm text-zinc-600 dark:text-zinc-400"> + Was this page helpful? + </p> + <div className="group grid h-8 grid-cols-[1fr,1px,1fr] overflow-hidden rounded-full border border-zinc-900/10 dark:border-white/10"> + <FeedbackButton data-response="yes">Yes</FeedbackButton> + <div className="bg-zinc-900/10 dark:bg-white/10" /> + <FeedbackButton data-response="no">No</FeedbackButton> + </div> + </form> + ) +}) + +const FeedbackThanks = forwardRef< + React.ElementRef<'div'>, + React.ComponentPropsWithoutRef<'div'> +>(function FeedbackThanks({ className, ...props }, ref) { + return ( + <div + {...props} + ref={ref} + className={clsx( + className, + 'absolute inset-0 flex justify-center md:justify-start', + )} + > + <div className="flex items-center gap-3 rounded-full bg-emerald-50/50 py-1 pl-1.5 pr-3 text-sm text-emerald-900 ring-1 ring-inset ring-emerald-500/20 dark:bg-emerald-500/5 dark:text-emerald-200 dark:ring-emerald-500/30"> + <CheckIcon className="h-5 w-5 flex-none fill-emerald-500 stroke-white dark:fill-emerald-200/20 dark:stroke-emerald-200" /> + Thanks for your feedback! + </div> + </div> + ) +}) + +export function Feedback() { + let [submitted, setSubmitted] = useState(false) + + function onSubmit(event: React.FormEvent<HTMLFormElement>) { + event.preventDefault() + + // event.nativeEvent.submitter.dataset.response + // => "yes" or "no" + + setSubmitted(true) + } + + return ( + <div className="relative h-8"> + <Transition show={!submitted}> + <FeedbackForm + className="duration-300 data-[leave]:pointer-events-none data-[closed]:opacity-0" + onSubmit={onSubmit} + /> + </Transition> + <Transition show={submitted}> + <FeedbackThanks className="delay-150 duration-300 data-[closed]:opacity-0" /> + </Transition> + </div> + ) +} diff --git a/src/components/FeedbackForm.tsx b/src/components/FeedbackForm.tsx index 1a5c1b058..33eb60e84 100644 --- a/src/components/FeedbackForm.tsx +++ b/src/components/FeedbackForm.tsx @@ -1,24 +1,14 @@ -import { ForwardRefRenderFunction, forwardRef, useState } from 'react' -import { Button, ButtonProps } from './Button' +'use client' -interface FeedbackFormProps { - onSubmit: (event: React.FormEvent<HTMLFormElement>) => void -} - -function FeedbackButton({ - children, - emoji, - ...props -}: ButtonProps & { emoji: string }) { - return ( - <Button variant="outline" className="group !block" {...props}> - <span className="flex items-center px-1"> - <span className="mr-2 grayscale group-hover:grayscale-0">{emoji}</span> - {children} - </span> - </Button> - ) -} +import { useState } from 'react' +import { Button } from './ui/button' +import { sendFeedback } from '@/actions/sendFeedback' +import { RadioGroup } from './ui/radio-group' +import { Label } from './ui/label' +import { RadioGroupItem } from '@radix-ui/react-radio-group' +import { useFormState } from 'react-dom' +import { CheckIcon } from './icons/CheckIcon' +import { usePathname } from 'next/navigation' const choices = [ { @@ -38,43 +28,63 @@ const choices = [ }, ] -const FeedbackForm: ForwardRefRenderFunction< - HTMLFormElement, - FeedbackFormProps -> = (props, ref) => { - const [choice, setChoice] = useState('') - const { onSubmit } = props +const initialState = { + message: '', +} - const selectedChoice = choices.find((c) => c.value === choice) +const FeedbackForm = () => { + const [state, formAction] = useFormState(sendFeedback, initialState) + const [selected, setSelected] = useState(false) + const pathname = usePathname() - return ( + return state.message ? ( + <div className="flex items-center gap-x-2 text-sm"> + <CheckIcon className="h-5 w-5 flex-none fill-green-500 stroke-white dark:fill-green-200/20 dark:stroke-green-200" /> + Thank you for your feedback! 🙌 + </div> + ) : ( <form - ref={ref} - onSubmit={onSubmit} + action={formAction} className="flex flex-col items-start justify-start gap-6" > - <p className="text-sm text-zinc-900 dark:text-white"> + <input + name="ua" + value={navigator.userAgent} + className="hidden" + readOnly + /> + <input + name="url" + value={`/docs${pathname}`} + className="hidden" + readOnly + /> + <Label htmlFor="choice" className="text-sm text-zinc-900 dark:text-white"> What did you think of this content? - </p> - {choice == '' && ( - <div className="flex flex-col gap-2 md:flex-row"> - {choices.map(({ label, value, emoji }) => ( - <FeedbackButton - emoji={emoji} - key={value} - onClick={() => setChoice(value)} - > + </Label> + <RadioGroup + className="flex flex-col gap-2 md:flex-row" + onChange={() => { + if (!selected) setSelected(true) + }} + name="choice" + id="choice" + > + {choices.map(({ label, value, emoji }) => ( + <div key={value} className="group flex items-center"> + <RadioGroupItem value={value} id={value} className="group"> + <span className="zincscale group-checked:zincscale-0 group-data-[state=checked]:zincscale-0 mr-2"> + {emoji} + </span> + </RadioGroupItem> + <Label htmlFor={value} className="cursor-pointer text-xs"> {label} - </FeedbackButton> - ))} - </div> - )} - {choice != '' && ( - <div className="flex w-full max-w-[400px] flex-col gap-4 rounded-lg p-2 text-gray-700 shadow-md ring-1 ring-gray-300 dark:bg-white/2.5 dark:text-gray-100 dark:ring-white/10 dark:hover:shadow-black/5"> - <div className="flex items-center"> - <span className="mr-2">{selectedChoice?.emoji}</span> - {selectedChoice?.label} + </Label> </div> + ))} + </RadioGroup> + {selected && ( + <div className="flex w-full max-w-[400px] flex-col gap-4 rounded-lg p-2 text-zinc-700 shadow-md ring-1 ring-zinc-300 dark:bg-white/2.5 dark:text-zinc-100 dark:ring-white/10 dark:hover:shadow-black/5"> <label htmlFor="comment" className="sr-only"> Comment </label> @@ -83,21 +93,14 @@ const FeedbackForm: ForwardRefRenderFunction< rows={5} name="comment" id="comment" - className="block w-full rounded-md border-0 bg-white p-2 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-primary-600 dark:bg-gray-700/70 dark:text-gray-50 dark:ring-gray-600 sm:text-sm sm:leading-6" + className="block w-full rounded-md border-0 bg-white p-2 py-1.5 text-zinc-900 shadow-sm ring-1 ring-inset ring-zinc-300 placeholder:text-zinc-400 focus:ring-2 focus:ring-inset focus:ring-primary-600 dark:bg-zinc-700/70 dark:text-zinc-50 dark:ring-zinc-600 sm:text-sm sm:leading-6" placeholder="We'd love to hear your feedback!" defaultValue={''} autoFocus /> </div> <div className="mt-2 flex justify-end"> - <Button - data-response={selectedChoice?.value} - type="submit" - variant="filled" - className="bg-primary" - > - Send - </Button> + <Button type="submit">Send</Button> </div> </div> )} @@ -105,4 +108,4 @@ const FeedbackForm: ForwardRefRenderFunction< ) } -export default forwardRef(FeedbackForm) +export default FeedbackForm diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index c33cd8759..926c47049 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -1,184 +1,26 @@ -import { forwardRef, Fragment, useState } from 'react' import Link from 'next/link' -import { useRouter } from 'next/router' -import { Transition } from '@headlessui/react' -import { Button } from '@/components/Button' -import { useCurrentNav } from '@/nav.config' -import FeedbackForm from './FeedbackForm' -import { GitHubIcon } from './icons/GitHubIcon' -import { ArrowTopRightOnSquareIcon } from '@heroicons/react/24/outline' -import type { FeedbackRequestBody } from '@/pages/api/feedback' -import { Spinner } from './Spinner' - -function CheckIcon(props) { +function XIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> - <circle cx="10" cy="10" r="10" strokeWidth="0" /> - <path - fill="none" - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth="1.5" - d="m6.75 10.813 2.438 2.437c1.218-4.469 4.062-6.5 4.062-6.5" - /> + <path d="M11.1527 8.92804L16.2525 3H15.044L10.6159 8.14724L7.07919 3H3L8.34821 10.7835L3 17H4.20855L8.88474 11.5643L12.6198 17H16.699L11.1524 8.92804H11.1527ZM9.49748 10.8521L8.95559 10.077L4.644 3.90978H6.50026L9.97976 8.88696L10.5216 9.66202L15.0446 16.1316H13.1883L9.49748 10.8524V10.8521Z" /> </svg> ) } -const FeedbackThanks = forwardRef(function FeedbackThanks( - { submitting }: { submitting: boolean }, - ref -) { +function GitHubIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( - <div - ref={ref as any} - className="flex items-center justify-center md:justify-start" - > - <div className="m-1 flex items-center gap-3 rounded-full bg-primary-50/50 py-1 pl-1.5 pr-3 text-sm text-primary-900 ring-1 ring-inset ring-primary-500/20 dark:bg-primary-500/5 dark:text-primary-200 dark:ring-primary-500/30"> - {submitting ? ( - <> - <Spinner /> - Submitting feedback - </> - ) : ( - <> - <CheckIcon className="h-5 w-5 flex-none fill-primary-500 stroke-white dark:fill-primary-200/20 dark:stroke-primary-200" /> - Thank you for your feedback! 🙌 - </> - )} - </div> - </div> - ) -}) - -function Feedback() { - const [submitting, setSubmitting] = useState(false) - const [submitted, setSubmitted] = useState(false) - - async function onSubmit(event) { - event.preventDefault() - - if (submitting) return - - const comment = event.target.elements.comment.value - - const data: FeedbackRequestBody = { - url: window.location.href, - ua: navigator.userAgent, - comment, - // "yes" or "no" - answer: event.nativeEvent.submitter.dataset.response, - } - - setSubmitting(true) - - await fetch('/docs/api/feedback', { - method: 'POST', - body: JSON.stringify(data), - headers: { - 'Content-Type': 'application/json', - }, - }) - - setSubmitting(false) - setSubmitted(true) - } - - return ( - <div className="relative"> - <Transition - show={!submitted && !submitting} - as={Fragment} - leaveFrom="opacity-100" - leaveTo="opacity-0" - leave="pointer-events-none duration-300" - > - <FeedbackForm onSubmit={onSubmit} /> - </Transition> - <Transition - show={submitted || submitting} - as={Fragment} - enterFrom="opacity-0" - enterTo="opacity-100" - enter="delay-150 duration-300" - > - <FeedbackThanks submitting={submitting} /> - </Transition> - </div> - ) -} - -function PageLink({ label, page, previous = false }) { - return ( - <> - <Button - href={page.href} - aria-label={`${label}: ${page.title}`} - variant="secondary" - arrow={previous ? 'left' : 'right'} - > - {label} - </Button> - <Link - href={page.href} - tabIndex={-1} - aria-hidden="true" - className="text-base font-semibold text-zinc-900 transition hover:text-zinc-600 dark:text-white dark:hover:text-zinc-300" - > - {page.title} - </Link> - </> - ) -} - -function PageNavigation() { - let router = useRouter() - let { navigation: currentNav } = useCurrentNav() - - if (!currentNav) return null - - let allPages = currentNav.flatMap((group) => group.links) - let currentPageIndex = allPages.findIndex( - (page) => page.href === router.pathname - ) - - if (currentPageIndex === -1) { - return null - } - - let previousPage = allPages[currentPageIndex - 1] - let nextPage = allPages[currentPageIndex + 1] - - if (!previousPage && !nextPage) { - return null - } - - return ( - <div className="flex"> - {previousPage && ( - <div className="flex flex-col items-start gap-3"> - <PageLink label="Previous" page={previousPage} previous /> - </div> - )} - {nextPage && ( - <div className="ml-auto flex flex-col items-end gap-3"> - <PageLink label="Next" page={nextPage} /> - </div> - )} - </div> - ) -} - -function TwitterIcon(props) { - return ( - <svg viewBox="0 0 24 24" aria-hidden="true" {...props}> - <path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" /> + <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> + <path + fillRule="evenodd" + clipRule="evenodd" + d="M10 1.667c-4.605 0-8.334 3.823-8.334 8.544 0 3.78 2.385 6.974 5.698 8.106.417.075.573-.182.573-.406 0-.203-.011-.875-.011-1.592-2.093.397-2.635-.522-2.802-1.002-.094-.246-.5-1.005-.854-1.207-.291-.16-.708-.556-.01-.567.656-.01 1.124.62 1.281.876.75 1.292 1.948.93 2.427.705.073-.555.291-.93.531-1.143-1.854-.213-3.791-.95-3.791-4.218 0-.929.322-1.698.854-2.296-.083-.214-.375-1.09.083-2.265 0 0 .698-.224 2.292.876a7.576 7.576 0 0 1 2.083-.288c.709 0 1.417.096 2.084.288 1.593-1.11 2.291-.875 2.291-.875.459 1.174.167 2.05.084 2.263.53.599.854 1.357.854 2.297 0 3.278-1.948 4.005-3.802 4.219.302.266.563.78.563 1.58 0 1.143-.011 2.061-.011 2.35 0 .224.156.491.573.405a8.365 8.365 0 0 0 4.11-3.116 8.707 8.707 0 0 0 1.567-4.99c0-4.721-3.73-8.545-8.334-8.545Z" + /> </svg> ) } -function DiscordIcon(props) { +function DiscordIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path d="M16.238 4.515a14.842 14.842 0 0 0-3.664-1.136.055.055 0 0 0-.059.027 10.35 10.35 0 0 0-.456.938 13.702 13.702 0 0 0-4.115 0 9.479 9.479 0 0 0-.464-.938.058.058 0 0 0-.058-.027c-1.266.218-2.497.6-3.664 1.136a.052.052 0 0 0-.024.02C1.4 8.023.76 11.424 1.074 14.782a.062.062 0 0 0 .024.042 14.923 14.923 0 0 0 4.494 2.272.058.058 0 0 0 .064-.02c.346-.473.654-.972.92-1.496a.057.057 0 0 0-.032-.08 9.83 9.83 0 0 1-1.404-.669.058.058 0 0 1-.029-.046.058.058 0 0 1 .023-.05c.094-.07.189-.144.279-.218a.056.056 0 0 1 .058-.008c2.946 1.345 6.135 1.345 9.046 0a.056.056 0 0 1 .059.007c.09.074.184.149.28.22a.058.058 0 0 1 .023.049.059.059 0 0 1-.028.046 9.224 9.224 0 0 1-1.405.669.058.058 0 0 0-.033.033.056.056 0 0 0 .002.047c.27.523.58 1.022.92 1.495a.056.056 0 0 0 .062.021 14.878 14.878 0 0 0 4.502-2.272.055.055 0 0 0 .016-.018.056.056 0 0 0 .008-.023c.375-3.883-.63-7.256-2.662-10.246a.046.046 0 0 0-.023-.021Zm-9.223 8.221c-.887 0-1.618-.814-1.618-1.814s.717-1.814 1.618-1.814c.908 0 1.632.821 1.618 1.814 0 1-.717 1.814-1.618 1.814Zm5.981 0c-.887 0-1.618-.814-1.618-1.814s.717-1.814 1.618-1.814c.908 0 1.632.821 1.618 1.814 0 1-.71 1.814-1.618 1.814Z" /> @@ -186,7 +28,7 @@ function DiscordIcon(props) { ) } -function YouTubeIcon(props) { +function YouTubeIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 576 512" aria-hidden="true" {...props}> <path d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"></path> @@ -194,9 +36,22 @@ function YouTubeIcon(props) { ) } -function SocialLink({ href, icon: Icon, children }) { +function SocialLink({ + href, + icon: Icon, + children, +}: { + href: string + icon: React.ComponentType<{ className?: string }> + children: React.ReactNode +}) { return ( - <Link href={href} className="group" target="_blank" rel="noopener"> + <Link + href={href} + className="group" + target="_blank" + rel="noopener noreferrer" + > <span className="sr-only">{children}</span> <Icon className="h-5 w-5 fill-zinc-700 transition group-hover:fill-zinc-900 dark:group-hover:fill-zinc-500" /> </Link> @@ -204,13 +59,8 @@ function SocialLink({ href, icon: Icon, children }) { } function SmallPrint() { - const router = useRouter() - return ( <div className="flex flex-col gap-10 border-t border-zinc-900/5 pt-8 dark:border-white/5"> - <div className="w-full"> - <Feedback key={router.pathname} /> - </div> <div className="flex flex-col items-center justify-between gap-5 sm:flex-row"> <div className="flex gap-4"> <p className="text-xs text-zinc-500 dark:text-zinc-300"> @@ -231,8 +81,8 @@ function SmallPrint() { </Link> </div> <div className="flex gap-4"> - <SocialLink href="https://x.com/nitric_io" icon={TwitterIcon}> - Follow us on Twitter + <SocialLink href="https://x.com/nitric_io" icon={XIcon}> + Follow us on X </SocialLink> <SocialLink href="https://github.com/nitrictech/nitric" @@ -255,27 +105,9 @@ function SmallPrint() { ) } -export function Footer({ disableEditGithub }) { - const router = useRouter() - - const branch = process.env.NEXT_PUBLIC_GITHUB_BRANCH || 'main' - +export function Footer() { return ( - <footer className="mx-auto max-w-2xl space-y-10 pb-16 lg:max-w-5xl"> - <div className="flex flex-col items-end gap-8 md:flex-row"> - {!disableEditGithub && ( - <div className="flex w-full items-center justify-center"> - <Link - href={`https://github.com/nitrictech/docs/edit/${branch}/src/pages${router.pathname}.mdx`} - className="flex items-center gap-1 text-sm text-zinc-600 hover:underline dark:text-zinc-400 md:ml-auto" - > - Edit this page on GitHub - <ArrowTopRightOnSquareIcon className="h-4 w-4" /> - </Link> - </div> - )} - </div> - <PageNavigation /> + <footer className="mx-auto w-full space-y-10 pb-16 lg:max-w-7xl"> <SmallPrint /> </footer> ) diff --git a/src/components/GettingStarted.tsx b/src/components/GettingStarted.tsx deleted file mode 100644 index 76c0ff11b..000000000 --- a/src/components/GettingStarted.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import Link from 'next/link' -import { useMotionValue } from 'framer-motion' - -import clsx from 'clsx' -import { cn } from '@/lib/utils' -import { - InformationCircleIcon, - RocketLaunchIcon, - WrenchScrewdriverIcon, -} from '@heroicons/react/24/outline' -import { ResourcePattern } from './ResourcePattern' - -function Block({ block }) { - let mouseX = useMotionValue(0) - let mouseY = useMotionValue(0) - - function onMouseMove({ currentTarget, clientX, clientY }) { - let { left, top } = currentTarget.getBoundingClientRect() - mouseX.set(clientX - left) - mouseY.set(clientY - top) - } - - return ( - <div - key={block.href} - onMouseMove={onMouseMove} - className={ - 'group relative flex rounded-2xl bg-zinc-50 transition-shadow hover:shadow-md hover:shadow-zinc-900/5 dark:bg-white/2.5 dark:hover:shadow-black/5' - } - > - <ResourcePattern {...block.pattern} mouseX={mouseX} mouseY={mouseY} /> - <div className="absolute inset-0 rounded-2xl ring-1 ring-inset ring-zinc-900/7.5 group-hover:ring-zinc-900/10 dark:ring-white/10 dark:group-hover:ring-white/20" /> - <div className="relative w-full rounded-2xl p-8"> - <div - className={clsx( - 'flex items-center gap-2.5', - block.description && 'mb-4' - )} - > - {block.icon && ( - <block.icon - className={cn('h-6 w-6 text-primary-light', block.iconClassName)} - /> - )} - <h3 className="text-lg font-semibold leading-7 text-zinc-900 dark:text-white"> - <Link href={block.href}> - <span className="absolute inset-0 rounded-2xl" /> - {block.name} - </Link> - </h3> - </div> - {block.description && ( - <p className="mt-1 text-sm text-zinc-600 dark:text-zinc-400"> - {block.description} - </p> - )} - </div> - </div> - ) -} - -const gettingStartedBlocks = [ - { - href: '/concepts/introduction', - name: 'What is Nitric', - icon: InformationCircleIcon, - description: - 'Learn about the Nitric architecture and how the framework works under the hood.', - }, - { - href: '/getting-started/quickstart', - name: 'Get started with Nitric', - icon: RocketLaunchIcon, - description: - 'Start building and deploy in minutes with our Quick Start guide.', - }, - { - href: '/reference/providers/custom/building-custom-provider', - name: 'Customize and extend Nitric', - icon: WrenchScrewdriverIcon, - description: 'Build your own cloud providers or extend ours.', - }, -] - -export function GettingStarted() { - return ( - <div className="my-16 xl:max-w-none"> - <div className="not-prose mt-4 grid grid-cols-1 gap-8 sm:grid-cols-2 xl:grid-cols-3"> - {gettingStartedBlocks.map((box) => ( - <Block key={box.href} block={box} /> - ))} - </div> - </div> - ) -} diff --git a/src/components/GitHubStarCount.tsx b/src/components/GitHubStarCount.tsx new file mode 100644 index 000000000..335335e63 --- /dev/null +++ b/src/components/GitHubStarCount.tsx @@ -0,0 +1,71 @@ +'use client' + +import clsx from 'clsx' +import React, { useEffect, useState } from 'react' + +const STAR_COUNT_KEY = 'nitric_github_star_count' +const STAR_COUNT_TIMESTAMP_KEY = 'nitric_github_star_count_timestamp' +const CACHE_DURATION = 1000 * 60 * 60 * 24 // 24 hours + +// Function to format star count like GitHub (e.g., 1.5k, 2M) +const formatStarCount = (count: number) => { + if (count >= 1000000) { + return (count / 1000000).toFixed(1).replace(/\.0$/, '') + 'M' + } else if (count >= 1000) { + return (count / 1000).toFixed(1).replace(/\.0$/, '') + 'k' + } + return count +} + +const GitHubStarCount = ({ className }: { className?: string }) => { + const [starCount, setStarCount] = useState(1100) + + useEffect(() => { + const fetchStarCount = async () => { + try { + const cachedStarCount = localStorage.getItem(STAR_COUNT_KEY) + const cachedTimestamp = localStorage.getItem(STAR_COUNT_TIMESTAMP_KEY) + const currentTime = new Date().getTime() + + // Check if cached data exists and is still valid + if ( + cachedStarCount && + cachedTimestamp && + currentTime - parseInt(cachedTimestamp) < CACHE_DURATION + ) { + setStarCount(JSON.parse(cachedStarCount)) + } else { + // Fetch from GitHub API if cache is expired or doesn't exist + const response = await fetch( + 'https://api.github.com/repos/nitrictech/nitric', + ) + if (!response.ok) { + throw new Error('Failed to fetch star count') + } + + const repoData = await response.json() + const starCount = repoData.stargazers_count + + // Update state with the new star count + setStarCount(starCount) + + // Cache the result with the current timestamp + localStorage.setItem(STAR_COUNT_KEY, JSON.stringify(starCount)) + localStorage.setItem(STAR_COUNT_TIMESTAMP_KEY, currentTime.toString()) + } + } catch (error) { + console.error('Error fetching star count:', error) + } + } + + fetchStarCount() + }, []) + + return ( + <div className={clsx('text-xs uppercase dark:text-zinc-300', className)}> + {formatStarCount(starCount)} + </div> + ) +} + +export default GitHubStarCount diff --git a/src/components/GridPattern.tsx b/src/components/GridPattern.tsx index be77ca4e1..520299114 100644 --- a/src/components/GridPattern.tsx +++ b/src/components/GridPattern.tsx @@ -1,15 +1,5 @@ -import React from 'react' import { useId } from 'react' -type GridPatternProps = { - width: number - height: number - x?: number | string - y?: number | string - squares?: [number, number][] - className?: string -} - export function GridPattern({ width, height, @@ -17,7 +7,13 @@ export function GridPattern({ y, squares, ...props -}: GridPatternProps) { +}: React.ComponentPropsWithoutRef<'svg'> & { + width: number + height: number + x: string | number + y: string | number + squares: Array<[x: number, y: number]> +}) { let patternId = useId() return ( diff --git a/src/components/Guides.tsx b/src/components/Guides.tsx new file mode 100644 index 000000000..6225c5577 --- /dev/null +++ b/src/components/Guides.tsx @@ -0,0 +1,54 @@ +import { Button } from '@/components/Button' +import { Heading } from '@/components/ui/heading' + +const guides = [ + { + href: '/authentication', + name: 'Authentication', + description: 'Learn how to authenticate your API requests.', + }, + { + href: '/pagination', + name: 'Pagination', + description: 'Understand how to work with paginated responses.', + }, + { + href: '/errors', + name: 'Errors', + description: + 'Read about the different types of errors returned by the API.', + }, + { + href: '/webhooks', + name: 'Webhooks', + description: + 'Learn how to programmatically configure webhooks for your app.', + }, +] + +export function Guides() { + return ( + <div className="my-16 xl:max-w-none"> + <Heading level={2} id="guides"> + Guides + </Heading> + <div className="not-prose mt-4 grid grid-cols-1 gap-8 border-t border-zinc-900/5 pt-10 dark:border-white/5 sm:grid-cols-2 xl:grid-cols-4"> + {guides.map((guide) => ( + <div key={guide.href}> + <h3 className="text-sm font-semibold text-zinc-900 dark:text-white"> + {guide.name} + </h3> + <p className="mt-1 text-sm text-zinc-600 dark:text-zinc-400"> + {guide.description} + </p> + <p className="mt-4"> + <Button href={guide.href} variant="text" arrow="right"> + Read more + </Button> + </p> + </div> + ))} + </div> + </div> + ) +} diff --git a/src/components/GuidesGrid.tsx b/src/components/GuidesGrid.tsx deleted file mode 100644 index a47258780..000000000 --- a/src/components/GuidesGrid.tsx +++ /dev/null @@ -1,183 +0,0 @@ -import Link from 'next/link' -import { motion, useMotionTemplate, useMotionValue } from 'framer-motion' - -import { GridPattern } from '@/components/GridPattern' -import { Heading } from '@/components/Heading' -import { ChatBubbleIcon } from '@/components/icons/ChatBubbleIcon' -import { EnvelopeIcon } from '@/components/icons/EnvelopeIcon' -import { UserIcon } from '@/components/icons/UserIcon' -import { UsersIcon } from '@/components/icons/UsersIcon' -import { CogIcon } from '@/components/icons/CogIcon' -import { DocumentIcon } from '@/components/icons/DocumentIcon' -import { ReactNode } from 'react' -import { cn } from '@/lib/utils' - -function GuideIcon({ icon: Icon, className }) { - return ( - <div className="flex h-7 w-7 items-center justify-center rounded-full bg-gray-800/5 ring-1 ring-zinc-900/25 backdrop-blur-[2px] transition duration-300 group-hover:bg-white/50 group-hover:ring-zinc-900/25 dark:bg-white/7.5 dark:ring-white/15 dark:group-hover:bg-primary-300/10 dark:group-hover:ring-primary-400"> - <Icon - className={cn( - 'h-5 w-5 fill-zinc-700/10 stroke-zinc-700 transition-colors duration-300 group-hover:stroke-zinc-900 dark:fill-white/10 dark:stroke-zinc-400 dark:group-hover:fill-primary-300/10 dark:group-hover:stroke-primary-400', - className - )} - /> - </div> - ) -} - -function GuideBackgroundPattern({ mouseX, mouseY, ...gridProps }) { - let maskImage = useMotionTemplate`radial-gradient(180px at ${mouseX}px ${mouseY}px, white, transparent)` - let style = { maskImage, WebkitMaskImage: maskImage } - - return ( - <div className="pointer-events-none"> - <div className="absolute inset-0 rounded-2xl transition duration-300 [mask-image:linear-gradient(white,transparent)] group-hover:opacity-50"> - <GridPattern - width={72} - height={56} - x="50%" - className="absolute inset-x-0 inset-y-[-30%] h-[160%] w-full skew-y-[-18deg] fill-black/[0.02] stroke-black/5 dark:fill-white/1 dark:stroke-white/2.5" - {...gridProps} - /> - </div> - <motion.div - className="absolute inset-0 rounded-2xl bg-gradient-to-r from-primary-100 to-secondary-100 opacity-0 transition duration-300 group-hover:opacity-100 dark:from-primary/10 dark:to-secondary/10" - style={style} - /> - <motion.div - className="absolute inset-0 rounded-2xl opacity-0 mix-blend-overlay transition duration-300 group-hover:opacity-100" - style={style} - > - <GridPattern - width={72} - height={56} - x="50%" - className="absolute inset-x-0 inset-y-[-30%] h-[160%] w-full skew-y-[-18deg] fill-black/50 stroke-black/70 dark:fill-white/2.5 dark:stroke-white/10" - {...gridProps} - /> - </motion.div> - </div> - ) -} - -const GuideIcons = { - cog: CogIcon, - document: DocumentIcon, - user: UserIcon, - users: UsersIcon, - chat: ChatBubbleIcon, - envelope: EnvelopeIcon, -} as const - -type GuideIconName = keyof typeof GuideIcons - -interface GuideLinkProps { - href: string - name: string - description: string - icon: GuideIconName - customIcon?: any - iconClassName?: string - pattern?: 1 | 2 | 3 | 4 -} - -const patterns = [ - { - y: 16, - squares: [ - [0, 1], - [1, 3], - ], - }, - { - y: -6, - squares: [ - [-1, 2], - [1, 3], - ], - }, - { - y: 32, - squares: [ - [0, 2], - [1, 4], - ], - }, - { - y: 22, - squares: [[0, 1]], - }, -] - -export function Guide({ - href, - name, - description, - icon = 'document', - pattern: patternId = 1, - customIcon, - iconClassName, -}: GuideLinkProps) { - let mouseX = useMotionValue(0) - let mouseY = useMotionValue(0) - - const pattern = patterns[patternId] - - function onMouseMove({ currentTarget, clientX, clientY }) { - let { left, top } = currentTarget.getBoundingClientRect() - mouseX.set(clientX - left) - mouseY.set(clientY - top) - } - - return ( - <div - key={href} - onMouseMove={onMouseMove} - className="group relative flex rounded-2xl bg-zinc-50 transition-shadow hover:shadow-md hover:shadow-zinc-900/5 dark:bg-white/2.5 dark:hover:shadow-black/5" - > - <GuideBackgroundPattern {...pattern} mouseX={mouseX} mouseY={mouseY} /> - <div className="absolute inset-0 rounded-2xl ring-1 ring-inset ring-zinc-900/7.5 group-hover:ring-zinc-900/10 dark:ring-white/10 dark:group-hover:ring-white/20" /> - <div className="relative rounded-2xl px-4 pb-4 pt-16"> - <GuideIcon - icon={customIcon || GuideIcons[icon]} - className={iconClassName} - /> - <h3 className="mt-4 text-sm font-semibold leading-7 text-zinc-900 dark:text-white"> - <Link href={href}> - <span className="absolute inset-0 rounded-2xl" /> - {name} - </Link> - </h3> - <p className="mt-1 text-sm text-zinc-600 dark:text-zinc-400"> - {description} - </p> - </div> - </div> - ) -} - -interface GuideGridProps { - title?: string - children: ReactNode -} - -export function GuidesGrid({ title, children }: GuideGridProps) { - return ( - <div className={cn('xl:max-w-none', title ? 'my-16' : 'my-8')}> - {title && ( - <Heading level={2} id="resources"> - {title} - </Heading> - )} - - <div - className={cn( - 'not-prose mt-4 grid grid-cols-1 gap-8 sm:grid-cols-2 xl:grid-cols-4', - title && 'border-t border-zinc-900/5 pt-10 dark:border-white/5' - )} - > - {children} - </div> - </div> - ) -} diff --git a/src/components/Header.tsx b/src/components/Header.tsx deleted file mode 100644 index f65431b0b..000000000 --- a/src/components/Header.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import { forwardRef } from 'react' -import Link from 'next/link' -import clsx from 'clsx' -import { motion, useScroll, useTransform } from 'framer-motion' - -import { Logo } from '@/components/Logo' -import { - MobileNavigation, - useIsInsideMobileNavigation, -} from '@/components/MobileNavigation' -import { useMobileNavigationStore } from '@/components/MobileNavigation' -import { ModeToggle } from '@/components/ModeToggle' -import { Search } from '@/components/Search' -import { topLevelNavigation } from '@/nav.config' -import { GitHubIcon } from './icons/GitHubIcon' -import { FaDiscord } from 'react-icons/fa' -import { StarIcon } from '@heroicons/react/24/outline' - -function TopLevelNavItem({ href, children }) { - const external = href.startsWith('http') - - return ( - <li className="flex"> - <Link - href={href} - target={external ? '_blank' : undefined} - rel={external ? 'noreferrer noopener' : undefined} - className="group flex text-sm font-semibold leading-5 text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white" - > - {children} - </Link> - </li> - ) -} - -export const Header = forwardRef<HTMLDivElement, { className?: string }>( - function Header({ className }, ref) { - let { isOpen: mobileNavIsOpen } = useMobileNavigationStore() - let isInsideMobileNavigation = useIsInsideMobileNavigation() - - let { scrollY } = useScroll() - let bgOpacityLight = useTransform(scrollY, [0, 72], [0.5, 0.9]) - let bgOpacityDark = useTransform(scrollY, [0, 72], [0.2, 0.8]) - - return ( - <motion.div - ref={ref} - className={clsx( - className, - 'fixed inset-x-0 top-0 z-50 flex h-14 items-center justify-between gap-12 px-4 transition sm:px-6 lg:left-72 lg:z-30 lg:px-8 xl:left-80', - !isInsideMobileNavigation && - 'backdrop-blur-sm dark:backdrop-blur lg:left-72 xl:left-80', - isInsideMobileNavigation - ? 'bg-white dark:bg-gray-800' - : 'bg-white/[var(--bg-opacity-light)] dark:bg-gray-800/[var(--bg-opacity-dark)]' - )} - style={ - { - '--bg-opacity-light': bgOpacityLight, - '--bg-opacity-dark': bgOpacityDark, - } as any - } - > - <div - className={clsx( - 'absolute inset-x-0 top-full h-px transition', - (isInsideMobileNavigation || !mobileNavIsOpen) && - 'bg-gray-800/7.5 dark:bg-white/7.5' - )} - /> - <div className="hidden lg:block"> - <Search /> - </div> - <div className="flex items-center gap-5 lg:hidden"> - <MobileNavigation /> - <Link href="/" aria-label="Home"> - <Logo className="h-6" /> - </Link> - </div> - <div className="flex items-center gap-5"> - <nav className="hidden md:block"> - <ul role="list" className="flex items-center gap-8"> - {topLevelNavigation.map(({ text, href }) => ( - <TopLevelNavItem key={href} href={href}> - {text} - </TopLevelNavItem> - ))} - - <TopLevelNavItem href="https://github.com/nitrictech/nitric"> - <StarIcon className="mr-1 h-5 w-5 text-zinc-600 group-hover:scale-105 dark:text-gray" /> - Star on GitHub - </TopLevelNavItem> - </ul> - </nav> - <div className="hidden md:block md:h-5 md:w-px md:bg-gray-800/10 md:dark:bg-white/15" /> - <div className="flex items-center gap-4"> - <div className="lg:hidden"> - <Search /> - </div> - <Link - className="hidden h-6 w-6 items-center justify-center rounded-md transition hover:bg-gray-800/5 dark:hover:bg-white/5 lg:flex" - href="https://nitric.io/chat" - target="_blank" - > - <FaDiscord className="h-5 w-5 fill-zinc-600 dark:fill-gray" /> - </Link> - <Link - className="hidden h-6 w-6 items-center justify-center rounded-md transition hover:bg-gray-800/5 dark:hover:bg-white/5 md:hidden lg:flex" - href="https://github.com/nitrictech/nitric" - target="_blank" - > - <GitHubIcon className="h-5 w-5 fill-zinc-600 dark:fill-gray" /> - </Link> - <ModeToggle /> - </div> - </div> - </motion.div> - ) - } -) diff --git a/src/components/Heading.tsx b/src/components/Heading.tsx deleted file mode 100644 index b8dca82d0..000000000 --- a/src/components/Heading.tsx +++ /dev/null @@ -1,113 +0,0 @@ -// @ts-nocheck - -import { useEffect, useRef } from 'react' -import Link from 'next/link' -import { useInView } from 'framer-motion' - -import { useSectionStore } from '@/components/SectionProvider' -import { Tag } from '@/components/Tag' -import { remToPx } from '@/lib/remToPx' - -function AnchorIcon(props) { - return ( - <svg - viewBox="0 0 20 20" - fill="none" - strokeLinecap="round" - aria-hidden="true" - {...props} - > - <path d="m6.5 11.5-.964-.964a3.535 3.535 0 1 1 5-5l.964.964m2 2 .964.964a3.536 3.536 0 0 1-5 5L8.5 13.5m0-5 3 3" /> - </svg> - ) -} - -function Eyebrow({ tag, label }) { - if (!tag && !label) { - return null - } - - return ( - <div className="flex items-center gap-x-3"> - {tag && <Tag>{tag}</Tag>} - {tag && label && ( - <span className="h-0.5 w-0.5 rounded-full bg-zinc-300 dark:bg-zinc-600" /> - )} - {label && ( - <span className="font-mono text-xs text-zinc-400">{label}</span> - )} - </div> - ) -} - -function Anchor({ id, inView, children }) { - return ( - <Link - href={`#${id}`} - className="group text-inherit no-underline hover:text-inherit" - > - {inView && ( - <div className="absolute ml-[calc(-1*var(--width))] mt-1 hidden w-[var(--width)] opacity-0 transition [--width:calc(2.625rem+0.5px+50%-min(50%,calc(theme(maxWidth.lg)+theme(spacing.8))))] group-hover:opacity-100 group-focus:opacity-100 md:block lg:z-50 2xl:[--width:theme(spacing.10)]"> - <div className="group/anchor block h-5 w-5 rounded-lg bg-zinc-50 ring-1 ring-inset ring-zinc-300 transition hover:ring-zinc-500 dark:bg-zinc-800 dark:ring-zinc-700 dark:hover:bg-zinc-700 dark:hover:ring-zinc-600"> - <AnchorIcon className="h-5 w-5 stroke-zinc-500 transition dark:stroke-zinc-400 dark:group-hover/anchor:stroke-white" /> - </div> - </div> - )} - {children} - </Link> - ) -} - -interface HeadingProps extends React.HTMLAttributes<HTMLHeadingElement> { - level?: number - children: React.ReactNode - id?: string - tag?: string - label?: string - anchor?: boolean -} - -export const Heading: React.FC<HeadingProps> = ({ - level = 2, - children, - id, - tag, - label, - anchor = true, - ...props -}) => { - const Component = `h${level}` - const ref = useRef<HTMLHeadingElement>(null) - const registerHeading = useSectionStore((s) => s.registerHeading) - - const inView = useInView(ref, { - margin: `${remToPx(-3.5)}px 0px 0px 0px`, - threshold: 0, - }) - - useEffect(() => { - if (level === 2) { - registerHeading({ id, ref, offsetRem: tag || label ? 8 : 6 }) - } - }, [id, level, ref, registerHeading, tag, label]) - - return ( - <> - <Eyebrow tag={tag} label={label} /> - <Component - ref={ref} - id={anchor ? id : undefined} - className={tag || label ? 'mt-2 scroll-mt-32' : 'scroll-mt-24'} - {...props} - > - {anchor ? ( - <Anchor id={id} inView={inView}> - {children} - </Anchor> - ) : ( - children - )} - </Component> - </> - ) -} diff --git a/src/components/HeroPattern.tsx b/src/components/HeroPattern.tsx index 11f069a92..7b5aedc7c 100644 --- a/src/components/HeroPattern.tsx +++ b/src/components/HeroPattern.tsx @@ -4,12 +4,12 @@ export function HeroPattern() { return ( <div className="absolute inset-0 -z-10 mx-0 max-w-none overflow-hidden"> <div className="absolute left-1/2 top-0 ml-[-38rem] h-[25rem] w-[81.25rem] dark:[mask-image:linear-gradient(white,transparent)]"> - <div className="absolute inset-0 bg-gradient-to-r from-[#2C40F7] to-[#C27AFA] opacity-40 [mask-image:radial-gradient(farthest-side_at_top,white,transparent)] dark:from-[#2C40F7]/30 dark:to-[#C27AFA]/30 dark:opacity-100"> + <div className="absolute inset-0 bg-gradient-to-r from-primary to-secondary opacity-40 [mask-image:radial-gradient(farthest-side_at_top,white,transparent)] dark:from-primary/30 dark:to-secondary/30 dark:opacity-100"> <GridPattern width={72} height={56} - x="-12" - y="4" + x={-12} + y={4} squares={[ [4, 3], [2, 1], diff --git a/src/components/HomeHeader.tsx b/src/components/HomeHeader.tsx index e71c5c082..ba651f4cd 100644 --- a/src/components/HomeHeader.tsx +++ b/src/components/HomeHeader.tsx @@ -1,6 +1,12 @@ import React from 'react' -export const HomeHeader = ({ title, description }) => { +export const HomeHeader = ({ + title, + description, +}: { + title: string + description: string +}) => { return ( <> <h1 className="mb-3 text-2xl sm:text-3xl">{title}</h1> diff --git a/src/components/InstallNitric.tsx b/src/components/InstallNitric.tsx deleted file mode 100644 index 844d423a0..000000000 --- a/src/components/InstallNitric.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React, { PropsWithChildren, useEffect, useState } from 'react' -import { CodeGroup } from './Code' - -// this function detects the operating system of the user and returns the name that will be used to sort the instructions -function detectOS() { - const userAgent = window.navigator.userAgent - if (userAgent.includes('Mac')) { - return 'macOS' - } else if (userAgent.includes('Win')) { - return 'Windows' - } - - return 'Linux' -} - -export const InstallNitric: React.FC<PropsWithChildren> = ({ children }) => { - const [defaultIndex, setDefaultIndex] = useState(0) - - useEffect(() => { - // this will only run on the client side - const OS = detectOS() - - React.Children.toArray(children).forEach( - (child: React.ReactElement, index) => { - // check based on the title prop of the children with the detected OS - if (child.props.title === OS) { - setDefaultIndex(index) - } - } - ) - }, []) - - return ( - <CodeGroup title="" compare={false} defaultIndex={defaultIndex}> - {children} - </CodeGroup> - ) -} diff --git a/src/components/InstallNitric/InstallNitric.tsx b/src/components/InstallNitric/InstallNitric.tsx new file mode 100644 index 000000000..b57ac41f6 --- /dev/null +++ b/src/components/InstallNitric/InstallNitric.tsx @@ -0,0 +1,24 @@ +import React, { Suspense } from 'react' +import { highlight } from 'codehike/code' +import { Schema } from '../code/CodeWithTabs' +import { parseProps } from 'codehike/blocks' +import CODE_THEME from '@/components/code/theme' +import { InstallNitricTabs } from './InstallNitricTabs.client' +import Pre from '../code/Pre' +import CodeContainer from '../code/CodeContainer' + +export const InstallNitric: React.FC = async (props) => { + const { tabs } = parseProps(props, Schema) + + const highlighted = await Promise.all( + tabs.map((tab) => highlight(tab, CODE_THEME)), + ) + + return ( + <CodeContainer> + <Suspense fallback={<Pre highlighted={highlighted[0]} {...props} />}> + <InstallNitricTabs highlighted={highlighted} tabs={tabs} /> + </Suspense> + </CodeContainer> + ) +} diff --git a/src/components/InstallNitric/InstallNitricTabs.client.tsx b/src/components/InstallNitric/InstallNitricTabs.client.tsx new file mode 100644 index 000000000..0cf021033 --- /dev/null +++ b/src/components/InstallNitric/InstallNitricTabs.client.tsx @@ -0,0 +1,45 @@ +'use client' + +import React from 'react' +import { HighlightedCode, RawCode } from 'codehike/code' +import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs' +import Pre from '../code/Pre' +import { OS, useOS } from './OSContext' + +interface InstallNitricProps { + highlighted: HighlightedCode[] + tabs: RawCode[] +} + +export const InstallNitricTabs: React.FC<InstallNitricProps> = ({ + highlighted, + tabs, +}) => { + const { currentOS, setCurrentOS } = useOS() + + return ( + <Tabs value={currentOS} onValueChange={(val) => setCurrentOS(val as OS)}> + <TabsList className="mt-auto h-10 bg-transparent"> + {tabs.map((tab) => ( + <TabsTrigger + key={tab.meta} + value={tab.meta} + className="group/tab relative hover:text-zinc-200 data-[state=active]:bg-transparent data-[state=active]:text-primary-300" + > + {tab.meta} + <div className="absolute inset-x-2 -bottom-[4.5px] h-px bg-primary-300 opacity-0 transition-opacity group-data-[state=active]/tab:opacity-100" /> + </TabsTrigger> + ))} + </TabsList> + {tabs.map((tab, i) => ( + <TabsContent + key={tab.meta} + value={tab.meta} + className="m-0 border-t border-zinc-300/10" + > + <Pre highlighted={highlighted[i]} /> + </TabsContent> + ))} + </Tabs> + ) +} diff --git a/src/components/InstallNitric/OSContext.tsx b/src/components/InstallNitric/OSContext.tsx new file mode 100644 index 000000000..4083115a5 --- /dev/null +++ b/src/components/InstallNitric/OSContext.tsx @@ -0,0 +1,52 @@ +'use client' + +import React, { + createContext, + PropsWithChildren, + useContext, + useEffect, + useState, +} from 'react' + +export type OS = 'Windows' | 'macOS' | 'Linux' + +export interface OSContextProps { + currentOS: OS + setCurrentOS: (os: OS) => void +} + +// this function detects the operating system of the user and returns the name that will be used to sort the instructions +function detectOS() { + const userAgent = window.navigator.userAgent + if (userAgent.includes('Mac')) { + return 'macOS' + } else if (userAgent.includes('Win')) { + return 'Windows' + } + + return 'Linux' +} + +export const OSContext = createContext<OSContextProps>({ + currentOS: 'macOS', // Default value + setCurrentOS: () => {}, // Default value +}) + +export const OSProvider: React.FC<PropsWithChildren> = ({ children }) => { + const [currentOS, setCurrentOS] = useState<OS>('macOS') // Set the initial OS here + + useEffect(() => { + // this will only run on the client side + setCurrentOS(detectOS()) + }, []) + + return ( + <OSContext.Provider value={{ currentOS, setCurrentOS }}> + {children} + </OSContext.Provider> + ) +} + +export const useOS = (): OSContextProps => { + return useContext(OSContext) +} diff --git a/src/components/InstallNitric/index.ts b/src/components/InstallNitric/index.ts new file mode 100644 index 000000000..ab1c4ccbf --- /dev/null +++ b/src/components/InstallNitric/index.ts @@ -0,0 +1 @@ +export { InstallNitric } from './InstallNitric' diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx deleted file mode 100644 index 7a5dfdd05..000000000 --- a/src/components/Layout.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import Link from 'next/link' -import { motion } from 'framer-motion' - -import { Footer } from '@/components/Footer' -import { Header } from '@/components/Header' -import { Logo } from '@/components/Logo' -import { Navigation } from '@/components/Navigation' -import { Prose } from '@/components/Prose' -import { SectionProvider } from '@/components/SectionProvider' -import { Note } from './mdx' -import { useVersions } from '@/lib/hooks/use-versions' - -const experimentalRuntimes = ['go', 'dart'] - -const v0Runtimes = ['csharp', 'jvm'] - -export function Layout({ children, sections = [], disableEditGithub = false }) { - const { - isNotLatest, - currentVersion, - currentSdk, - currentSdkLabel, - latestLink, - } = useVersions() - - return ( - <SectionProvider sections={sections}> - <div className="lg:ml-72 xl:ml-80"> - <motion.header - layoutScroll - className="contents lg:pointer-events-none lg:fixed lg:inset-0 lg:z-40 lg:flex" - > - <div className="contents lg:pointer-events-auto lg:block lg:w-72 lg:overflow-y-auto lg:border-r lg:border-zinc-900/10 lg:px-6 lg:pb-8 lg:pt-4 lg:dark:border-white/10 xl:w-80"> - <div className="mt-2 hidden lg:flex"> - <Link href="/" aria-label="Home"> - <Logo className="h-6" /> - </Link> - </div> - <Header /> - <Navigation className="hidden lg:mt-10 lg:block" /> - </div> - </motion.header> - <div className="relative px-4 pt-14 sm:px-6 lg:px-8"> - <main className="py-16"> - <Prose as="article"> - {experimentalRuntimes.includes(currentSdk) && ( - <Note> - The {currentSdkLabel} SDK is currently in experimental status. - If you would like to provide feedback, please reach out to us - with your suggestions and comments on our{' '} - <Link - className="ml-1" - href="https://nitric.io/chat" - target="_blank" - > - Discord - </Link> - . - </Note> - )} - - {isNotLatest && - latestLink && - (!v0Runtimes.includes(currentSdk) ? ( - <Note> - Note: You are viewing documentation for version{' '} - {currentVersion} of {currentSdkLabel}.{' '} - <Link href={latestLink}>View the latest version</Link>. - </Note> - ) : ( - <Note> - The {currentSdkLabel} SDK currently only supports legacy - versions of Nitric prior to v1. This version is maintained - for compatibility with existing projects and not recommended - for new projects. New projects should be started using a{' '} - <Link className="ml-1" href="/#libraries"> - supported SDK - </Link>{' '} - (presented automatically using the `nitric new` command) or - <Link - className="ml-1" - href="https://nitric.io/chat" - target="_blank" - > - get in touch - </Link>{' '} - to request an update to the latest version. - </Note> - ))} - - {children} - </Prose> - </main> - <Footer disableEditGithub={disableEditGithub} /> - </div> - </div> - </SectionProvider> - ) -} diff --git a/src/components/Libraries.tsx b/src/components/Libraries.tsx index ac0d0342c..ff7cdf1d0 100644 --- a/src/components/Libraries.tsx +++ b/src/components/Libraries.tsx @@ -1,6 +1,5 @@ import Image from 'next/image' -import { Heading } from '@/components/Heading' import logoNode from '@/images/logos/node.svg' import logoPython from '@/images/logos/python.svg' import logoCsharp from '@/images/logos/csharp.svg' @@ -9,6 +8,7 @@ import logoJava from '@/images/logos/java.svg' import logoDart from '@/images/logos/dart.svg' import Link from 'next/link' import { ArrowRightIcon } from '@heroicons/react/24/outline' +import { Heading } from './ui/heading' const libraries = [ { @@ -56,7 +56,7 @@ export interface LibrariesProps { export function Libraries({ minimal = false }: LibrariesProps) { if (minimal) { return ( - <div className="flex h-fit w-fit items-center"> + <div className="flex h-fit w-fit items-center gap-2"> {libraries.map((library) => ( <Link href={library.href} diff --git a/src/components/Logo.tsx b/src/components/Logo.tsx index fe9a6e844..06a98230a 100644 --- a/src/components/Logo.tsx +++ b/src/components/Logo.tsx @@ -1,6 +1,9 @@ import clsx from 'clsx' -export function Logo({ className, ...props }) { +export function Logo({ + className, + ...props +}: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg className={clsx('text-gray-800 dark:text-white', className)} diff --git a/src/components/MDXContent.tsx b/src/components/MDXContent.tsx new file mode 100644 index 000000000..b12019475 --- /dev/null +++ b/src/components/MDXContent.tsx @@ -0,0 +1,31 @@ +import React from 'react' +import * as mdxComponents from '@/components/mdx' +import { compile, run } from '@mdx-js/mdx' +import * as runtime from 'react/jsx-runtime' +import { MDXComponents } from 'mdx/types' +import { mdxOptions } from '@/mdx/mdx-options.mjs' + +interface MDXContentProps { + mdx: string +} + +const MDXContent = async ({ mdx }: MDXContentProps) => { + /// Compile the MDX source code to a function body + const code = String( + await compile(mdx, { + outputFormat: 'function-body', + ...mdxOptions, + jsx: false, // Disable JSX transformation, as it's already transformed by the runtime + }), + ) + + // Run the compiled code with the runtime and get the default export + const { default: MDXContent } = await run(code, { + ...runtime, + baseUrl: import.meta.url, + } as any) + + return <MDXContent components={mdxComponents as MDXComponents} /> +} + +export default MDXContent diff --git a/src/components/MobileNavigation.tsx b/src/components/MobileNavigation.tsx deleted file mode 100644 index d451f2a68..000000000 --- a/src/components/MobileNavigation.tsx +++ /dev/null @@ -1,132 +0,0 @@ -import { createContext, Fragment, useContext } from 'react' -import { Dialog, Transition } from '@headlessui/react' -import { motion } from 'framer-motion' -import { create, StoreApi } from 'zustand' - -import { Header } from '@/components/Header' -import { Navigation } from '@/components/Navigation' - -interface MenuIconProps { - className?: string -} - -function MenuIcon(props: MenuIconProps) { - return ( - <svg - viewBox="0 0 10 9" - fill="none" - strokeLinecap="round" - aria-hidden="true" - {...props} - > - <path d="M.5 1h9M.5 8h9M.5 4.5h9" /> - </svg> - ) -} - -interface XIconProps { - className?: string -} - -function XIcon(props: XIconProps) { - return ( - <svg - viewBox="0 0 10 9" - fill="none" - strokeLinecap="round" - aria-hidden="true" - {...props} - > - <path d="m1.5 1 7 7M8.5 1l-7 7" /> - </svg> - ) -} - -const IsInsideMobileNavigationContext = createContext(false) - -export function useIsInsideMobileNavigation() { - return useContext(IsInsideMobileNavigationContext) -} - -interface MobileNavigationStore { - isOpen: boolean - open: () => void - close: () => void - toggle: () => void -} - -export const useMobileNavigationStore = create<MobileNavigationStore>( - (set: StoreApi<MobileNavigationStore>['setState']) => ({ - isOpen: false, - open: () => set({ isOpen: true }), - close: () => set({ isOpen: false }), - toggle: () => set((state) => ({ isOpen: !state.isOpen })), - }) -) - -export function MobileNavigation() { - let isInsideMobileNavigation = useIsInsideMobileNavigation() - let { isOpen, toggle, close } = useMobileNavigationStore() - let ToggleIcon = isOpen ? XIcon : MenuIcon - - return ( - <IsInsideMobileNavigationContext.Provider value={true}> - <button - type="button" - className="flex h-6 w-6 items-center justify-center rounded-md transition hover:bg-gray-800/5 dark:hover:bg-white/5" - aria-label="Toggle navigation" - onClick={toggle} - > - <ToggleIcon className="w-2.5 stroke-zinc-900 dark:stroke-white" /> - </button> - {!isInsideMobileNavigation && ( - <Transition.Root show={isOpen} as={Fragment}> - <Dialog onClose={close} className="fixed inset-0 z-50 lg:hidden"> - <Transition.Child - as={Fragment} - enter="duration-300 ease-out" - enterFrom="opacity-0" - enterTo="opacity-100" - leave="duration-200 ease-in" - leaveFrom="opacity-100" - leaveTo="opacity-0" - > - <div className="fixed inset-0 top-14 bg-zinc-400/20 backdrop-blur-sm dark:bg-black/40" /> - </Transition.Child> - - <Dialog.Panel> - <Transition.Child - as={Fragment} - enter="duration-300 ease-out" - enterFrom="opacity-0" - enterTo="opacity-100" - leave="duration-200 ease-in" - leaveFrom="opacity-100" - leaveTo="opacity-0" - > - <Header /> - </Transition.Child> - - <Transition.Child - as={Fragment} - enter="duration-500 ease-in-out" - enterFrom="-translate-x-full" - enterTo="translate-x-0" - leave="duration-500 ease-in-out" - leaveFrom="translate-x-0" - leaveTo="-translate-x-full" - > - <motion.div - layoutScroll - className="fixed bottom-0 left-0 top-14 w-full overflow-y-auto bg-white px-4 pb-4 pt-6 shadow-lg shadow-zinc-900/10 ring-1 ring-zinc-900/7.5 dark:bg-gray-800 dark:ring-zinc-800 min-[416px]:max-w-sm sm:px-6 sm:pb-10" - > - <Navigation /> - </motion.div> - </Transition.Child> - </Dialog.Panel> - </Dialog> - </Transition.Root> - )} - </IsInsideMobileNavigationContext.Provider> - ) -} diff --git a/src/components/ModeToggle.tsx b/src/components/ModeToggle.tsx deleted file mode 100644 index f7ec81d25..000000000 --- a/src/components/ModeToggle.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { MoonIcon, SunIcon } from '@heroicons/react/24/outline' - -export function ModeToggle() { - function disableTransitionsTemporarily() { - document.documentElement.classList.add('[&_*]:!transition-none') - window.setTimeout(() => { - document.documentElement.classList.remove('[&_*]:!transition-none') - }, 0) - } - - function toggleMode() { - disableTransitionsTemporarily() - - let darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)') - let isSystemDarkMode = darkModeMediaQuery.matches - let isDarkMode = document.documentElement.classList.toggle('dark') - - if (isDarkMode === isSystemDarkMode) { - delete window.localStorage.isDarkMode - } else { - window.localStorage.isDarkMode = isDarkMode - } - } - - return ( - <button - type="button" - className="flex h-6 w-6 items-center justify-center rounded-md transition hover:bg-gray-800/5 dark:hover:bg-white/5" - aria-label="Toggle dark mode" - onClick={toggleMode} - > - <SunIcon className="h-5 w-5 stroke-zinc-900 dark:hidden" /> - <MoonIcon className="hidden h-5 w-5 stroke-gray dark:block" /> - </button> - ) -} diff --git a/src/components/Navigation.tsx b/src/components/Navigation.tsx deleted file mode 100644 index 8e243e68a..000000000 --- a/src/components/Navigation.tsx +++ /dev/null @@ -1,395 +0,0 @@ -import { useEffect, useRef } from 'react' -import Link from 'next/link' -import { useRouter } from 'next/router' -import clsx from 'clsx' -import { AnimatePresence, motion, useIsPresent } from 'framer-motion' -import { capitalize } from 'radash' - -import { useIsInsideMobileNavigation } from '@/components/MobileNavigation' -import { useSectionStore } from '@/components/SectionProvider' -import { Tag } from '@/components/Tag' -import { remToPx } from '@/lib/remToPx' -import { - DocNavGroup, - Version, - topLevelNavigation, - useCurrentNav, -} from '@/nav.config' -import { ArrowLeftIcon, ChevronLeftIcon } from '@heroicons/react/24/outline' -import { VersionSelect } from './VersionSelect' -import { useVersions } from '@/lib/hooks/use-versions' -import { Badge } from './ui/badge' - -function useInitialValue(value, condition = true) { - let initialValue = useRef(value).current - return condition ? initialValue : value -} - -function TopLevelNavItem({ href, children }) { - const external = href.startsWith('http') - - return ( - <li className="md:hidden"> - <Link - href={href} - target={external ? '_blank' : undefined} - rel={external ? 'noreferrer noopener' : undefined} - className="block py-1 text-sm text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white" - > - {children} - </Link> - </li> - ) -} - -interface NavLinkProps { - href: string - tag?: string - badge?: string - active?: boolean - isAnchorLink?: boolean - children: React.ReactNode - iconPosition?: 'start' | 'end' - className?: string - iconClassName?: string - icon?: React.ForwardRefExoticComponent< - React.PropsWithoutRef<React.SVGProps<SVGSVGElement>> & { - title?: string - titleId?: string - } - > -} - -function NavLink({ - href, - tag, - active, - children, - className, - iconClassName, - isAnchorLink, - icon: Icon, - iconPosition = 'start', - badge, -}: NavLinkProps) { - return ( - <Link - href={href} - aria-current={active ? 'page' : undefined} - className={clsx( - 'flex gap-2 py-1 pr-3 text-sm transition', - isAnchorLink ? 'pl-7' : Icon && iconPosition === 'start' ? '' : 'pl-4', - active - ? 'text-zinc-900 dark:text-white' - : 'text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white', - Icon ? 'items-center justify-start' : 'justify-between', - className - )} - > - {Icon && iconPosition === 'start' && ( - <Icon className={clsx('h-4 w-4', iconClassName)} /> - )} - - <span className="truncate">{children}</span> - - {badge && ( - <Badge variant="outline" className="ml-1 px-2 py-0 text-[12px]"> - {badge} - </Badge> - )} - - {tag && ( - <Tag variant="small" color="zinc"> - {tag} - </Tag> - )} - - {Icon && iconPosition === 'end' && ( - <Icon className={clsx('h-4 w-4', iconClassName)} /> - )} - </Link> - ) -} - -function VisibleSectionHighlight({ group, pathname }) { - let [sections, visibleSections] = useInitialValue( - [ - useSectionStore((s) => s.sections), - useSectionStore((s) => s.visibleSections), - ], - useIsInsideMobileNavigation() - ) - - let isPresent = useIsPresent() - let firstVisibleSectionIndex = Math.max( - 0, - [{ id: '_top' }, ...sections].findIndex( - (section) => section.id === visibleSections[0] - ) - ) - let itemHeight = remToPx(2) - let height = isPresent - ? Math.max(1, visibleSections.length) * itemHeight - : itemHeight - let top = - group.links.findIndex((link) => link.href === pathname) * itemHeight + - firstVisibleSectionIndex * itemHeight - - return ( - <motion.div - layout - initial={{ opacity: 0 }} - animate={{ opacity: 1, transition: { delay: 0.2 } }} - exit={{ opacity: 0 }} - className="absolute inset-x-0 top-0 bg-zinc-800/2.5 will-change-transform dark:bg-white/2.5" - style={{ borderRadius: 8, height, top }} - /> - ) -} - -function ActivePageMarker({ group, pathname }) { - let itemHeight = remToPx(2) - let offset = remToPx(0.25) - let activePageIndex = group.links.findIndex((link) => link.href === pathname) - let top = offset + activePageIndex * itemHeight - - return ( - <motion.div - layout - className="absolute left-2 h-6 w-px bg-primary-500" - initial={{ opacity: 0 }} - animate={{ opacity: 1, transition: { delay: 0.2 } }} - exit={{ opacity: 0 }} - style={{ top }} - /> - ) -} - -function NavigationGroup({ group, className }) { - // If this is the mobile navigation then we always render the initial - // state, so that the state does not change during the close animation. - // The state will still update when we re-open (re-render) the navigation. - let isInsideMobileNavigation = useIsInsideMobileNavigation() - let [router, sections] = useInitialValue( - [useRouter(), useSectionStore((s) => s.sections)], - isInsideMobileNavigation - ) - - let isActiveGroup = - group.links.findIndex((link) => link.href === router.pathname) !== -1 - - return ( - <li className={clsx('relative mt-6', className)}> - <motion.h2 - layout="position" - className="text-xs font-semibold text-zinc-900 dark:text-white" - > - {group.title} - </motion.h2> - <div className="relative mt-3 pl-2"> - <AnimatePresence initial={!isInsideMobileNavigation}> - {isActiveGroup && ( - <VisibleSectionHighlight group={group} pathname={router.pathname} /> - )} - </AnimatePresence> - <motion.div - layout - className="absolute inset-y-0 left-2 w-px bg-gray-800/10 dark:bg-white/5" - /> - <AnimatePresence initial={false}> - {isActiveGroup && ( - <ActivePageMarker group={group} pathname={router.pathname} /> - )} - </AnimatePresence> - <ul role="list" className="border-l border-transparent"> - {group.links.map((link) => ( - <motion.li key={link.href} layout="position" className="relative"> - <NavLink - icon={link.icon} - iconPosition={'end'} - href={link.href} - active={link.href === router.pathname} - > - {link.title} - </NavLink> - <AnimatePresence mode="popLayout" initial={false}> - {link.href === router.pathname && sections.length > 0 && ( - <motion.ul - role="list" - initial={{ opacity: 0 }} - animate={{ - opacity: 1, - transition: { delay: 0.1 }, - }} - exit={{ - opacity: 0, - transition: { duration: 0.15 }, - }} - > - {sections.map((section) => ( - <li key={section.id}> - <NavLink - href={`${link.href}#${section.id}`} - tag={section.tag} - isAnchorLink - > - {section.title} - </NavLink> - </li> - ))} - </motion.ul> - )} - </AnimatePresence> - </motion.li> - ))} - </ul> - </div> - </li> - ) -} - -function HomeNavigationGroup({ - group, - className, -}: { - className?: string - group: DocNavGroup -}) { - const router = useRouter() - - return ( - <li - className={clsx( - 'relative', - group.showDividerAbove ? 'mt-3' : 'mt-6', - className - )} - > - {group.title && ( - <motion.h2 - layout="position" - className="text-xs font-semibold text-zinc-900 dark:text-white" - > - {group.title} - </motion.h2> - )} - {group.showDividerAbove && ( - <div className="mx-1 h-[1px] w-1/2 bg-zinc-800/90" /> - )} - <div className="relative mt-3 pl-1"> - <ul role="list" className="border-l border-transparent"> - {group.links.map((link) => ( - <motion.li key={link.href} layout="position" className="relative"> - <NavLink - icon={link.icon} - href={link.href} - badge={link.badge} - active={link.href === router.pathname} - > - {link.title} - </NavLink> - </motion.li> - ))} - </ul> - </div> - </li> - ) -} - -export function Navigation(props) { - const { - navigation, - displayDocsMenu, - parent: firstParent, - secondLevelParent, - pathname, - } = useCurrentNav() - const { isReferenceDocs } = useVersions() - - const parent = firstParent || secondLevelParent - - useEffect(() => { - const currentLink = document.querySelector( - `#doc-nav [href="/docs${pathname}"]` - ) - if (currentLink) { - const elementTop = currentLink.getBoundingClientRect().top - const windowHeight = window.innerHeight - if ( - elementTop > windowHeight || - elementTop + currentLink.scrollHeight < 0 - ) { - // Perform any desired action when the element is not visible - currentLink.scrollIntoView() - } - } - }, []) - - return ( - <nav {...props} id="doc-nav"> - {!displayDocsMenu && ( - <div className="mb-4 flex flex-col gap-4"> - <Link - href={ - secondLevelParent - ? `/${secondLevelParent.href.split('/')[1]}` - : '/' - } - className="group flex items-center text-sm text-zinc-600 hover:text-zinc-900 dark:text-zinc-400" - > - <ChevronLeftIcon className="mr-0.5 h-5 w-5 transition-transform group-hover:-translate-x-1" /> - - {secondLevelParent - ? `Back to ${capitalize(secondLevelParent.href.split('/')[1])}` - : 'Back to Home'} - </Link> - {parent && ( - <div className="flex items-center"> - <NavLink - icon={parent.icon} - href={parent.href} - active={parent.href === pathname} - className="text-lg" - iconClassName="w-5 h-5" - > - {parent.title} - </NavLink> - {parent?.versions && isReferenceDocs && ( - <VersionSelect versions={parent.versions} /> - )} - </div> - )} - </div> - )} - - <ul role="list"> - {!displayDocsMenu ? ( - <> - <div className="hidden lg:block"> - {topLevelNavigation.map(({ text, href }) => ( - <TopLevelNavItem key={href} href={href}> - {text} - </TopLevelNavItem> - ))} - </div> - {navigation.map((group, groupIndex) => ( - <NavigationGroup - key={groupIndex} - group={group} - className={groupIndex === 0 && 'md:mt-0'} - /> - ))} - </> - ) : ( - navigation.map((group, groupIndex) => ( - <HomeNavigationGroup - key={groupIndex} - group={group} - className={groupIndex === 0 ? 'md:mt-0' : undefined} - /> - )) - )} - </ul> - </nav> - ) -} diff --git a/src/components/NitricLogo.tsx b/src/components/NitricLogo.tsx deleted file mode 100644 index 7df19c2b2..000000000 --- a/src/components/NitricLogo.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import React from 'react' - -const NitricLogo = (props) => { - return ( - <svg viewBox="0 0 141 160" aria-hidden="true" {...props}> - <g opacity="0.1"> - <mask id="path-1-inside-1_482_2019" fill="#000000"> - <path - fillRule="evenodd" - clipRule="evenodd" - d="M118.446 92.7423C118.587 92.601 118.725 92.458 118.861 92.3131C122.02 88.9822 123.786 84.5615 123.783 79.9598C123.778 75.204 121.885 70.644 118.518 67.2833L70.3204 19.0869L70.2501 19.1573L70.2311 19.1383L22.0337 67.3347C20.3645 69.0002 19.0401 70.9781 18.1363 73.1555C17.2325 75.333 16.7671 77.6672 16.7666 80.0246C16.7661 82.3819 17.2306 84.7161 18.1335 86.8941C19.0364 89.0721 20.36 91.0506 22.0286 92.7166L32.9038 103.591L70.3096 66.206L84.0903 79.9717L59.3681 104.667C57.6999 106.333 56.3766 108.311 55.4737 110.488C54.5708 112.665 54.1061 114.998 54.1061 117.355C54.1061 119.712 54.5708 122.046 55.4737 124.223C56.3766 126.4 57.6999 128.378 59.3681 130.044L70.2483 140.913L107.663 103.519L107.733 103.449L118.446 92.7423Z" - /> - </mask> - <path - d="M118.861 92.3131L118.549 92.0172L118.548 92.0191L118.861 92.3131ZM118.446 92.7423L118.75 93.0464L118.75 93.0459L118.446 92.7423ZM123.783 79.9598L124.212 79.9595V79.9595L123.783 79.9598ZM118.518 67.2833L118.214 67.5873L118.214 67.5876L118.518 67.2833ZM70.3204 19.0869L70.6244 18.7829L70.3202 18.4787L70.0162 18.7831L70.3204 19.0869ZM70.2501 19.1573L69.9462 19.4614L70.2504 19.7654L70.5543 19.4611L70.2501 19.1573ZM70.2311 19.1383L70.535 18.8342L70.231 18.5304L69.9271 18.8343L70.2311 19.1383ZM22.0337 67.3347L22.3374 67.639L22.3377 67.6387L22.0337 67.3347ZM18.1363 73.1555L18.5334 73.3203L18.1363 73.1555ZM16.7666 80.0246L17.1965 80.0246L16.7666 80.0246ZM18.1335 86.8941L18.5307 86.7295H18.5307L18.1335 86.8941ZM22.0286 92.7166L22.3326 92.4126L22.3324 92.4123L22.0286 92.7166ZM32.9038 103.591L32.5998 103.895L32.9037 104.199L33.2077 103.895L32.9038 103.591ZM70.3096 66.206L70.6134 65.9019L70.3095 65.5983L70.0057 65.9019L70.3096 66.206ZM84.0903 79.9717L84.3942 80.2758L84.6987 79.9717L84.3942 79.6675L84.0903 79.9717ZM59.3681 104.667L59.6719 104.971L59.6719 104.971L59.3681 104.667ZM55.4737 110.488L55.0766 110.323L55.0766 110.323L55.4737 110.488ZM55.4737 124.223L55.8708 124.058L55.8708 124.058L55.4737 124.223ZM59.3681 130.044L59.6719 129.74L59.6719 129.739L59.3681 130.044ZM70.2483 140.913L69.9445 141.217L70.2484 141.521L70.5522 141.217L70.2483 140.913ZM107.663 103.519L107.359 103.215L107.359 103.215L107.663 103.519ZM107.733 103.449L108.037 103.753L108.037 103.753L107.733 103.449ZM118.548 92.0191C118.415 92.1606 118.28 92.3003 118.142 92.4387L118.75 93.0459C118.894 92.9016 119.036 92.7555 119.175 92.607L118.548 92.0191ZM123.353 79.9602C123.356 84.4514 121.633 88.7661 118.549 92.0172L119.173 92.6089C122.408 89.1982 124.216 84.6715 124.212 79.9595L123.353 79.9602ZM118.214 67.5876C121.501 70.8677 123.349 75.3184 123.353 79.9602L124.212 79.9595C124.208 75.0896 122.269 70.4203 118.821 66.979L118.214 67.5876ZM70.0164 19.3909L118.214 67.5873L118.822 66.9793L70.6244 18.7829L70.0164 19.3909ZM70.5543 19.4611L70.6246 19.3907L70.0162 18.7831L69.9459 18.8535L70.5543 19.4611ZM70.554 18.8532L70.535 18.8342L69.9272 19.4424L69.9462 19.4614L70.554 18.8532ZM69.9271 18.8343L21.7297 67.0307L22.3377 67.6387L70.5351 19.4423L69.9271 18.8343ZM21.7301 67.0304C20.0208 68.7357 18.6647 70.761 17.7392 72.9907L18.5334 73.3203C19.4155 71.1951 20.7081 69.2646 22.3374 67.639L21.7301 67.0304ZM17.7392 72.9907C16.8138 75.2204 16.3372 77.6106 16.3367 80.0245L17.1965 80.0246C17.197 77.7238 17.6513 75.4456 18.5334 73.3203L17.7392 72.9907ZM16.3367 80.0245C16.3362 82.4384 16.8118 84.8286 17.7364 87.0587L18.5307 86.7295C17.6494 84.6037 17.1961 82.3255 17.1965 80.0246L16.3367 80.0245ZM17.7364 87.0587C18.6609 89.2889 20.0163 91.3149 21.7249 93.0208L22.3324 92.4123C20.7038 90.7863 19.4119 88.8552 18.5307 86.7295L17.7364 87.0587ZM21.7246 93.0206L32.5998 103.895L33.2078 103.287L22.3326 92.4126L21.7246 93.0206ZM33.2077 103.895L70.6135 66.5101L70.0057 65.9019L32.5999 103.287L33.2077 103.895ZM84.3942 79.6675L70.6134 65.9019L70.0058 66.5102L83.7865 80.2758L84.3942 79.6675ZM59.6719 104.971L84.3942 80.2758L83.7865 79.6675L59.0643 104.363L59.6719 104.971ZM55.8708 110.653C56.7521 108.528 58.0437 106.597 59.6719 104.971L59.0643 104.363C57.3562 106.069 56.0011 108.094 55.0766 110.323L55.8708 110.653ZM54.536 117.355C54.536 115.055 54.9896 112.777 55.8708 110.652L55.0766 110.323C54.152 112.552 53.6762 114.942 53.6762 117.355H54.536ZM55.8708 124.058C54.9896 121.933 54.536 119.656 54.536 117.355H53.6762C53.6762 119.769 54.152 122.158 55.0766 124.387L55.8708 124.058ZM59.6719 129.739C58.0437 128.114 56.7521 126.183 55.8708 124.058L55.0766 124.387C56.0011 126.617 57.3562 128.643 59.0644 130.348L59.6719 129.739ZM70.5522 140.609L59.6719 129.74L59.0643 130.348L69.9445 141.217L70.5522 140.609ZM107.359 103.215L69.9444 140.609L70.5522 141.217L107.967 103.823L107.359 103.215ZM107.429 103.145L107.359 103.215L107.967 103.823L108.037 103.753L107.429 103.145ZM118.142 92.4382L107.429 103.145L108.037 103.753L118.75 93.0464L118.142 92.4382Z" - fill="#000000" - mask="url(#path-1-inside-1_482_2019)" - /> - </g> - <g opacity="0.1"> - <mask id="path-3-inside-2_482_2019" fill="#000000"> - <path - fillRule="evenodd" - clipRule="evenodd" - d="M133.54 96.7352C133.726 96.5495 133.907 96.3619 134.086 96.1715C138.235 91.7968 140.554 85.9909 140.549 79.9473C140.544 73.7013 138.057 67.7124 133.634 63.2987L70.3347 0L70.2425 0.0924017L70.2175 0.0674626L6.91755 63.3662C4.72526 65.5535 2.98587 68.1512 1.79889 71.0109C0.611908 73.8707 0.000626018 76.9363 4.8014e-07 80.0323C-0.000624772 83.1284 0.609421 86.194 1.79525 89.0545C2.98107 91.9149 4.71941 94.5134 6.91086 96.7014L21.1938 110.983L70.3206 61.8838L88.4195 79.9629L55.9506 112.396C53.7597 114.584 52.0217 117.182 50.8359 120.041C49.6501 122.9 49.0398 125.965 49.0398 129.061C49.0398 132.156 49.6501 135.221 50.8359 138.08C52.0217 140.94 53.7597 143.538 55.9506 145.725L70.2401 160L119.379 110.889L119.471 110.797L133.54 96.7352Z" - /> - </mask> - <path - d="M134.086 96.1715L133.774 95.8756L133.772 95.8775L134.086 96.1715ZM133.54 96.7352L133.844 97.0393L133.845 97.0388L133.54 96.7352ZM140.549 79.9473L140.979 79.947V79.947L140.549 79.9473ZM133.634 63.2987L133.33 63.6027L133.331 63.603L133.634 63.2987ZM70.3347 0L70.6387 -0.303997L70.3345 -0.608192L70.0305 -0.30379L70.3347 0ZM70.2425 0.0924017L69.9386 0.396498L70.2428 0.700494L70.5467 0.396192L70.2425 0.0924017ZM70.2175 0.0674626L70.5214 -0.236634L70.2174 -0.540422L69.9135 -0.236535L70.2175 0.0674626ZM6.91755 63.3662L7.22121 63.6705L7.22155 63.6702L6.91755 63.3662ZM1.79889 71.0109L1.40182 70.8461H1.40182L1.79889 71.0109ZM4.8014e-07 80.0323L-0.429913 80.0323L4.8014e-07 80.0323ZM1.79525 89.0545L2.19238 88.8898L1.79525 89.0545ZM6.91086 96.7014L7.21485 96.3974L7.21462 96.3971L6.91086 96.7014ZM21.1938 110.983L20.8898 111.287L21.1937 111.591L21.4977 111.287L21.1938 110.983ZM70.3206 61.8838L70.6244 61.5797L70.3205 61.2761L70.0167 61.5797L70.3206 61.8838ZM88.4195 79.9629L88.7233 80.267L89.0278 79.9629L88.7233 79.6587L88.4195 79.9629ZM55.9506 112.396L56.2544 112.7L56.2544 112.7L55.9506 112.396ZM50.8359 120.041L50.4388 119.876L50.4387 119.876L50.8359 120.041ZM50.8359 138.08L51.233 137.915L51.233 137.915L50.8359 138.08ZM55.9506 145.725L56.2544 145.421L56.2543 145.421L55.9506 145.725ZM70.2401 160L69.9363 160.304L70.2402 160.608L70.544 160.304L70.2401 160ZM119.379 110.889L119.075 110.585L119.075 110.585L119.379 110.889ZM119.471 110.797L119.775 111.101L119.775 111.101L119.471 110.797ZM133.772 95.8775C133.597 96.0644 133.418 96.2489 133.236 96.4316L133.845 97.0388C134.033 96.8502 134.218 96.6593 134.399 96.4654L133.772 95.8775ZM140.119 79.9477C140.124 85.8809 137.847 91.5808 133.774 95.8756L134.398 96.4673C138.622 92.0128 140.984 86.1009 140.979 79.947L140.119 79.9477ZM133.331 63.603C137.673 67.9361 140.114 73.8157 140.119 79.9477L140.979 79.947C140.974 73.5869 138.442 67.4887 133.938 62.9944L133.331 63.603ZM70.0307 0.303997L133.33 63.6027L133.938 62.9947L70.6387 -0.303997L70.0307 0.303997ZM70.5467 0.396192L70.6389 0.30379L70.0305 -0.30379L69.9383 -0.211389L70.5467 0.396192ZM70.5463 -0.211695L70.5214 -0.236634L69.9136 0.371559L69.9386 0.396498L70.5463 -0.211695ZM69.9135 -0.236535L6.61356 63.0622L7.22155 63.6702L70.5215 0.37146L69.9135 -0.236535ZM6.6139 63.0618C4.38162 65.2891 2.61047 67.9341 1.40182 70.8461L2.19596 71.1757C3.36126 68.3682 5.06891 65.8179 7.22121 63.6705L6.6139 63.0618ZM1.40182 70.8461C0.193168 73.7581 -0.429276 76.8797 -0.429913 80.0323L0.429914 80.0324C0.430528 76.9929 1.03065 73.9833 2.19596 71.1757L1.40182 70.8461ZM-0.429913 80.0323C-0.43055 83.1848 0.190638 86.3065 1.39811 89.2191L2.19238 88.8898C1.0282 86.0816 0.4293 83.0719 0.429914 80.0324L-0.429913 80.0323ZM1.39811 89.2191C2.60558 92.1317 4.37566 94.7776 6.60711 97.0056L7.21462 96.3971C5.06316 94.2491 3.35656 91.698 2.19238 88.8898L1.39811 89.2191ZM6.60688 97.0054L20.8898 111.287L21.4978 110.679L7.21485 96.3974L6.60688 97.0054ZM21.4977 111.287L70.6245 62.1879L70.0167 61.5797L20.8899 110.679L21.4977 111.287ZM88.7233 79.6587L70.6244 61.5797L70.0168 62.188L88.1157 80.267L88.7233 79.6587ZM56.2544 112.7L88.7233 80.267L88.1157 79.6587L55.6468 112.092L56.2544 112.7ZM51.233 120.206C52.3972 117.399 54.1035 114.849 56.2544 112.7L55.6468 112.092C53.416 114.32 51.6462 116.965 50.4388 119.876L51.233 120.206ZM49.4697 129.061C49.4697 126.022 50.0688 123.013 51.233 120.206L50.4387 119.876C49.2313 122.788 48.6098 125.909 48.6098 129.061H49.4697ZM51.233 137.915C50.0688 135.108 49.4697 132.099 49.4697 129.061H48.6098C48.6098 132.212 49.2313 135.333 50.4387 138.245L51.233 137.915ZM56.2543 145.421C54.1035 143.273 52.3972 140.723 51.233 137.915L50.4387 138.245C51.6462 141.157 53.416 143.802 55.6468 146.029L56.2543 145.421ZM70.544 159.696L56.2544 145.421L55.6467 146.029L69.9363 160.304L70.544 159.696ZM119.075 110.585L69.9362 159.696L70.544 160.304L119.683 111.193L119.075 110.585ZM119.167 110.493L119.075 110.585L119.683 111.193L119.775 111.101L119.167 110.493ZM133.237 96.4311L119.167 110.493L119.775 111.101L133.844 97.0393L133.237 96.4311Z" - fill="#000000" - mask="url(#path-3-inside-2_482_2019)" - /> - </g> - <g clipPath="url(#clip0_482_2019)"> - <path - fillRule="evenodd" - clipRule="evenodd" - d="M33.6319 90.0797L41.9798 98.4269L88.7375 51.6953L70.6324 33.6006L33.6358 70.5964C32.3545 71.8749 31.3379 73.3931 30.6442 75.0645C29.9504 76.736 29.5931 78.5277 29.5928 80.3372C29.5924 82.1468 29.949 83.9385 30.642 85.6104C31.3351 87.2822 32.3511 88.8009 33.6319 90.0797Z" - fill="#061499" - /> - <path - fillRule="evenodd" - clipRule="evenodd" - d="M107.961 89.7704C107.857 89.8816 107.751 89.9913 107.643 90.0998L99.4194 98.3185L99.3657 98.3721L70.6458 127.076L62.294 118.733C61.0135 117.454 59.9977 115.936 59.3046 114.264C58.6116 112.593 58.2549 110.802 58.2549 108.993C58.2549 107.184 58.6116 105.392 59.3046 103.721C59.9977 102.05 61.0135 100.532 62.294 99.2532L81.271 80.297L62.3492 61.3959C61.0698 60.1175 60.055 58.5997 59.3627 56.9292C58.6703 55.2587 58.3139 53.4683 58.3139 51.6602C58.3139 49.8521 58.6703 48.0617 59.3627 46.3912C60.055 44.7207 61.0698 43.2029 62.3492 41.9244L70.701 33.5615L107.697 70.5574C110.282 73.137 111.736 76.6373 111.739 80.2879C111.742 83.8202 110.386 87.2135 107.961 89.7704Z" - fill="#2C40F7" - /> - </g> - <defs> - <clipPath id="clip0_482_2019"> - <rect - width="82.5434" - height="93.5144" - fill="#2C40F7" - transform="translate(29.2017 33.5615)" - /> - </clipPath> - </defs> - </svg> - ) -} - -export default NitricLogo diff --git a/src/components/NitricWhiteLogo.tsx b/src/components/NitricWhiteLogo.tsx deleted file mode 100644 index d47c403c0..000000000 --- a/src/components/NitricWhiteLogo.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import React from 'react' - -const NitricWhiteLogo = (props) => { - return ( - <svg viewBox="0 0 141 160" aria-hidden="true" {...props}> - <g opacity="0.1"> - <mask id="path-1-inside-1_482_2019" fill="white"> - <path - fillRule="evenodd" - clipRule="evenodd" - d="M118.446 92.7423C118.587 92.601 118.725 92.458 118.861 92.3131C122.02 88.9822 123.786 84.5615 123.783 79.9598C123.778 75.204 121.885 70.644 118.518 67.2833L70.3204 19.0869L70.2501 19.1573L70.2311 19.1383L22.0337 67.3347C20.3645 69.0002 19.0401 70.9781 18.1363 73.1555C17.2325 75.333 16.7671 77.6672 16.7666 80.0246C16.7661 82.3819 17.2306 84.7161 18.1335 86.8941C19.0364 89.0721 20.36 91.0506 22.0286 92.7166L32.9038 103.591L70.3096 66.206L84.0903 79.9717L59.3681 104.667C57.6999 106.333 56.3766 108.311 55.4737 110.488C54.5708 112.665 54.1061 114.998 54.1061 117.355C54.1061 119.712 54.5708 122.046 55.4737 124.223C56.3766 126.4 57.6999 128.378 59.3681 130.044L70.2483 140.913L107.663 103.519L107.733 103.449L118.446 92.7423Z" - /> - </mask> - <path - d="M118.861 92.3131L118.549 92.0172L118.548 92.0191L118.861 92.3131ZM118.446 92.7423L118.75 93.0464L118.75 93.0459L118.446 92.7423ZM123.783 79.9598L124.212 79.9595V79.9595L123.783 79.9598ZM118.518 67.2833L118.214 67.5873L118.214 67.5876L118.518 67.2833ZM70.3204 19.0869L70.6244 18.7829L70.3202 18.4787L70.0162 18.7831L70.3204 19.0869ZM70.2501 19.1573L69.9462 19.4614L70.2504 19.7654L70.5543 19.4611L70.2501 19.1573ZM70.2311 19.1383L70.535 18.8342L70.231 18.5304L69.9271 18.8343L70.2311 19.1383ZM22.0337 67.3347L22.3374 67.639L22.3377 67.6387L22.0337 67.3347ZM18.1363 73.1555L18.5334 73.3203L18.1363 73.1555ZM16.7666 80.0246L17.1965 80.0246L16.7666 80.0246ZM18.1335 86.8941L18.5307 86.7295H18.5307L18.1335 86.8941ZM22.0286 92.7166L22.3326 92.4126L22.3324 92.4123L22.0286 92.7166ZM32.9038 103.591L32.5998 103.895L32.9037 104.199L33.2077 103.895L32.9038 103.591ZM70.3096 66.206L70.6134 65.9019L70.3095 65.5983L70.0057 65.9019L70.3096 66.206ZM84.0903 79.9717L84.3942 80.2758L84.6987 79.9717L84.3942 79.6675L84.0903 79.9717ZM59.3681 104.667L59.6719 104.971L59.6719 104.971L59.3681 104.667ZM55.4737 110.488L55.0766 110.323L55.0766 110.323L55.4737 110.488ZM55.4737 124.223L55.8708 124.058L55.8708 124.058L55.4737 124.223ZM59.3681 130.044L59.6719 129.74L59.6719 129.739L59.3681 130.044ZM70.2483 140.913L69.9445 141.217L70.2484 141.521L70.5522 141.217L70.2483 140.913ZM107.663 103.519L107.359 103.215L107.359 103.215L107.663 103.519ZM107.733 103.449L108.037 103.753L108.037 103.753L107.733 103.449ZM118.548 92.0191C118.415 92.1606 118.28 92.3003 118.142 92.4387L118.75 93.0459C118.894 92.9016 119.036 92.7555 119.175 92.607L118.548 92.0191ZM123.353 79.9602C123.356 84.4514 121.633 88.7661 118.549 92.0172L119.173 92.6089C122.408 89.1982 124.216 84.6715 124.212 79.9595L123.353 79.9602ZM118.214 67.5876C121.501 70.8677 123.349 75.3184 123.353 79.9602L124.212 79.9595C124.208 75.0896 122.269 70.4203 118.821 66.979L118.214 67.5876ZM70.0164 19.3909L118.214 67.5873L118.822 66.9793L70.6244 18.7829L70.0164 19.3909ZM70.5543 19.4611L70.6246 19.3907L70.0162 18.7831L69.9459 18.8535L70.5543 19.4611ZM70.554 18.8532L70.535 18.8342L69.9272 19.4424L69.9462 19.4614L70.554 18.8532ZM69.9271 18.8343L21.7297 67.0307L22.3377 67.6387L70.5351 19.4423L69.9271 18.8343ZM21.7301 67.0304C20.0208 68.7357 18.6647 70.761 17.7392 72.9907L18.5334 73.3203C19.4155 71.1951 20.7081 69.2646 22.3374 67.639L21.7301 67.0304ZM17.7392 72.9907C16.8138 75.2204 16.3372 77.6106 16.3367 80.0245L17.1965 80.0246C17.197 77.7238 17.6513 75.4456 18.5334 73.3203L17.7392 72.9907ZM16.3367 80.0245C16.3362 82.4384 16.8118 84.8286 17.7364 87.0587L18.5307 86.7295C17.6494 84.6037 17.1961 82.3255 17.1965 80.0246L16.3367 80.0245ZM17.7364 87.0587C18.6609 89.2889 20.0163 91.3149 21.7249 93.0208L22.3324 92.4123C20.7038 90.7863 19.4119 88.8552 18.5307 86.7295L17.7364 87.0587ZM21.7246 93.0206L32.5998 103.895L33.2078 103.287L22.3326 92.4126L21.7246 93.0206ZM33.2077 103.895L70.6135 66.5101L70.0057 65.9019L32.5999 103.287L33.2077 103.895ZM84.3942 79.6675L70.6134 65.9019L70.0058 66.5102L83.7865 80.2758L84.3942 79.6675ZM59.6719 104.971L84.3942 80.2758L83.7865 79.6675L59.0643 104.363L59.6719 104.971ZM55.8708 110.653C56.7521 108.528 58.0437 106.597 59.6719 104.971L59.0643 104.363C57.3562 106.069 56.0011 108.094 55.0766 110.323L55.8708 110.653ZM54.536 117.355C54.536 115.055 54.9896 112.777 55.8708 110.652L55.0766 110.323C54.152 112.552 53.6762 114.942 53.6762 117.355H54.536ZM55.8708 124.058C54.9896 121.933 54.536 119.656 54.536 117.355H53.6762C53.6762 119.769 54.152 122.158 55.0766 124.387L55.8708 124.058ZM59.6719 129.739C58.0437 128.114 56.7521 126.183 55.8708 124.058L55.0766 124.387C56.0011 126.617 57.3562 128.643 59.0644 130.348L59.6719 129.739ZM70.5522 140.609L59.6719 129.74L59.0643 130.348L69.9445 141.217L70.5522 140.609ZM107.359 103.215L69.9444 140.609L70.5522 141.217L107.967 103.823L107.359 103.215ZM107.429 103.145L107.359 103.215L107.967 103.823L108.037 103.753L107.429 103.145ZM118.142 92.4382L107.429 103.145L108.037 103.753L118.75 93.0464L118.142 92.4382Z" - fill="white" - mask="url(#path-1-inside-1_482_2019)" - /> - </g> - <g opacity="0.1"> - <mask id="path-3-inside-2_482_2019" fill="white"> - <path - fillRule="evenodd" - clipRule="evenodd" - d="M133.54 96.7352C133.726 96.5495 133.907 96.3619 134.086 96.1715C138.235 91.7968 140.554 85.9909 140.549 79.9473C140.544 73.7013 138.057 67.7124 133.634 63.2987L70.3347 0L70.2425 0.0924017L70.2175 0.0674626L6.91755 63.3662C4.72526 65.5535 2.98587 68.1512 1.79889 71.0109C0.611908 73.8707 0.000626018 76.9363 4.8014e-07 80.0323C-0.000624772 83.1284 0.609421 86.194 1.79525 89.0545C2.98107 91.9149 4.71941 94.5134 6.91086 96.7014L21.1938 110.983L70.3206 61.8838L88.4195 79.9629L55.9506 112.396C53.7597 114.584 52.0217 117.182 50.8359 120.041C49.6501 122.9 49.0398 125.965 49.0398 129.061C49.0398 132.156 49.6501 135.221 50.8359 138.08C52.0217 140.94 53.7597 143.538 55.9506 145.725L70.2401 160L119.379 110.889L119.471 110.797L133.54 96.7352Z" - /> - </mask> - <path - d="M134.086 96.1715L133.774 95.8756L133.772 95.8775L134.086 96.1715ZM133.54 96.7352L133.844 97.0393L133.845 97.0388L133.54 96.7352ZM140.549 79.9473L140.979 79.947V79.947L140.549 79.9473ZM133.634 63.2987L133.33 63.6027L133.331 63.603L133.634 63.2987ZM70.3347 0L70.6387 -0.303997L70.3345 -0.608192L70.0305 -0.30379L70.3347 0ZM70.2425 0.0924017L69.9386 0.396498L70.2428 0.700494L70.5467 0.396192L70.2425 0.0924017ZM70.2175 0.0674626L70.5214 -0.236634L70.2174 -0.540422L69.9135 -0.236535L70.2175 0.0674626ZM6.91755 63.3662L7.22121 63.6705L7.22155 63.6702L6.91755 63.3662ZM1.79889 71.0109L1.40182 70.8461H1.40182L1.79889 71.0109ZM4.8014e-07 80.0323L-0.429913 80.0323L4.8014e-07 80.0323ZM1.79525 89.0545L2.19238 88.8898L1.79525 89.0545ZM6.91086 96.7014L7.21485 96.3974L7.21462 96.3971L6.91086 96.7014ZM21.1938 110.983L20.8898 111.287L21.1937 111.591L21.4977 111.287L21.1938 110.983ZM70.3206 61.8838L70.6244 61.5797L70.3205 61.2761L70.0167 61.5797L70.3206 61.8838ZM88.4195 79.9629L88.7233 80.267L89.0278 79.9629L88.7233 79.6587L88.4195 79.9629ZM55.9506 112.396L56.2544 112.7L56.2544 112.7L55.9506 112.396ZM50.8359 120.041L50.4388 119.876L50.4387 119.876L50.8359 120.041ZM50.8359 138.08L51.233 137.915L51.233 137.915L50.8359 138.08ZM55.9506 145.725L56.2544 145.421L56.2543 145.421L55.9506 145.725ZM70.2401 160L69.9363 160.304L70.2402 160.608L70.544 160.304L70.2401 160ZM119.379 110.889L119.075 110.585L119.075 110.585L119.379 110.889ZM119.471 110.797L119.775 111.101L119.775 111.101L119.471 110.797ZM133.772 95.8775C133.597 96.0644 133.418 96.2489 133.236 96.4316L133.845 97.0388C134.033 96.8502 134.218 96.6593 134.399 96.4654L133.772 95.8775ZM140.119 79.9477C140.124 85.8809 137.847 91.5808 133.774 95.8756L134.398 96.4673C138.622 92.0128 140.984 86.1009 140.979 79.947L140.119 79.9477ZM133.331 63.603C137.673 67.9361 140.114 73.8157 140.119 79.9477L140.979 79.947C140.974 73.5869 138.442 67.4887 133.938 62.9944L133.331 63.603ZM70.0307 0.303997L133.33 63.6027L133.938 62.9947L70.6387 -0.303997L70.0307 0.303997ZM70.5467 0.396192L70.6389 0.30379L70.0305 -0.30379L69.9383 -0.211389L70.5467 0.396192ZM70.5463 -0.211695L70.5214 -0.236634L69.9136 0.371559L69.9386 0.396498L70.5463 -0.211695ZM69.9135 -0.236535L6.61356 63.0622L7.22155 63.6702L70.5215 0.37146L69.9135 -0.236535ZM6.6139 63.0618C4.38162 65.2891 2.61047 67.9341 1.40182 70.8461L2.19596 71.1757C3.36126 68.3682 5.06891 65.8179 7.22121 63.6705L6.6139 63.0618ZM1.40182 70.8461C0.193168 73.7581 -0.429276 76.8797 -0.429913 80.0323L0.429914 80.0324C0.430528 76.9929 1.03065 73.9833 2.19596 71.1757L1.40182 70.8461ZM-0.429913 80.0323C-0.43055 83.1848 0.190638 86.3065 1.39811 89.2191L2.19238 88.8898C1.0282 86.0816 0.4293 83.0719 0.429914 80.0324L-0.429913 80.0323ZM1.39811 89.2191C2.60558 92.1317 4.37566 94.7776 6.60711 97.0056L7.21462 96.3971C5.06316 94.2491 3.35656 91.698 2.19238 88.8898L1.39811 89.2191ZM6.60688 97.0054L20.8898 111.287L21.4978 110.679L7.21485 96.3974L6.60688 97.0054ZM21.4977 111.287L70.6245 62.1879L70.0167 61.5797L20.8899 110.679L21.4977 111.287ZM88.7233 79.6587L70.6244 61.5797L70.0168 62.188L88.1157 80.267L88.7233 79.6587ZM56.2544 112.7L88.7233 80.267L88.1157 79.6587L55.6468 112.092L56.2544 112.7ZM51.233 120.206C52.3972 117.399 54.1035 114.849 56.2544 112.7L55.6468 112.092C53.416 114.32 51.6462 116.965 50.4388 119.876L51.233 120.206ZM49.4697 129.061C49.4697 126.022 50.0688 123.013 51.233 120.206L50.4387 119.876C49.2313 122.788 48.6098 125.909 48.6098 129.061H49.4697ZM51.233 137.915C50.0688 135.108 49.4697 132.099 49.4697 129.061H48.6098C48.6098 132.212 49.2313 135.333 50.4387 138.245L51.233 137.915ZM56.2543 145.421C54.1035 143.273 52.3972 140.723 51.233 137.915L50.4387 138.245C51.6462 141.157 53.416 143.802 55.6468 146.029L56.2543 145.421ZM70.544 159.696L56.2544 145.421L55.6467 146.029L69.9363 160.304L70.544 159.696ZM119.075 110.585L69.9362 159.696L70.544 160.304L119.683 111.193L119.075 110.585ZM119.167 110.493L119.075 110.585L119.683 111.193L119.775 111.101L119.167 110.493ZM133.237 96.4311L119.167 110.493L119.775 111.101L133.844 97.0393L133.237 96.4311Z" - fill="white" - mask="url(#path-3-inside-2_482_2019)" - /> - </g> - <g clipPath="url(#clip0_482_2019)"> - <path - fillRule="evenodd" - clipRule="evenodd" - d="M33.6319 90.0797L41.9798 98.4269L88.7375 51.6953L70.6324 33.6006L33.6358 70.5964C32.3545 71.8749 31.3379 73.3931 30.6442 75.0645C29.9504 76.736 29.5931 78.5277 29.5928 80.3372C29.5924 82.1468 29.949 83.9385 30.642 85.6104C31.3351 87.2822 32.3511 88.8009 33.6319 90.0797Z" - fill="#D2D0DD" - /> - <path - fillRule="evenodd" - clipRule="evenodd" - d="M107.961 89.7704C107.857 89.8816 107.751 89.9913 107.643 90.0998L99.4194 98.3185L99.3657 98.3721L70.6458 127.076L62.294 118.733C61.0135 117.454 59.9977 115.936 59.3046 114.264C58.6116 112.593 58.2549 110.802 58.2549 108.993C58.2549 107.184 58.6116 105.392 59.3046 103.721C59.9977 102.05 61.0135 100.532 62.294 99.2532L81.271 80.297L62.3492 61.3959C61.0698 60.1175 60.055 58.5997 59.3627 56.9292C58.6703 55.2587 58.3139 53.4683 58.3139 51.6602C58.3139 49.8521 58.6703 48.0617 59.3627 46.3912C60.055 44.7207 61.0698 43.2029 62.3492 41.9244L70.701 33.5615L107.697 70.5574C110.282 73.137 111.736 76.6373 111.739 80.2879C111.742 83.8202 110.386 87.2135 107.961 89.7704Z" - fill="white" - /> - </g> - <defs> - <clipPath id="clip0_482_2019"> - <rect - width="82.5434" - height="93.5144" - fill="white" - transform="translate(29.2017 33.5615)" - /> - </clipPath> - </defs> - </svg> - ) -} - -export default NitricWhiteLogo diff --git a/src/components/Prose.tsx b/src/components/Prose.tsx index a9708128c..4a8718789 100644 --- a/src/components/Prose.tsx +++ b/src/components/Prose.tsx @@ -1,19 +1,23 @@ -import React from 'react' import clsx from 'clsx' -interface ProseProps extends React.PropsWithChildren { - as?: React.ElementType - className?: string -} - -export function Prose({ - as: Component = 'div', +export function Prose<T extends React.ElementType = 'div'>({ + as, className, ...props -}: ProseProps) { +}: Omit<React.ComponentPropsWithoutRef<T>, 'as' | 'className'> & { + as?: T + className?: string +}) { + let Component = as ?? 'div' + return ( <Component - className={clsx(className, 'prose dark:prose-invert')} + className={clsx( + className, + 'prose dark:prose-invert', + // // `html :where(& > *)` is used to select all direct children without an increase in specificity like you'd get from just `& > *` + // '[html_:where(&>*)]:mx-auto [html_:where(&>*)]:max-w-2xl [html_:where(&>*)]:lg:mx-[calc(50%-min(50%,theme(maxWidth.lg)))] [html_:where(&>*)]:lg:max-w-3xl', + )} {...props} /> ) diff --git a/src/components/Providers.tsx b/src/components/Providers.tsx deleted file mode 100644 index ba9af8ea5..000000000 --- a/src/components/Providers.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import Image from 'next/image' - -import { Heading } from '@/components/Heading' -import logoAws from '@/images/logos/aws.svg' -import logoAwsLight from '@/images/logos/aws-dark-text.svg' -import logoAzure from '@/images/logos/azure.svg' -import logoGCP from '@/images/logos/gcp.svg' -import Link from 'next/link' -import { - ArrowRightIcon, - Cog8ToothIcon, - WrenchScrewdriverIcon, - CloudIcon, -} from '@heroicons/react/24/outline' - -const providers = [ - { - href: '/reference/providers', - name: 'Overview', - description: 'Learn about our Nitric providers', - icon: CloudIcon, - }, - { - href: '/reference/providers/custom/building-custom-provider', - name: 'Build', - description: 'Building a custom provider', - icon: WrenchScrewdriverIcon, - }, - { - href: '/reference/providers/custom/extend-standard-provider', - name: 'Extend', - description: 'Extending a standard provider', - icon: Cog8ToothIcon, - }, - { - href: '/reference/providers/aws', - name: 'AWS', - description: 'View full reference for AWS', - logo: logoAws, - lightLogo: logoAwsLight, - }, - { - href: '/reference/providers/gcp', - name: 'Google Cloud', - description: 'View full reference for GCP', - logo: logoGCP, - }, - { - href: '/reference/providers/azure', - name: 'Azure', - description: 'View full reference for Azure', - logo: logoAzure, - }, -] - -export function Providers() { - return ( - <div className="my-16 xl:max-w-none"> - <Heading level={2} id="providers"> - Providers - </Heading> - <div className="not-prose mt-4 grid grid-cols-1 gap-x-6 gap-y-10 border-t border-zinc-900/5 pt-10 dark:border-white/5 sm:grid-cols-2 xl:max-w-none xl:grid-cols-3"> - {providers.map((provider) => ( - <Link - href={provider.href} - key={provider.name} - className={ - 'group relative flex items-center gap-4 rounded-2xl bg-zinc-50 p-4 transition-shadow hover:shadow-md hover:shadow-zinc-900/5 dark:bg-white/2.5 dark:hover:shadow-black/5' - } - > - <div className="absolute inset-0 rounded-2xl ring-1 ring-inset ring-zinc-900/7.5 group-hover:ring-zinc-900/10 dark:ring-white/10 dark:group-hover:ring-white/20" /> - {provider.icon ? ( - <provider.icon className="h-10 w-10" /> - ) : provider.lightLogo ? ( - <> - <Image - src={provider.logo} - alt={provider.name + ' Logo'} - className={'hidden h-10 w-10 dark:flex'} - unoptimized - /> - <Image - src={provider.lightLogo} - alt={provider.name + ' Logo'} - className={'h-10 w-10 dark:hidden'} - unoptimized - /> - </> - ) : ( - <Image - src={provider.logo} - alt={provider.name + ' Logo'} - className={'h-10 w-10'} - unoptimized - /> - )} - <div className="flex-auto"> - <h3 className="text-lg font-semibold text-zinc-900 dark:text-white"> - {provider.name} - </h3> - <p className="mt-1 text-sm text-zinc-600 dark:text-zinc-400"> - {provider.description} - </p> - </div> - <ArrowRightIcon className="h-5 w-5 -translate-x-1 transition-transform group-hover:translate-x-0" /> - </Link> - ))} - </div> - </div> - ) -} diff --git a/src/components/ResourcePattern.tsx b/src/components/ResourcePattern.tsx deleted file mode 100644 index 780c45f2c..000000000 --- a/src/components/ResourcePattern.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { motion, useMotionTemplate } from 'framer-motion' -import { GridPattern } from './GridPattern' - -export function ResourcePattern({ mouseX, mouseY, ...gridProps }) { - let maskImage = useMotionTemplate`radial-gradient(180px at ${mouseX}px ${mouseY}px, white, transparent)` - let style = { maskImage, WebkitMaskImage: maskImage } - - return ( - <div className="pointer-events-none"> - <motion.div - className="absolute inset-0 rounded-2xl bg-gradient-to-r from-primary-100 to-secondary-100 opacity-0 transition duration-300 group-hover:opacity-100 dark:from-primary/10 dark:to-secondary/10" - style={style} - /> - <motion.div - className="absolute inset-0 rounded-2xl opacity-0 mix-blend-overlay transition duration-300 group-hover:opacity-100" - style={style} - > - <GridPattern - width={72} - height={56} - x="50%" - className="absolute inset-x-0 inset-y-[-30%] h-[160%] w-full skew-y-[-18deg] fill-black/50 stroke-black/70 dark:fill-white/2.5 dark:stroke-white/10" - {...gridProps} - /> - </motion.div> - </div> - ) -} diff --git a/src/components/Resources.tsx b/src/components/Resources.tsx new file mode 100644 index 000000000..80f24e168 --- /dev/null +++ b/src/components/Resources.tsx @@ -0,0 +1,186 @@ +'use client' + +import Link from 'next/link' +import { + type MotionValue, + motion, + useMotionTemplate, + useMotionValue, +} from 'framer-motion' + +import { GridPattern } from '@/components/GridPattern' +import { Heading } from '@/components/ui/heading' +import { ChatBubbleIcon } from '@/components/icons/ChatBubbleIcon' +import { EnvelopeIcon } from '@/components/icons/EnvelopeIcon' +import { UserIcon } from '@/components/icons/UserIcon' +import { UsersIcon } from '@/components/icons/UsersIcon' + +interface Resource { + href: string + name: string + description: string + icon: React.ComponentType<{ className?: string }> + pattern: Omit< + React.ComponentPropsWithoutRef<typeof GridPattern>, + 'width' | 'height' | 'x' + > +} + +const resources: Array<Resource> = [ + { + href: '/contacts', + name: 'Contacts', + description: + 'Learn about the contact model and how to create, retrieve, update, delete, and list contacts.', + icon: UserIcon, + pattern: { + y: 16, + squares: [ + [0, 1], + [1, 3], + ], + }, + }, + { + href: '/conversations', + name: 'Conversations', + description: + 'Learn about the conversation model and how to create, retrieve, update, delete, and list conversations.', + icon: ChatBubbleIcon, + pattern: { + y: -6, + squares: [ + [-1, 2], + [1, 3], + ], + }, + }, + { + href: '/messages', + name: 'Messages', + description: + 'Learn about the message model and how to create, retrieve, update, delete, and list messages.', + icon: EnvelopeIcon, + pattern: { + y: 32, + squares: [ + [0, 2], + [1, 4], + ], + }, + }, + { + href: '/groups', + name: 'Groups', + description: + 'Learn about the group model and how to create, retrieve, update, delete, and list groups.', + icon: UsersIcon, + pattern: { + y: 22, + squares: [[0, 1]], + }, + }, +] + +function ResourceIcon({ icon: Icon }: { icon: Resource['icon'] }) { + return ( + <div className="flex h-7 w-7 items-center justify-center rounded-full bg-zinc-900/5 ring-1 ring-zinc-900/25 backdrop-blur-[2px] transition duration-300 group-hover:bg-white/50 group-hover:ring-zinc-900/25 dark:bg-white/7.5 dark:ring-white/15 dark:group-hover:bg-emerald-300/10 dark:group-hover:ring-emerald-400"> + <Icon className="h-5 w-5 fill-zinc-700/10 stroke-zinc-700 transition-colors duration-300 group-hover:stroke-zinc-900 dark:fill-white/10 dark:stroke-zinc-400 dark:group-hover:fill-emerald-300/10 dark:group-hover:stroke-emerald-400" /> + </div> + ) +} + +function ResourcePattern({ + mouseX, + mouseY, + ...gridProps +}: Resource['pattern'] & { + mouseX: MotionValue<number> + mouseY: MotionValue<number> +}) { + let maskImage = useMotionTemplate`radial-gradient(180px at ${mouseX}px ${mouseY}px, white, transparent)` + let style = { maskImage, WebkitMaskImage: maskImage } + + return ( + <div className="pointer-events-none"> + <div className="absolute inset-0 rounded-2xl transition duration-300 [mask-image:linear-gradient(white,transparent)] group-hover:opacity-50"> + <GridPattern + width={72} + height={56} + x="50%" + className="absolute inset-x-0 inset-y-[-30%] h-[160%] w-full skew-y-[-18deg] fill-black/[0.02] stroke-black/5 dark:fill-white/1 dark:stroke-white/2.5" + {...gridProps} + /> + </div> + <motion.div + className="absolute inset-0 rounded-2xl bg-gradient-to-r from-[#D7EDEA] to-[#F4FBDF] opacity-0 transition duration-300 group-hover:opacity-100 dark:from-[#202D2E] dark:to-[#303428]" + style={style} + /> + <motion.div + className="absolute inset-0 rounded-2xl opacity-0 mix-blend-overlay transition duration-300 group-hover:opacity-100" + style={style} + > + <GridPattern + width={72} + height={56} + x="50%" + className="absolute inset-x-0 inset-y-[-30%] h-[160%] w-full skew-y-[-18deg] fill-black/50 stroke-black/70 dark:fill-white/2.5 dark:stroke-white/10" + {...gridProps} + /> + </motion.div> + </div> + ) +} + +function Resource({ resource }: { resource: Resource }) { + let mouseX = useMotionValue(0) + let mouseY = useMotionValue(0) + + function onMouseMove({ + currentTarget, + clientX, + clientY, + }: React.MouseEvent<HTMLDivElement>) { + let { left, top } = currentTarget.getBoundingClientRect() + mouseX.set(clientX - left) + mouseY.set(clientY - top) + } + + return ( + <div + key={resource.href} + onMouseMove={onMouseMove} + className="group relative flex rounded-2xl bg-zinc-50 transition-shadow hover:shadow-md hover:shadow-zinc-900/5 dark:bg-white/2.5 dark:hover:shadow-black/5" + > + <ResourcePattern {...resource.pattern} mouseX={mouseX} mouseY={mouseY} /> + <div className="absolute inset-0 rounded-2xl ring-1 ring-inset ring-zinc-900/7.5 group-hover:ring-zinc-900/10 dark:ring-white/10 dark:group-hover:ring-white/20" /> + <div className="relative rounded-2xl px-4 pb-4 pt-16"> + <ResourceIcon icon={resource.icon} /> + <h3 className="mt-4 text-sm font-semibold leading-7 text-zinc-900 dark:text-white"> + <Link href={resource.href}> + <span className="absolute inset-0 rounded-2xl" /> + {resource.name} + </Link> + </h3> + <p className="mt-1 text-sm text-zinc-600 dark:text-zinc-400"> + {resource.description} + </p> + </div> + </div> + ) +} + +export function Resources() { + return ( + <div className="my-16 xl:max-w-none"> + <Heading level={2} id="resources"> + Resources + </Heading> + <div className="not-prose mt-4 grid grid-cols-1 gap-8 border-t border-zinc-900/5 pt-10 dark:border-white/5 sm:grid-cols-2 xl:grid-cols-4"> + {resources.map((resource) => ( + <Resource key={resource.href} resource={resource} /> + ))} + </div> + </div> + ) +} diff --git a/src/components/SectionProvider.tsx b/src/components/SectionProvider.tsx deleted file mode 100644 index e61290627..000000000 --- a/src/components/SectionProvider.tsx +++ /dev/null @@ -1,127 +0,0 @@ -// @ts-nocheck - -import { - createContext, - useContext, - useEffect, - useLayoutEffect, - useState, -} from 'react' -import { createStore, useStore } from 'zustand' - -import { remToPx } from '@/lib/remToPx' - -function createSectionStore(sections) { - return createStore((set) => ({ - sections, - visibleSections: [], - setVisibleSections: (visibleSections) => - set((state) => - state.visibleSections.join() === visibleSections.join() - ? {} - : { visibleSections } - ), - registerHeading: ({ id, ref, offsetRem }) => - set((state) => { - return { - sections: state.sections.map((section) => { - if (section.id === id) { - return { - ...section, - headingRef: ref, - offsetRem, - } - } - return section - }), - } - }), - })) -} - -// offset for header -const headerOffset = 40 - -function useVisibleSections(sectionStore) { - let setVisibleSections = useStore(sectionStore, (s) => s.setVisibleSections) - let sections = useStore(sectionStore, (s) => s.sections) - - useEffect(() => { - function checkVisibleSections() { - let { innerHeight, scrollY } = window - let newVisibleSections = [] - - scrollY = scrollY - headerOffset - - for ( - let sectionIndex = 0; - sectionIndex < sections.length; - sectionIndex++ - ) { - let { id, headingRef, offsetRem } = sections[sectionIndex] - - if (!headingRef) return - - let offset = remToPx(offsetRem) - let top = headingRef.current.getBoundingClientRect().top + scrollY - - if (sectionIndex === 0 && top - offset > scrollY) { - newVisibleSections.push('_top') - } - - let nextSection = sections[sectionIndex + 1] - let bottom = - (nextSection?.headingRef.current.getBoundingClientRect().top ?? - Infinity) + - scrollY - - remToPx(nextSection?.offsetRem ?? 0) - - if ( - (top > scrollY && top < scrollY + innerHeight) || - (bottom > scrollY && bottom < scrollY + innerHeight) || - (top <= scrollY && bottom >= scrollY + innerHeight) - ) { - newVisibleSections.push(id) - } - } - - setVisibleSections(newVisibleSections) - } - - let raf = window.requestAnimationFrame(() => checkVisibleSections()) - window.addEventListener('scroll', checkVisibleSections, { passive: true }) - window.addEventListener('resize', checkVisibleSections) - - return () => { - window.cancelAnimationFrame(raf) - window.removeEventListener('scroll', checkVisibleSections) - window.removeEventListener('resize', checkVisibleSections) - } - }, [setVisibleSections, sections]) -} - -const SectionStoreContext = createContext() - -const useIsomorphicLayoutEffect = - typeof window === 'undefined' ? useEffect : useLayoutEffect - -export function SectionProvider({ sections, children }) { - let [sectionStore] = useState(() => createSectionStore(sections)) - - useVisibleSections(sectionStore) - - useIsomorphicLayoutEffect(() => { - sectionStore.setState({ sections }) - }, [sectionStore, sections]) - - return ( - <SectionStoreContext.Provider value={sectionStore}> - {children} - </SectionStoreContext.Provider> - ) -} - -export function useSectionStore(selector) { - let store = useContext(SectionStoreContext) - return useStore(store, selector) -} diff --git a/src/components/ShowIfLang.tsx b/src/components/ShowIfLang.tsx new file mode 100644 index 000000000..357840574 --- /dev/null +++ b/src/components/ShowIfLang.tsx @@ -0,0 +1,24 @@ +import { cn } from '@/lib/utils' + +const classes: Record<string, string> = { + javascript: 'group-data-[current-lang="javascript"]/body:block', + typescript: 'group-data-[current-lang="typescript"]/body:block', + dart: 'group-data-[current-lang="dart"]/body:block', + python: 'group-data-[current-lang="python"]/body:block', + go: 'group-data-[current-lang="go"]/body:block', +} + +export function ShowIfLang({ + children, + lang, +}: { + children: React.ReactNode + lang: string +}) { + if (!classes[lang]) { + console.error(`No class found for language in ShowIfLang: ${lang}`) + return null + } + + return <div className={cn('hidden', classes[lang])}>{children}</div> +} diff --git a/src/components/Spinner.tsx b/src/components/Spinner.tsx deleted file mode 100644 index c93095600..000000000 --- a/src/components/Spinner.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import clsx from 'clsx' -import React from 'react' - -interface Props { - className?: string -} - -export const Spinner: React.FC<Props> = ({ className }) => { - return ( - <div role="status"> - <svg - aria-hidden="true" - className={clsx( - 'h-5 w-5 animate-spin fill-primary-500 text-gray-200 dark:text-primary-300', - className - )} - viewBox="0 0 100 101" - fill="none" - > - <path - d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" - fill="currentColor" - /> - <path - d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" - fill="currentFill" - /> - </svg> - <span className="sr-only">Loading...</span> - </div> - ) -} diff --git a/src/components/Tabs.tsx b/src/components/Tabs.tsx deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/components/Tag.tsx b/src/components/Tag.tsx index 55bdf026e..06b21d644 100644 --- a/src/components/Tag.tsx +++ b/src/components/Tag.tsx @@ -1,14 +1,15 @@ import clsx from 'clsx' const variantStyles = { + small: '', medium: 'rounded-lg px-1.5 ring-1 ring-inset', } const colorStyles = { - pink: { - small: 'text-pink-500 dark:text-pink-400', + emerald: { + small: 'text-emerald-500 dark:text-emerald-400', medium: - 'ring-pink-300 dark:ring-pink-400/30 bg-pink-400/10 text-pink-500 dark:text-pink-400', + 'ring-emerald-300 dark:ring-emerald-400/30 bg-emerald-400/10 text-emerald-500 dark:text-emerald-400', }, sky: { small: 'text-sky-500', @@ -26,24 +27,27 @@ const colorStyles = { 'ring-rose-200 bg-rose-50 text-red-500 dark:ring-rose-500/20 dark:bg-rose-400/10 dark:text-rose-400', }, zinc: { - small: 'text-zinc-500 dark:text-zinc-200', + small: 'text-zinc-400 dark:text-zinc-500', medium: 'ring-zinc-200 bg-zinc-50 text-zinc-500 dark:ring-zinc-500/20 dark:bg-zinc-400/10 dark:text-zinc-400', }, } const valueColorMap = { - get: 'pink', - post: 'sky', - put: 'amber', - delete: 'rose', -} + GET: 'emerald', + POST: 'sky', + PUT: 'amber', + DELETE: 'rose', +} as Record<string, keyof typeof colorStyles> export function Tag({ children, variant = 'medium', - color = valueColorMap[children.toLowerCase()] ?? 'zinc', - className = '', + color = valueColorMap[children] ?? 'emerald', +}: { + children: keyof typeof valueColorMap & (string | {}) + variant?: keyof typeof variantStyles + color?: keyof typeof colorStyles }) { return ( <span @@ -51,7 +55,6 @@ export function Tag({ 'font-mono text-[0.625rem] font-semibold leading-6', variantStyles[variant], colorStyles[color][variant], - className )} > {children} diff --git a/src/components/ThemeToggle.tsx b/src/components/ThemeToggle.tsx new file mode 100644 index 000000000..eb9969fd7 --- /dev/null +++ b/src/components/ThemeToggle.tsx @@ -0,0 +1,44 @@ +import { useEffect, useState } from 'react' +import { useTheme } from 'next-themes' + +function SunIcon(props: React.ComponentPropsWithoutRef<'svg'>) { + return ( + <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}> + <path d="M12.5 10a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0Z" /> + <path + strokeLinecap="round" + d="M10 5.5v-1M13.182 6.818l.707-.707M14.5 10h1M13.182 13.182l.707.707M10 15.5v-1M6.11 13.889l.708-.707M4.5 10h1M6.11 6.111l.708.707" + /> + </svg> + ) +} + +function MoonIcon(props: React.ComponentPropsWithoutRef<'svg'>) { + return ( + <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}> + <path d="M15.224 11.724a5.5 5.5 0 0 1-6.949-6.949 5.5 5.5 0 1 0 6.949 6.949Z" /> + </svg> + ) +} + +export function ThemeToggle() { + let { resolvedTheme, setTheme } = useTheme() + let otherTheme = resolvedTheme === 'dark' ? 'light' : 'dark' + let [mounted, setMounted] = useState(false) + + useEffect(() => { + setMounted(true) + }, []) + + return ( + <button + type="button" + className="flex h-6 w-6 items-center justify-center rounded-md transition hover:bg-zinc-900/5 dark:hover:bg-white/5" + aria-label={mounted ? `Switch to ${otherTheme} theme` : 'Toggle theme'} + onClick={() => setTheme(otherTheme)} + > + <SunIcon className="h-5 w-5 stroke-zinc-900 dark:hidden" /> + <MoonIcon className="hidden h-5 w-5 stroke-white dark:block" /> + </button> + ) +} diff --git a/src/components/VersionSelect.tsx b/src/components/VersionSelect.tsx deleted file mode 100644 index df9503f2f..000000000 --- a/src/components/VersionSelect.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import * as React from 'react' - -import { - Select, - SelectContent, - SelectGroup, - SelectItem, - SelectLabel, - SelectTrigger, - SelectValue, -} from '@/components/ui/select' -import type { Version } from '@/nav.config' -import { useRouter } from 'next/router' -import { useVersions } from '@/lib/hooks/use-versions' -import { Badge } from './ui/badge' -import { cn } from '@/lib/utils' - -export function VersionSelect({ - versions, - className, -}: { - versions: Version[] - className?: string -}) { - const router = useRouter() - const { currentVersion, currentSdk, latestVersion, latestLink } = - useVersions(versions) - - const handleVersionSelect = React.useCallback( - (newVersion: string) => { - router.push( - latestVersion === newVersion - ? latestLink - : `/reference/${currentSdk}/${newVersion}` - ) - }, - [versions] - ) - - return ( - <Select value={currentVersion || ''} onValueChange={handleVersionSelect}> - <SelectTrigger - name="version-select" - aria-label="Select a version" - className={'font-semi-bold ml-auto w-[80px] font-mono text-sm'} - > - <SelectValue placeholder="Select a version"> - {currentVersion} - </SelectValue> - </SelectTrigger> - <SelectContent> - <SelectGroup> - <SelectLabel>Releases</SelectLabel> - {versions.map((version) => ( - <SelectItem - key={version} - value={version} - className={cn( - 'text-xs', - currentVersion === version && 'font-semibold' - )} - > - Version {version}{' '} - {version === latestVersion && ( - <Badge variant="default" className="ml-2 text-white"> - Latest - </Badge> - )} - </SelectItem> - ))} - </SelectGroup> - </SelectContent> - </Select> - ) -} diff --git a/src/components/code/Code.tsx b/src/components/code/Code.tsx new file mode 100644 index 000000000..84af59548 --- /dev/null +++ b/src/components/code/Code.tsx @@ -0,0 +1,23 @@ +import { highlight, RawCode } from 'codehike/code' +import Pre from './Pre' +import CodeContainer from './CodeContainer' +import CODE_THEME from './theme' + +export async function Code({ + codeblock, +}: { + codeblock: RawCode + isPanel?: boolean +}) { + const highlighted = await highlight(codeblock, CODE_THEME) + + const fileName = highlighted.meta + + const isPanel = !!fileName + + return ( + <CodeContainer> + <Pre highlighted={highlighted} showPanel={isPanel} /> + </CodeContainer> + ) +} diff --git a/src/components/code/CodeContainer.tsx b/src/components/code/CodeContainer.tsx new file mode 100644 index 000000000..25ea3d568 --- /dev/null +++ b/src/components/code/CodeContainer.tsx @@ -0,0 +1,18 @@ +import React from 'react' + +const CodeContainer: React.FC<React.PropsWithChildren> = ({ children }) => { + return ( + <div className="w-full max-w-full"> + <div + tabIndex={0} + className={ + 'not-prose group relative mb-6 w-full max-w-full overflow-hidden rounded-md border border-white/5 bg-code shadow-[inset_0px_0px_33px_-10px_#00000008,0px_0px_38px_-2px_#00000030]' + } + > + {children} + </div> + </div> + ) +} + +export default CodeContainer diff --git a/src/components/code/CodeSwitcher.tsx b/src/components/code/CodeSwitcher.tsx new file mode 100644 index 000000000..705c0996d --- /dev/null +++ b/src/components/code/CodeSwitcher.tsx @@ -0,0 +1,29 @@ +import React, { Suspense } from 'react' +import { highlight, RawCode } from 'codehike/code' +import CodeContainer from './CodeContainer' +import { CodeSwitcherSelect } from './CodeSwitcherSelect' +import CODE_THEME from './theme' +import Pre, { HandlerProps } from './Pre' + +export async function CodeSwitcher({ + code, + ...props +}: { + code: RawCode[] + showPanel?: boolean + className?: string +} & HandlerProps) { + const highlighted = await Promise.all( + code.map((codeblock) => highlight(codeblock, CODE_THEME)), + ) + + return ( + <CodeContainer> + <Suspense + fallback={<Pre highlighted={highlighted[0]} {...props} showPanel />} + > + <CodeSwitcherSelect highlighted={highlighted} {...props} /> + </Suspense> + </CodeContainer> + ) +} diff --git a/src/components/code/CodeSwitcherSelect.tsx b/src/components/code/CodeSwitcherSelect.tsx new file mode 100644 index 000000000..eb146edb2 --- /dev/null +++ b/src/components/code/CodeSwitcherSelect.tsx @@ -0,0 +1,96 @@ +'use client' + +import React from 'react' +import { HighlightedCode } from 'codehike/code' +import Pre, { HandlerProps } from './Pre' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '../ui/select' +import useLang, { LanguageId } from '@/hooks/useLang' +import { cn } from '@/lib/utils' + +const languageMap: Record<string, string> = { + javascript: 'JavaScript', + python: 'Python', + typescript: 'TypeScript', + go: 'Go', + dart: 'Dart', + java: 'JVM', + Kotlin: 'Kotlin', + csharp: 'C#', +} + +export function CodeSwitcherSelect({ + highlighted, + showPanel = true, + ...props +}: { + highlighted: HighlightedCode[] + className?: string + showPanel?: boolean +} & HandlerProps) { + const { currentLanguage, setCurrentLanguage } = useLang() + + // Make sure the selected language is in the list of languages in this code block + const selectedLang = + !currentLanguage || highlighted.find((h) => h.lang === currentLanguage) + ? currentLanguage + : (() => { + console.warn( + `CodeSwitcher missing ${currentLanguage} example - defaulting to ${highlighted[0].lang}: ${highlighted[0].meta}`, + ) + return highlighted[0].lang + })() + + const selectedCode = highlighted.find((code) => code.lang === selectedLang)! + + return ( + <> + {showPanel && ( + <> + <Select + value={selectedLang} + onValueChange={(lang) => { + // This is necessary to fix a ui update delay causing 200ms lag + setTimeout(() => setCurrentLanguage(lang as LanguageId), 0) + }} + > + <SelectTrigger + aria-label="Switch code language" + className="absolute right-20 top-1.5 hidden h-8 w-[120px] bg-white/5 text-2xs font-medium text-zinc-400 ring-1 ring-inset ring-zinc-300/10 hover:bg-white/7.5 dark:bg-white/2.5 dark:hover:bg-white/5 md:flex" + > + <SelectValue /> + </SelectTrigger> + <SelectContent position="item-aligned"> + {highlighted.map(({ lang }, index) => ( + <SelectItem key={index} value={lang}> + {languageMap[lang] || lang} + </SelectItem> + ))} + </SelectContent> + </Select> + <select + aria-label="Switch code language" + onChange={(e) => setCurrentLanguage(e.target.value as LanguageId)} + className={cn( + 'flex h-8 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50', + 'absolute right-20 top-1.5 w-[120px] bg-white/5 font-sans text-2xs font-medium text-zinc-400 ring-1 ring-inset ring-zinc-300/10 hover:bg-white/7.5 dark:bg-white/2.5 dark:hover:bg-white/5 md:hidden', + )} + value={selectedLang} + > + {highlighted.map(({ lang }, index) => ( + <option key={index} value={lang} className="font-sans text-sm"> + {languageMap[lang] || lang} + </option> + ))} + </select> + </> + )} + <Pre highlighted={selectedCode} {...props} showPanel={showPanel} /> + </> + ) +} diff --git a/src/components/code/CodeWithTabs.tsx b/src/components/code/CodeWithTabs.tsx new file mode 100644 index 000000000..dc5bfa163 --- /dev/null +++ b/src/components/code/CodeWithTabs.tsx @@ -0,0 +1,54 @@ +import React from 'react' +import { Block, CodeBlock, parseProps } from 'codehike/blocks' +import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' +import { highlight, HighlightedCode, RawCode } from 'codehike/code' +import { z } from 'zod' +import Pre from './Pre' +import CodeContainer from './CodeContainer' +import CODE_THEME from './theme' + +export const Schema = Block.extend({ tabs: z.array(CodeBlock) }) +export async function CodeWithTabs(props: unknown) { + const { tabs } = parseProps(props, Schema) + + const highlighted = await Promise.all( + tabs.map((tab) => highlight(tab, CODE_THEME)), + ) + + return <CodeTabs tabs={tabs} highlighted={highlighted} /> +} + +export function CodeTabs(props: { + tabs: RawCode[] + highlighted: HighlightedCode[] +}) { + const { tabs, highlighted } = props + + return ( + <CodeContainer> + <Tabs defaultValue={tabs[0]?.meta}> + <TabsList className="mt-auto h-10 bg-transparent"> + {tabs.map((tab) => ( + <TabsTrigger + key={tab.meta} + value={tab.meta} + className="group/tab relative hover:text-zinc-200 data-[state=active]:bg-transparent data-[state=active]:text-primary-300" + > + {tab.meta} + <div className="absolute inset-x-2 -bottom-[4.5px] h-px bg-primary-300 opacity-0 transition-opacity group-data-[state=active]/tab:opacity-100" /> + </TabsTrigger> + ))} + </TabsList> + {tabs.map((tab, i) => ( + <TabsContent + key={tab.meta} + value={tab.meta} + className="m-0 border-t border-zinc-300/10" + > + <Pre highlighted={highlighted[i]} copyButtonClassName="top-12" /> + </TabsContent> + ))} + </Tabs> + </CodeContainer> + ) +} diff --git a/src/components/code/CopyButton.tsx b/src/components/code/CopyButton.tsx new file mode 100644 index 000000000..715b185d4 --- /dev/null +++ b/src/components/code/CopyButton.tsx @@ -0,0 +1,68 @@ +'use client' + +import clsx from 'clsx' +import { useEffect, useState } from 'react' +import { ClipboardIcon } from '../icons/ClipboardIcon' + +export function CopyButton({ + code, + showPanel, + className, +}: { + code: string + showPanel?: boolean + className?: string +}) { + const [copyCount, setCopyCount] = useState(0) + const copied = copyCount > 0 + + useEffect(() => { + if (copyCount > 0) { + const timeout = setTimeout(() => setCopyCount(0), 1000) + return () => { + clearTimeout(timeout) + } + } + }, [copyCount]) + + return ( + <button + type="button" + className={clsx( + 'group/button absolute right-2 h-8 rounded-md px-1.5 py-1 text-2xs font-medium backdrop-blur transition', + showPanel ? 'top-1.5' : 'top-2.5', + copied + ? 'bg-primary-400/10 ring-primary-400/20' + : 'bg-white/5 ring-1 ring-inset ring-zinc-300/10 hover:bg-white/7.5 dark:bg-white/2.5 dark:hover:bg-white/5', + !showPanel && + 'opacity-0 focus:opacity-100 group-hover:opacity-100 group-focus:opacity-100', + className, + )} + onClick={() => { + window.navigator.clipboard.writeText(code).then(() => { + setCopyCount((count) => count + 1) + }) + }} + > + <span + aria-hidden={copied} + className={clsx( + 'pointer-events-none flex items-center gap-0.5 text-zinc-400 transition duration-300', + copied && '-translate-y-1.5 opacity-0', + )} + > + <ClipboardIcon className="size-4 fill-zinc-500/20 stroke-zinc-500 transition-colors group-hover/button:stroke-zinc-400" /> + Copy + </span> + <span + aria-hidden={!copied} + className={clsx( + 'pointer-events-none absolute inset-0 flex items-center justify-center text-primary-400 transition duration-300', + !copied && 'translate-y-1.5 opacity-0', + )} + > + Copied + </span> + </button> + ) +} diff --git a/src/components/code/ImportCode.tsx b/src/components/code/ImportCode.tsx new file mode 100644 index 000000000..d26c8d736 --- /dev/null +++ b/src/components/code/ImportCode.tsx @@ -0,0 +1,27 @@ +import React from 'react' +import { Code } from './Code' +import { RawCode } from 'codehike/code' +import path from 'path' +import fs from 'fs/promises' + +export const ImportCode: React.FC<{ file: string; meta: string }> = async ({ + file, + meta = '', +}) => { + try { + const contents = await fs.readFile(path.join(process.cwd(), file), 'utf-8') + + const lang = path.extname(file).replace('.', '') + + const codeBlock: RawCode = { + value: contents.trim(), + lang, + meta, + } + + return <Code codeblock={codeBlock} /> + } catch (error) { + console.error('Error reading file for ImportCode:', error) + return <div>Error reading file {file} for ImportCode</div> + } +} diff --git a/src/components/code/Pre.tsx b/src/components/code/Pre.tsx new file mode 100644 index 000000000..0024a63a8 --- /dev/null +++ b/src/components/code/Pre.tsx @@ -0,0 +1,70 @@ +import { HighlightedCode, Pre as CodeHikePre } from 'codehike/code' +import React from 'react' +import { callout } from './annotations/callout' +import { CopyButton } from './CopyButton' +import { className } from './annotations/classname' +import { fold } from './annotations/fold' +import { + collapse, + collapseContent, + collapseTrigger, +} from './annotations/collapse' +import { tokenTransitions } from './annotations/token-transitions' +import { cn } from '@/lib/utils' + +export interface HandlerProps { + enableTransitions?: boolean +} + +type Props = { + highlighted: HighlightedCode + showPanel?: boolean + className?: string + copyButtonClassName?: string +} & HandlerProps + +const Pre: React.FC<Props> = ({ + highlighted, + showPanel, + enableTransitions, + className, + copyButtonClassName, +}) => { + const fileName = highlighted.meta + + let handlers = [callout, fold, collapse, collapseTrigger, collapseContent] + // TODO: Fix transitions, they currently break colours in the code when switching languages + if (enableTransitions) { + handlers = [...handlers, tokenTransitions] + } + + return ( + <> + {showPanel && !!fileName && ( + <div className="flex h-10 items-center justify-start pr-12 font-display text-xs font-semibold text-zinc-400"> + {/* one-off breakpoint to hide the filename on extremely narrow screens - to avoid interfering with the lang select */} + <span className="hidden whitespace-nowrap px-4 py-2 min-[320px]:block"> + {fileName} + </span> + </div> + )} + <CopyButton + code={highlighted.code} + showPanel={showPanel} + className={copyButtonClassName} + /> + <CodeHikePre + code={highlighted} + handlers={handlers} + className={cn('overflow-auto overscroll-x-contain p-4', className)} + style={{ + ...highlighted.style, + fontSize: '0.875rem', + background: 'transparent !important', + }} + /> + </> + ) +} + +export default Pre diff --git a/src/components/code/annotations/callout.tsx b/src/components/code/annotations/callout.tsx new file mode 100644 index 000000000..079ffaeef --- /dev/null +++ b/src/components/code/annotations/callout.tsx @@ -0,0 +1,38 @@ +// from: https://codehike.org/docs/code/callout +import { InlineAnnotation, AnnotationHandler } from 'codehike/code' + +export const callout: AnnotationHandler = { + name: 'callout', + transform: (annotation: InlineAnnotation) => { + const { name, query, lineNumber, fromColumn, toColumn, data } = annotation + return { + name, + query, + fromLineNumber: lineNumber, + toLineNumber: lineNumber, + data: { ...data, column: (fromColumn + toColumn) / 2 }, + } + }, + Block: ({ annotation, children }) => { + const { column } = annotation.data + + return ( + <> + {children} + <div + style={{ + minWidth: `${column + 4}ch`, + boxShadow: 'inset 0 1px 0 0 #ffffff0d', + }} + className="relative -ml-[1ch] mt-1 w-fit whitespace-break-spaces rounded-md border bg-zinc-700 px-2 text-zinc-200" + > + <div + style={{ left: `${column}ch` }} + className="absolute -top-[0px] size-2 -translate-y-1/2 rotate-45 border-l-4 border-t-4 border-zinc-700" + /> + {annotation.query} + </div> + </> + ) + }, +} diff --git a/src/components/code/annotations/classname.tsx b/src/components/code/annotations/classname.tsx new file mode 100644 index 000000000..371897a54 --- /dev/null +++ b/src/components/code/annotations/classname.tsx @@ -0,0 +1,11 @@ +import { AnnotationHandler } from 'codehike/code' + +export const className: AnnotationHandler = { + name: 'className', + Block: ({ annotation, children }) => ( + <div className={annotation.query}>{children}</div> + ), + Inline: ({ annotation, children }) => ( + <span className={annotation.query}>{children}</span> + ), +} diff --git a/src/components/code/annotations/collapse.tsx b/src/components/code/annotations/collapse.tsx new file mode 100644 index 000000000..dc92ebb75 --- /dev/null +++ b/src/components/code/annotations/collapse.tsx @@ -0,0 +1,67 @@ +import { + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from '@/components/ui/collapsible' +import { AnnotationHandler, BlockAnnotation, InnerLine } from 'codehike/code' +import { ChevronDownIcon } from 'lucide-react' + +export const collapse: AnnotationHandler = { + name: 'collapse', + transform: (annotation: BlockAnnotation) => { + const { fromLineNumber } = annotation + return [ + annotation, + { + ...annotation, + fromLineNumber: fromLineNumber, + toLineNumber: fromLineNumber, + name: 'CollapseTrigger', + }, + { + ...annotation, + fromLineNumber: fromLineNumber + 1, + name: 'CollapseContent', + }, + ] + }, + Block: ({ annotation, children }) => { + return ( + <Collapsible defaultOpen={annotation.query !== 'collapsed'}> + {children} + </Collapsible> + ) + }, +} + +const icon = ( + <ChevronDownIcon + className="mb-0.5 inline-block select-none opacity-30 transition group-hover:!opacity-100 group-data-[state=closed]:-rotate-90 group-data-[state=closed]:opacity-80" + size={15} + /> +) +export const collapseTrigger: AnnotationHandler = { + name: 'CollapseTrigger', + onlyIfAnnotated: true, + AnnotatedLine: ({ annotation, ...props }) => ( + <CollapsibleTrigger className="group contents"> + <InnerLine merge={props} data={{ icon }} /> + </CollapsibleTrigger> + ), + Line: (props) => { + const icon = props.data?.icon as React.ReactNode + return ( + <div className="table-row"> + <span className="table-cell w-5 text-center">{icon}</span> + <div className="table-cell"> + <InnerLine merge={props} /> + </div> + </div> + ) + }, +} + +export const collapseContent: AnnotationHandler = { + name: 'CollapseContent', + Block: CollapsibleContent, +} diff --git a/src/components/code/annotations/fold.tsx b/src/components/code/annotations/fold.tsx new file mode 100644 index 000000000..f8322bec1 --- /dev/null +++ b/src/components/code/annotations/fold.tsx @@ -0,0 +1,20 @@ +'use client' +import { AnnotationHandler } from 'codehike/code' +import { useState } from 'react' + +export const InlineFold: AnnotationHandler['Inline'] = ({ children }) => { + const [folded, setFolded] = useState(true) + if (!folded) { + return children + } + return ( + <button onClick={() => setFolded(false)} aria-label="Expand"> + ... + </button> + ) +} + +export const fold: AnnotationHandler = { + name: 'fold', + Inline: InlineFold, +} diff --git a/src/components/code/annotations/token-transitions.client.tsx b/src/components/code/annotations/token-transitions.client.tsx new file mode 100644 index 000000000..70ab2425d --- /dev/null +++ b/src/components/code/annotations/token-transitions.client.tsx @@ -0,0 +1,50 @@ +'use client' + +import { CustomPreProps, InnerPre, getPreRef } from 'codehike/code' +import { + TokenTransitionsSnapshot, + calculateTransitions, + getStartingSnapshot, +} from 'codehike/utils/token-transitions' +import React from 'react' + +const MAX_TRANSITION_DURATION = 900 // milliseconds + +export class SmoothPre extends React.Component<CustomPreProps> { + ref: React.RefObject<HTMLPreElement> + constructor(props: CustomPreProps) { + super(props) + this.ref = getPreRef(this.props) + } + + render() { + return <InnerPre merge={this.props} style={{ position: 'relative' }} /> + } + + getSnapshotBeforeUpdate() { + return getStartingSnapshot(this.ref.current!) + } + + componentDidUpdate( + prevProps: never, + prevState: never, + snapshot: TokenTransitionsSnapshot, + ) { + const transitions = calculateTransitions(this.ref.current!, snapshot) + transitions.forEach(({ element, keyframes, options }) => { + const { translateX, translateY, ...kf } = keyframes as any + if (translateX && translateY) { + kf.translate = [ + `${translateX[0]}px ${translateY[0]}px`, + `${translateX[1]}px ${translateY[1]}px`, + ] + } + element.animate(kf, { + duration: options.duration * MAX_TRANSITION_DURATION, + delay: options.delay * MAX_TRANSITION_DURATION, + easing: options.easing, + fill: 'backwards', + }) + }) + } +} diff --git a/src/components/code/annotations/token-transitions.tsx b/src/components/code/annotations/token-transitions.tsx new file mode 100644 index 000000000..e2f833095 --- /dev/null +++ b/src/components/code/annotations/token-transitions.tsx @@ -0,0 +1,12 @@ +// from: https://codehike.org/docs/code/token-transitions + +import { AnnotationHandler, InnerToken } from 'codehike/code' +import { SmoothPre } from './token-transitions.client' + +export const tokenTransitions: AnnotationHandler = { + name: 'token-transitions', + PreWithRef: SmoothPre, + Token: (props) => ( + <InnerToken merge={props} style={{ display: 'inline-block' }} /> + ), +} diff --git a/src/components/code/theme.ts b/src/components/code/theme.ts new file mode 100644 index 000000000..5bcd3df37 --- /dev/null +++ b/src/components/code/theme.ts @@ -0,0 +1,6530 @@ +import { Theme } from '@code-hike/lighter' + +const theme: Theme = { + name: 'Catppuccin Macchiato', + type: 'dark', + colors: { + focusBorder: '#c6a0f6', + foreground: '#cad3f5', + disabledForeground: '#a5adcb', + 'widget.shadow': '#1e203080', + 'selection.background': '#c6a0f666', + descriptionForeground: '#cad3f5', + errorForeground: '#ed8796', + 'icon.foreground': '#c6a0f6', + 'sash.hoverBorder': '#c6a0f6', + 'window.activeBorder': '#00000000', + 'window.inactiveBorder': '#00000000', + 'textBlockQuote.background': '#1e2030', + 'textBlockQuote.border': '#181926', + 'textCodeBlock.background': '#24273a', + 'textLink.activeForeground': '#91d7e3', + 'textLink.foreground': '#8aadf4', + 'textPreformat.foreground': '#cad3f5', + 'textSeparator.foreground': '#c6a0f6', + 'activityBar.background': '#181926', + 'activityBar.foreground': '#c6a0f6', + 'activityBar.dropBorder': '#c6a0f633', + 'activityBar.inactiveForeground': '#6e738d', + 'activityBar.border': '#00000000', + 'activityBarBadge.background': '#c6a0f6', + 'activityBarBadge.foreground': '#181926', + 'activityBar.activeBorder': '#00000000', + 'activityBar.activeBackground': '#00000000', + 'activityBar.activeFocusBorder': '#00000000', + 'activityBarTop.foreground': '#c6a0f6', + 'activityBarTop.activeBorder': '#00000000', + 'activityBarTop.inactiveForeground': '#6e738d', + 'activityBarTop.dropBorder': '#c6a0f633', + 'badge.background': '#494d64', + 'badge.foreground': '#cad3f5', + 'breadcrumb.activeSelectionForeground': '#c6a0f6', + 'breadcrumb.background': '#24273a', + 'breadcrumb.focusForeground': '#c6a0f6', + 'breadcrumb.foreground': '#cad3f5cc', + 'breadcrumbPicker.background': '#1e2030', + 'button.background': '#c6a0f6', + 'button.foreground': '#181926', + 'button.border': '#00000000', + 'button.separator': '#00000000', + 'button.hoverBackground': '#dac1f9', + 'button.secondaryForeground': '#cad3f5', + 'button.secondaryBackground': '#5b6078', + 'button.secondaryHoverBackground': '#6a708c', + 'checkbox.background': '#494d64', + 'checkbox.border': '#00000000', + 'checkbox.foreground': '#c6a0f6', + 'dropdown.background': '#1e2030', + 'dropdown.listBackground': '#5b6078', + 'dropdown.border': '#c6a0f6', + 'dropdown.foreground': '#cad3f5', + 'debugToolBar.background': '#181926', + 'debugToolBar.border': '#00000000', + 'debugExceptionWidget.background': '#181926', + 'debugExceptionWidget.border': '#c6a0f6', + 'debugTokenExpression.number': '#f5a97f', + 'debugTokenExpression.boolean': '#c6a0f6', + 'debugTokenExpression.string': '#a6da95', + 'debugTokenExpression.error': '#ed8796', + 'debugIcon.breakpointForeground': '#ed8796', + 'debugIcon.breakpointDisabledForeground': '#ed879699', + 'debugIcon.breakpointUnverifiedForeground': '#a47487', + 'debugIcon.breakpointCurrentStackframeForeground': '#5b6078', + 'debugIcon.breakpointStackframeForeground': '#5b6078', + 'debugIcon.startForeground': '#a6da95', + 'debugIcon.pauseForeground': '#8aadf4', + 'debugIcon.stopForeground': '#ed8796', + 'debugIcon.disconnectForeground': '#5b6078', + 'debugIcon.restartForeground': '#8bd5ca', + 'debugIcon.stepOverForeground': '#c6a0f6', + 'debugIcon.stepIntoForeground': '#cad3f5', + 'debugIcon.stepOutForeground': '#cad3f5', + 'debugIcon.continueForeground': '#a6da95', + 'debugIcon.stepBackForeground': '#5b6078', + 'debugConsole.infoForeground': '#8aadf4', + 'debugConsole.warningForeground': '#f5a97f', + 'debugConsole.errorForeground': '#ed8796', + 'debugConsole.sourceForeground': '#f4dbd6', + 'debugConsoleInputIcon.foreground': '#cad3f5', + 'diffEditor.border': '#5b6078', + 'diffEditor.insertedTextBackground': '#a6da951a', + 'diffEditor.removedTextBackground': '#ed87961a', + 'diffEditor.insertedLineBackground': '#a6da9526', + 'diffEditor.removedLineBackground': '#ed879626', + 'diffEditor.diagonalFill': '#5b607899', + 'diffEditorOverview.insertedForeground': '#a6da95cc', + 'diffEditorOverview.removedForeground': '#ed8796cc', + 'editor.background': '#232333ff', + 'editor.findMatchBackground': '#604456', + 'editor.findMatchBorder': '#ed879633', + 'editor.findMatchHighlightBackground': '#455c6d', + 'editor.findMatchHighlightBorder': '#91d7e333', + 'editor.findRangeHighlightBackground': '#455c6d', + 'editor.findRangeHighlightBorder': '#91d7e333', + 'editor.foldBackground': '#91d7e340', + 'editor.foreground': '#cad3f5', + 'editor.hoverHighlightBackground': '#91d7e340', + 'editor.lineHighlightBackground': '#cad3f512', + 'editor.lineHighlightBorder': '#00000000', + 'editor.rangeHighlightBackground': '#ffffff10', + 'editor.rangeHighlightBorder': '#00000000', + 'editor.selectionBackground': '#939ab740', + 'editor.selectionHighlightBackground': '#939ab733', + 'editor.selectionHighlightBorder': '#939ab733', + 'editor.wordHighlightBackground': '#939ab733', + 'editorBracketMatch.background': '#939ab71a', + 'editorBracketMatch.border': '#939ab7', + 'editorCodeLens.foreground': '#8087a2', + 'editorCursor.background': '#24273a', + 'editorCursor.foreground': '#f4dbd6', + 'editorGroup.border': '#5b6078', + 'editorGroup.dropBackground': '#c6a0f633', + 'editorGroup.emptyBackground': '#24273a', + 'editorGroupHeader.tabsBackground': '#161620ff', + 'editorGutter.addedBackground': '#a6da95', + 'editorGutter.background': '#24273a', + 'editorGutter.commentRangeForeground': '#363a4f', + 'editorGutter.commentGlyphForeground': '#c6a0f6', + 'editorGutter.deletedBackground': '#ed8796', + 'editorGutter.foldingControlForeground': '#939ab7', + 'editorGutter.modifiedBackground': '#eed49f', + 'editorHoverWidget.background': '#1e2030', + 'editorHoverWidget.border': '#5b6078', + 'editorHoverWidget.foreground': '#cad3f5', + 'editorIndentGuide.activeBackground': '#5b6078', + 'editorIndentGuide.background': '#494d64', + 'editorInlayHint.foreground': '#5b6078', + 'editorInlayHint.background': '#1e2030bf', + 'editorInlayHint.typeForeground': '#b8c0e0', + 'editorInlayHint.typeBackground': '#1e2030bf', + 'editorInlayHint.parameterForeground': '#a5adcb', + 'editorInlayHint.parameterBackground': '#1e2030bf', + 'editorLineNumber.activeForeground': '#c6a0f6', + 'editorLineNumber.foreground': '#8087a2', + 'editorLink.activeForeground': '#c6a0f6', + 'editorMarkerNavigation.background': '#1e2030', + 'editorMarkerNavigationError.background': '#ed8796', + 'editorMarkerNavigationInfo.background': '#8aadf4', + 'editorMarkerNavigationWarning.background': '#f5a97f', + 'editorOverviewRuler.background': '#1e2030', + 'editorOverviewRuler.border': '#cad3f512', + 'editorOverviewRuler.modifiedForeground': '#eed49f', + 'editorRuler.foreground': '#5b6078', + 'editor.stackFrameHighlightBackground': '#eed49f26', + 'editor.focusedStackFrameHighlightBackground': '#a6da9526', + 'editorStickyScrollHover.background': '#363a4f', + 'editorSuggestWidget.background': '#1e2030', + 'editorSuggestWidget.border': '#5b6078', + 'editorSuggestWidget.foreground': '#cad3f5', + 'editorSuggestWidget.highlightForeground': '#c6a0f6', + 'editorSuggestWidget.selectedBackground': '#363a4f', + 'editorWhitespace.foreground': '#939ab766', + 'editorWidget.background': '#1e2030', + 'editorWidget.foreground': '#cad3f5', + 'editorWidget.resizeBorder': '#5b6078', + 'editorLightBulb.foreground': '#eed49f', + 'editorError.foreground': '#ed8796', + 'editorError.border': '#00000000', + 'editorError.background': '#00000000', + 'editorWarning.foreground': '#f5a97f', + 'editorWarning.border': '#00000000', + 'editorWarning.background': '#00000000', + 'editorInfo.foreground': '#8aadf4', + 'editorInfo.border': '#00000000', + 'editorInfo.background': '#00000000', + 'problemsErrorIcon.foreground': '#ed8796', + 'problemsInfoIcon.foreground': '#8aadf4', + 'problemsWarningIcon.foreground': '#f5a97f', + 'extensionButton.prominentForeground': '#181926', + 'extensionButton.prominentBackground': '#c6a0f6', + 'extensionButton.separator': '#24273a', + 'extensionButton.prominentHoverBackground': '#dac1f9', + 'extensionBadge.remoteBackground': '#8aadf4', + 'extensionBadge.remoteForeground': '#181926', + 'extensionIcon.starForeground': '#eed49f', + 'extensionIcon.verifiedForeground': '#a6da95', + 'extensionIcon.preReleaseForeground': '#5b6078', + 'extensionIcon.sponsorForeground': '#f5bde6', + 'gitDecoration.addedResourceForeground': '#a6da95', + 'gitDecoration.conflictingResourceForeground': '#c6a0f6', + 'gitDecoration.deletedResourceForeground': '#ed8796', + 'gitDecoration.ignoredResourceForeground': '#6e738d', + 'gitDecoration.modifiedResourceForeground': '#eed49f', + 'gitDecoration.stageDeletedResourceForeground': '#ed8796', + 'gitDecoration.stageModifiedResourceForeground': '#eed49f', + 'gitDecoration.submoduleResourceForeground': '#8aadf4', + 'gitDecoration.untrackedResourceForeground': '#a6da95', + 'input.background': '#363a4f', + 'input.border': '#00000000', + 'input.foreground': '#cad3f5', + 'input.placeholderForeground': '#cad3f573', + 'inputOption.activeBackground': '#5b6078', + 'inputOption.activeBorder': '#c6a0f6', + 'inputOption.activeForeground': '#cad3f5', + 'inputValidation.errorBackground': '#ed8796', + 'inputValidation.errorBorder': '#18192633', + 'inputValidation.errorForeground': '#181926', + 'inputValidation.infoBackground': '#8aadf4', + 'inputValidation.infoBorder': '#18192633', + 'inputValidation.infoForeground': '#181926', + 'inputValidation.warningBackground': '#f5a97f', + 'inputValidation.warningBorder': '#18192633', + 'inputValidation.warningForeground': '#181926', + 'list.activeSelectionBackground': '#363a4f', + 'list.activeSelectionForeground': '#cad3f5', + 'list.dropBackground': '#c6a0f633', + 'list.focusBackground': '#363a4f', + 'list.focusForeground': '#cad3f5', + 'list.focusOutline': '#00000000', + 'list.highlightForeground': '#c6a0f6', + 'list.hoverBackground': '#363a4f80', + 'list.hoverForeground': '#cad3f5', + 'list.inactiveSelectionBackground': '#363a4f', + 'list.inactiveSelectionForeground': '#cad3f5', + 'list.warningForeground': '#f5a97f', + 'listFilterWidget.background': '#494d64', + 'listFilterWidget.noMatchesOutline': '#ed8796', + 'listFilterWidget.outline': '#00000000', + 'tree.indentGuidesStroke': '#939ab7', + 'tree.inactiveIndentGuidesStroke': '#494d64', + 'menu.background': '#24273a', + 'menu.border': '#24273a80', + 'menu.foreground': '#cad3f5', + 'menu.selectionBackground': '#5b6078', + 'menu.selectionBorder': '#00000000', + 'menu.selectionForeground': '#cad3f5', + 'menu.separatorBackground': '#5b6078', + 'menubar.selectionBackground': '#494d64', + 'menubar.selectionForeground': '#cad3f5', + 'merge.commonContentBackground': '#494d64', + 'merge.commonHeaderBackground': '#5b6078', + 'merge.currentContentBackground': '#a6da9533', + 'merge.currentHeaderBackground': '#a6da9566', + 'merge.incomingContentBackground': '#8aadf433', + 'merge.incomingHeaderBackground': '#8aadf466', + 'minimap.background': '#1e203080', + 'minimap.findMatchHighlight': '#91d7e34d', + 'minimap.selectionHighlight': '#5b6078bf', + 'minimap.selectionOccurrenceHighlight': '#5b6078bf', + 'minimap.warningHighlight': '#f5a97fbf', + 'minimap.errorHighlight': '#ed8796bf', + 'minimapSlider.background': '#c6a0f633', + 'minimapSlider.hoverBackground': '#c6a0f666', + 'minimapSlider.activeBackground': '#c6a0f699', + 'minimapGutter.addedBackground': '#a6da95bf', + 'minimapGutter.deletedBackground': '#ed8796bf', + 'minimapGutter.modifiedBackground': '#eed49fbf', + 'notificationCenter.border': '#c6a0f6', + 'notificationCenterHeader.foreground': '#cad3f5', + 'notificationCenterHeader.background': '#1e2030', + 'notificationToast.border': '#c6a0f6', + 'notifications.foreground': '#cad3f5', + 'notifications.background': '#1e2030', + 'notifications.border': '#c6a0f6', + 'notificationLink.foreground': '#8aadf4', + 'notificationsErrorIcon.foreground': '#ed8796', + 'notificationsWarningIcon.foreground': '#f5a97f', + 'notificationsInfoIcon.foreground': '#8aadf4', + 'panel.background': '#24273a', + 'panel.border': '#5b6078', + 'panelSection.border': '#5b6078', + 'panelSection.dropBackground': '#c6a0f633', + 'panelTitle.activeBorder': '#c6a0f6', + 'panelTitle.activeForeground': '#cad3f5', + 'panelTitle.inactiveForeground': '#a5adcb', + 'peekView.border': '#c6a0f6', + 'peekViewEditor.background': '#1e2030', + 'peekViewEditorGutter.background': '#1e2030', + 'peekViewEditor.matchHighlightBackground': '#91d7e34d', + 'peekViewEditor.matchHighlightBorder': '#00000000', + 'peekViewResult.background': '#1e2030', + 'peekViewResult.fileForeground': '#cad3f5', + 'peekViewResult.lineForeground': '#cad3f5', + 'peekViewResult.matchHighlightBackground': '#91d7e34d', + 'peekViewResult.selectionBackground': '#363a4f', + 'peekViewResult.selectionForeground': '#cad3f5', + 'peekViewTitle.background': '#24273a', + 'peekViewTitleDescription.foreground': '#b8c0e0b3', + 'peekViewTitleLabel.foreground': '#cad3f5', + 'pickerGroup.border': '#c6a0f6', + 'pickerGroup.foreground': '#c6a0f6', + 'progressBar.background': '#c6a0f6', + 'scrollbar.shadow': '#181926', + 'scrollbarSlider.activeBackground': '#363a4f66', + 'scrollbarSlider.background': '#5b607880', + 'scrollbarSlider.hoverBackground': '#6e738d', + 'settings.focusedRowBackground': '#5b607833', + 'settings.headerForeground': '#cad3f5', + 'settings.modifiedItemIndicator': '#c6a0f6', + 'settings.dropdownBackground': '#494d64', + 'settings.dropdownListBorder': '#00000000', + 'settings.textInputBackground': '#494d64', + 'settings.textInputBorder': '#00000000', + 'settings.numberInputBackground': '#494d64', + 'settings.numberInputBorder': '#00000000', + 'sideBar.background': '#1e2030', + 'sideBar.dropBackground': '#c6a0f633', + 'sideBar.foreground': '#cad3f5', + 'sideBar.border': '#00000000', + 'sideBarSectionHeader.background': '#1e2030', + 'sideBarSectionHeader.foreground': '#cad3f5', + 'sideBarTitle.foreground': '#c6a0f6', + 'banner.background': '#494d64', + 'banner.foreground': '#cad3f5', + 'banner.iconForeground': '#cad3f5', + 'statusBar.background': '#181926', + 'statusBar.foreground': '#cad3f5', + 'statusBar.border': '#00000000', + 'statusBar.noFolderBackground': '#181926', + 'statusBar.noFolderForeground': '#cad3f5', + 'statusBar.noFolderBorder': '#00000000', + 'statusBar.debuggingBackground': '#f5a97f', + 'statusBar.debuggingForeground': '#181926', + 'statusBar.debuggingBorder': '#00000000', + 'statusBarItem.remoteBackground': '#8aadf4', + 'statusBarItem.remoteForeground': '#181926', + 'statusBarItem.activeBackground': '#5b607866', + 'statusBarItem.hoverBackground': '#5b607833', + 'statusBarItem.prominentForeground': '#c6a0f6', + 'statusBarItem.prominentBackground': '#00000000', + 'statusBarItem.prominentHoverBackground': '#5b607833', + 'statusBarItem.errorForeground': '#ed8796', + 'statusBarItem.errorBackground': '#00000000', + 'statusBarItem.warningForeground': '#f5a97f', + 'statusBarItem.warningBackground': '#00000000', + 'commandCenter.foreground': '#b8c0e0', + 'commandCenter.inactiveForeground': '#b8c0e0', + 'commandCenter.activeForeground': '#c6a0f6', + 'commandCenter.background': '#1e2030', + 'commandCenter.activeBackground': '#5b607833', + 'commandCenter.border': '#00000000', + 'commandCenter.inactiveBorder': '#00000000', + 'commandCenter.activeBorder': '#c6a0f6', + 'tab.activeBackground': '#414161ff', + 'tab.activeBorder': '#ffffffff', + 'tab.activeBorderTop': '#232333ff', + 'tab.activeForeground': '#ffffffff', + 'tab.activeModifiedBorder': '#eed49f', + 'tab.border': '#1e2030', + 'tab.hoverBackground': '#2e324a', + 'tab.hoverBorder': '#00000000', + 'tab.hoverForeground': '#c6a0f6', + 'tab.inactiveBackground': '#1d1d2aff', + 'tab.inactiveForeground': '#6e738d', + 'tab.inactiveModifiedBorder': '#eed49f4d', + 'tab.lastPinnedBorder': '#c6a0f6', + 'tab.unfocusedActiveBackground': '#1e2030', + 'tab.unfocusedActiveBorder': '#00000000', + 'tab.unfocusedActiveBorderTop': '#c6a0f64d', + 'tab.unfocusedInactiveBackground': '#141620', + 'terminal.foreground': '#cad3f5', + 'terminal.ansiBlack': '#a5adcb', + 'terminal.ansiRed': '#ed8796', + 'terminal.ansiGreen': '#a6da95', + 'terminal.ansiYellow': '#eed49f', + 'terminal.ansiBlue': '#8aadf4', + 'terminal.ansiMagenta': '#f5bde6', + 'terminal.ansiCyan': '#91d7e3', + 'terminal.ansiWhite': '#b8c0e0', + 'terminal.ansiBrightBlack': '#5b6078', + 'terminal.ansiBrightRed': '#ed8796', + 'terminal.ansiBrightGreen': '#a6da95', + 'terminal.ansiBrightYellow': '#eed49f', + 'terminal.ansiBrightBlue': '#8aadf4', + 'terminal.ansiBrightMagenta': '#f5bde6', + 'terminal.ansiBrightCyan': '#91d7e3', + 'terminal.ansiBrightWhite': '#494d64', + 'terminal.selectionBackground': '#5b6078', + 'terminal.inactiveSelectionBackground': '#5b607880', + 'terminalCursor.background': '#24273a', + 'terminalCursor.foreground': '#f4dbd6', + 'terminal.border': '#5b6078', + 'terminal.dropBackground': '#c6a0f633', + 'terminal.tab.activeBorder': '#c6a0f6', + 'terminalCommandDecoration.defaultBackground': '#5b6078', + 'terminalCommandDecoration.successBackground': '#a6da95', + 'terminalCommandDecoration.errorBackground': '#ed8796', + 'titleBar.activeBackground': '#181926', + 'titleBar.activeForeground': '#cad3f5', + 'titleBar.inactiveBackground': '#181926', + 'titleBar.inactiveForeground': '#cad3f580', + 'titleBar.border': '#00000000', + 'welcomePage.tileBackground': '#1e2030', + 'welcomePage.progress.background': '#181926', + 'welcomePage.progress.foreground': '#c6a0f6', + 'walkThrough.embeddedEditorBackground': '#24273a4d', + 'symbolIcon.textForeground': '#cad3f5', + 'symbolIcon.arrayForeground': '#f5a97f', + 'symbolIcon.booleanForeground': '#c6a0f6', + 'symbolIcon.classForeground': '#eed49f', + 'symbolIcon.colorForeground': '#f5bde6', + 'symbolIcon.constantForeground': '#f5a97f', + 'symbolIcon.constructorForeground': '#b7bdf8', + 'symbolIcon.enumeratorForeground': '#eed49f', + 'symbolIcon.enumeratorMemberForeground': '#eed49f', + 'symbolIcon.eventForeground': '#f5bde6', + 'symbolIcon.fieldForeground': '#cad3f5', + 'symbolIcon.fileForeground': '#c6a0f6', + 'symbolIcon.folderForeground': '#c6a0f6', + 'symbolIcon.functionForeground': '#8aadf4', + 'symbolIcon.interfaceForeground': '#eed49f', + 'symbolIcon.keyForeground': '#8bd5ca', + 'symbolIcon.keywordForeground': '#c6a0f6', + 'symbolIcon.methodForeground': '#8aadf4', + 'symbolIcon.moduleForeground': '#cad3f5', + 'symbolIcon.namespaceForeground': '#eed49f', + 'symbolIcon.nullForeground': '#ee99a0', + 'symbolIcon.numberForeground': '#f5a97f', + 'symbolIcon.objectForeground': '#eed49f', + 'symbolIcon.operatorForeground': '#8bd5ca', + 'symbolIcon.packageForeground': '#f0c6c6', + 'symbolIcon.propertyForeground': '#ee99a0', + 'symbolIcon.referenceForeground': '#eed49f', + 'symbolIcon.snippetForeground': '#f0c6c6', + 'symbolIcon.stringForeground': '#a6da95', + 'symbolIcon.structForeground': '#8bd5ca', + 'symbolIcon.typeParameterForeground': '#ee99a0', + 'symbolIcon.unitForeground': '#cad3f5', + 'symbolIcon.variableForeground': '#cad3f5', + 'charts.foreground': '#cad3f5', + 'charts.lines': '#b8c0e0', + 'charts.red': '#ed8796', + 'charts.blue': '#8aadf4', + 'charts.yellow': '#eed49f', + 'charts.orange': '#f5a97f', + 'charts.green': '#a6da95', + 'charts.purple': '#c6a0f6', + 'errorLens.errorBackground': '#ed879626', + 'errorLens.errorBackgroundLight': '#ed879626', + 'errorLens.errorForeground': '#ed8796', + 'errorLens.errorForegroundLight': '#ed8796', + 'errorLens.errorMessageBackground': '#ed879626', + 'errorLens.hintBackground': '#a6da9526', + 'errorLens.hintBackgroundLight': '#a6da9526', + 'errorLens.hintForeground': '#a6da95', + 'errorLens.hintForegroundLight': '#a6da95', + 'errorLens.hintMessageBackground': '#a6da9526', + 'errorLens.infoBackground': '#8aadf426', + 'errorLens.infoBackgroundLight': '#8aadf426', + 'errorLens.infoForeground': '#8aadf4', + 'errorLens.infoForegroundLight': '#8aadf4', + 'errorLens.infoMessageBackground': '#8aadf426', + 'errorLens.statusBarErrorForeground': '#ed8796', + 'errorLens.statusBarHintForeground': '#a6da95', + 'errorLens.statusBarIconErrorForeground': '#ed8796', + 'errorLens.statusBarIconWarningForeground': '#f5a97f', + 'errorLens.statusBarInfoForeground': '#8aadf4', + 'errorLens.statusBarWarningForeground': '#f5a97f', + 'errorLens.warningBackground': '#f5a97f26', + 'errorLens.warningBackgroundLight': '#f5a97f26', + 'errorLens.warningForeground': '#f5a97f', + 'errorLens.warningForegroundLight': '#f5a97f', + 'errorLens.warningMessageBackground': '#f5a97f26', + 'issues.closed': '#c6a0f6', + 'issues.newIssueDecoration': '#f4dbd6', + 'issues.open': '#a6da95', + 'pullRequests.closed': '#ed8796', + 'pullRequests.draft': '#939ab7', + 'pullRequests.merged': '#c6a0f6', + 'pullRequests.notification': '#cad3f5', + 'pullRequests.open': '#a6da95', + 'gitlens.gutterBackgroundColor': '#363a4f4d', + 'gitlens.gutterForegroundColor': '#cad3f5', + 'gitlens.gutterUncommittedForegroundColor': '#c6a0f6', + 'gitlens.trailingLineBackgroundColor': '#00000000', + 'gitlens.trailingLineForegroundColor': '#cad3f54d', + 'gitlens.lineHighlightBackgroundColor': '#c6a0f626', + 'gitlens.lineHighlightOverviewRulerColor': '#c6a0f6cc', + 'gitlens.openAutolinkedIssueIconColor': '#a6da95', + 'gitlens.closedAutolinkedIssueIconColor': '#c6a0f6', + 'gitlens.closedPullRequestIconColor': '#ed8796', + 'gitlens.openPullRequestIconColor': '#a6da95', + 'gitlens.mergedPullRequestIconColor': '#c6a0f6', + 'gitlens.unpublishedChangesIconColor': '#a6da95', + 'gitlens.unpublishedCommitIconColor': '#a6da95', + 'gitlens.unpulledChangesIconColor': '#f5a97f', + 'gitlens.decorations.branchAheadForegroundColor': '#a6da95', + 'gitlens.decorations.branchBehindForegroundColor': '#f5a97f', + 'gitlens.decorations.branchDivergedForegroundColor': '#eed49f', + 'gitlens.decorations.branchUnpublishedForegroundColor': '#a6da95', + 'gitlens.decorations.branchMissingUpstreamForegroundColor': '#f5a97f', + 'gitlens.decorations.statusMergingOrRebasingConflictForegroundColor': + '#ee99a0', + 'gitlens.decorations.statusMergingOrRebasingForegroundColor': '#eed49f', + 'gitlens.decorations.workspaceRepoMissingForegroundColor': '#a5adcb', + 'gitlens.decorations.workspaceCurrentForegroundColor': '#c6a0f6', + 'gitlens.decorations.workspaceRepoOpenForegroundColor': '#c6a0f6', + 'gitlens.decorations.worktreeHasUncommittedChangesForegroundColor': + '#f5a97f', + 'gitlens.decorations.worktreeMissingForegroundColor': '#ee99a0', + 'gitlens.graphLane1Color': '#c6a0f6', + 'gitlens.graphLane2Color': '#eed49f', + 'gitlens.graphLane3Color': '#8aadf4', + 'gitlens.graphLane4Color': '#f0c6c6', + 'gitlens.graphLane5Color': '#a6da95', + 'gitlens.graphLane6Color': '#b7bdf8', + 'gitlens.graphLane7Color': '#f4dbd6', + 'gitlens.graphLane8Color': '#ed8796', + 'gitlens.graphLane9Color': '#8bd5ca', + 'gitlens.graphLane10Color': '#f5bde6', + 'gitlens.graphChangesColumnAddedColor': '#a6da95', + 'gitlens.graphChangesColumnDeletedColor': '#ed8796', + 'gitlens.graphMinimapMarkerHeadColor': '#a6da95', + 'gitlens.graphScrollMarkerHeadColor': '#a6da95', + 'gitlens.graphMinimapMarkerUpstreamColor': '#96d382', + 'gitlens.graphScrollMarkerUpstreamColor': '#96d382', + 'gitlens.graphMinimapMarkerHighlightsColor': '#eed49f', + 'gitlens.graphScrollMarkerHighlightsColor': '#eed49f', + 'gitlens.graphMinimapMarkerLocalBranchesColor': '#8aadf4', + 'gitlens.graphScrollMarkerLocalBranchesColor': '#8aadf4', + 'gitlens.graphMinimapMarkerRemoteBranchesColor': '#739df2', + 'gitlens.graphScrollMarkerRemoteBranchesColor': '#739df2', + 'gitlens.graphMinimapMarkerStashesColor': '#c6a0f6', + 'gitlens.graphScrollMarkerStashesColor': '#c6a0f6', + 'gitlens.graphMinimapMarkerTagsColor': '#f0c6c6', + 'gitlens.graphScrollMarkerTagsColor': '#f0c6c6', + 'editorBracketHighlight.foreground1': '#ed8796', + 'editorBracketHighlight.foreground2': '#f5a97f', + 'editorBracketHighlight.foreground3': '#eed49f', + 'editorBracketHighlight.foreground4': '#a6da95', + 'editorBracketHighlight.foreground5': '#7dc4e4', + 'editorBracketHighlight.foreground6': '#c6a0f6', + 'editorBracketHighlight.unexpectedBracket.foreground': '#ee99a0', + 'button.secondaryBorder': '#c6a0f6', + 'table.headerBackground': '#363a4f', + 'table.headerForeground': '#cad3f5', + 'list.focusAndSelectionBackground': '#494d64', + 'editor.infoForeground': '#7637ffff', + }, + semanticHighlighting: true, + semanticTokenColors: { + enumMember: { + foreground: '#8bd5ca', + }, + selfKeyword: { + foreground: '#ed8796', + }, + boolean: { + foreground: '#f5a97f', + }, + number: { + foreground: '#f5a97f', + }, + 'variable.defaultLibrary': { + foreground: '#ee99a0', + }, + 'class:python': { + foreground: '#eed49f', + }, + 'class.builtin:python': { + foreground: '#c6a0f6', + }, + 'variable.typeHint:python': { + foreground: '#eed49f', + }, + 'function.decorator:python': { + foreground: '#f5a97f', + }, + 'variable.readonly:javascript': { + foreground: '#cad3f5', + }, + 'variable.readonly:typescript': { + foreground: '#cad3f5', + }, + 'property.readonly:javascript': { + foreground: '#cad3f5', + }, + 'property.readonly:typescript': { + foreground: '#cad3f5', + }, + 'variable.readonly:javascriptreact': { + foreground: '#cad3f5', + }, + 'variable.readonly:typescriptreact': { + foreground: '#cad3f5', + }, + 'property.readonly:javascriptreact': { + foreground: '#cad3f5', + }, + 'property.readonly:typescriptreact': { + foreground: '#cad3f5', + }, + 'variable.readonly:scala': { + foreground: '#cad3f5', + }, + 'type.defaultLibrary:go': { + foreground: '#c6a0f6', + }, + 'variable.readonly.defaultLibrary:go': { + foreground: '#c6a0f6', + }, + tomlArrayKey: { + foreground: '#8aadf4', + fontStyle: '', + }, + tomlTableKey: { + foreground: '#8aadf4', + fontStyle: '', + }, + 'builtinAttribute.attribute.library:rust': { + foreground: '#8aadf4', + }, + 'generic.attribute:rust': { + foreground: '#cad3f5', + }, + 'constant.builtin.readonly:nix': { + foreground: '#c6a0f6', + }, + heading: { + foreground: '#ed8796', + }, + 'text.emph': { + foreground: '#ed8796', + fontStyle: 'italic', + }, + 'text.strong': { + foreground: '#ed8796', + fontStyle: 'bold', + }, + 'text.math': { + foreground: '#f0c6c6', + }, + pol: { + foreground: '#f0c6c6', + }, + }, + tokenColors: [ + { + name: 'Basic text & variable names (incl. leading punctuation)', + scope: [ + 'text', + 'source', + 'variable.other.readwrite', + 'punctuation.definition.variable', + ], + settings: { + foreground: '#ffffffff', + fontStyle: 'normal', + }, + }, + { + name: 'Parentheses, Brackets, Braces', + scope: 'punctuation', + settings: { + foreground: '#939ab7', + fontStyle: '', + }, + }, + { + name: 'Comments', + scope: ['comment', 'punctuation.definition.comment'], + settings: { + foreground: '#838383ff', + fontStyle: 'italic', + }, + }, + { + scope: ['string', 'punctuation.definition.string'], + settings: { + foreground: '#d1ffb6ff', + fontStyle: 'normal', + }, + }, + { + scope: 'constant.character.escape', + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'Booleans, constants, numbers', + scope: [ + 'constant.numeric', + 'variable.other.constant', + 'entity.name.constant', + 'constant.language.boolean', + 'constant.language.false', + 'constant.language.true', + 'keyword.other.unit.user-defined', + 'keyword.other.unit.suffix.floating-point', + ], + settings: { + foreground: '#f5a97f', + }, + }, + { + scope: [ + 'keyword', + 'keyword.operator.word', + 'keyword.operator.new', + 'variable.language.super', + 'support.type.primitive', + 'storage.type', + 'storage.modifier', + 'punctuation.definition.keyword', + ], + settings: { + foreground: '#c492ffff', + fontStyle: 'normal', + }, + }, + { + scope: 'entity.name.tag.documentation', + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'Punctuation', + scope: [ + 'keyword.operator', + 'punctuation.accessor', + 'punctuation.definition.generic', + 'meta.function.closure punctuation.section.parameters', + 'punctuation.definition.tag', + 'punctuation.separator.key-value', + ], + settings: { + foreground: '#8bd5ca', + }, + }, + { + scope: [ + 'entity.name.function', + 'meta.function-call.method', + 'support.function', + 'support.function.misc', + 'variable.function', + ], + settings: { + foreground: '#6F9BFAFF', + }, + }, + { + name: 'Classes', + scope: [ + 'entity.name.class', + 'entity.other.inherited-class', + 'support.class', + 'meta.function-call.constructor', + 'entity.name.struct', + ], + settings: { + foreground: '#eed49f', + fontStyle: 'italic', + }, + }, + { + name: 'Enum', + scope: 'entity.name.enum', + settings: { + foreground: '#eed49f', + fontStyle: 'italic', + }, + }, + { + name: 'Enum member', + scope: [ + 'meta.enum variable.other.readwrite', + 'variable.other.enummember', + ], + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Object properties', + scope: 'meta.property.object', + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Types', + scope: [ + 'meta.type', + 'meta.type-alias', + 'support.type', + 'entity.name.type', + ], + settings: { + foreground: '#e9d5a5ff', + fontStyle: 'italic', + }, + }, + { + name: 'Decorators', + scope: [ + 'meta.annotation variable.function', + 'meta.annotation variable.annotation.function', + 'meta.annotation punctuation.definition.annotation', + 'meta.decorator', + 'punctuation.decorator', + ], + settings: { + foreground: '#f5a97f', + }, + }, + { + scope: ['variable.parameter', 'meta.function.parameters'], + settings: { + foreground: '#ee99a0', + fontStyle: 'italic', + }, + }, + { + name: 'Built-ins', + scope: ['constant.language', 'support.function.builtin'], + settings: { + foreground: '#ed8796', + }, + }, + { + scope: 'entity.other.attribute-name.documentation', + settings: { + foreground: '#ed8796', + }, + }, + { + name: 'Preprocessor directives', + scope: ['keyword.control.directive', 'punctuation.definition.directive'], + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'Type parameters', + scope: 'punctuation.definition.typeparameters', + settings: { + foreground: '#91d7e3', + }, + }, + { + name: 'Namespaces', + scope: 'entity.name.namespace', + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'Property names (left hand assignments in json/yaml/css)', + scope: 'support.type.property-name.css', + settings: { + foreground: '#8aadf4', + fontStyle: '', + }, + }, + { + name: 'This/Self keyword', + scope: [ + 'variable.language.this', + 'variable.language.this punctuation.definition.variable', + ], + settings: { + foreground: '#ed8796', + }, + }, + { + name: 'Object properties', + scope: 'variable.object.property', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'String template interpolation', + scope: ['string.template variable', 'string variable'], + settings: { + foreground: '#cad3f5', + }, + }, + { + name: '`new` as bold', + scope: 'keyword.operator.new', + settings: { + foreground: '#9affc8ff', + fontStyle: 'normal', + }, + }, + { + name: 'C++ extern keyword', + scope: 'storage.modifier.specifier.extern.cpp', + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'C++ scope resolution', + scope: [ + 'entity.name.scope-resolution.template.call.cpp', + 'entity.name.scope-resolution.parameter.cpp', + 'entity.name.scope-resolution.cpp', + 'entity.name.scope-resolution.function.definition.cpp', + ], + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'C++ doc keywords', + scope: 'storage.type.class.doxygen', + settings: { + fontStyle: '', + }, + }, + { + name: 'C++ operators', + scope: ['storage.modifier.reference.cpp'], + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'C# Interpolated Strings', + scope: 'meta.interpolation.cs', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'C# xml-style docs', + scope: 'comment.block.documentation.cs', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'Classes, reflecting the className color in JSX', + scope: [ + 'source.css entity.other.attribute-name.class.css', + 'entity.other.attribute-name.parent-selector.css punctuation.definition.entity.css', + ], + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'Operators', + scope: 'punctuation.separator.operator.css', + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Pseudo classes', + scope: 'source.css entity.other.attribute-name.pseudo-class', + settings: { + foreground: '#8bd5ca', + }, + }, + { + scope: 'source.css constant.other.unicode-range', + settings: { + foreground: '#f5a97f', + }, + }, + { + scope: 'source.css variable.parameter.url', + settings: { + foreground: '#a6da95', + fontStyle: '', + }, + }, + { + name: 'CSS vendored property names', + scope: ['support.type.vendored.property-name'], + settings: { + foreground: '#91d7e3', + }, + }, + { + name: 'Less/SCSS right-hand variables (@/$-prefixed)', + scope: [ + 'source.css meta.property-value variable', + 'source.css meta.property-value variable.other.less', + 'source.css meta.property-value variable.other.less punctuation.definition.variable.less', + 'meta.definition.variable.scss', + ], + settings: { + foreground: '#ee99a0', + }, + }, + { + name: 'CSS variables (--prefixed)', + scope: [ + 'source.css meta.property-list variable', + 'meta.property-list variable.other.less', + 'meta.property-list variable.other.less punctuation.definition.variable.less', + ], + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'CSS Percentage values, styled the same as numbers', + scope: 'keyword.other.unit.percentage.css', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'CSS Attribute selectors, styled the same as strings', + scope: 'source.css meta.attribute-selector', + settings: { + foreground: '#a6da95', + }, + }, + { + name: 'JSON/YAML keys, other left-hand assignments', + scope: [ + 'keyword.other.definition.ini', + 'punctuation.support.type.property-name.json', + 'support.type.property-name.json', + 'punctuation.support.type.property-name.toml', + 'support.type.property-name.toml', + 'entity.name.tag.yaml', + 'punctuation.support.type.property-name.yaml', + 'support.type.property-name.yaml', + ], + settings: { + foreground: '#8aadf4', + fontStyle: '', + }, + }, + { + name: 'JSON/YAML constants', + scope: ['constant.language.json', 'constant.language.yaml'], + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'YAML anchors', + scope: ['entity.name.type.anchor.yaml', 'variable.other.alias.yaml'], + settings: { + foreground: '#eed49f', + fontStyle: '', + }, + }, + { + name: 'TOML tables / ini groups', + scope: [ + 'support.type.property-name.table', + 'entity.name.section.group-title.ini', + ], + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'TOML dates', + scope: 'constant.other.time.datetime.offset.toml', + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'YAML anchor puctuation', + scope: [ + 'punctuation.definition.anchor.yaml', + 'punctuation.definition.alias.yaml', + ], + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'YAML triple dashes', + scope: 'entity.other.document.begin.yaml', + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'Markup Diff', + scope: 'markup.changed.diff', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Diff', + scope: [ + 'meta.diff.header.from-file', + 'meta.diff.header.to-file', + 'punctuation.definition.from-file.diff', + 'punctuation.definition.to-file.diff', + ], + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'Diff Inserted', + scope: 'markup.inserted.diff', + settings: { + foreground: '#a6da95', + }, + }, + { + name: 'Diff Deleted', + scope: 'markup.deleted.diff', + settings: { + foreground: '#ed8796', + }, + }, + { + name: 'dotenv left-hand side assignments', + scope: ['variable.other.env'], + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'dotenv reference to existing env variable', + scope: ['string.quoted variable.other.env'], + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'GDScript functions', + scope: 'support.function.builtin.gdscript', + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'GDScript constants', + scope: 'constant.language.gdscript', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Comment keywords', + scope: 'comment meta.annotation.go', + settings: { + foreground: '#ee99a0', + }, + }, + { + name: 'go:embed, go:build, etc.', + scope: 'comment meta.annotation.parameters.go', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Go constants (nil, true, false)', + scope: 'constant.language.go', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'GraphQL variables', + scope: 'variable.graphql', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'GraphQL aliases', + scope: 'string.unquoted.alias.graphql', + settings: { + foreground: '#f0c6c6', + }, + }, + { + name: 'GraphQL enum members', + scope: 'constant.character.enum.graphql', + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'GraphQL field in types', + scope: + 'meta.objectvalues.graphql constant.object.key.graphql string.unquoted.graphql', + settings: { + foreground: '#f0c6c6', + }, + }, + { + name: 'HTML/XML DOCTYPE as keyword', + scope: [ + 'keyword.other.doctype', + 'meta.tag.sgml.doctype punctuation.definition.tag', + 'meta.tag.metadata.doctype entity.name.tag', + 'meta.tag.metadata.doctype punctuation.definition.tag', + ], + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'HTML/XML-like <tags/>', + scope: ['entity.name.tag'], + settings: { + foreground: '#8aadf4', + fontStyle: '', + }, + }, + { + name: 'Special characters like &', + scope: [ + 'text.html constant.character.entity', + 'text.html constant.character.entity punctuation', + 'constant.character.entity.xml', + 'constant.character.entity.xml punctuation', + 'constant.character.entity.js.jsx', + 'constant.charactger.entity.js.jsx punctuation', + 'constant.character.entity.tsx', + 'constant.character.entity.tsx punctuation', + ], + settings: { + foreground: '#ed8796', + }, + }, + { + name: 'HTML/XML tag attribute values', + scope: ['entity.other.attribute-name'], + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'Components', + scope: [ + 'support.class.component', + 'support.class.component.jsx', + 'support.class.component.tsx', + 'support.class.component.vue', + ], + settings: { + foreground: '#f5bde6', + fontStyle: '', + }, + }, + { + name: 'Annotations', + scope: ['punctuation.definition.annotation', 'storage.type.annotation'], + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Java enums', + scope: 'constant.other.enum.java', + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Java imports', + scope: 'storage.modifier.import.java', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'Javadoc', + scope: + 'comment.block.javadoc.java keyword.other.documentation.javadoc.java', + settings: { + fontStyle: '', + }, + }, + { + name: 'Exported Variable', + scope: 'meta.export variable.other.readwrite.js', + settings: { + foreground: '#ee99a0', + }, + }, + { + name: 'JS/TS constants & properties', + scope: [ + 'variable.other.constant.js', + 'variable.other.constant.ts', + 'variable.other.property.js', + 'variable.other.property.ts', + ], + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'JSDoc; these are mainly params, so styled as such', + scope: [ + 'variable.other.jsdoc', + 'comment.block.documentation variable.other', + ], + settings: { + foreground: '#ee99a0', + fontStyle: '', + }, + }, + { + name: 'JSDoc keywords', + scope: 'storage.type.class.jsdoc', + settings: { + fontStyle: '', + }, + }, + { + scope: 'support.type.object.console.js', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'Node constants as keywords (module, etc.)', + scope: ['support.constant.node', 'support.type.object.module.js'], + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'implements as keyword', + scope: 'storage.modifier.implements', + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'Builtin types', + scope: [ + 'constant.language.null.js', + 'constant.language.null.ts', + 'constant.language.undefined.js', + 'constant.language.undefined.ts', + 'support.type.builtin.ts', + ], + settings: { + foreground: '#c6a0f6', + }, + }, + { + scope: 'variable.parameter.generic', + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'Arrow functions', + scope: [ + 'keyword.declaration.function.arrow.js', + 'storage.type.function.arrow.ts', + ], + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Decorator punctuations (decorators inherit from blue functions, instead of styleguide peach)', + scope: 'punctuation.decorator.ts', + settings: { + foreground: '#8aadf4', + fontStyle: 'italic', + }, + }, + { + name: 'Extra JS/TS keywords', + scope: [ + 'keyword.operator.expression.in.js', + 'keyword.operator.expression.in.ts', + 'keyword.operator.expression.infer.ts', + 'keyword.operator.expression.instanceof.js', + 'keyword.operator.expression.instanceof.ts', + 'keyword.operator.expression.is', + 'keyword.operator.expression.keyof.ts', + 'keyword.operator.expression.of.js', + 'keyword.operator.expression.of.ts', + 'keyword.operator.expression.typeof.ts', + ], + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'Julia macros', + scope: 'support.function.macro.julia', + settings: { + foreground: '#8bd5ca', + fontStyle: 'italic', + }, + }, + { + name: 'Julia language constants (true, false)', + scope: 'constant.language.julia', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Julia other constants (these seem to be arguments inside arrays)', + scope: 'constant.other.symbol.julia', + settings: { + foreground: '#ee99a0', + }, + }, + { + name: 'LaTeX preamble', + scope: 'text.tex keyword.control.preamble', + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'LaTeX be functions', + scope: 'text.tex support.function.be', + settings: { + foreground: '#91d7e3', + }, + }, + { + name: 'LaTeX math', + scope: 'constant.other.general.math.tex', + settings: { + foreground: '#f0c6c6', + }, + }, + { + name: 'Lua docstring keywords', + scope: + 'comment.line.double-dash.documentation.lua storage.type.annotation.lua', + settings: { + foreground: '#c6a0f6', + fontStyle: '', + }, + }, + { + name: 'Lua docstring variables', + scope: [ + 'comment.line.double-dash.documentation.lua entity.name.variable.lua', + 'comment.line.double-dash.documentation.lua variable.lua', + ], + settings: { + foreground: '#cad3f5', + }, + }, + { + scope: [ + 'heading.1.markdown punctuation.definition.heading.markdown', + 'heading.1.markdown', + 'heading.1.quarto punctuation.definition.heading.quarto', + 'heading.1.quarto', + 'markup.heading.atx.1.mdx', + 'markup.heading.atx.1.mdx punctuation.definition.heading.mdx', + 'markup.heading.setext.1.markdown', + 'markup.heading.heading-0.asciidoc', + ], + settings: { + foreground: '#ed8796', + }, + }, + { + scope: [ + 'heading.2.markdown punctuation.definition.heading.markdown', + 'heading.2.markdown', + 'heading.2.quarto punctuation.definition.heading.quarto', + 'heading.2.quarto', + 'markup.heading.atx.2.mdx', + 'markup.heading.atx.2.mdx punctuation.definition.heading.mdx', + 'markup.heading.setext.2.markdown', + 'markup.heading.heading-1.asciidoc', + ], + settings: { + foreground: '#f5a97f', + }, + }, + { + scope: [ + 'heading.3.markdown punctuation.definition.heading.markdown', + 'heading.3.markdown', + 'heading.3.quarto punctuation.definition.heading.quarto', + 'heading.3.quarto', + 'markup.heading.atx.3.mdx', + 'markup.heading.atx.3.mdx punctuation.definition.heading.mdx', + 'markup.heading.heading-2.asciidoc', + ], + settings: { + foreground: '#eed49f', + }, + }, + { + scope: [ + 'heading.4.markdown punctuation.definition.heading.markdown', + 'heading.4.markdown', + 'heading.4.quarto punctuation.definition.heading.quarto', + 'heading.4.quarto', + 'markup.heading.atx.4.mdx', + 'markup.heading.atx.4.mdx punctuation.definition.heading.mdx', + 'markup.heading.heading-3.asciidoc', + ], + settings: { + foreground: '#a6da95', + }, + }, + { + scope: [ + 'heading.5.markdown punctuation.definition.heading.markdown', + 'heading.5.markdown', + 'heading.5.quarto punctuation.definition.heading.quarto', + 'heading.5.quarto', + 'markup.heading.atx.5.mdx', + 'markup.heading.atx.5.mdx punctuation.definition.heading.mdx', + 'markup.heading.heading-4.asciidoc', + ], + settings: { + foreground: '#8aadf4', + }, + }, + { + scope: [ + 'heading.6.markdown punctuation.definition.heading.markdown', + 'heading.6.markdown', + 'heading.6.quarto punctuation.definition.heading.quarto', + 'heading.6.quarto', + 'markup.heading.atx.6.mdx', + 'markup.heading.atx.6.mdx punctuation.definition.heading.mdx', + 'markup.heading.heading-5.asciidoc', + ], + settings: { + foreground: '#c6a0f6', + }, + }, + { + scope: 'markup.bold', + settings: { + foreground: '#ed8796', + fontStyle: 'bold', + }, + }, + { + scope: 'markup.italic', + settings: { + foreground: '#ed8796', + fontStyle: 'italic', + }, + }, + { + scope: 'markup.strikethrough', + settings: { + foreground: '#a5adcb', + fontStyle: 'strikethrough', + }, + }, + { + name: 'Markdown auto links', + scope: ['punctuation.definition.link', 'markup.underline.link'], + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'Markdown links', + scope: [ + 'text.html.markdown punctuation.definition.link.title', + 'text.html.quarto punctuation.definition.link.title', + 'string.other.link.title.markdown', + 'string.other.link.title.quarto', + 'markup.link', + 'punctuation.definition.constant.markdown', + 'punctuation.definition.constant.quarto', + 'constant.other.reference.link.markdown', + 'constant.other.reference.link.quarto', + 'markup.substitution.attribute-reference', + ], + settings: { + foreground: '#b7bdf8', + }, + }, + { + name: 'Markdown code spans', + scope: [ + 'punctuation.definition.raw.markdown', + 'punctuation.definition.raw.quarto', + 'markup.inline.raw.string.markdown', + 'markup.inline.raw.string.quarto', + 'markup.raw.block.markdown', + 'markup.raw.block.quarto', + ], + settings: { + foreground: '#a6da95', + }, + }, + { + name: 'Markdown triple backtick language identifier', + scope: 'fenced_code.block.language', + settings: { + foreground: '#91d7e3', + }, + }, + { + name: 'Markdown triple backticks', + scope: [ + 'markup.fenced_code.block punctuation.definition', + 'markup.raw support.asciidoc', + ], + settings: { + foreground: '#939ab7', + }, + }, + { + name: 'Markdown quotes', + scope: ['markup.quote', 'punctuation.definition.quote.begin'], + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'Markdown separators', + scope: 'meta.separator.markdown', + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Markdown list bullets', + scope: [ + 'punctuation.definition.list.begin.markdown', + 'punctuation.definition.list.begin.quarto', + 'markup.list.bullet', + ], + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Quarto headings', + scope: 'markup.heading.quarto', + settings: { + fontStyle: 'bold', + }, + }, + { + name: 'Nix attribute names', + scope: [ + 'entity.other.attribute-name.multipart.nix', + 'entity.other.attribute-name.single.nix', + ], + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'Nix parameter names', + scope: 'variable.parameter.name.nix', + settings: { + foreground: '#cad3f5', + fontStyle: '', + }, + }, + { + name: 'Nix interpolated parameter names', + scope: 'meta.embedded variable.parameter.name.nix', + settings: { + foreground: '#b7bdf8', + fontStyle: '', + }, + }, + { + name: 'Nix paths', + scope: 'string.unquoted.path.nix', + settings: { + foreground: '#f5bde6', + fontStyle: '', + }, + }, + { + name: 'PHP Attributes', + scope: ['support.attribute.builtin', 'meta.attribute.php'], + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'PHP Parameters (needed for the leading dollar sign)', + scope: 'meta.function.parameters.php punctuation.definition.variable.php', + settings: { + foreground: '#ee99a0', + }, + }, + { + name: 'PHP Constants (null, __FILE__, etc.)', + scope: 'constant.language.php', + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'PHP functions', + scope: 'text.html.php support.function', + settings: { + foreground: '#91d7e3', + }, + }, + { + name: 'PHPdoc keywords', + scope: 'keyword.other.phpdoc.php', + settings: { + fontStyle: '', + }, + }, + { + name: 'Python argument functions reset to text, otherwise they inherit blue from function-call', + scope: [ + 'support.variable.magic.python', + 'meta.function-call.arguments.python', + ], + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'Python double underscore functions', + scope: ['support.function.magic.python'], + settings: { + foreground: '#91d7e3', + fontStyle: 'italic', + }, + }, + { + name: 'Python `self` keyword', + scope: [ + 'variable.parameter.function.language.special.self.python', + 'variable.language.special.self.python', + ], + settings: { + foreground: '#ed8796', + fontStyle: 'italic', + }, + }, + { + name: 'python keyword flow/logical (for ... in)', + scope: ['keyword.control.flow.python', 'keyword.operator.logical.python'], + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'python storage type', + scope: 'storage.type.function.python', + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'python function support', + scope: [ + 'support.token.decorator.python', + 'meta.function.decorator.identifier.python', + ], + settings: { + foreground: '#91d7e3', + }, + }, + { + name: 'python function calls', + scope: ['meta.function-call.python'], + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'python function decorators', + scope: [ + 'entity.name.function.decorator.python', + 'punctuation.definition.decorator.python', + ], + settings: { + foreground: '#f5a97f', + fontStyle: 'italic', + }, + }, + { + name: 'python placeholder reset to normal string', + scope: 'constant.character.format.placeholder.other.python', + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'Python exception & builtins such as exit()', + scope: [ + 'support.type.exception.python', + 'support.function.builtin.python', + ], + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'entity.name.type', + scope: ['support.type.python'], + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'python constants (True/False)', + scope: 'constant.language.python', + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'Arguments accessed later in the function body', + scope: ['meta.indexed-name.python', 'meta.item-access.python'], + settings: { + foreground: '#ee99a0', + fontStyle: 'italic', + }, + }, + { + name: 'Python f-strings/binary/unicode storage types', + scope: 'storage.type.string.python', + settings: { + foreground: '#a6da95', + fontStyle: 'italic', + }, + }, + { + name: 'Python type hints', + scope: 'meta.function.parameters.python', + settings: { + fontStyle: '', + }, + }, + { + name: 'Regex string begin/end in JS/TS', + scope: [ + 'string.regexp punctuation.definition.string.begin', + 'string.regexp punctuation.definition.string.end', + ], + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'Regex anchors (^, $)', + scope: 'keyword.control.anchor.regexp', + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'Regex regular string match', + scope: 'string.regexp.ts', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'Regex group parenthesis & backreference (\\1, \\2, \\3, ...)', + scope: [ + 'punctuation.definition.group.regexp', + 'keyword.other.back-reference.regexp', + ], + settings: { + foreground: '#a6da95', + }, + }, + { + name: 'Regex character class []', + scope: 'punctuation.definition.character-class.regexp', + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'Regex character classes (\\d, \\w, \\s)', + scope: 'constant.other.character-class.regexp', + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'Regex range', + scope: 'constant.other.character-class.range.regexp', + settings: { + foreground: '#f4dbd6', + }, + }, + { + name: 'Regex quantifier', + scope: 'keyword.operator.quantifier.regexp', + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Regex constant/numeric', + scope: 'constant.character.numeric.regexp', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Regex lookaheads, negative lookaheads, lookbehinds, negative lookbehinds', + scope: [ + 'punctuation.definition.group.no-capture.regexp', + 'meta.assertion.look-ahead.regexp', + 'meta.assertion.negative-look-ahead.regexp', + ], + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'Rust attribute', + scope: [ + 'meta.annotation.rust', + 'meta.annotation.rust punctuation', + 'meta.attribute.rust', + 'punctuation.definition.attribute.rust', + ], + settings: { + foreground: '#eed49f', + fontStyle: 'italic', + }, + }, + { + name: 'Rust attribute strings', + scope: [ + 'meta.attribute.rust string.quoted.double.rust', + 'meta.attribute.rust string.quoted.single.char.rust', + ], + settings: { + fontStyle: '', + }, + }, + { + name: 'Rust keyword', + scope: [ + 'entity.name.function.macro.rules.rust', + 'storage.type.module.rust', + 'storage.modifier.rust', + 'storage.type.struct.rust', + 'storage.type.enum.rust', + 'storage.type.trait.rust', + 'storage.type.union.rust', + 'storage.type.impl.rust', + 'storage.type.rust', + 'storage.type.function.rust', + 'storage.type.type.rust', + ], + settings: { + foreground: '#c6a0f6', + fontStyle: '', + }, + }, + { + name: 'Rust u/i32, u/i64, etc.', + scope: 'entity.name.type.numeric.rust', + settings: { + foreground: '#c6a0f6', + fontStyle: '', + }, + }, + { + name: 'Rust generic', + scope: 'meta.generic.rust', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Rust impl', + scope: 'entity.name.impl.rust', + settings: { + foreground: '#eed49f', + fontStyle: 'italic', + }, + }, + { + name: 'Rust module', + scope: 'entity.name.module.rust', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Rust trait', + scope: 'entity.name.trait.rust', + settings: { + foreground: '#eed49f', + fontStyle: 'italic', + }, + }, + { + name: 'Rust struct', + scope: 'storage.type.source.rust', + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'Rust union', + scope: 'entity.name.union.rust', + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'Rust enum member', + scope: 'meta.enum.rust storage.type.source.rust', + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Rust macro', + scope: [ + 'support.macro.rust', + 'meta.macro.rust support.function.rust', + 'entity.name.function.macro.rust', + ], + settings: { + foreground: '#8aadf4', + fontStyle: 'italic', + }, + }, + { + name: 'Rust lifetime', + scope: ['storage.modifier.lifetime.rust', 'entity.name.type.lifetime'], + settings: { + foreground: '#8aadf4', + fontStyle: 'italic', + }, + }, + { + name: 'Rust string formatting', + scope: 'string.quoted.double.rust constant.other.placeholder.rust', + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'Rust return type generic', + scope: + 'meta.function.return-type.rust meta.generic.rust storage.type.rust', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'Rust functions', + scope: 'meta.function.call.rust', + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'Rust angle brackets', + scope: 'punctuation.brackets.angle.rust', + settings: { + foreground: '#91d7e3', + }, + }, + { + name: 'Rust constants', + scope: 'constant.other.caps.rust', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Rust function parameters', + scope: ['meta.function.definition.rust variable.other.rust'], + settings: { + foreground: '#ee99a0', + }, + }, + { + name: 'Rust closure variables', + scope: 'meta.function.call.rust variable.other.rust', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'Rust self', + scope: 'variable.language.self.rust', + settings: { + foreground: '#ed8796', + }, + }, + { + name: 'Rust metavariable names', + scope: [ + 'variable.other.metavariable.name.rust', + 'meta.macro.metavariable.rust keyword.operator.macro.dollar.rust', + ], + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'Shell shebang', + scope: [ + 'comment.line.shebang', + 'comment.line.shebang punctuation.definition.comment', + 'comment.line.shebang', + 'punctuation.definition.comment.shebang.shell', + 'meta.shebang.shell', + ], + settings: { + foreground: '#f5bde6', + fontStyle: 'italic', + }, + }, + { + name: 'Shell shebang command', + scope: 'comment.line.shebang constant.language', + settings: { + foreground: '#8bd5ca', + fontStyle: 'italic', + }, + }, + { + name: 'Shell interpolated command', + scope: [ + 'meta.function-call.arguments.shell punctuation.definition.variable.shell', + 'meta.function-call.arguments.shell punctuation.section.interpolation', + 'meta.function-call.arguments.shell punctuation.definition.variable.shell', + 'meta.function-call.arguments.shell punctuation.section.interpolation', + ], + settings: { + foreground: '#ed8796', + }, + }, + { + name: 'Shell interpolated command variable', + scope: + 'meta.string meta.interpolation.parameter.shell variable.other.readwrite', + settings: { + foreground: '#f5a97f', + fontStyle: 'italic', + }, + }, + { + scope: [ + 'source.shell punctuation.section.interpolation', + 'punctuation.definition.evaluation.backticks.shell', + ], + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Shell EOF', + scope: 'entity.name.tag.heredoc.shell', + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'Shell quoted variable', + scope: 'string.quoted.double.shell variable.other.normal.shell', + settings: { + foreground: '#cad3f5', + }, + }, + ], +} + +const catppuccinMocha = { + name: 'Catppuccin Mocha', + type: 'dark', + colors: { + focusBorder: '#cba6f7', + foreground: '#cdd6f4', + disabledForeground: '#a6adc8', + 'widget.shadow': '#18182580', + 'selection.background': '#cba6f766', + descriptionForeground: '#cdd6f4', + errorForeground: '#f38ba8', + 'icon.foreground': '#cba6f7', + 'sash.hoverBorder': '#cba6f7', + 'window.activeBorder': '#00000000', + 'window.inactiveBorder': '#00000000', + 'textBlockQuote.background': '#181825', + 'textBlockQuote.border': '#11111b', + 'textCodeBlock.background': '#1e1e2e', + 'textLink.activeForeground': '#89dceb', + 'textLink.foreground': '#89b4fa', + 'textPreformat.foreground': '#cdd6f4', + 'textSeparator.foreground': '#cba6f7', + 'activityBar.background': '#11111b', + 'activityBar.foreground': '#cba6f7', + 'activityBar.dropBorder': '#cba6f733', + 'activityBar.inactiveForeground': '#6c7086', + 'activityBar.border': '#00000000', + 'activityBarBadge.background': '#cba6f7', + 'activityBarBadge.foreground': '#11111b', + 'activityBar.activeBorder': '#00000000', + 'activityBar.activeBackground': '#00000000', + 'activityBar.activeFocusBorder': '#00000000', + 'activityBarTop.foreground': '#cba6f7', + 'activityBarTop.activeBorder': '#00000000', + 'activityBarTop.inactiveForeground': '#6c7086', + 'activityBarTop.dropBorder': '#cba6f733', + 'badge.background': '#45475a', + 'badge.foreground': '#cdd6f4', + 'breadcrumb.activeSelectionForeground': '#cba6f7', + 'breadcrumb.background': '#1e1e2e', + 'breadcrumb.focusForeground': '#cba6f7', + 'breadcrumb.foreground': '#cdd6f4cc', + 'breadcrumbPicker.background': '#181825', + 'button.background': '#cba6f7', + 'button.foreground': '#11111b', + 'button.border': '#00000000', + 'button.separator': '#00000000', + 'button.hoverBackground': '#dec7fa', + 'button.secondaryForeground': '#cdd6f4', + 'button.secondaryBackground': '#585b70', + 'button.secondaryHoverBackground': '#686b84', + 'checkbox.background': '#45475a', + 'checkbox.border': '#00000000', + 'checkbox.foreground': '#cba6f7', + 'dropdown.background': '#181825', + 'dropdown.listBackground': '#585b70', + 'dropdown.border': '#cba6f7', + 'dropdown.foreground': '#cdd6f4', + 'debugToolBar.background': '#11111b', + 'debugToolBar.border': '#00000000', + 'debugExceptionWidget.background': '#11111b', + 'debugExceptionWidget.border': '#cba6f7', + 'debugTokenExpression.number': '#fab387', + 'debugTokenExpression.boolean': '#cba6f7', + 'debugTokenExpression.string': '#a6e3a1', + 'debugTokenExpression.error': '#f38ba8', + 'debugIcon.breakpointForeground': '#f38ba8', + 'debugIcon.breakpointDisabledForeground': '#f38ba899', + 'debugIcon.breakpointUnverifiedForeground': '#a6738c', + 'debugIcon.breakpointCurrentStackframeForeground': '#585b70', + 'debugIcon.breakpointStackframeForeground': '#585b70', + 'debugIcon.startForeground': '#a6e3a1', + 'debugIcon.pauseForeground': '#89b4fa', + 'debugIcon.stopForeground': '#f38ba8', + 'debugIcon.disconnectForeground': '#585b70', + 'debugIcon.restartForeground': '#94e2d5', + 'debugIcon.stepOverForeground': '#cba6f7', + 'debugIcon.stepIntoForeground': '#cdd6f4', + 'debugIcon.stepOutForeground': '#cdd6f4', + 'debugIcon.continueForeground': '#a6e3a1', + 'debugIcon.stepBackForeground': '#585b70', + 'debugConsole.infoForeground': '#89b4fa', + 'debugConsole.warningForeground': '#fab387', + 'debugConsole.errorForeground': '#f38ba8', + 'debugConsole.sourceForeground': '#f5e0dc', + 'debugConsoleInputIcon.foreground': '#cdd6f4', + 'diffEditor.border': '#585b70', + 'diffEditor.insertedTextBackground': '#a6e3a11a', + 'diffEditor.removedTextBackground': '#f38ba81a', + 'diffEditor.insertedLineBackground': '#a6e3a126', + 'diffEditor.removedLineBackground': '#f38ba826', + 'diffEditor.diagonalFill': '#585b7099', + 'diffEditorOverview.insertedForeground': '#a6e3a1cc', + 'diffEditorOverview.removedForeground': '#f38ba8cc', + 'editor.background': '#1e1e2e', + 'editor.findMatchBackground': '#5e3f53', + 'editor.findMatchBorder': '#f38ba833', + 'editor.findMatchHighlightBackground': '#3e5767', + 'editor.findMatchHighlightBorder': '#89dceb33', + 'editor.findRangeHighlightBackground': '#3e5767', + 'editor.findRangeHighlightBorder': '#89dceb33', + 'editor.foldBackground': '#89dceb40', + 'editor.foreground': '#cdd6f4', + 'editor.hoverHighlightBackground': '#89dceb40', + 'editor.lineHighlightBackground': '#cdd6f412', + 'editor.lineHighlightBorder': '#00000000', + 'editor.rangeHighlightBackground': '#89dceb40', + 'editor.rangeHighlightBorder': '#00000000', + 'editor.selectionBackground': '#9399b240', + 'editor.selectionHighlightBackground': '#9399b233', + 'editor.selectionHighlightBorder': '#9399b233', + 'editor.wordHighlightBackground': '#9399b233', + 'editorBracketMatch.background': '#9399b21a', + 'editorBracketMatch.border': '#9399b2', + 'editorCodeLens.foreground': '#7f849c', + 'editorCursor.background': '#1e1e2e', + 'editorCursor.foreground': '#f5e0dc', + 'editorGroup.border': '#585b70', + 'editorGroup.dropBackground': '#cba6f733', + 'editorGroup.emptyBackground': '#1e1e2e', + 'editorGroupHeader.tabsBackground': '#11111b', + 'editorGutter.addedBackground': '#a6e3a1', + 'editorGutter.background': '#1e1e2e', + 'editorGutter.commentRangeForeground': '#313244', + 'editorGutter.commentGlyphForeground': '#cba6f7', + 'editorGutter.deletedBackground': '#f38ba8', + 'editorGutter.foldingControlForeground': '#9399b2', + 'editorGutter.modifiedBackground': '#f9e2af', + 'editorHoverWidget.background': '#181825', + 'editorHoverWidget.border': '#585b70', + 'editorHoverWidget.foreground': '#cdd6f4', + 'editorIndentGuide.activeBackground': '#585b70', + 'editorIndentGuide.background': '#45475a', + 'editorInlayHint.foreground': '#585b70', + 'editorInlayHint.background': '#181825bf', + 'editorInlayHint.typeForeground': '#bac2de', + 'editorInlayHint.typeBackground': '#181825bf', + 'editorInlayHint.parameterForeground': '#a6adc8', + 'editorInlayHint.parameterBackground': '#181825bf', + 'editorLineNumber.activeForeground': '#cba6f7', + 'editorLineNumber.foreground': '#7f849c', + 'editorLink.activeForeground': '#cba6f7', + 'editorMarkerNavigation.background': '#181825', + 'editorMarkerNavigationError.background': '#f38ba8', + 'editorMarkerNavigationInfo.background': '#89b4fa', + 'editorMarkerNavigationWarning.background': '#fab387', + 'editorOverviewRuler.background': '#181825', + 'editorOverviewRuler.border': '#cdd6f412', + 'editorOverviewRuler.modifiedForeground': '#f9e2af', + 'editorRuler.foreground': '#585b70', + 'editor.stackFrameHighlightBackground': '#f9e2af26', + 'editor.focusedStackFrameHighlightBackground': '#a6e3a126', + 'editorStickyScrollHover.background': '#313244', + 'editorSuggestWidget.background': '#181825', + 'editorSuggestWidget.border': '#585b70', + 'editorSuggestWidget.foreground': '#cdd6f4', + 'editorSuggestWidget.highlightForeground': '#cba6f7', + 'editorSuggestWidget.selectedBackground': '#313244', + 'editorWhitespace.foreground': '#9399b266', + 'editorWidget.background': '#181825', + 'editorWidget.foreground': '#cdd6f4', + 'editorWidget.resizeBorder': '#585b70', + 'editorLightBulb.foreground': '#f9e2af', + 'editorError.foreground': '#f38ba8', + 'editorError.border': '#00000000', + 'editorError.background': '#00000000', + 'editorWarning.foreground': '#fab387', + 'editorWarning.border': '#00000000', + 'editorWarning.background': '#00000000', + 'editorInfo.foreground': '#89b4fa', + 'editorInfo.border': '#00000000', + 'editorInfo.background': '#00000000', + 'problemsErrorIcon.foreground': '#f38ba8', + 'problemsInfoIcon.foreground': '#89b4fa', + 'problemsWarningIcon.foreground': '#fab387', + 'extensionButton.prominentForeground': '#11111b', + 'extensionButton.prominentBackground': '#cba6f7', + 'extensionButton.separator': '#1e1e2e', + 'extensionButton.prominentHoverBackground': '#dec7fa', + 'extensionBadge.remoteBackground': '#89b4fa', + 'extensionBadge.remoteForeground': '#11111b', + 'extensionIcon.starForeground': '#f9e2af', + 'extensionIcon.verifiedForeground': '#a6e3a1', + 'extensionIcon.preReleaseForeground': '#585b70', + 'extensionIcon.sponsorForeground': '#f5c2e7', + 'gitDecoration.addedResourceForeground': '#a6e3a1', + 'gitDecoration.conflictingResourceForeground': '#cba6f7', + 'gitDecoration.deletedResourceForeground': '#f38ba8', + 'gitDecoration.ignoredResourceForeground': '#6c7086', + 'gitDecoration.modifiedResourceForeground': '#f9e2af', + 'gitDecoration.stageDeletedResourceForeground': '#f38ba8', + 'gitDecoration.stageModifiedResourceForeground': '#f9e2af', + 'gitDecoration.submoduleResourceForeground': '#89b4fa', + 'gitDecoration.untrackedResourceForeground': '#a6e3a1', + 'input.background': '#313244', + 'input.border': '#00000000', + 'input.foreground': '#cdd6f4', + 'input.placeholderForeground': '#cdd6f473', + 'inputOption.activeBackground': '#585b70', + 'inputOption.activeBorder': '#cba6f7', + 'inputOption.activeForeground': '#cdd6f4', + 'inputValidation.errorBackground': '#f38ba8', + 'inputValidation.errorBorder': '#11111b33', + 'inputValidation.errorForeground': '#11111b', + 'inputValidation.infoBackground': '#89b4fa', + 'inputValidation.infoBorder': '#11111b33', + 'inputValidation.infoForeground': '#11111b', + 'inputValidation.warningBackground': '#fab387', + 'inputValidation.warningBorder': '#11111b33', + 'inputValidation.warningForeground': '#11111b', + 'list.activeSelectionBackground': '#313244', + 'list.activeSelectionForeground': '#cdd6f4', + 'list.dropBackground': '#cba6f733', + 'list.focusBackground': '#313244', + 'list.focusForeground': '#cdd6f4', + 'list.focusOutline': '#00000000', + 'list.highlightForeground': '#cba6f7', + 'list.hoverBackground': '#31324480', + 'list.hoverForeground': '#cdd6f4', + 'list.inactiveSelectionBackground': '#313244', + 'list.inactiveSelectionForeground': '#cdd6f4', + 'list.warningForeground': '#fab387', + 'listFilterWidget.background': '#45475a', + 'listFilterWidget.noMatchesOutline': '#f38ba8', + 'listFilterWidget.outline': '#00000000', + 'tree.indentGuidesStroke': '#9399b2', + 'tree.inactiveIndentGuidesStroke': '#45475a', + 'menu.background': '#1e1e2e', + 'menu.border': '#1e1e2e80', + 'menu.foreground': '#cdd6f4', + 'menu.selectionBackground': '#585b70', + 'menu.selectionBorder': '#00000000', + 'menu.selectionForeground': '#cdd6f4', + 'menu.separatorBackground': '#585b70', + 'menubar.selectionBackground': '#45475a', + 'menubar.selectionForeground': '#cdd6f4', + 'merge.commonContentBackground': '#45475a', + 'merge.commonHeaderBackground': '#585b70', + 'merge.currentContentBackground': '#a6e3a133', + 'merge.currentHeaderBackground': '#a6e3a166', + 'merge.incomingContentBackground': '#89b4fa33', + 'merge.incomingHeaderBackground': '#89b4fa66', + 'minimap.background': '#18182580', + 'minimap.findMatchHighlight': '#89dceb4d', + 'minimap.selectionHighlight': '#585b70bf', + 'minimap.selectionOccurrenceHighlight': '#585b70bf', + 'minimap.warningHighlight': '#fab387bf', + 'minimap.errorHighlight': '#f38ba8bf', + 'minimapSlider.background': '#cba6f733', + 'minimapSlider.hoverBackground': '#cba6f766', + 'minimapSlider.activeBackground': '#cba6f799', + 'minimapGutter.addedBackground': '#a6e3a1bf', + 'minimapGutter.deletedBackground': '#f38ba8bf', + 'minimapGutter.modifiedBackground': '#f9e2afbf', + 'notificationCenter.border': '#cba6f7', + 'notificationCenterHeader.foreground': '#cdd6f4', + 'notificationCenterHeader.background': '#181825', + 'notificationToast.border': '#cba6f7', + 'notifications.foreground': '#cdd6f4', + 'notifications.background': '#181825', + 'notifications.border': '#cba6f7', + 'notificationLink.foreground': '#89b4fa', + 'notificationsErrorIcon.foreground': '#f38ba8', + 'notificationsWarningIcon.foreground': '#fab387', + 'notificationsInfoIcon.foreground': '#89b4fa', + 'panel.background': '#1e1e2e', + 'panel.border': '#585b70', + 'panelSection.border': '#585b70', + 'panelSection.dropBackground': '#cba6f733', + 'panelTitle.activeBorder': '#cba6f7', + 'panelTitle.activeForeground': '#cdd6f4', + 'panelTitle.inactiveForeground': '#a6adc8', + 'peekView.border': '#cba6f7', + 'peekViewEditor.background': '#181825', + 'peekViewEditorGutter.background': '#181825', + 'peekViewEditor.matchHighlightBackground': '#89dceb4d', + 'peekViewEditor.matchHighlightBorder': '#00000000', + 'peekViewResult.background': '#181825', + 'peekViewResult.fileForeground': '#cdd6f4', + 'peekViewResult.lineForeground': '#cdd6f4', + 'peekViewResult.matchHighlightBackground': '#89dceb4d', + 'peekViewResult.selectionBackground': '#313244', + 'peekViewResult.selectionForeground': '#cdd6f4', + 'peekViewTitle.background': '#1e1e2e', + 'peekViewTitleDescription.foreground': '#bac2deb3', + 'peekViewTitleLabel.foreground': '#cdd6f4', + 'pickerGroup.border': '#cba6f7', + 'pickerGroup.foreground': '#cba6f7', + 'progressBar.background': '#cba6f7', + 'scrollbar.shadow': '#11111b', + 'scrollbarSlider.activeBackground': '#31324466', + 'scrollbarSlider.background': '#585b7080', + 'scrollbarSlider.hoverBackground': '#6c7086', + 'settings.focusedRowBackground': '#585b7033', + 'settings.headerForeground': '#cdd6f4', + 'settings.modifiedItemIndicator': '#cba6f7', + 'settings.dropdownBackground': '#45475a', + 'settings.dropdownListBorder': '#00000000', + 'settings.textInputBackground': '#45475a', + 'settings.textInputBorder': '#00000000', + 'settings.numberInputBackground': '#45475a', + 'settings.numberInputBorder': '#00000000', + 'sideBar.background': '#181825', + 'sideBar.dropBackground': '#cba6f733', + 'sideBar.foreground': '#cdd6f4', + 'sideBar.border': '#00000000', + 'sideBarSectionHeader.background': '#181825', + 'sideBarSectionHeader.foreground': '#cdd6f4', + 'sideBarTitle.foreground': '#cba6f7', + 'banner.background': '#45475a', + 'banner.foreground': '#cdd6f4', + 'banner.iconForeground': '#cdd6f4', + 'statusBar.background': '#11111b', + 'statusBar.foreground': '#cdd6f4', + 'statusBar.border': '#00000000', + 'statusBar.noFolderBackground': '#11111b', + 'statusBar.noFolderForeground': '#cdd6f4', + 'statusBar.noFolderBorder': '#00000000', + 'statusBar.debuggingBackground': '#fab387', + 'statusBar.debuggingForeground': '#11111b', + 'statusBar.debuggingBorder': '#00000000', + 'statusBarItem.remoteBackground': '#89b4fa', + 'statusBarItem.remoteForeground': '#11111b', + 'statusBarItem.activeBackground': '#585b7066', + 'statusBarItem.hoverBackground': '#585b7033', + 'statusBarItem.prominentForeground': '#cba6f7', + 'statusBarItem.prominentBackground': '#00000000', + 'statusBarItem.prominentHoverBackground': '#585b7033', + 'statusBarItem.errorForeground': '#f38ba8', + 'statusBarItem.errorBackground': '#00000000', + 'statusBarItem.warningForeground': '#fab387', + 'statusBarItem.warningBackground': '#00000000', + 'commandCenter.foreground': '#bac2de', + 'commandCenter.inactiveForeground': '#bac2de', + 'commandCenter.activeForeground': '#cba6f7', + 'commandCenter.background': '#181825', + 'commandCenter.activeBackground': '#585b7033', + 'commandCenter.border': '#00000000', + 'commandCenter.inactiveBorder': '#00000000', + 'commandCenter.activeBorder': '#cba6f7', + 'tab.activeBackground': '#1e1e2e', + 'tab.activeBorder': '#00000000', + 'tab.activeBorderTop': '#cba6f7', + 'tab.activeForeground': '#cba6f7', + 'tab.activeModifiedBorder': '#f9e2af', + 'tab.border': '#181825', + 'tab.hoverBackground': '#28283d', + 'tab.hoverBorder': '#00000000', + 'tab.hoverForeground': '#cba6f7', + 'tab.inactiveBackground': '#181825', + 'tab.inactiveForeground': '#6c7086', + 'tab.inactiveModifiedBorder': '#f9e2af4d', + 'tab.lastPinnedBorder': '#cba6f7', + 'tab.unfocusedActiveBackground': '#181825', + 'tab.unfocusedActiveBorder': '#00000000', + 'tab.unfocusedActiveBorderTop': '#cba6f74d', + 'tab.unfocusedInactiveBackground': '#0e0e16', + 'terminal.foreground': '#cdd6f4', + 'terminal.ansiBlack': '#a6adc8', + 'terminal.ansiRed': '#f38ba8', + 'terminal.ansiGreen': '#a6e3a1', + 'terminal.ansiYellow': '#f9e2af', + 'terminal.ansiBlue': '#89b4fa', + 'terminal.ansiMagenta': '#f5c2e7', + 'terminal.ansiCyan': '#89dceb', + 'terminal.ansiWhite': '#bac2de', + 'terminal.ansiBrightBlack': '#585b70', + 'terminal.ansiBrightRed': '#f38ba8', + 'terminal.ansiBrightGreen': '#a6e3a1', + 'terminal.ansiBrightYellow': '#f9e2af', + 'terminal.ansiBrightBlue': '#89b4fa', + 'terminal.ansiBrightMagenta': '#f5c2e7', + 'terminal.ansiBrightCyan': '#89dceb', + 'terminal.ansiBrightWhite': '#45475a', + 'terminal.selectionBackground': '#585b70', + 'terminal.inactiveSelectionBackground': '#585b7080', + 'terminalCursor.background': '#1e1e2e', + 'terminalCursor.foreground': '#f5e0dc', + 'terminal.border': '#585b70', + 'terminal.dropBackground': '#cba6f733', + 'terminal.tab.activeBorder': '#cba6f7', + 'terminalCommandDecoration.defaultBackground': '#585b70', + 'terminalCommandDecoration.successBackground': '#a6e3a1', + 'terminalCommandDecoration.errorBackground': '#f38ba8', + 'titleBar.activeBackground': '#11111b', + 'titleBar.activeForeground': '#cdd6f4', + 'titleBar.inactiveBackground': '#11111b', + 'titleBar.inactiveForeground': '#cdd6f480', + 'titleBar.border': '#00000000', + 'welcomePage.tileBackground': '#181825', + 'welcomePage.progress.background': '#11111b', + 'welcomePage.progress.foreground': '#cba6f7', + 'walkThrough.embeddedEditorBackground': '#1e1e2e4d', + 'symbolIcon.textForeground': '#cdd6f4', + 'symbolIcon.arrayForeground': '#fab387', + 'symbolIcon.booleanForeground': '#cba6f7', + 'symbolIcon.classForeground': '#f9e2af', + 'symbolIcon.colorForeground': '#f5c2e7', + 'symbolIcon.constantForeground': '#fab387', + 'symbolIcon.constructorForeground': '#b4befe', + 'symbolIcon.enumeratorForeground': '#f9e2af', + 'symbolIcon.enumeratorMemberForeground': '#f9e2af', + 'symbolIcon.eventForeground': '#f5c2e7', + 'symbolIcon.fieldForeground': '#cdd6f4', + 'symbolIcon.fileForeground': '#cba6f7', + 'symbolIcon.folderForeground': '#cba6f7', + 'symbolIcon.functionForeground': '#89b4fa', + 'symbolIcon.interfaceForeground': '#f9e2af', + 'symbolIcon.keyForeground': '#94e2d5', + 'symbolIcon.keywordForeground': '#cba6f7', + 'symbolIcon.methodForeground': '#89b4fa', + 'symbolIcon.moduleForeground': '#cdd6f4', + 'symbolIcon.namespaceForeground': '#f9e2af', + 'symbolIcon.nullForeground': '#eba0ac', + 'symbolIcon.numberForeground': '#fab387', + 'symbolIcon.objectForeground': '#f9e2af', + 'symbolIcon.operatorForeground': '#94e2d5', + 'symbolIcon.packageForeground': '#f2cdcd', + 'symbolIcon.propertyForeground': '#eba0ac', + 'symbolIcon.referenceForeground': '#f9e2af', + 'symbolIcon.snippetForeground': '#f2cdcd', + 'symbolIcon.stringForeground': '#a6e3a1', + 'symbolIcon.structForeground': '#94e2d5', + 'symbolIcon.typeParameterForeground': '#eba0ac', + 'symbolIcon.unitForeground': '#cdd6f4', + 'symbolIcon.variableForeground': '#cdd6f4', + 'charts.foreground': '#cdd6f4', + 'charts.lines': '#bac2de', + 'charts.red': '#f38ba8', + 'charts.blue': '#89b4fa', + 'charts.yellow': '#f9e2af', + 'charts.orange': '#fab387', + 'charts.green': '#a6e3a1', + 'charts.purple': '#cba6f7', + 'errorLens.errorBackground': '#f38ba826', + 'errorLens.errorBackgroundLight': '#f38ba826', + 'errorLens.errorForeground': '#f38ba8', + 'errorLens.errorForegroundLight': '#f38ba8', + 'errorLens.errorMessageBackground': '#f38ba826', + 'errorLens.hintBackground': '#a6e3a126', + 'errorLens.hintBackgroundLight': '#a6e3a126', + 'errorLens.hintForeground': '#a6e3a1', + 'errorLens.hintForegroundLight': '#a6e3a1', + 'errorLens.hintMessageBackground': '#a6e3a126', + 'errorLens.infoBackground': '#89b4fa26', + 'errorLens.infoBackgroundLight': '#89b4fa26', + 'errorLens.infoForeground': '#89b4fa', + 'errorLens.infoForegroundLight': '#89b4fa', + 'errorLens.infoMessageBackground': '#89b4fa26', + 'errorLens.statusBarErrorForeground': '#f38ba8', + 'errorLens.statusBarHintForeground': '#a6e3a1', + 'errorLens.statusBarIconErrorForeground': '#f38ba8', + 'errorLens.statusBarIconWarningForeground': '#fab387', + 'errorLens.statusBarInfoForeground': '#89b4fa', + 'errorLens.statusBarWarningForeground': '#fab387', + 'errorLens.warningBackground': '#fab38726', + 'errorLens.warningBackgroundLight': '#fab38726', + 'errorLens.warningForeground': '#fab387', + 'errorLens.warningForegroundLight': '#fab387', + 'errorLens.warningMessageBackground': '#fab38726', + 'issues.closed': '#cba6f7', + 'issues.newIssueDecoration': '#f5e0dc', + 'issues.open': '#a6e3a1', + 'pullRequests.closed': '#f38ba8', + 'pullRequests.draft': '#9399b2', + 'pullRequests.merged': '#cba6f7', + 'pullRequests.notification': '#cdd6f4', + 'pullRequests.open': '#a6e3a1', + 'gitlens.gutterBackgroundColor': '#3132444d', + 'gitlens.gutterForegroundColor': '#cdd6f4', + 'gitlens.gutterUncommittedForegroundColor': '#cba6f7', + 'gitlens.trailingLineBackgroundColor': '#00000000', + 'gitlens.trailingLineForegroundColor': '#cdd6f44d', + 'gitlens.lineHighlightBackgroundColor': '#cba6f726', + 'gitlens.lineHighlightOverviewRulerColor': '#cba6f7cc', + 'gitlens.openAutolinkedIssueIconColor': '#a6e3a1', + 'gitlens.closedAutolinkedIssueIconColor': '#cba6f7', + 'gitlens.closedPullRequestIconColor': '#f38ba8', + 'gitlens.openPullRequestIconColor': '#a6e3a1', + 'gitlens.mergedPullRequestIconColor': '#cba6f7', + 'gitlens.unpublishedChangesIconColor': '#a6e3a1', + 'gitlens.unpublishedCommitIconColor': '#a6e3a1', + 'gitlens.unpulledChangesIconColor': '#fab387', + 'gitlens.decorations.branchAheadForegroundColor': '#a6e3a1', + 'gitlens.decorations.branchBehindForegroundColor': '#fab387', + 'gitlens.decorations.branchDivergedForegroundColor': '#f9e2af', + 'gitlens.decorations.branchUnpublishedForegroundColor': '#a6e3a1', + 'gitlens.decorations.branchMissingUpstreamForegroundColor': '#fab387', + 'gitlens.decorations.statusMergingOrRebasingConflictForegroundColor': + '#eba0ac', + 'gitlens.decorations.statusMergingOrRebasingForegroundColor': '#f9e2af', + 'gitlens.decorations.workspaceRepoMissingForegroundColor': '#a6adc8', + 'gitlens.decorations.workspaceCurrentForegroundColor': '#cba6f7', + 'gitlens.decorations.workspaceRepoOpenForegroundColor': '#cba6f7', + 'gitlens.decorations.worktreeHasUncommittedChangesForegroundColor': + '#fab387', + 'gitlens.decorations.worktreeMissingForegroundColor': '#eba0ac', + 'gitlens.graphLane1Color': '#cba6f7', + 'gitlens.graphLane2Color': '#f9e2af', + 'gitlens.graphLane3Color': '#89b4fa', + 'gitlens.graphLane4Color': '#f2cdcd', + 'gitlens.graphLane5Color': '#a6e3a1', + 'gitlens.graphLane6Color': '#b4befe', + 'gitlens.graphLane7Color': '#f5e0dc', + 'gitlens.graphLane8Color': '#f38ba8', + 'gitlens.graphLane9Color': '#94e2d5', + 'gitlens.graphLane10Color': '#f5c2e7', + 'gitlens.graphChangesColumnAddedColor': '#a6e3a1', + 'gitlens.graphChangesColumnDeletedColor': '#f38ba8', + 'gitlens.graphMinimapMarkerHeadColor': '#a6e3a1', + 'gitlens.graphScrollMarkerHeadColor': '#a6e3a1', + 'gitlens.graphMinimapMarkerUpstreamColor': '#93dd8d', + 'gitlens.graphScrollMarkerUpstreamColor': '#93dd8d', + 'gitlens.graphMinimapMarkerHighlightsColor': '#f9e2af', + 'gitlens.graphScrollMarkerHighlightsColor': '#f9e2af', + 'gitlens.graphMinimapMarkerLocalBranchesColor': '#89b4fa', + 'gitlens.graphScrollMarkerLocalBranchesColor': '#89b4fa', + 'gitlens.graphMinimapMarkerRemoteBranchesColor': '#71a4f9', + 'gitlens.graphScrollMarkerRemoteBranchesColor': '#71a4f9', + 'gitlens.graphMinimapMarkerStashesColor': '#cba6f7', + 'gitlens.graphScrollMarkerStashesColor': '#cba6f7', + 'gitlens.graphMinimapMarkerTagsColor': '#f2cdcd', + 'gitlens.graphScrollMarkerTagsColor': '#f2cdcd', + 'editorBracketHighlight.foreground1': '#f38ba8', + 'editorBracketHighlight.foreground2': '#fab387', + 'editorBracketHighlight.foreground3': '#f9e2af', + 'editorBracketHighlight.foreground4': '#a6e3a1', + 'editorBracketHighlight.foreground5': '#74c7ec', + 'editorBracketHighlight.foreground6': '#cba6f7', + 'editorBracketHighlight.unexpectedBracket.foreground': '#eba0ac', + 'button.secondaryBorder': '#cba6f7', + 'table.headerBackground': '#313244', + 'table.headerForeground': '#cdd6f4', + 'list.focusAndSelectionBackground': '#45475a', + }, + semanticHighlighting: true, + semanticTokenColors: { + enumMember: { + foreground: '#94e2d5', + }, + selfKeyword: { + foreground: '#f38ba8', + }, + boolean: { + foreground: '#fab387', + }, + number: { + foreground: '#fab387', + }, + 'variable.defaultLibrary': { + foreground: '#eba0ac', + }, + 'class:python': { + foreground: '#f9e2af', + }, + 'class.builtin:python': { + foreground: '#cba6f7', + }, + 'variable.typeHint:python': { + foreground: '#f9e2af', + }, + 'function.decorator:python': { + foreground: '#fab387', + }, + 'variable.readonly:javascript': { + foreground: '#cdd6f4', + }, + 'variable.readonly:typescript': { + foreground: '#cdd6f4', + }, + 'property.readonly:javascript': { + foreground: '#cdd6f4', + }, + 'property.readonly:typescript': { + foreground: '#cdd6f4', + }, + 'variable.readonly:javascriptreact': { + foreground: '#cdd6f4', + }, + 'variable.readonly:typescriptreact': { + foreground: '#cdd6f4', + }, + 'property.readonly:javascriptreact': { + foreground: '#cdd6f4', + }, + 'property.readonly:typescriptreact': { + foreground: '#cdd6f4', + }, + 'variable.readonly:scala': { + foreground: '#cdd6f4', + }, + 'type.defaultLibrary:go': { + foreground: '#cba6f7', + }, + 'variable.readonly.defaultLibrary:go': { + foreground: '#cba6f7', + }, + tomlArrayKey: { + foreground: '#89b4fa', + fontStyle: '', + }, + tomlTableKey: { + foreground: '#89b4fa', + fontStyle: '', + }, + 'builtinAttribute.attribute.library:rust': { + foreground: '#89b4fa', + }, + 'generic.attribute:rust': { + foreground: '#cdd6f4', + }, + 'constant.builtin.readonly:nix': { + foreground: '#cba6f7', + }, + heading: { + foreground: '#f38ba8', + }, + 'text.emph': { + foreground: '#f38ba8', + fontStyle: 'italic', + }, + 'text.strong': { + foreground: '#f38ba8', + fontStyle: 'bold', + }, + 'text.math': { + foreground: '#f2cdcd', + }, + pol: { + foreground: '#f2cdcd', + }, + }, + tokenColors: [ + { + name: 'Basic text & variable names (incl. leading punctuation)', + scope: [ + 'text', + 'source', + 'variable.other.readwrite', + 'punctuation.definition.variable', + ], + settings: { + foreground: '#cdd6f4', + }, + }, + { + name: 'Parentheses, Brackets, Braces', + scope: 'punctuation', + settings: { + foreground: '#9399b2', + fontStyle: '', + }, + }, + { + name: 'Comments', + scope: ['comment', 'punctuation.definition.comment'], + settings: { + foreground: '#6c7086', + fontStyle: 'italic', + }, + }, + { + scope: ['string', 'punctuation.definition.string'], + settings: { + foreground: '#a6e3a1', + }, + }, + { + scope: 'constant.character.escape', + settings: { + foreground: '#f5c2e7', + }, + }, + { + name: 'Booleans, constants, numbers', + scope: [ + 'constant.numeric', + 'variable.other.constant', + 'entity.name.constant', + 'constant.language.boolean', + 'constant.language.false', + 'constant.language.true', + 'keyword.other.unit.user-defined', + 'keyword.other.unit.suffix.floating-point', + ], + settings: { + foreground: '#fab387', + }, + }, + { + scope: [ + 'keyword', + 'keyword.operator.word', + 'keyword.operator.new', + 'variable.language.super', + 'support.type.primitive', + 'storage.type', + 'storage.modifier', + 'punctuation.definition.keyword', + ], + settings: { + foreground: '#cba6f7', + fontStyle: '', + }, + }, + { + scope: 'entity.name.tag.documentation', + settings: { + foreground: '#cba6f7', + }, + }, + { + name: 'Punctuation', + scope: [ + 'keyword.operator', + 'punctuation.accessor', + 'punctuation.definition.generic', + 'meta.function.closure punctuation.section.parameters', + 'punctuation.definition.tag', + 'punctuation.separator.key-value', + ], + settings: { + foreground: '#94e2d5', + }, + }, + { + scope: [ + 'entity.name.function', + 'meta.function-call.method', + 'support.function', + 'support.function.misc', + 'variable.function', + ], + settings: { + foreground: '#89b4fa', + fontStyle: 'italic', + }, + }, + { + name: 'Classes', + scope: [ + 'entity.name.class', + 'entity.other.inherited-class', + 'support.class', + 'meta.function-call.constructor', + 'entity.name.struct', + ], + settings: { + foreground: '#f9e2af', + fontStyle: 'italic', + }, + }, + { + name: 'Enum', + scope: 'entity.name.enum', + settings: { + foreground: '#f9e2af', + fontStyle: 'italic', + }, + }, + { + name: 'Enum member', + scope: [ + 'meta.enum variable.other.readwrite', + 'variable.other.enummember', + ], + settings: { + foreground: '#94e2d5', + }, + }, + { + name: 'Object properties', + scope: 'meta.property.object', + settings: { + foreground: '#94e2d5', + }, + }, + { + name: 'Types', + scope: [ + 'meta.type', + 'meta.type-alias', + 'support.type', + 'entity.name.type', + ], + settings: { + foreground: '#f9e2af', + fontStyle: 'italic', + }, + }, + { + name: 'Decorators', + scope: [ + 'meta.annotation variable.function', + 'meta.annotation variable.annotation.function', + 'meta.annotation punctuation.definition.annotation', + 'meta.decorator', + 'punctuation.decorator', + ], + settings: { + foreground: '#fab387', + }, + }, + { + scope: ['variable.parameter', 'meta.function.parameters'], + settings: { + foreground: '#eba0ac', + fontStyle: 'italic', + }, + }, + { + name: 'Built-ins', + scope: ['constant.language', 'support.function.builtin'], + settings: { + foreground: '#f38ba8', + }, + }, + { + scope: 'entity.other.attribute-name.documentation', + settings: { + foreground: '#f38ba8', + }, + }, + { + name: 'Preprocessor directives', + scope: ['keyword.control.directive', 'punctuation.definition.directive'], + settings: { + foreground: '#f9e2af', + }, + }, + { + name: 'Type parameters', + scope: 'punctuation.definition.typeparameters', + settings: { + foreground: '#89dceb', + }, + }, + { + name: 'Namespaces', + scope: 'entity.name.namespace', + settings: { + foreground: '#f9e2af', + }, + }, + { + name: 'Property names (left hand assignments in json/yaml/css)', + scope: 'support.type.property-name.css', + settings: { + foreground: '#89b4fa', + fontStyle: '', + }, + }, + { + name: 'This/Self keyword', + scope: [ + 'variable.language.this', + 'variable.language.this punctuation.definition.variable', + ], + settings: { + foreground: '#f38ba8', + }, + }, + { + name: 'Object properties', + scope: 'variable.object.property', + settings: { + foreground: '#cdd6f4', + }, + }, + { + name: 'String template interpolation', + scope: ['string.template variable', 'string variable'], + settings: { + foreground: '#cdd6f4', + }, + }, + { + name: '`new` as bold', + scope: 'keyword.operator.new', + settings: { + fontStyle: 'bold', + }, + }, + { + name: 'C++ extern keyword', + scope: 'storage.modifier.specifier.extern.cpp', + settings: { + foreground: '#cba6f7', + }, + }, + { + name: 'C++ scope resolution', + scope: [ + 'entity.name.scope-resolution.template.call.cpp', + 'entity.name.scope-resolution.parameter.cpp', + 'entity.name.scope-resolution.cpp', + 'entity.name.scope-resolution.function.definition.cpp', + ], + settings: { + foreground: '#f9e2af', + }, + }, + { + name: 'C++ doc keywords', + scope: 'storage.type.class.doxygen', + settings: { + fontStyle: '', + }, + }, + { + name: 'C++ operators', + scope: ['storage.modifier.reference.cpp'], + settings: { + foreground: '#94e2d5', + }, + }, + { + name: 'C# Interpolated Strings', + scope: 'meta.interpolation.cs', + settings: { + foreground: '#cdd6f4', + }, + }, + { + name: 'C# xml-style docs', + scope: 'comment.block.documentation.cs', + settings: { + foreground: '#cdd6f4', + }, + }, + { + name: 'Classes, reflecting the className color in JSX', + scope: [ + 'source.css entity.other.attribute-name.class.css', + 'entity.other.attribute-name.parent-selector.css punctuation.definition.entity.css', + ], + settings: { + foreground: '#f9e2af', + }, + }, + { + name: 'Operators', + scope: 'punctuation.separator.operator.css', + settings: { + foreground: '#94e2d5', + }, + }, + { + name: 'Pseudo classes', + scope: 'source.css entity.other.attribute-name.pseudo-class', + settings: { + foreground: '#94e2d5', + }, + }, + { + scope: 'source.css constant.other.unicode-range', + settings: { + foreground: '#fab387', + }, + }, + { + scope: 'source.css variable.parameter.url', + settings: { + foreground: '#a6e3a1', + fontStyle: '', + }, + }, + { + name: 'CSS vendored property names', + scope: ['support.type.vendored.property-name'], + settings: { + foreground: '#89dceb', + }, + }, + { + name: 'Less/SCSS right-hand variables (@/$-prefixed)', + scope: [ + 'source.css meta.property-value variable', + 'source.css meta.property-value variable.other.less', + 'source.css meta.property-value variable.other.less punctuation.definition.variable.less', + 'meta.definition.variable.scss', + ], + settings: { + foreground: '#eba0ac', + }, + }, + { + name: 'CSS variables (--prefixed)', + scope: [ + 'source.css meta.property-list variable', + 'meta.property-list variable.other.less', + 'meta.property-list variable.other.less punctuation.definition.variable.less', + ], + settings: { + foreground: '#89b4fa', + }, + }, + { + name: 'CSS Percentage values, styled the same as numbers', + scope: 'keyword.other.unit.percentage.css', + settings: { + foreground: '#fab387', + }, + }, + { + name: 'CSS Attribute selectors, styled the same as strings', + scope: 'source.css meta.attribute-selector', + settings: { + foreground: '#a6e3a1', + }, + }, + { + name: 'JSON/YAML keys, other left-hand assignments', + scope: [ + 'keyword.other.definition.ini', + 'punctuation.support.type.property-name.json', + 'support.type.property-name.json', + 'punctuation.support.type.property-name.toml', + 'support.type.property-name.toml', + 'entity.name.tag.yaml', + 'punctuation.support.type.property-name.yaml', + 'support.type.property-name.yaml', + ], + settings: { + foreground: '#89b4fa', + fontStyle: '', + }, + }, + { + name: 'JSON/YAML constants', + scope: ['constant.language.json', 'constant.language.yaml'], + settings: { + foreground: '#fab387', + }, + }, + { + name: 'YAML anchors', + scope: ['entity.name.type.anchor.yaml', 'variable.other.alias.yaml'], + settings: { + foreground: '#f9e2af', + fontStyle: '', + }, + }, + { + name: 'TOML tables / ini groups', + scope: [ + 'support.type.property-name.table', + 'entity.name.section.group-title.ini', + ], + settings: { + foreground: '#f9e2af', + }, + }, + { + name: 'TOML dates', + scope: 'constant.other.time.datetime.offset.toml', + settings: { + foreground: '#f5c2e7', + }, + }, + { + name: 'YAML anchor puctuation', + scope: [ + 'punctuation.definition.anchor.yaml', + 'punctuation.definition.alias.yaml', + ], + settings: { + foreground: '#f5c2e7', + }, + }, + { + name: 'YAML triple dashes', + scope: 'entity.other.document.begin.yaml', + settings: { + foreground: '#f5c2e7', + }, + }, + { + name: 'Markup Diff', + scope: 'markup.changed.diff', + settings: { + foreground: '#fab387', + }, + }, + { + name: 'Diff', + scope: [ + 'meta.diff.header.from-file', + 'meta.diff.header.to-file', + 'punctuation.definition.from-file.diff', + 'punctuation.definition.to-file.diff', + ], + settings: { + foreground: '#89b4fa', + }, + }, + { + name: 'Diff Inserted', + scope: 'markup.inserted.diff', + settings: { + foreground: '#a6e3a1', + }, + }, + { + name: 'Diff Deleted', + scope: 'markup.deleted.diff', + settings: { + foreground: '#f38ba8', + }, + }, + { + name: 'dotenv left-hand side assignments', + scope: ['variable.other.env'], + settings: { + foreground: '#89b4fa', + }, + }, + { + name: 'dotenv reference to existing env variable', + scope: ['string.quoted variable.other.env'], + settings: { + foreground: '#cdd6f4', + }, + }, + { + name: 'GDScript functions', + scope: 'support.function.builtin.gdscript', + settings: { + foreground: '#89b4fa', + }, + }, + { + name: 'GDScript constants', + scope: 'constant.language.gdscript', + settings: { + foreground: '#fab387', + }, + }, + { + name: 'Comment keywords', + scope: 'comment meta.annotation.go', + settings: { + foreground: '#eba0ac', + }, + }, + { + name: 'go:embed, go:build, etc.', + scope: 'comment meta.annotation.parameters.go', + settings: { + foreground: '#fab387', + }, + }, + { + name: 'Go constants (nil, true, false)', + scope: 'constant.language.go', + settings: { + foreground: '#fab387', + }, + }, + { + name: 'GraphQL variables', + scope: 'variable.graphql', + settings: { + foreground: '#cdd6f4', + }, + }, + { + name: 'GraphQL aliases', + scope: 'string.unquoted.alias.graphql', + settings: { + foreground: '#f2cdcd', + }, + }, + { + name: 'GraphQL enum members', + scope: 'constant.character.enum.graphql', + settings: { + foreground: '#94e2d5', + }, + }, + { + name: 'GraphQL field in types', + scope: + 'meta.objectvalues.graphql constant.object.key.graphql string.unquoted.graphql', + settings: { + foreground: '#f2cdcd', + }, + }, + { + name: 'HTML/XML DOCTYPE as keyword', + scope: [ + 'keyword.other.doctype', + 'meta.tag.sgml.doctype punctuation.definition.tag', + 'meta.tag.metadata.doctype entity.name.tag', + 'meta.tag.metadata.doctype punctuation.definition.tag', + ], + settings: { + foreground: '#cba6f7', + }, + }, + { + name: 'HTML/XML-like <tags/>', + scope: ['entity.name.tag'], + settings: { + foreground: '#89b4fa', + fontStyle: '', + }, + }, + { + name: 'Special characters like &', + scope: [ + 'text.html constant.character.entity', + 'text.html constant.character.entity punctuation', + 'constant.character.entity.xml', + 'constant.character.entity.xml punctuation', + 'constant.character.entity.js.jsx', + 'constant.charactger.entity.js.jsx punctuation', + 'constant.character.entity.tsx', + 'constant.character.entity.tsx punctuation', + ], + settings: { + foreground: '#f38ba8', + }, + }, + { + name: 'HTML/XML tag attribute values', + scope: ['entity.other.attribute-name'], + settings: { + foreground: '#f9e2af', + }, + }, + { + name: 'Components', + scope: [ + 'support.class.component', + 'support.class.component.jsx', + 'support.class.component.tsx', + 'support.class.component.vue', + ], + settings: { + foreground: '#f5c2e7', + fontStyle: '', + }, + }, + { + name: 'Annotations', + scope: ['punctuation.definition.annotation', 'storage.type.annotation'], + settings: { + foreground: '#fab387', + }, + }, + { + name: 'Java enums', + scope: 'constant.other.enum.java', + settings: { + foreground: '#94e2d5', + }, + }, + { + name: 'Java imports', + scope: 'storage.modifier.import.java', + settings: { + foreground: '#cdd6f4', + }, + }, + { + name: 'Javadoc', + scope: + 'comment.block.javadoc.java keyword.other.documentation.javadoc.java', + settings: { + fontStyle: '', + }, + }, + { + name: 'Exported Variable', + scope: 'meta.export variable.other.readwrite.js', + settings: { + foreground: '#eba0ac', + }, + }, + { + name: 'JS/TS constants & properties', + scope: [ + 'variable.other.constant.js', + 'variable.other.constant.ts', + 'variable.other.property.js', + 'variable.other.property.ts', + ], + settings: { + foreground: '#cdd6f4', + }, + }, + { + name: 'JSDoc; these are mainly params, so styled as such', + scope: [ + 'variable.other.jsdoc', + 'comment.block.documentation variable.other', + ], + settings: { + foreground: '#eba0ac', + fontStyle: '', + }, + }, + { + name: 'JSDoc keywords', + scope: 'storage.type.class.jsdoc', + settings: { + fontStyle: '', + }, + }, + { + scope: 'support.type.object.console.js', + settings: { + foreground: '#cdd6f4', + }, + }, + { + name: 'Node constants as keywords (module, etc.)', + scope: ['support.constant.node', 'support.type.object.module.js'], + settings: { + foreground: '#cba6f7', + }, + }, + { + name: 'implements as keyword', + scope: 'storage.modifier.implements', + settings: { + foreground: '#cba6f7', + }, + }, + { + name: 'Builtin types', + scope: [ + 'constant.language.null.js', + 'constant.language.null.ts', + 'constant.language.undefined.js', + 'constant.language.undefined.ts', + 'support.type.builtin.ts', + ], + settings: { + foreground: '#cba6f7', + }, + }, + { + scope: 'variable.parameter.generic', + settings: { + foreground: '#f9e2af', + }, + }, + { + name: 'Arrow functions', + scope: [ + 'keyword.declaration.function.arrow.js', + 'storage.type.function.arrow.ts', + ], + settings: { + foreground: '#94e2d5', + }, + }, + { + name: 'Decorator punctuations (decorators inherit from blue functions, instead of styleguide peach)', + scope: 'punctuation.decorator.ts', + settings: { + foreground: '#89b4fa', + fontStyle: 'italic', + }, + }, + { + name: 'Extra JS/TS keywords', + scope: [ + 'keyword.operator.expression.in.js', + 'keyword.operator.expression.in.ts', + 'keyword.operator.expression.infer.ts', + 'keyword.operator.expression.instanceof.js', + 'keyword.operator.expression.instanceof.ts', + 'keyword.operator.expression.is', + 'keyword.operator.expression.keyof.ts', + 'keyword.operator.expression.of.js', + 'keyword.operator.expression.of.ts', + 'keyword.operator.expression.typeof.ts', + ], + settings: { + foreground: '#cba6f7', + }, + }, + { + name: 'Julia macros', + scope: 'support.function.macro.julia', + settings: { + foreground: '#94e2d5', + fontStyle: 'italic', + }, + }, + { + name: 'Julia language constants (true, false)', + scope: 'constant.language.julia', + settings: { + foreground: '#fab387', + }, + }, + { + name: 'Julia other constants (these seem to be arguments inside arrays)', + scope: 'constant.other.symbol.julia', + settings: { + foreground: '#eba0ac', + }, + }, + { + name: 'LaTeX preamble', + scope: 'text.tex keyword.control.preamble', + settings: { + foreground: '#94e2d5', + }, + }, + { + name: 'LaTeX be functions', + scope: 'text.tex support.function.be', + settings: { + foreground: '#89dceb', + }, + }, + { + name: 'LaTeX math', + scope: 'constant.other.general.math.tex', + settings: { + foreground: '#f2cdcd', + }, + }, + { + name: 'Lua docstring keywords', + scope: + 'comment.line.double-dash.documentation.lua storage.type.annotation.lua', + settings: { + foreground: '#cba6f7', + fontStyle: '', + }, + }, + { + name: 'Lua docstring variables', + scope: [ + 'comment.line.double-dash.documentation.lua entity.name.variable.lua', + 'comment.line.double-dash.documentation.lua variable.lua', + ], + settings: { + foreground: '#cdd6f4', + }, + }, + { + scope: [ + 'heading.1.markdown punctuation.definition.heading.markdown', + 'heading.1.markdown', + 'heading.1.quarto punctuation.definition.heading.quarto', + 'heading.1.quarto', + 'markup.heading.atx.1.mdx', + 'markup.heading.atx.1.mdx punctuation.definition.heading.mdx', + 'markup.heading.setext.1.markdown', + 'markup.heading.heading-0.asciidoc', + ], + settings: { + foreground: '#f38ba8', + }, + }, + { + scope: [ + 'heading.2.markdown punctuation.definition.heading.markdown', + 'heading.2.markdown', + 'heading.2.quarto punctuation.definition.heading.quarto', + 'heading.2.quarto', + 'markup.heading.atx.2.mdx', + 'markup.heading.atx.2.mdx punctuation.definition.heading.mdx', + 'markup.heading.setext.2.markdown', + 'markup.heading.heading-1.asciidoc', + ], + settings: { + foreground: '#fab387', + }, + }, + { + scope: [ + 'heading.3.markdown punctuation.definition.heading.markdown', + 'heading.3.markdown', + 'heading.3.quarto punctuation.definition.heading.quarto', + 'heading.3.quarto', + 'markup.heading.atx.3.mdx', + 'markup.heading.atx.3.mdx punctuation.definition.heading.mdx', + 'markup.heading.heading-2.asciidoc', + ], + settings: { + foreground: '#f9e2af', + }, + }, + { + scope: [ + 'heading.4.markdown punctuation.definition.heading.markdown', + 'heading.4.markdown', + 'heading.4.quarto punctuation.definition.heading.quarto', + 'heading.4.quarto', + 'markup.heading.atx.4.mdx', + 'markup.heading.atx.4.mdx punctuation.definition.heading.mdx', + 'markup.heading.heading-3.asciidoc', + ], + settings: { + foreground: '#a6e3a1', + }, + }, + { + scope: [ + 'heading.5.markdown punctuation.definition.heading.markdown', + 'heading.5.markdown', + 'heading.5.quarto punctuation.definition.heading.quarto', + 'heading.5.quarto', + 'markup.heading.atx.5.mdx', + 'markup.heading.atx.5.mdx punctuation.definition.heading.mdx', + 'markup.heading.heading-4.asciidoc', + ], + settings: { + foreground: '#89b4fa', + }, + }, + { + scope: [ + 'heading.6.markdown punctuation.definition.heading.markdown', + 'heading.6.markdown', + 'heading.6.quarto punctuation.definition.heading.quarto', + 'heading.6.quarto', + 'markup.heading.atx.6.mdx', + 'markup.heading.atx.6.mdx punctuation.definition.heading.mdx', + 'markup.heading.heading-5.asciidoc', + ], + settings: { + foreground: '#cba6f7', + }, + }, + { + scope: 'markup.bold', + settings: { + foreground: '#f38ba8', + fontStyle: 'bold', + }, + }, + { + scope: 'markup.italic', + settings: { + foreground: '#f38ba8', + fontStyle: 'italic', + }, + }, + { + scope: 'markup.strikethrough', + settings: { + foreground: '#a6adc8', + fontStyle: 'strikethrough', + }, + }, + { + name: 'Markdown auto links', + scope: ['punctuation.definition.link', 'markup.underline.link'], + settings: { + foreground: '#89b4fa', + }, + }, + { + name: 'Markdown links', + scope: [ + 'text.html.markdown punctuation.definition.link.title', + 'text.html.quarto punctuation.definition.link.title', + 'string.other.link.title.markdown', + 'string.other.link.title.quarto', + 'markup.link', + 'punctuation.definition.constant.markdown', + 'punctuation.definition.constant.quarto', + 'constant.other.reference.link.markdown', + 'constant.other.reference.link.quarto', + 'markup.substitution.attribute-reference', + ], + settings: { + foreground: '#b4befe', + }, + }, + { + name: 'Markdown code spans', + scope: [ + 'punctuation.definition.raw.markdown', + 'punctuation.definition.raw.quarto', + 'markup.inline.raw.string.markdown', + 'markup.inline.raw.string.quarto', + 'markup.raw.block.markdown', + 'markup.raw.block.quarto', + ], + settings: { + foreground: '#a6e3a1', + }, + }, + { + name: 'Markdown triple backtick language identifier', + scope: 'fenced_code.block.language', + settings: { + foreground: '#89dceb', + }, + }, + { + name: 'Markdown triple backticks', + scope: [ + 'markup.fenced_code.block punctuation.definition', + 'markup.raw support.asciidoc', + ], + settings: { + foreground: '#9399b2', + }, + }, + { + name: 'Markdown quotes', + scope: ['markup.quote', 'punctuation.definition.quote.begin'], + settings: { + foreground: '#f5c2e7', + }, + }, + { + name: 'Markdown separators', + scope: 'meta.separator.markdown', + settings: { + foreground: '#94e2d5', + }, + }, + { + name: 'Markdown list bullets', + scope: [ + 'punctuation.definition.list.begin.markdown', + 'punctuation.definition.list.begin.quarto', + 'markup.list.bullet', + ], + settings: { + foreground: '#94e2d5', + }, + }, + { + name: 'Quarto headings', + scope: 'markup.heading.quarto', + settings: { + fontStyle: 'bold', + }, + }, + { + name: 'Nix attribute names', + scope: [ + 'entity.other.attribute-name.multipart.nix', + 'entity.other.attribute-name.single.nix', + ], + settings: { + foreground: '#89b4fa', + }, + }, + { + name: 'Nix parameter names', + scope: 'variable.parameter.name.nix', + settings: { + foreground: '#cdd6f4', + fontStyle: '', + }, + }, + { + name: 'Nix interpolated parameter names', + scope: 'meta.embedded variable.parameter.name.nix', + settings: { + foreground: '#b4befe', + fontStyle: '', + }, + }, + { + name: 'Nix paths', + scope: 'string.unquoted.path.nix', + settings: { + foreground: '#f5c2e7', + fontStyle: '', + }, + }, + { + name: 'PHP Attributes', + scope: ['support.attribute.builtin', 'meta.attribute.php'], + settings: { + foreground: '#f9e2af', + }, + }, + { + name: 'PHP Parameters (needed for the leading dollar sign)', + scope: 'meta.function.parameters.php punctuation.definition.variable.php', + settings: { + foreground: '#eba0ac', + }, + }, + { + name: 'PHP Constants (null, __FILE__, etc.)', + scope: 'constant.language.php', + settings: { + foreground: '#cba6f7', + }, + }, + { + name: 'PHP functions', + scope: 'text.html.php support.function', + settings: { + foreground: '#89dceb', + }, + }, + { + name: 'PHPdoc keywords', + scope: 'keyword.other.phpdoc.php', + settings: { + fontStyle: '', + }, + }, + { + name: 'Python argument functions reset to text, otherwise they inherit blue from function-call', + scope: [ + 'support.variable.magic.python', + 'meta.function-call.arguments.python', + ], + settings: { + foreground: '#cdd6f4', + }, + }, + { + name: 'Python double underscore functions', + scope: ['support.function.magic.python'], + settings: { + foreground: '#89dceb', + fontStyle: 'italic', + }, + }, + { + name: 'Python `self` keyword', + scope: [ + 'variable.parameter.function.language.special.self.python', + 'variable.language.special.self.python', + ], + settings: { + foreground: '#f38ba8', + fontStyle: 'italic', + }, + }, + { + name: 'python keyword flow/logical (for ... in)', + scope: ['keyword.control.flow.python', 'keyword.operator.logical.python'], + settings: { + foreground: '#cba6f7', + }, + }, + { + name: 'python storage type', + scope: 'storage.type.function.python', + settings: { + foreground: '#cba6f7', + }, + }, + { + name: 'python function support', + scope: [ + 'support.token.decorator.python', + 'meta.function.decorator.identifier.python', + ], + settings: { + foreground: '#89dceb', + }, + }, + { + name: 'python function calls', + scope: ['meta.function-call.python'], + settings: { + foreground: '#89b4fa', + }, + }, + { + name: 'python function decorators', + scope: [ + 'entity.name.function.decorator.python', + 'punctuation.definition.decorator.python', + ], + settings: { + foreground: '#fab387', + fontStyle: 'italic', + }, + }, + { + name: 'python placeholder reset to normal string', + scope: 'constant.character.format.placeholder.other.python', + settings: { + foreground: '#f5c2e7', + }, + }, + { + name: 'Python exception & builtins such as exit()', + scope: [ + 'support.type.exception.python', + 'support.function.builtin.python', + ], + settings: { + foreground: '#fab387', + }, + }, + { + name: 'entity.name.type', + scope: ['support.type.python'], + settings: { + foreground: '#fab387', + }, + }, + { + name: 'python constants (True/False)', + scope: 'constant.language.python', + settings: { + foreground: '#cba6f7', + }, + }, + { + name: 'Arguments accessed later in the function body', + scope: ['meta.indexed-name.python', 'meta.item-access.python'], + settings: { + foreground: '#eba0ac', + fontStyle: 'italic', + }, + }, + { + name: 'Python f-strings/binary/unicode storage types', + scope: 'storage.type.string.python', + settings: { + foreground: '#a6e3a1', + fontStyle: 'italic', + }, + }, + { + name: 'Python type hints', + scope: 'meta.function.parameters.python', + settings: { + fontStyle: '', + }, + }, + { + name: 'Regex string begin/end in JS/TS', + scope: [ + 'string.regexp punctuation.definition.string.begin', + 'string.regexp punctuation.definition.string.end', + ], + settings: { + foreground: '#f5c2e7', + }, + }, + { + name: 'Regex anchors (^, $)', + scope: 'keyword.control.anchor.regexp', + settings: { + foreground: '#cba6f7', + }, + }, + { + name: 'Regex regular string match', + scope: 'string.regexp.ts', + settings: { + foreground: '#cdd6f4', + }, + }, + { + name: 'Regex group parenthesis & backreference (\\1, \\2, \\3, ...)', + scope: [ + 'punctuation.definition.group.regexp', + 'keyword.other.back-reference.regexp', + ], + settings: { + foreground: '#a6e3a1', + }, + }, + { + name: 'Regex character class []', + scope: 'punctuation.definition.character-class.regexp', + settings: { + foreground: '#f9e2af', + }, + }, + { + name: 'Regex character classes (\\d, \\w, \\s)', + scope: 'constant.other.character-class.regexp', + settings: { + foreground: '#f5c2e7', + }, + }, + { + name: 'Regex range', + scope: 'constant.other.character-class.range.regexp', + settings: { + foreground: '#f5e0dc', + }, + }, + { + name: 'Regex quantifier', + scope: 'keyword.operator.quantifier.regexp', + settings: { + foreground: '#94e2d5', + }, + }, + { + name: 'Regex constant/numeric', + scope: 'constant.character.numeric.regexp', + settings: { + foreground: '#fab387', + }, + }, + { + name: 'Regex lookaheads, negative lookaheads, lookbehinds, negative lookbehinds', + scope: [ + 'punctuation.definition.group.no-capture.regexp', + 'meta.assertion.look-ahead.regexp', + 'meta.assertion.negative-look-ahead.regexp', + ], + settings: { + foreground: '#89b4fa', + }, + }, + { + name: 'Rust attribute', + scope: [ + 'meta.annotation.rust', + 'meta.annotation.rust punctuation', + 'meta.attribute.rust', + 'punctuation.definition.attribute.rust', + ], + settings: { + foreground: '#f9e2af', + fontStyle: 'italic', + }, + }, + { + name: 'Rust attribute strings', + scope: [ + 'meta.attribute.rust string.quoted.double.rust', + 'meta.attribute.rust string.quoted.single.char.rust', + ], + settings: { + fontStyle: '', + }, + }, + { + name: 'Rust keyword', + scope: [ + 'entity.name.function.macro.rules.rust', + 'storage.type.module.rust', + 'storage.modifier.rust', + 'storage.type.struct.rust', + 'storage.type.enum.rust', + 'storage.type.trait.rust', + 'storage.type.union.rust', + 'storage.type.impl.rust', + 'storage.type.rust', + 'storage.type.function.rust', + 'storage.type.type.rust', + ], + settings: { + foreground: '#cba6f7', + fontStyle: '', + }, + }, + { + name: 'Rust u/i32, u/i64, etc.', + scope: 'entity.name.type.numeric.rust', + settings: { + foreground: '#cba6f7', + fontStyle: '', + }, + }, + { + name: 'Rust generic', + scope: 'meta.generic.rust', + settings: { + foreground: '#fab387', + }, + }, + { + name: 'Rust impl', + scope: 'entity.name.impl.rust', + settings: { + foreground: '#f9e2af', + fontStyle: 'italic', + }, + }, + { + name: 'Rust module', + scope: 'entity.name.module.rust', + settings: { + foreground: '#fab387', + }, + }, + { + name: 'Rust trait', + scope: 'entity.name.trait.rust', + settings: { + foreground: '#f9e2af', + fontStyle: 'italic', + }, + }, + { + name: 'Rust struct', + scope: 'storage.type.source.rust', + settings: { + foreground: '#f9e2af', + }, + }, + { + name: 'Rust union', + scope: 'entity.name.union.rust', + settings: { + foreground: '#f9e2af', + }, + }, + { + name: 'Rust enum member', + scope: 'meta.enum.rust storage.type.source.rust', + settings: { + foreground: '#94e2d5', + }, + }, + { + name: 'Rust macro', + scope: [ + 'support.macro.rust', + 'meta.macro.rust support.function.rust', + 'entity.name.function.macro.rust', + ], + settings: { + foreground: '#89b4fa', + fontStyle: 'italic', + }, + }, + { + name: 'Rust lifetime', + scope: ['storage.modifier.lifetime.rust', 'entity.name.type.lifetime'], + settings: { + foreground: '#89b4fa', + fontStyle: 'italic', + }, + }, + { + name: 'Rust string formatting', + scope: 'string.quoted.double.rust constant.other.placeholder.rust', + settings: { + foreground: '#f5c2e7', + }, + }, + { + name: 'Rust return type generic', + scope: + 'meta.function.return-type.rust meta.generic.rust storage.type.rust', + settings: { + foreground: '#cdd6f4', + }, + }, + { + name: 'Rust functions', + scope: 'meta.function.call.rust', + settings: { + foreground: '#89b4fa', + }, + }, + { + name: 'Rust angle brackets', + scope: 'punctuation.brackets.angle.rust', + settings: { + foreground: '#89dceb', + }, + }, + { + name: 'Rust constants', + scope: 'constant.other.caps.rust', + settings: { + foreground: '#fab387', + }, + }, + { + name: 'Rust function parameters', + scope: ['meta.function.definition.rust variable.other.rust'], + settings: { + foreground: '#eba0ac', + }, + }, + { + name: 'Rust closure variables', + scope: 'meta.function.call.rust variable.other.rust', + settings: { + foreground: '#cdd6f4', + }, + }, + { + name: 'Rust self', + scope: 'variable.language.self.rust', + settings: { + foreground: '#f38ba8', + }, + }, + { + name: 'Rust metavariable names', + scope: [ + 'variable.other.metavariable.name.rust', + 'meta.macro.metavariable.rust keyword.operator.macro.dollar.rust', + ], + settings: { + foreground: '#f5c2e7', + }, + }, + { + name: 'Shell shebang', + scope: [ + 'comment.line.shebang', + 'comment.line.shebang punctuation.definition.comment', + 'comment.line.shebang', + 'punctuation.definition.comment.shebang.shell', + 'meta.shebang.shell', + ], + settings: { + foreground: '#f5c2e7', + fontStyle: 'italic', + }, + }, + { + name: 'Shell shebang command', + scope: 'comment.line.shebang constant.language', + settings: { + foreground: '#94e2d5', + fontStyle: 'italic', + }, + }, + { + name: 'Shell interpolated command', + scope: [ + 'meta.function-call.arguments.shell punctuation.definition.variable.shell', + 'meta.function-call.arguments.shell punctuation.section.interpolation', + 'meta.function-call.arguments.shell punctuation.definition.variable.shell', + 'meta.function-call.arguments.shell punctuation.section.interpolation', + ], + settings: { + foreground: '#f38ba8', + }, + }, + { + name: 'Shell interpolated command variable', + scope: + 'meta.string meta.interpolation.parameter.shell variable.other.readwrite', + settings: { + foreground: '#fab387', + fontStyle: 'italic', + }, + }, + { + scope: [ + 'source.shell punctuation.section.interpolation', + 'punctuation.definition.evaluation.backticks.shell', + ], + settings: { + foreground: '#94e2d5', + }, + }, + { + name: 'Shell EOF', + scope: 'entity.name.tag.heredoc.shell', + settings: { + foreground: '#cba6f7', + }, + }, + { + name: 'Shell quoted variable', + scope: 'string.quoted.double.shell variable.other.normal.shell', + settings: { + foreground: '#cdd6f4', + }, + }, + ], +} + +const catppuccinMacchiato = { + name: 'Catppuccin Macchiato', + type: 'dark', + colors: { + focusBorder: '#c6a0f6', + foreground: '#cad3f5', + disabledForeground: '#a5adcb', + 'widget.shadow': '#1e203080', + 'selection.background': '#c6a0f666', + descriptionForeground: '#cad3f5', + errorForeground: '#ed8796', + 'icon.foreground': '#c6a0f6', + 'sash.hoverBorder': '#c6a0f6', + 'window.activeBorder': '#00000000', + 'window.inactiveBorder': '#00000000', + 'textBlockQuote.background': '#1e2030', + 'textBlockQuote.border': '#181926', + 'textCodeBlock.background': '#24273a', + 'textLink.activeForeground': '#91d7e3', + 'textLink.foreground': '#8aadf4', + 'textPreformat.foreground': '#cad3f5', + 'textSeparator.foreground': '#c6a0f6', + 'activityBar.background': '#181926', + 'activityBar.foreground': '#c6a0f6', + 'activityBar.dropBorder': '#c6a0f633', + 'activityBar.inactiveForeground': '#6e738d', + 'activityBar.border': '#00000000', + 'activityBarBadge.background': '#c6a0f6', + 'activityBarBadge.foreground': '#181926', + 'activityBar.activeBorder': '#00000000', + 'activityBar.activeBackground': '#00000000', + 'activityBar.activeFocusBorder': '#00000000', + 'activityBarTop.foreground': '#c6a0f6', + 'activityBarTop.activeBorder': '#00000000', + 'activityBarTop.inactiveForeground': '#6e738d', + 'activityBarTop.dropBorder': '#c6a0f633', + 'badge.background': '#494d64', + 'badge.foreground': '#cad3f5', + 'breadcrumb.activeSelectionForeground': '#c6a0f6', + 'breadcrumb.background': '#24273a', + 'breadcrumb.focusForeground': '#c6a0f6', + 'breadcrumb.foreground': '#cad3f5cc', + 'breadcrumbPicker.background': '#1e2030', + 'button.background': '#c6a0f6', + 'button.foreground': '#181926', + 'button.border': '#00000000', + 'button.separator': '#00000000', + 'button.hoverBackground': '#dac1f9', + 'button.secondaryForeground': '#cad3f5', + 'button.secondaryBackground': '#5b6078', + 'button.secondaryHoverBackground': '#6a708c', + 'checkbox.background': '#494d64', + 'checkbox.border': '#00000000', + 'checkbox.foreground': '#c6a0f6', + 'dropdown.background': '#1e2030', + 'dropdown.listBackground': '#5b6078', + 'dropdown.border': '#c6a0f6', + 'dropdown.foreground': '#cad3f5', + 'debugToolBar.background': '#181926', + 'debugToolBar.border': '#00000000', + 'debugExceptionWidget.background': '#181926', + 'debugExceptionWidget.border': '#c6a0f6', + 'debugTokenExpression.number': '#f5a97f', + 'debugTokenExpression.boolean': '#c6a0f6', + 'debugTokenExpression.string': '#a6da95', + 'debugTokenExpression.error': '#ed8796', + 'debugIcon.breakpointForeground': '#ed8796', + 'debugIcon.breakpointDisabledForeground': '#ed879699', + 'debugIcon.breakpointUnverifiedForeground': '#a47487', + 'debugIcon.breakpointCurrentStackframeForeground': '#5b6078', + 'debugIcon.breakpointStackframeForeground': '#5b6078', + 'debugIcon.startForeground': '#a6da95', + 'debugIcon.pauseForeground': '#8aadf4', + 'debugIcon.stopForeground': '#ed8796', + 'debugIcon.disconnectForeground': '#5b6078', + 'debugIcon.restartForeground': '#8bd5ca', + 'debugIcon.stepOverForeground': '#c6a0f6', + 'debugIcon.stepIntoForeground': '#cad3f5', + 'debugIcon.stepOutForeground': '#cad3f5', + 'debugIcon.continueForeground': '#a6da95', + 'debugIcon.stepBackForeground': '#5b6078', + 'debugConsole.infoForeground': '#8aadf4', + 'debugConsole.warningForeground': '#f5a97f', + 'debugConsole.errorForeground': '#ed8796', + 'debugConsole.sourceForeground': '#f4dbd6', + 'debugConsoleInputIcon.foreground': '#cad3f5', + 'diffEditor.border': '#5b6078', + 'diffEditor.insertedTextBackground': '#a6da951a', + 'diffEditor.removedTextBackground': '#ed87961a', + 'diffEditor.insertedLineBackground': '#a6da9526', + 'diffEditor.removedLineBackground': '#ed879626', + 'diffEditor.diagonalFill': '#5b607899', + 'diffEditorOverview.insertedForeground': '#a6da95cc', + 'diffEditorOverview.removedForeground': '#ed8796cc', + 'editor.background': '#272140ff', + 'editor.findMatchBackground': '#604456', + 'editor.findMatchBorder': '#ed879633', + 'editor.findMatchHighlightBackground': '#455c6d', + 'editor.findMatchHighlightBorder': '#91d7e333', + 'editor.findRangeHighlightBackground': '#455c6d', + 'editor.findRangeHighlightBorder': '#91d7e333', + 'editor.foldBackground': '#91d7e340', + 'editor.foreground': '#cad3f5', + 'editor.hoverHighlightBackground': '#91d7e340', + 'editor.lineHighlightBackground': '#cad3f512', + 'editor.lineHighlightBorder': '#00000000', + 'editor.rangeHighlightBackground': '#00000040', + 'editor.rangeHighlightBorder': '#00000000', + 'editor.selectionBackground': '#939ab740', + 'editor.selectionHighlightBackground': '#939ab733', + 'editor.selectionHighlightBorder': '#939ab733', + 'editor.wordHighlightBackground': '#939ab733', + 'editorBracketMatch.background': '#939ab71a', + 'editorBracketMatch.border': '#939ab7', + 'editorCodeLens.foreground': '#8087a2', + 'editorCursor.background': '#24273a', + 'editorCursor.foreground': '#f4dbd6', + 'editorGroup.border': '#5b6078', + 'editorGroup.dropBackground': '#c6a0f633', + 'editorGroup.emptyBackground': '#24273a', + 'editorGroupHeader.tabsBackground': '#181926', + 'editorGutter.addedBackground': '#a6da95', + 'editorGutter.background': '#24273a', + 'editorGutter.commentRangeForeground': '#363a4f', + 'editorGutter.commentGlyphForeground': '#c6a0f6', + 'editorGutter.deletedBackground': '#ed8796', + 'editorGutter.foldingControlForeground': '#939ab7', + 'editorGutter.modifiedBackground': '#eed49f', + 'editorHoverWidget.background': '#1e2030', + 'editorHoverWidget.border': '#5b6078', + 'editorHoverWidget.foreground': '#cad3f5', + 'editorIndentGuide.activeBackground': '#5b6078', + 'editorIndentGuide.background': '#494d64', + 'editorInlayHint.foreground': '#5b6078', + 'editorInlayHint.background': '#1e2030bf', + 'editorInlayHint.typeForeground': '#b8c0e0', + 'editorInlayHint.typeBackground': '#1e2030bf', + 'editorInlayHint.parameterForeground': '#a5adcb', + 'editorInlayHint.parameterBackground': '#1e2030bf', + 'editorLineNumber.activeForeground': '#c6a0f6', + 'editorLineNumber.foreground': '#8087a2', + 'editorLink.activeForeground': '#c6a0f6', + 'editorMarkerNavigation.background': '#1e2030', + 'editorMarkerNavigationError.background': '#ed8796', + 'editorMarkerNavigationInfo.background': '#8aadf4', + 'editorMarkerNavigationWarning.background': '#f5a97f', + 'editorOverviewRuler.background': '#1e2030', + 'editorOverviewRuler.border': '#cad3f512', + 'editorOverviewRuler.modifiedForeground': '#eed49f', + 'editorRuler.foreground': '#5b6078', + 'editor.stackFrameHighlightBackground': '#eed49f26', + 'editor.focusedStackFrameHighlightBackground': '#a6da9526', + 'editorStickyScrollHover.background': '#363a4f', + 'editorSuggestWidget.background': '#1e2030', + 'editorSuggestWidget.border': '#5b6078', + 'editorSuggestWidget.foreground': '#cad3f5', + 'editorSuggestWidget.highlightForeground': '#c6a0f6', + 'editorSuggestWidget.selectedBackground': '#363a4f', + 'editorWhitespace.foreground': '#939ab766', + 'editorWidget.background': '#1e2030', + 'editorWidget.foreground': '#cad3f5', + 'editorWidget.resizeBorder': '#5b6078', + 'editorLightBulb.foreground': '#eed49f', + 'editorError.foreground': '#ed8796', + 'editorError.border': '#00000000', + 'editorError.background': '#00000000', + 'editorWarning.foreground': '#f5a97f', + 'editorWarning.border': '#00000000', + 'editorWarning.background': '#00000000', + 'editorInfo.foreground': '#8aadf4', + 'editorInfo.border': '#00000000', + 'editorInfo.background': '#00000000', + 'problemsErrorIcon.foreground': '#ed8796', + 'problemsInfoIcon.foreground': '#8aadf4', + 'problemsWarningIcon.foreground': '#f5a97f', + 'extensionButton.prominentForeground': '#181926', + 'extensionButton.prominentBackground': '#c6a0f6', + 'extensionButton.separator': '#24273a', + 'extensionButton.prominentHoverBackground': '#dac1f9', + 'extensionBadge.remoteBackground': '#8aadf4', + 'extensionBadge.remoteForeground': '#181926', + 'extensionIcon.starForeground': '#eed49f', + 'extensionIcon.verifiedForeground': '#a6da95', + 'extensionIcon.preReleaseForeground': '#5b6078', + 'extensionIcon.sponsorForeground': '#f5bde6', + 'gitDecoration.addedResourceForeground': '#a6da95', + 'gitDecoration.conflictingResourceForeground': '#c6a0f6', + 'gitDecoration.deletedResourceForeground': '#ed8796', + 'gitDecoration.ignoredResourceForeground': '#6e738d', + 'gitDecoration.modifiedResourceForeground': '#eed49f', + 'gitDecoration.stageDeletedResourceForeground': '#ed8796', + 'gitDecoration.stageModifiedResourceForeground': '#eed49f', + 'gitDecoration.submoduleResourceForeground': '#8aadf4', + 'gitDecoration.untrackedResourceForeground': '#a6da95', + 'input.background': '#363a4f', + 'input.border': '#00000000', + 'input.foreground': '#cad3f5', + 'input.placeholderForeground': '#cad3f573', + 'inputOption.activeBackground': '#5b6078', + 'inputOption.activeBorder': '#c6a0f6', + 'inputOption.activeForeground': '#cad3f5', + 'inputValidation.errorBackground': '#ed8796', + 'inputValidation.errorBorder': '#18192633', + 'inputValidation.errorForeground': '#181926', + 'inputValidation.infoBackground': '#8aadf4', + 'inputValidation.infoBorder': '#18192633', + 'inputValidation.infoForeground': '#181926', + 'inputValidation.warningBackground': '#f5a97f', + 'inputValidation.warningBorder': '#18192633', + 'inputValidation.warningForeground': '#181926', + 'list.activeSelectionBackground': '#363a4f', + 'list.activeSelectionForeground': '#cad3f5', + 'list.dropBackground': '#c6a0f633', + 'list.focusBackground': '#363a4f', + 'list.focusForeground': '#cad3f5', + 'list.focusOutline': '#00000000', + 'list.highlightForeground': '#c6a0f6', + 'list.hoverBackground': '#363a4f80', + 'list.hoverForeground': '#cad3f5', + 'list.inactiveSelectionBackground': '#363a4f', + 'list.inactiveSelectionForeground': '#cad3f5', + 'list.warningForeground': '#f5a97f', + 'listFilterWidget.background': '#494d64', + 'listFilterWidget.noMatchesOutline': '#ed8796', + 'listFilterWidget.outline': '#00000000', + 'tree.indentGuidesStroke': '#939ab7', + 'tree.inactiveIndentGuidesStroke': '#494d64', + 'menu.background': '#24273a', + 'menu.border': '#24273a80', + 'menu.foreground': '#cad3f5', + 'menu.selectionBackground': '#5b6078', + 'menu.selectionBorder': '#00000000', + 'menu.selectionForeground': '#cad3f5', + 'menu.separatorBackground': '#5b6078', + 'menubar.selectionBackground': '#494d64', + 'menubar.selectionForeground': '#cad3f5', + 'merge.commonContentBackground': '#494d64', + 'merge.commonHeaderBackground': '#5b6078', + 'merge.currentContentBackground': '#a6da9533', + 'merge.currentHeaderBackground': '#a6da9566', + 'merge.incomingContentBackground': '#8aadf433', + 'merge.incomingHeaderBackground': '#8aadf466', + 'minimap.background': '#1e203080', + 'minimap.findMatchHighlight': '#91d7e34d', + 'minimap.selectionHighlight': '#5b6078bf', + 'minimap.selectionOccurrenceHighlight': '#5b6078bf', + 'minimap.warningHighlight': '#f5a97fbf', + 'minimap.errorHighlight': '#ed8796bf', + 'minimapSlider.background': '#c6a0f633', + 'minimapSlider.hoverBackground': '#c6a0f666', + 'minimapSlider.activeBackground': '#c6a0f699', + 'minimapGutter.addedBackground': '#a6da95bf', + 'minimapGutter.deletedBackground': '#ed8796bf', + 'minimapGutter.modifiedBackground': '#eed49fbf', + 'notificationCenter.border': '#c6a0f6', + 'notificationCenterHeader.foreground': '#cad3f5', + 'notificationCenterHeader.background': '#1e2030', + 'notificationToast.border': '#c6a0f6', + 'notifications.foreground': '#cad3f5', + 'notifications.background': '#1e2030', + 'notifications.border': '#c6a0f6', + 'notificationLink.foreground': '#8aadf4', + 'notificationsErrorIcon.foreground': '#ed8796', + 'notificationsWarningIcon.foreground': '#f5a97f', + 'notificationsInfoIcon.foreground': '#8aadf4', + 'panel.background': '#24273a', + 'panel.border': '#5b6078', + 'panelSection.border': '#5b6078', + 'panelSection.dropBackground': '#c6a0f633', + 'panelTitle.activeBorder': '#c6a0f6', + 'panelTitle.activeForeground': '#cad3f5', + 'panelTitle.inactiveForeground': '#a5adcb', + 'peekView.border': '#c6a0f6', + 'peekViewEditor.background': '#1e2030', + 'peekViewEditorGutter.background': '#1e2030', + 'peekViewEditor.matchHighlightBackground': '#91d7e34d', + 'peekViewEditor.matchHighlightBorder': '#00000000', + 'peekViewResult.background': '#1e2030', + 'peekViewResult.fileForeground': '#cad3f5', + 'peekViewResult.lineForeground': '#cad3f5', + 'peekViewResult.matchHighlightBackground': '#91d7e34d', + 'peekViewResult.selectionBackground': '#363a4f', + 'peekViewResult.selectionForeground': '#cad3f5', + 'peekViewTitle.background': '#24273a', + 'peekViewTitleDescription.foreground': '#b8c0e0b3', + 'peekViewTitleLabel.foreground': '#cad3f5', + 'pickerGroup.border': '#c6a0f6', + 'pickerGroup.foreground': '#c6a0f6', + 'progressBar.background': '#c6a0f6', + 'scrollbar.shadow': '#181926', + 'scrollbarSlider.activeBackground': '#363a4f66', + 'scrollbarSlider.background': '#5b607880', + 'scrollbarSlider.hoverBackground': '#6e738d', + 'settings.focusedRowBackground': '#5b607833', + 'settings.headerForeground': '#cad3f5', + 'settings.modifiedItemIndicator': '#c6a0f6', + 'settings.dropdownBackground': '#494d64', + 'settings.dropdownListBorder': '#00000000', + 'settings.textInputBackground': '#494d64', + 'settings.textInputBorder': '#00000000', + 'settings.numberInputBackground': '#494d64', + 'settings.numberInputBorder': '#00000000', + 'sideBar.background': '#1e2030', + 'sideBar.dropBackground': '#c6a0f633', + 'sideBar.foreground': '#cad3f5', + 'sideBar.border': '#00000000', + 'sideBarSectionHeader.background': '#1e2030', + 'sideBarSectionHeader.foreground': '#cad3f5', + 'sideBarTitle.foreground': '#c6a0f6', + 'banner.background': '#494d64', + 'banner.foreground': '#cad3f5', + 'banner.iconForeground': '#cad3f5', + 'statusBar.background': '#181926', + 'statusBar.foreground': '#cad3f5', + 'statusBar.border': '#00000000', + 'statusBar.noFolderBackground': '#181926', + 'statusBar.noFolderForeground': '#cad3f5', + 'statusBar.noFolderBorder': '#00000000', + 'statusBar.debuggingBackground': '#f5a97f', + 'statusBar.debuggingForeground': '#181926', + 'statusBar.debuggingBorder': '#00000000', + 'statusBarItem.remoteBackground': '#8aadf4', + 'statusBarItem.remoteForeground': '#181926', + 'statusBarItem.activeBackground': '#5b607866', + 'statusBarItem.hoverBackground': '#5b607833', + 'statusBarItem.prominentForeground': '#c6a0f6', + 'statusBarItem.prominentBackground': '#00000000', + 'statusBarItem.prominentHoverBackground': '#5b607833', + 'statusBarItem.errorForeground': '#ed8796', + 'statusBarItem.errorBackground': '#00000000', + 'statusBarItem.warningForeground': '#f5a97f', + 'statusBarItem.warningBackground': '#00000000', + 'commandCenter.foreground': '#b8c0e0', + 'commandCenter.inactiveForeground': '#b8c0e0', + 'commandCenter.activeForeground': '#c6a0f6', + 'commandCenter.background': '#1e2030', + 'commandCenter.activeBackground': '#5b607833', + 'commandCenter.border': '#00000000', + 'commandCenter.inactiveBorder': '#00000000', + 'commandCenter.activeBorder': '#c6a0f6', + 'tab.activeBackground': '#24273a', + 'tab.activeBorder': '#00000000', + 'tab.activeBorderTop': '#c6a0f6', + 'tab.activeForeground': '#c6a0f6', + 'tab.activeModifiedBorder': '#eed49f', + 'tab.border': '#1e2030', + 'tab.hoverBackground': '#2e324a', + 'tab.hoverBorder': '#00000000', + 'tab.hoverForeground': '#c6a0f6', + 'tab.inactiveBackground': '#1e2030', + 'tab.inactiveForeground': '#6e738d', + 'tab.inactiveModifiedBorder': '#eed49f4d', + 'tab.lastPinnedBorder': '#c6a0f6', + 'tab.unfocusedActiveBackground': '#1e2030', + 'tab.unfocusedActiveBorder': '#00000000', + 'tab.unfocusedActiveBorderTop': '#c6a0f64d', + 'tab.unfocusedInactiveBackground': '#141620', + 'terminal.foreground': '#cad3f5', + 'terminal.ansiBlack': '#a5adcb', + 'terminal.ansiRed': '#ed8796', + 'terminal.ansiGreen': '#a6da95', + 'terminal.ansiYellow': '#eed49f', + 'terminal.ansiBlue': '#8aadf4', + 'terminal.ansiMagenta': '#f5bde6', + 'terminal.ansiCyan': '#91d7e3', + 'terminal.ansiWhite': '#b8c0e0', + 'terminal.ansiBrightBlack': '#5b6078', + 'terminal.ansiBrightRed': '#ed8796', + 'terminal.ansiBrightGreen': '#a6da95', + 'terminal.ansiBrightYellow': '#eed49f', + 'terminal.ansiBrightBlue': '#8aadf4', + 'terminal.ansiBrightMagenta': '#f5bde6', + 'terminal.ansiBrightCyan': '#91d7e3', + 'terminal.ansiBrightWhite': '#494d64', + 'terminal.selectionBackground': '#5b6078', + 'terminal.inactiveSelectionBackground': '#5b607880', + 'terminalCursor.background': '#24273a', + 'terminalCursor.foreground': '#f4dbd6', + 'terminal.border': '#5b6078', + 'terminal.dropBackground': '#c6a0f633', + 'terminal.tab.activeBorder': '#c6a0f6', + 'terminalCommandDecoration.defaultBackground': '#5b6078', + 'terminalCommandDecoration.successBackground': '#a6da95', + 'terminalCommandDecoration.errorBackground': '#ed8796', + 'titleBar.activeBackground': '#181926', + 'titleBar.activeForeground': '#cad3f5', + 'titleBar.inactiveBackground': '#181926', + 'titleBar.inactiveForeground': '#cad3f580', + 'titleBar.border': '#00000000', + 'welcomePage.tileBackground': '#1e2030', + 'welcomePage.progress.background': '#181926', + 'welcomePage.progress.foreground': '#c6a0f6', + 'walkThrough.embeddedEditorBackground': '#24273a4d', + 'symbolIcon.textForeground': '#cad3f5', + 'symbolIcon.arrayForeground': '#f5a97f', + 'symbolIcon.booleanForeground': '#c6a0f6', + 'symbolIcon.classForeground': '#eed49f', + 'symbolIcon.colorForeground': '#f5bde6', + 'symbolIcon.constantForeground': '#f5a97f', + 'symbolIcon.constructorForeground': '#b7bdf8', + 'symbolIcon.enumeratorForeground': '#eed49f', + 'symbolIcon.enumeratorMemberForeground': '#eed49f', + 'symbolIcon.eventForeground': '#f5bde6', + 'symbolIcon.fieldForeground': '#cad3f5', + 'symbolIcon.fileForeground': '#c6a0f6', + 'symbolIcon.folderForeground': '#c6a0f6', + 'symbolIcon.functionForeground': '#8aadf4', + 'symbolIcon.interfaceForeground': '#eed49f', + 'symbolIcon.keyForeground': '#8bd5ca', + 'symbolIcon.keywordForeground': '#c6a0f6', + 'symbolIcon.methodForeground': '#8aadf4', + 'symbolIcon.moduleForeground': '#cad3f5', + 'symbolIcon.namespaceForeground': '#eed49f', + 'symbolIcon.nullForeground': '#ee99a0', + 'symbolIcon.numberForeground': '#f5a97f', + 'symbolIcon.objectForeground': '#eed49f', + 'symbolIcon.operatorForeground': '#8bd5ca', + 'symbolIcon.packageForeground': '#f0c6c6', + 'symbolIcon.propertyForeground': '#ee99a0', + 'symbolIcon.referenceForeground': '#eed49f', + 'symbolIcon.snippetForeground': '#f0c6c6', + 'symbolIcon.stringForeground': '#a6da95', + 'symbolIcon.structForeground': '#8bd5ca', + 'symbolIcon.typeParameterForeground': '#ee99a0', + 'symbolIcon.unitForeground': '#cad3f5', + 'symbolIcon.variableForeground': '#cad3f5', + 'charts.foreground': '#cad3f5', + 'charts.lines': '#b8c0e0', + 'charts.red': '#ed8796', + 'charts.blue': '#8aadf4', + 'charts.yellow': '#eed49f', + 'charts.orange': '#f5a97f', + 'charts.green': '#a6da95', + 'charts.purple': '#c6a0f6', + 'errorLens.errorBackground': '#ed879626', + 'errorLens.errorBackgroundLight': '#ed879626', + 'errorLens.errorForeground': '#ed8796', + 'errorLens.errorForegroundLight': '#ed8796', + 'errorLens.errorMessageBackground': '#ed879626', + 'errorLens.hintBackground': '#a6da9526', + 'errorLens.hintBackgroundLight': '#a6da9526', + 'errorLens.hintForeground': '#a6da95', + 'errorLens.hintForegroundLight': '#a6da95', + 'errorLens.hintMessageBackground': '#a6da9526', + 'errorLens.infoBackground': '#8aadf426', + 'errorLens.infoBackgroundLight': '#8aadf426', + 'errorLens.infoForeground': '#8aadf4', + 'errorLens.infoForegroundLight': '#8aadf4', + 'errorLens.infoMessageBackground': '#8aadf426', + 'errorLens.statusBarErrorForeground': '#ed8796', + 'errorLens.statusBarHintForeground': '#a6da95', + 'errorLens.statusBarIconErrorForeground': '#ed8796', + 'errorLens.statusBarIconWarningForeground': '#f5a97f', + 'errorLens.statusBarInfoForeground': '#8aadf4', + 'errorLens.statusBarWarningForeground': '#f5a97f', + 'errorLens.warningBackground': '#f5a97f26', + 'errorLens.warningBackgroundLight': '#f5a97f26', + 'errorLens.warningForeground': '#f5a97f', + 'errorLens.warningForegroundLight': '#f5a97f', + 'errorLens.warningMessageBackground': '#f5a97f26', + 'issues.closed': '#c6a0f6', + 'issues.newIssueDecoration': '#f4dbd6', + 'issues.open': '#a6da95', + 'pullRequests.closed': '#ed8796', + 'pullRequests.draft': '#939ab7', + 'pullRequests.merged': '#c6a0f6', + 'pullRequests.notification': '#cad3f5', + 'pullRequests.open': '#a6da95', + 'gitlens.gutterBackgroundColor': '#363a4f4d', + 'gitlens.gutterForegroundColor': '#cad3f5', + 'gitlens.gutterUncommittedForegroundColor': '#c6a0f6', + 'gitlens.trailingLineBackgroundColor': '#00000000', + 'gitlens.trailingLineForegroundColor': '#cad3f54d', + 'gitlens.lineHighlightBackgroundColor': '#c6a0f626', + 'gitlens.lineHighlightOverviewRulerColor': '#c6a0f6cc', + 'gitlens.openAutolinkedIssueIconColor': '#a6da95', + 'gitlens.closedAutolinkedIssueIconColor': '#c6a0f6', + 'gitlens.closedPullRequestIconColor': '#ed8796', + 'gitlens.openPullRequestIconColor': '#a6da95', + 'gitlens.mergedPullRequestIconColor': '#c6a0f6', + 'gitlens.unpublishedChangesIconColor': '#a6da95', + 'gitlens.unpublishedCommitIconColor': '#a6da95', + 'gitlens.unpulledChangesIconColor': '#f5a97f', + 'gitlens.decorations.branchAheadForegroundColor': '#a6da95', + 'gitlens.decorations.branchBehindForegroundColor': '#f5a97f', + 'gitlens.decorations.branchDivergedForegroundColor': '#eed49f', + 'gitlens.decorations.branchUnpublishedForegroundColor': '#a6da95', + 'gitlens.decorations.branchMissingUpstreamForegroundColor': '#f5a97f', + 'gitlens.decorations.statusMergingOrRebasingConflictForegroundColor': + '#ee99a0', + 'gitlens.decorations.statusMergingOrRebasingForegroundColor': '#eed49f', + 'gitlens.decorations.workspaceRepoMissingForegroundColor': '#a5adcb', + 'gitlens.decorations.workspaceCurrentForegroundColor': '#c6a0f6', + 'gitlens.decorations.workspaceRepoOpenForegroundColor': '#c6a0f6', + 'gitlens.decorations.worktreeHasUncommittedChangesForegroundColor': + '#f5a97f', + 'gitlens.decorations.worktreeMissingForegroundColor': '#ee99a0', + 'gitlens.graphLane1Color': '#c6a0f6', + 'gitlens.graphLane2Color': '#eed49f', + 'gitlens.graphLane3Color': '#8aadf4', + 'gitlens.graphLane4Color': '#f0c6c6', + 'gitlens.graphLane5Color': '#a6da95', + 'gitlens.graphLane6Color': '#b7bdf8', + 'gitlens.graphLane7Color': '#f4dbd6', + 'gitlens.graphLane8Color': '#ed8796', + 'gitlens.graphLane9Color': '#8bd5ca', + 'gitlens.graphLane10Color': '#f5bde6', + 'gitlens.graphChangesColumnAddedColor': '#a6da95', + 'gitlens.graphChangesColumnDeletedColor': '#ed8796', + 'gitlens.graphMinimapMarkerHeadColor': '#a6da95', + 'gitlens.graphScrollMarkerHeadColor': '#a6da95', + 'gitlens.graphMinimapMarkerUpstreamColor': '#96d382', + 'gitlens.graphScrollMarkerUpstreamColor': '#96d382', + 'gitlens.graphMinimapMarkerHighlightsColor': '#eed49f', + 'gitlens.graphScrollMarkerHighlightsColor': '#eed49f', + 'gitlens.graphMinimapMarkerLocalBranchesColor': '#8aadf4', + 'gitlens.graphScrollMarkerLocalBranchesColor': '#8aadf4', + 'gitlens.graphMinimapMarkerRemoteBranchesColor': '#739df2', + 'gitlens.graphScrollMarkerRemoteBranchesColor': '#739df2', + 'gitlens.graphMinimapMarkerStashesColor': '#c6a0f6', + 'gitlens.graphScrollMarkerStashesColor': '#c6a0f6', + 'gitlens.graphMinimapMarkerTagsColor': '#f0c6c6', + 'gitlens.graphScrollMarkerTagsColor': '#f0c6c6', + 'editorBracketHighlight.foreground1': '#ed8796', + 'editorBracketHighlight.foreground2': '#f5a97f', + 'editorBracketHighlight.foreground3': '#eed49f', + 'editorBracketHighlight.foreground4': '#a6da95', + 'editorBracketHighlight.foreground5': '#7dc4e4', + 'editorBracketHighlight.foreground6': '#c6a0f6', + 'editorBracketHighlight.unexpectedBracket.foreground': '#ee99a0', + 'button.secondaryBorder': '#c6a0f6', + 'table.headerBackground': '#363a4f', + 'table.headerForeground': '#cad3f5', + 'list.focusAndSelectionBackground': '#494d64', + }, + semanticHighlighting: true, + semanticTokenColors: { + enumMember: { + foreground: '#8bd5ca', + }, + selfKeyword: { + foreground: '#ed8796', + }, + boolean: { + foreground: '#f5a97f', + }, + number: { + foreground: '#f5a97f', + }, + 'variable.defaultLibrary': { + foreground: '#ee99a0', + }, + 'class:python': { + foreground: '#eed49f', + }, + 'class.builtin:python': { + foreground: '#c6a0f6', + }, + 'variable.typeHint:python': { + foreground: '#eed49f', + }, + 'function.decorator:python': { + foreground: '#f5a97f', + }, + 'variable.readonly:javascript': { + foreground: '#cad3f5', + }, + 'variable.readonly:typescript': { + foreground: '#cad3f5', + }, + 'property.readonly:javascript': { + foreground: '#cad3f5', + }, + 'property.readonly:typescript': { + foreground: '#cad3f5', + }, + 'variable.readonly:javascriptreact': { + foreground: '#cad3f5', + }, + 'variable.readonly:typescriptreact': { + foreground: '#cad3f5', + }, + 'property.readonly:javascriptreact': { + foreground: '#cad3f5', + }, + 'property.readonly:typescriptreact': { + foreground: '#cad3f5', + }, + 'variable.readonly:scala': { + foreground: '#cad3f5', + }, + 'type.defaultLibrary:go': { + foreground: '#c6a0f6', + }, + 'variable.readonly.defaultLibrary:go': { + foreground: '#c6a0f6', + }, + tomlArrayKey: { + foreground: '#8aadf4', + fontStyle: '', + }, + tomlTableKey: { + foreground: '#8aadf4', + fontStyle: '', + }, + 'builtinAttribute.attribute.library:rust': { + foreground: '#8aadf4', + }, + 'generic.attribute:rust': { + foreground: '#cad3f5', + }, + 'constant.builtin.readonly:nix': { + foreground: '#c6a0f6', + }, + heading: { + foreground: '#ed8796', + }, + 'text.emph': { + foreground: '#ed8796', + fontStyle: 'italic', + }, + 'text.strong': { + foreground: '#ed8796', + fontStyle: 'bold', + }, + 'text.math': { + foreground: '#f0c6c6', + }, + pol: { + foreground: '#f0c6c6', + }, + }, + tokenColors: [ + { + name: 'Basic text & variable names (incl. leading punctuation)', + scope: [ + 'text', + 'source', + 'variable.other.readwrite', + 'punctuation.definition.variable', + ], + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'Parentheses, Brackets, Braces', + scope: 'punctuation', + settings: { + foreground: '#939ab7', + fontStyle: '', + }, + }, + { + name: 'Comments', + scope: ['comment', 'punctuation.definition.comment'], + settings: { + foreground: '#6e738d', + fontStyle: 'italic', + }, + }, + { + scope: ['string', 'punctuation.definition.string'], + settings: { + foreground: '#a6da95', + }, + }, + { + scope: 'constant.character.escape', + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'Booleans, constants, numbers', + scope: [ + 'constant.numeric', + 'variable.other.constant', + 'entity.name.constant', + 'constant.language.boolean', + 'constant.language.false', + 'constant.language.true', + 'keyword.other.unit.user-defined', + 'keyword.other.unit.suffix.floating-point', + ], + settings: { + foreground: '#f5a97f', + }, + }, + { + scope: [ + 'keyword', + 'keyword.operator.word', + 'keyword.operator.new', + 'variable.language.super', + 'support.type.primitive', + 'storage.type', + 'storage.modifier', + 'punctuation.definition.keyword', + ], + settings: { + foreground: '#bf89ebff', + fontStyle: 'normal', + }, + }, + { + scope: 'entity.name.tag.documentation', + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'Punctuation', + scope: [ + 'keyword.operator', + 'punctuation.accessor', + 'punctuation.definition.generic', + 'meta.function.closure punctuation.section.parameters', + 'punctuation.definition.tag', + 'punctuation.separator.key-value', + ], + settings: { + foreground: '#66e0ccff', + fontStyle: 'normal', + }, + }, + { + scope: [ + 'entity.name.function', + 'meta.function-call.method', + 'support.function', + 'support.function.misc', + 'variable.function', + ], + settings: { + foreground: '#7ea2f7ff', + fontStyle: 'italic', + }, + }, + { + name: 'Classes', + scope: [ + 'entity.name.class', + 'entity.other.inherited-class', + 'support.class', + 'meta.function-call.constructor', + 'entity.name.struct', + ], + settings: { + foreground: '#eed49f', + fontStyle: 'italic', + }, + }, + { + name: 'Enum', + scope: 'entity.name.enum', + settings: { + foreground: '#eed49f', + fontStyle: 'italic', + }, + }, + { + name: 'Enum member', + scope: [ + 'meta.enum variable.other.readwrite', + 'variable.other.enummember', + ], + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Object properties', + scope: 'meta.property.object', + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Types', + scope: [ + 'meta.type', + 'meta.type-alias', + 'support.type', + 'entity.name.type', + ], + settings: { + foreground: '#eed49f', + fontStyle: 'italic', + }, + }, + { + name: 'Decorators', + scope: [ + 'meta.annotation variable.function', + 'meta.annotation variable.annotation.function', + 'meta.annotation punctuation.definition.annotation', + 'meta.decorator', + 'punctuation.decorator', + ], + settings: { + foreground: '#f5a97f', + }, + }, + { + scope: ['variable.parameter', 'meta.function.parameters'], + settings: { + foreground: '#ee8d94ff', + fontStyle: 'italic', + }, + }, + { + name: 'Built-ins', + scope: ['constant.language', 'support.function.builtin'], + settings: { + foreground: '#ed8796', + }, + }, + { + scope: 'entity.other.attribute-name.documentation', + settings: { + foreground: '#ed8796', + }, + }, + { + name: 'Preprocessor directives', + scope: ['keyword.control.directive', 'punctuation.definition.directive'], + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'Type parameters', + scope: 'punctuation.definition.typeparameters', + settings: { + foreground: '#91d7e3', + }, + }, + { + name: 'Namespaces', + scope: 'entity.name.namespace', + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'Property names (left hand assignments in json/yaml/css)', + scope: 'support.type.property-name.css', + settings: { + foreground: '#8aadf4', + fontStyle: '', + }, + }, + { + name: 'This/Self keyword', + scope: [ + 'variable.language.this', + 'variable.language.this punctuation.definition.variable', + ], + settings: { + foreground: '#ed8796', + }, + }, + { + name: 'Object properties', + scope: 'variable.object.property', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'String template interpolation', + scope: ['string.template variable', 'string variable'], + settings: { + foreground: '#cad3f5', + }, + }, + { + name: '`new` as bold', + scope: 'keyword.operator.new', + settings: { + fontStyle: 'bold', + }, + }, + { + name: 'C++ extern keyword', + scope: 'storage.modifier.specifier.extern.cpp', + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'C++ scope resolution', + scope: [ + 'entity.name.scope-resolution.template.call.cpp', + 'entity.name.scope-resolution.parameter.cpp', + 'entity.name.scope-resolution.cpp', + 'entity.name.scope-resolution.function.definition.cpp', + ], + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'C++ doc keywords', + scope: 'storage.type.class.doxygen', + settings: { + fontStyle: '', + }, + }, + { + name: 'C++ operators', + scope: ['storage.modifier.reference.cpp'], + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'C# Interpolated Strings', + scope: 'meta.interpolation.cs', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'C# xml-style docs', + scope: 'comment.block.documentation.cs', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'Classes, reflecting the className color in JSX', + scope: [ + 'source.css entity.other.attribute-name.class.css', + 'entity.other.attribute-name.parent-selector.css punctuation.definition.entity.css', + ], + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'Operators', + scope: 'punctuation.separator.operator.css', + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Pseudo classes', + scope: 'source.css entity.other.attribute-name.pseudo-class', + settings: { + foreground: '#8bd5ca', + }, + }, + { + scope: 'source.css constant.other.unicode-range', + settings: { + foreground: '#f5a97f', + }, + }, + { + scope: 'source.css variable.parameter.url', + settings: { + foreground: '#a6da95', + fontStyle: '', + }, + }, + { + name: 'CSS vendored property names', + scope: ['support.type.vendored.property-name'], + settings: { + foreground: '#91d7e3', + }, + }, + { + name: 'Less/SCSS right-hand variables (@/$-prefixed)', + scope: [ + 'source.css meta.property-value variable', + 'source.css meta.property-value variable.other.less', + 'source.css meta.property-value variable.other.less punctuation.definition.variable.less', + 'meta.definition.variable.scss', + ], + settings: { + foreground: '#ee99a0', + }, + }, + { + name: 'CSS variables (--prefixed)', + scope: [ + 'source.css meta.property-list variable', + 'meta.property-list variable.other.less', + 'meta.property-list variable.other.less punctuation.definition.variable.less', + ], + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'CSS Percentage values, styled the same as numbers', + scope: 'keyword.other.unit.percentage.css', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'CSS Attribute selectors, styled the same as strings', + scope: 'source.css meta.attribute-selector', + settings: { + foreground: '#a6da95', + }, + }, + { + name: 'JSON/YAML keys, other left-hand assignments', + scope: [ + 'keyword.other.definition.ini', + 'punctuation.support.type.property-name.json', + 'support.type.property-name.json', + 'punctuation.support.type.property-name.toml', + 'support.type.property-name.toml', + 'entity.name.tag.yaml', + 'punctuation.support.type.property-name.yaml', + 'support.type.property-name.yaml', + ], + settings: { + foreground: '#8aadf4', + fontStyle: '', + }, + }, + { + name: 'JSON/YAML constants', + scope: ['constant.language.json', 'constant.language.yaml'], + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'YAML anchors', + scope: ['entity.name.type.anchor.yaml', 'variable.other.alias.yaml'], + settings: { + foreground: '#eed49f', + fontStyle: '', + }, + }, + { + name: 'TOML tables / ini groups', + scope: [ + 'support.type.property-name.table', + 'entity.name.section.group-title.ini', + ], + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'TOML dates', + scope: 'constant.other.time.datetime.offset.toml', + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'YAML anchor puctuation', + scope: [ + 'punctuation.definition.anchor.yaml', + 'punctuation.definition.alias.yaml', + ], + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'YAML triple dashes', + scope: 'entity.other.document.begin.yaml', + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'Markup Diff', + scope: 'markup.changed.diff', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Diff', + scope: [ + 'meta.diff.header.from-file', + 'meta.diff.header.to-file', + 'punctuation.definition.from-file.diff', + 'punctuation.definition.to-file.diff', + ], + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'Diff Inserted', + scope: 'markup.inserted.diff', + settings: { + foreground: '#a6da95', + }, + }, + { + name: 'Diff Deleted', + scope: 'markup.deleted.diff', + settings: { + foreground: '#ed8796', + }, + }, + { + name: 'dotenv left-hand side assignments', + scope: ['variable.other.env'], + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'dotenv reference to existing env variable', + scope: ['string.quoted variable.other.env'], + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'GDScript functions', + scope: 'support.function.builtin.gdscript', + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'GDScript constants', + scope: 'constant.language.gdscript', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Comment keywords', + scope: 'comment meta.annotation.go', + settings: { + foreground: '#ee99a0', + }, + }, + { + name: 'go:embed, go:build, etc.', + scope: 'comment meta.annotation.parameters.go', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Go constants (nil, true, false)', + scope: 'constant.language.go', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'GraphQL variables', + scope: 'variable.graphql', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'GraphQL aliases', + scope: 'string.unquoted.alias.graphql', + settings: { + foreground: '#f0c6c6', + }, + }, + { + name: 'GraphQL enum members', + scope: 'constant.character.enum.graphql', + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'GraphQL field in types', + scope: + 'meta.objectvalues.graphql constant.object.key.graphql string.unquoted.graphql', + settings: { + foreground: '#f0c6c6', + }, + }, + { + name: 'HTML/XML DOCTYPE as keyword', + scope: [ + 'keyword.other.doctype', + 'meta.tag.sgml.doctype punctuation.definition.tag', + 'meta.tag.metadata.doctype entity.name.tag', + 'meta.tag.metadata.doctype punctuation.definition.tag', + ], + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'HTML/XML-like <tags/>', + scope: ['entity.name.tag'], + settings: { + foreground: '#8aadf4', + fontStyle: '', + }, + }, + { + name: 'Special characters like &', + scope: [ + 'text.html constant.character.entity', + 'text.html constant.character.entity punctuation', + 'constant.character.entity.xml', + 'constant.character.entity.xml punctuation', + 'constant.character.entity.js.jsx', + 'constant.charactger.entity.js.jsx punctuation', + 'constant.character.entity.tsx', + 'constant.character.entity.tsx punctuation', + ], + settings: { + foreground: '#ed8796', + }, + }, + { + name: 'HTML/XML tag attribute values', + scope: ['entity.other.attribute-name'], + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'Components', + scope: [ + 'support.class.component', + 'support.class.component.jsx', + 'support.class.component.tsx', + 'support.class.component.vue', + ], + settings: { + foreground: '#f5bde6', + fontStyle: '', + }, + }, + { + name: 'Annotations', + scope: ['punctuation.definition.annotation', 'storage.type.annotation'], + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Java enums', + scope: 'constant.other.enum.java', + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Java imports', + scope: 'storage.modifier.import.java', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'Javadoc', + scope: + 'comment.block.javadoc.java keyword.other.documentation.javadoc.java', + settings: { + fontStyle: '', + }, + }, + { + name: 'Exported Variable', + scope: 'meta.export variable.other.readwrite.js', + settings: { + foreground: '#ee99a0', + }, + }, + { + name: 'JS/TS constants & properties', + scope: [ + 'variable.other.constant.js', + 'variable.other.constant.ts', + 'variable.other.property.js', + 'variable.other.property.ts', + ], + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'JSDoc; these are mainly params, so styled as such', + scope: [ + 'variable.other.jsdoc', + 'comment.block.documentation variable.other', + ], + settings: { + foreground: '#ee99a0', + fontStyle: '', + }, + }, + { + name: 'JSDoc keywords', + scope: 'storage.type.class.jsdoc', + settings: { + fontStyle: '', + }, + }, + { + scope: 'support.type.object.console.js', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'Node constants as keywords (module, etc.)', + scope: ['support.constant.node', 'support.type.object.module.js'], + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'implements as keyword', + scope: 'storage.modifier.implements', + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'Builtin types', + scope: [ + 'constant.language.null.js', + 'constant.language.null.ts', + 'constant.language.undefined.js', + 'constant.language.undefined.ts', + 'support.type.builtin.ts', + ], + settings: { + foreground: '#c6a0f6', + }, + }, + { + scope: 'variable.parameter.generic', + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'Arrow functions', + scope: [ + 'keyword.declaration.function.arrow.js', + 'storage.type.function.arrow.ts', + ], + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Decorator punctuations (decorators inherit from blue functions, instead of styleguide peach)', + scope: 'punctuation.decorator.ts', + settings: { + foreground: '#8aadf4', + fontStyle: 'italic', + }, + }, + { + name: 'Extra JS/TS keywords', + scope: [ + 'keyword.operator.expression.in.js', + 'keyword.operator.expression.in.ts', + 'keyword.operator.expression.infer.ts', + 'keyword.operator.expression.instanceof.js', + 'keyword.operator.expression.instanceof.ts', + 'keyword.operator.expression.is', + 'keyword.operator.expression.keyof.ts', + 'keyword.operator.expression.of.js', + 'keyword.operator.expression.of.ts', + 'keyword.operator.expression.typeof.ts', + ], + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'Julia macros', + scope: 'support.function.macro.julia', + settings: { + foreground: '#8bd5ca', + fontStyle: 'italic', + }, + }, + { + name: 'Julia language constants (true, false)', + scope: 'constant.language.julia', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Julia other constants (these seem to be arguments inside arrays)', + scope: 'constant.other.symbol.julia', + settings: { + foreground: '#ee99a0', + }, + }, + { + name: 'LaTeX preamble', + scope: 'text.tex keyword.control.preamble', + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'LaTeX be functions', + scope: 'text.tex support.function.be', + settings: { + foreground: '#91d7e3', + }, + }, + { + name: 'LaTeX math', + scope: 'constant.other.general.math.tex', + settings: { + foreground: '#f0c6c6', + }, + }, + { + name: 'Lua docstring keywords', + scope: + 'comment.line.double-dash.documentation.lua storage.type.annotation.lua', + settings: { + foreground: '#c6a0f6', + fontStyle: '', + }, + }, + { + name: 'Lua docstring variables', + scope: [ + 'comment.line.double-dash.documentation.lua entity.name.variable.lua', + 'comment.line.double-dash.documentation.lua variable.lua', + ], + settings: { + foreground: '#cad3f5', + }, + }, + { + scope: [ + 'heading.1.markdown punctuation.definition.heading.markdown', + 'heading.1.markdown', + 'heading.1.quarto punctuation.definition.heading.quarto', + 'heading.1.quarto', + 'markup.heading.atx.1.mdx', + 'markup.heading.atx.1.mdx punctuation.definition.heading.mdx', + 'markup.heading.setext.1.markdown', + 'markup.heading.heading-0.asciidoc', + ], + settings: { + foreground: '#ed8796', + }, + }, + { + scope: [ + 'heading.2.markdown punctuation.definition.heading.markdown', + 'heading.2.markdown', + 'heading.2.quarto punctuation.definition.heading.quarto', + 'heading.2.quarto', + 'markup.heading.atx.2.mdx', + 'markup.heading.atx.2.mdx punctuation.definition.heading.mdx', + 'markup.heading.setext.2.markdown', + 'markup.heading.heading-1.asciidoc', + ], + settings: { + foreground: '#f5a97f', + }, + }, + { + scope: [ + 'heading.3.markdown punctuation.definition.heading.markdown', + 'heading.3.markdown', + 'heading.3.quarto punctuation.definition.heading.quarto', + 'heading.3.quarto', + 'markup.heading.atx.3.mdx', + 'markup.heading.atx.3.mdx punctuation.definition.heading.mdx', + 'markup.heading.heading-2.asciidoc', + ], + settings: { + foreground: '#eed49f', + }, + }, + { + scope: [ + 'heading.4.markdown punctuation.definition.heading.markdown', + 'heading.4.markdown', + 'heading.4.quarto punctuation.definition.heading.quarto', + 'heading.4.quarto', + 'markup.heading.atx.4.mdx', + 'markup.heading.atx.4.mdx punctuation.definition.heading.mdx', + 'markup.heading.heading-3.asciidoc', + ], + settings: { + foreground: '#a6da95', + }, + }, + { + scope: [ + 'heading.5.markdown punctuation.definition.heading.markdown', + 'heading.5.markdown', + 'heading.5.quarto punctuation.definition.heading.quarto', + 'heading.5.quarto', + 'markup.heading.atx.5.mdx', + 'markup.heading.atx.5.mdx punctuation.definition.heading.mdx', + 'markup.heading.heading-4.asciidoc', + ], + settings: { + foreground: '#8aadf4', + }, + }, + { + scope: [ + 'heading.6.markdown punctuation.definition.heading.markdown', + 'heading.6.markdown', + 'heading.6.quarto punctuation.definition.heading.quarto', + 'heading.6.quarto', + 'markup.heading.atx.6.mdx', + 'markup.heading.atx.6.mdx punctuation.definition.heading.mdx', + 'markup.heading.heading-5.asciidoc', + ], + settings: { + foreground: '#c6a0f6', + }, + }, + { + scope: 'markup.bold', + settings: { + foreground: '#ed8796', + fontStyle: 'bold', + }, + }, + { + scope: 'markup.italic', + settings: { + foreground: '#ed8796', + fontStyle: 'italic', + }, + }, + { + scope: 'markup.strikethrough', + settings: { + foreground: '#a5adcb', + fontStyle: 'strikethrough', + }, + }, + { + name: 'Markdown auto links', + scope: ['punctuation.definition.link', 'markup.underline.link'], + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'Markdown links', + scope: [ + 'text.html.markdown punctuation.definition.link.title', + 'text.html.quarto punctuation.definition.link.title', + 'string.other.link.title.markdown', + 'string.other.link.title.quarto', + 'markup.link', + 'punctuation.definition.constant.markdown', + 'punctuation.definition.constant.quarto', + 'constant.other.reference.link.markdown', + 'constant.other.reference.link.quarto', + 'markup.substitution.attribute-reference', + ], + settings: { + foreground: '#b7bdf8', + }, + }, + { + name: 'Markdown code spans', + scope: [ + 'punctuation.definition.raw.markdown', + 'punctuation.definition.raw.quarto', + 'markup.inline.raw.string.markdown', + 'markup.inline.raw.string.quarto', + 'markup.raw.block.markdown', + 'markup.raw.block.quarto', + ], + settings: { + foreground: '#a6da95', + }, + }, + { + name: 'Markdown triple backtick language identifier', + scope: 'fenced_code.block.language', + settings: { + foreground: '#91d7e3', + }, + }, + { + name: 'Markdown triple backticks', + scope: [ + 'markup.fenced_code.block punctuation.definition', + 'markup.raw support.asciidoc', + ], + settings: { + foreground: '#939ab7', + }, + }, + { + name: 'Markdown quotes', + scope: ['markup.quote', 'punctuation.definition.quote.begin'], + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'Markdown separators', + scope: 'meta.separator.markdown', + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Markdown list bullets', + scope: [ + 'punctuation.definition.list.begin.markdown', + 'punctuation.definition.list.begin.quarto', + 'markup.list.bullet', + ], + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Quarto headings', + scope: 'markup.heading.quarto', + settings: { + fontStyle: 'bold', + }, + }, + { + name: 'Nix attribute names', + scope: [ + 'entity.other.attribute-name.multipart.nix', + 'entity.other.attribute-name.single.nix', + ], + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'Nix parameter names', + scope: 'variable.parameter.name.nix', + settings: { + foreground: '#cad3f5', + fontStyle: '', + }, + }, + { + name: 'Nix interpolated parameter names', + scope: 'meta.embedded variable.parameter.name.nix', + settings: { + foreground: '#b7bdf8', + fontStyle: '', + }, + }, + { + name: 'Nix paths', + scope: 'string.unquoted.path.nix', + settings: { + foreground: '#f5bde6', + fontStyle: '', + }, + }, + { + name: 'PHP Attributes', + scope: ['support.attribute.builtin', 'meta.attribute.php'], + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'PHP Parameters (needed for the leading dollar sign)', + scope: 'meta.function.parameters.php punctuation.definition.variable.php', + settings: { + foreground: '#ee99a0', + }, + }, + { + name: 'PHP Constants (null, __FILE__, etc.)', + scope: 'constant.language.php', + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'PHP functions', + scope: 'text.html.php support.function', + settings: { + foreground: '#91d7e3', + }, + }, + { + name: 'PHPdoc keywords', + scope: 'keyword.other.phpdoc.php', + settings: { + fontStyle: '', + }, + }, + { + name: 'Python argument functions reset to text, otherwise they inherit blue from function-call', + scope: [ + 'support.variable.magic.python', + 'meta.function-call.arguments.python', + ], + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'Python double underscore functions', + scope: ['support.function.magic.python'], + settings: { + foreground: '#91d7e3', + fontStyle: 'italic', + }, + }, + { + name: 'Python `self` keyword', + scope: [ + 'variable.parameter.function.language.special.self.python', + 'variable.language.special.self.python', + ], + settings: { + foreground: '#ed8796', + fontStyle: 'italic', + }, + }, + { + name: 'python keyword flow/logical (for ... in)', + scope: ['keyword.control.flow.python', 'keyword.operator.logical.python'], + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'python storage type', + scope: 'storage.type.function.python', + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'python function support', + scope: [ + 'support.token.decorator.python', + 'meta.function.decorator.identifier.python', + ], + settings: { + foreground: '#91d7e3', + }, + }, + { + name: 'python function calls', + scope: ['meta.function-call.python'], + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'python function decorators', + scope: [ + 'entity.name.function.decorator.python', + 'punctuation.definition.decorator.python', + ], + settings: { + foreground: '#f5a97f', + fontStyle: 'italic', + }, + }, + { + name: 'python placeholder reset to normal string', + scope: 'constant.character.format.placeholder.other.python', + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'Python exception & builtins such as exit()', + scope: [ + 'support.type.exception.python', + 'support.function.builtin.python', + ], + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'entity.name.type', + scope: ['support.type.python'], + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'python constants (True/False)', + scope: 'constant.language.python', + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'Arguments accessed later in the function body', + scope: ['meta.indexed-name.python', 'meta.item-access.python'], + settings: { + foreground: '#ee99a0', + fontStyle: 'italic', + }, + }, + { + name: 'Python f-strings/binary/unicode storage types', + scope: 'storage.type.string.python', + settings: { + foreground: '#a6da95', + fontStyle: 'italic', + }, + }, + { + name: 'Python type hints', + scope: 'meta.function.parameters.python', + settings: { + fontStyle: '', + }, + }, + { + name: 'Regex string begin/end in JS/TS', + scope: [ + 'string.regexp punctuation.definition.string.begin', + 'string.regexp punctuation.definition.string.end', + ], + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'Regex anchors (^, $)', + scope: 'keyword.control.anchor.regexp', + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'Regex regular string match', + scope: 'string.regexp.ts', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'Regex group parenthesis & backreference (\\1, \\2, \\3, ...)', + scope: [ + 'punctuation.definition.group.regexp', + 'keyword.other.back-reference.regexp', + ], + settings: { + foreground: '#a6da95', + }, + }, + { + name: 'Regex character class []', + scope: 'punctuation.definition.character-class.regexp', + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'Regex character classes (\\d, \\w, \\s)', + scope: 'constant.other.character-class.regexp', + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'Regex range', + scope: 'constant.other.character-class.range.regexp', + settings: { + foreground: '#f4dbd6', + }, + }, + { + name: 'Regex quantifier', + scope: 'keyword.operator.quantifier.regexp', + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Regex constant/numeric', + scope: 'constant.character.numeric.regexp', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Regex lookaheads, negative lookaheads, lookbehinds, negative lookbehinds', + scope: [ + 'punctuation.definition.group.no-capture.regexp', + 'meta.assertion.look-ahead.regexp', + 'meta.assertion.negative-look-ahead.regexp', + ], + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'Rust attribute', + scope: [ + 'meta.annotation.rust', + 'meta.annotation.rust punctuation', + 'meta.attribute.rust', + 'punctuation.definition.attribute.rust', + ], + settings: { + foreground: '#eed49f', + fontStyle: 'italic', + }, + }, + { + name: 'Rust attribute strings', + scope: [ + 'meta.attribute.rust string.quoted.double.rust', + 'meta.attribute.rust string.quoted.single.char.rust', + ], + settings: { + fontStyle: '', + }, + }, + { + name: 'Rust keyword', + scope: [ + 'entity.name.function.macro.rules.rust', + 'storage.type.module.rust', + 'storage.modifier.rust', + 'storage.type.struct.rust', + 'storage.type.enum.rust', + 'storage.type.trait.rust', + 'storage.type.union.rust', + 'storage.type.impl.rust', + 'storage.type.rust', + 'storage.type.function.rust', + 'storage.type.type.rust', + ], + settings: { + foreground: '#c6a0f6', + fontStyle: '', + }, + }, + { + name: 'Rust u/i32, u/i64, etc.', + scope: 'entity.name.type.numeric.rust', + settings: { + foreground: '#c6a0f6', + fontStyle: '', + }, + }, + { + name: 'Rust generic', + scope: 'meta.generic.rust', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Rust impl', + scope: 'entity.name.impl.rust', + settings: { + foreground: '#eed49f', + fontStyle: 'italic', + }, + }, + { + name: 'Rust module', + scope: 'entity.name.module.rust', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Rust trait', + scope: 'entity.name.trait.rust', + settings: { + foreground: '#eed49f', + fontStyle: 'italic', + }, + }, + { + name: 'Rust struct', + scope: 'storage.type.source.rust', + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'Rust union', + scope: 'entity.name.union.rust', + settings: { + foreground: '#eed49f', + }, + }, + { + name: 'Rust enum member', + scope: 'meta.enum.rust storage.type.source.rust', + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Rust macro', + scope: [ + 'support.macro.rust', + 'meta.macro.rust support.function.rust', + 'entity.name.function.macro.rust', + ], + settings: { + foreground: '#8aadf4', + fontStyle: 'italic', + }, + }, + { + name: 'Rust lifetime', + scope: ['storage.modifier.lifetime.rust', 'entity.name.type.lifetime'], + settings: { + foreground: '#8aadf4', + fontStyle: 'italic', + }, + }, + { + name: 'Rust string formatting', + scope: 'string.quoted.double.rust constant.other.placeholder.rust', + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'Rust return type generic', + scope: + 'meta.function.return-type.rust meta.generic.rust storage.type.rust', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'Rust functions', + scope: 'meta.function.call.rust', + settings: { + foreground: '#8aadf4', + }, + }, + { + name: 'Rust angle brackets', + scope: 'punctuation.brackets.angle.rust', + settings: { + foreground: '#91d7e3', + }, + }, + { + name: 'Rust constants', + scope: 'constant.other.caps.rust', + settings: { + foreground: '#f5a97f', + }, + }, + { + name: 'Rust function parameters', + scope: ['meta.function.definition.rust variable.other.rust'], + settings: { + foreground: '#ee99a0', + }, + }, + { + name: 'Rust closure variables', + scope: 'meta.function.call.rust variable.other.rust', + settings: { + foreground: '#cad3f5', + }, + }, + { + name: 'Rust self', + scope: 'variable.language.self.rust', + settings: { + foreground: '#ed8796', + }, + }, + { + name: 'Rust metavariable names', + scope: [ + 'variable.other.metavariable.name.rust', + 'meta.macro.metavariable.rust keyword.operator.macro.dollar.rust', + ], + settings: { + foreground: '#f5bde6', + }, + }, + { + name: 'Shell shebang', + scope: [ + 'comment.line.shebang', + 'comment.line.shebang punctuation.definition.comment', + 'comment.line.shebang', + 'punctuation.definition.comment.shebang.shell', + 'meta.shebang.shell', + ], + settings: { + foreground: '#f5bde6', + fontStyle: 'italic', + }, + }, + { + name: 'Shell shebang command', + scope: 'comment.line.shebang constant.language', + settings: { + foreground: '#8bd5ca', + fontStyle: 'italic', + }, + }, + { + name: 'Shell interpolated command', + scope: [ + 'meta.function-call.arguments.shell punctuation.definition.variable.shell', + 'meta.function-call.arguments.shell punctuation.section.interpolation', + 'meta.function-call.arguments.shell punctuation.definition.variable.shell', + 'meta.function-call.arguments.shell punctuation.section.interpolation', + ], + settings: { + foreground: '#ed8796', + }, + }, + { + name: 'Shell interpolated command variable', + scope: + 'meta.string meta.interpolation.parameter.shell variable.other.readwrite', + settings: { + foreground: '#f5a97f', + fontStyle: 'italic', + }, + }, + { + scope: [ + 'source.shell punctuation.section.interpolation', + 'punctuation.definition.evaluation.backticks.shell', + ], + settings: { + foreground: '#8bd5ca', + }, + }, + { + name: 'Shell EOF', + scope: 'entity.name.tag.heredoc.shell', + settings: { + foreground: '#c6a0f6', + }, + }, + { + name: 'Shell quoted variable', + scope: 'string.quoted.double.shell variable.other.normal.shell', + settings: { + foreground: '#cad3f5', + }, + }, + ], +} + +// export default theme +export default catppuccinMacchiato diff --git a/src/components/icons/BellIcon.tsx b/src/components/icons/BellIcon.tsx index 09062dd9b..1c0c2291c 100644 --- a/src/components/icons/BellIcon.tsx +++ b/src/components/icons/BellIcon.tsx @@ -1,4 +1,4 @@ -export function BellIcon(props) { +export function BellIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/BoltIcon.tsx b/src/components/icons/BoltIcon.tsx index 1278a7fe8..308d997cc 100644 --- a/src/components/icons/BoltIcon.tsx +++ b/src/components/icons/BoltIcon.tsx @@ -1,4 +1,4 @@ -export function BoltIcon(props) { +export function BoltIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/BookIcon.tsx b/src/components/icons/BookIcon.tsx index d560f41c8..9f7709bc3 100644 --- a/src/components/icons/BookIcon.tsx +++ b/src/components/icons/BookIcon.tsx @@ -1,4 +1,4 @@ -export function BookIcon(props) { +export function BookIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/CalendarIcon.tsx b/src/components/icons/CalendarIcon.tsx index 8d0a57c8d..e9d374867 100644 --- a/src/components/icons/CalendarIcon.tsx +++ b/src/components/icons/CalendarIcon.tsx @@ -1,4 +1,4 @@ -export function CalendarIcon(props) { +export function CalendarIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/CartIcon.tsx b/src/components/icons/CartIcon.tsx index e42462467..30c9438f7 100644 --- a/src/components/icons/CartIcon.tsx +++ b/src/components/icons/CartIcon.tsx @@ -1,4 +1,4 @@ -export function CartIcon(props) { +export function CartIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/ChatBubbleIcon.tsx b/src/components/icons/ChatBubbleIcon.tsx index b929ec643..418427b05 100644 --- a/src/components/icons/ChatBubbleIcon.tsx +++ b/src/components/icons/ChatBubbleIcon.tsx @@ -1,4 +1,4 @@ -export function ChatBubbleIcon(props) { +export function ChatBubbleIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/CheckIcon.tsx b/src/components/icons/CheckIcon.tsx index 33d2b249a..b9433644d 100644 --- a/src/components/icons/CheckIcon.tsx +++ b/src/components/icons/CheckIcon.tsx @@ -1,4 +1,4 @@ -export function CheckIcon(props) { +export function CheckIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/ChevronRightLeftIcon.tsx b/src/components/icons/ChevronRightLeftIcon.tsx index 2dbaa18c4..281c9de52 100644 --- a/src/components/icons/ChevronRightLeftIcon.tsx +++ b/src/components/icons/ChevronRightLeftIcon.tsx @@ -1,4 +1,6 @@ -export function ChevronRightLeftIcon(props) { +export function ChevronRightLeftIcon( + props: React.ComponentPropsWithoutRef<'svg'>, +) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/ClipboardIcon.tsx b/src/components/icons/ClipboardIcon.tsx index 9c8c55cee..33d997b5b 100644 --- a/src/components/icons/ClipboardIcon.tsx +++ b/src/components/icons/ClipboardIcon.tsx @@ -1,4 +1,4 @@ -export function ClipboardIcon(props) { +export function ClipboardIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/CogIcon.tsx b/src/components/icons/CogIcon.tsx index 57023fc7c..cedecf542 100644 --- a/src/components/icons/CogIcon.tsx +++ b/src/components/icons/CogIcon.tsx @@ -1,4 +1,4 @@ -export function CogIcon(props) { +export function CogIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/CopyIcon.tsx b/src/components/icons/CopyIcon.tsx index aadede17d..0eedaaa4c 100644 --- a/src/components/icons/CopyIcon.tsx +++ b/src/components/icons/CopyIcon.tsx @@ -1,4 +1,4 @@ -export function CopyIcon(props) { +export function CopyIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/DocumentIcon.tsx b/src/components/icons/DocumentIcon.tsx index b576db048..8f83d2094 100644 --- a/src/components/icons/DocumentIcon.tsx +++ b/src/components/icons/DocumentIcon.tsx @@ -1,4 +1,4 @@ -export function DocumentIcon(props) { +export function DocumentIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/EnvelopeIcon.tsx b/src/components/icons/EnvelopeIcon.tsx index 17ab4fa95..de57e4c47 100644 --- a/src/components/icons/EnvelopeIcon.tsx +++ b/src/components/icons/EnvelopeIcon.tsx @@ -1,4 +1,4 @@ -export function EnvelopeIcon(props) { +export function EnvelopeIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/FaceSmileIcon.tsx b/src/components/icons/FaceSmileIcon.tsx index 4c01755a3..7c855a63e 100644 --- a/src/components/icons/FaceSmileIcon.tsx +++ b/src/components/icons/FaceSmileIcon.tsx @@ -1,4 +1,4 @@ -export function FaceSmileIcon(props) { +export function FaceSmileIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/FolderIcon.tsx b/src/components/icons/FolderIcon.tsx index c59b6e0ac..050c77bb7 100644 --- a/src/components/icons/FolderIcon.tsx +++ b/src/components/icons/FolderIcon.tsx @@ -1,4 +1,4 @@ -export function FolderIcon(props) { +export function FolderIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/GitHubIcon.tsx b/src/components/icons/GitHubIcon.tsx index d212759da..231a144eb 100644 --- a/src/components/icons/GitHubIcon.tsx +++ b/src/components/icons/GitHubIcon.tsx @@ -1,4 +1,4 @@ -export function GitHubIcon(props) { +export function GitHubIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/LinkIcon.tsx b/src/components/icons/LinkIcon.tsx index 2dace2318..f77d6184a 100644 --- a/src/components/icons/LinkIcon.tsx +++ b/src/components/icons/LinkIcon.tsx @@ -1,4 +1,4 @@ -export function LinkIcon(props) { +export function LinkIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/ListIcon.tsx b/src/components/icons/ListIcon.tsx index ea45c0a6d..69354ec06 100644 --- a/src/components/icons/ListIcon.tsx +++ b/src/components/icons/ListIcon.tsx @@ -1,4 +1,4 @@ -export function ListIcon(props) { +export function ListIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/MagnifyingGlassIcon.tsx b/src/components/icons/MagnifyingGlassIcon.tsx index 309359c29..5e219f634 100644 --- a/src/components/icons/MagnifyingGlassIcon.tsx +++ b/src/components/icons/MagnifyingGlassIcon.tsx @@ -1,4 +1,6 @@ -export function MagnifyingGlassIcon(props) { +export function MagnifyingGlassIcon( + props: React.ComponentPropsWithoutRef<'svg'>, +) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path strokeWidth="0" d="M2.5 8.5a6 6 0 1 1 12 0 6 6 0 0 1-12 0Z" /> diff --git a/src/components/icons/MapPinIcon.tsx b/src/components/icons/MapPinIcon.tsx index b581a6d68..6070adb13 100644 --- a/src/components/icons/MapPinIcon.tsx +++ b/src/components/icons/MapPinIcon.tsx @@ -1,4 +1,4 @@ -export function MapPinIcon(props) { +export function MapPinIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/PackageIcon.tsx b/src/components/icons/PackageIcon.tsx index cb0bc98d2..6bd9225f5 100644 --- a/src/components/icons/PackageIcon.tsx +++ b/src/components/icons/PackageIcon.tsx @@ -1,4 +1,4 @@ -export function PackageIcon(props) { +export function PackageIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/PaperAirplaneIcon.tsx b/src/components/icons/PaperAirplaneIcon.tsx index 6f96ea84b..12c29b915 100644 --- a/src/components/icons/PaperAirplaneIcon.tsx +++ b/src/components/icons/PaperAirplaneIcon.tsx @@ -1,4 +1,6 @@ -export function PaperAirplaneIcon(props) { +export function PaperAirplaneIcon( + props: React.ComponentPropsWithoutRef<'svg'>, +) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/PaperClipIcon.tsx b/src/components/icons/PaperClipIcon.tsx index cdd72437a..db51c7f70 100644 --- a/src/components/icons/PaperClipIcon.tsx +++ b/src/components/icons/PaperClipIcon.tsx @@ -1,4 +1,4 @@ -export function PaperClipIcon(props) { +export function PaperClipIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/ShapesIcon.tsx b/src/components/icons/ShapesIcon.tsx index 5dd29fd0d..ac57a52ca 100644 --- a/src/components/icons/ShapesIcon.tsx +++ b/src/components/icons/ShapesIcon.tsx @@ -1,4 +1,4 @@ -export function ShapesIcon(props) { +export function ShapesIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/ShirtIcon.tsx b/src/components/icons/ShirtIcon.tsx index 30c67b920..f8cdfd508 100644 --- a/src/components/icons/ShirtIcon.tsx +++ b/src/components/icons/ShirtIcon.tsx @@ -1,4 +1,4 @@ -export function ShirtIcon(props) { +export function ShirtIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/SquaresPlusIcon.tsx b/src/components/icons/SquaresPlusIcon.tsx index 39a507a4e..0005f59d5 100644 --- a/src/components/icons/SquaresPlusIcon.tsx +++ b/src/components/icons/SquaresPlusIcon.tsx @@ -1,4 +1,4 @@ -export function SquaresPlusIcon(props) { +export function SquaresPlusIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/TagIcon.tsx b/src/components/icons/TagIcon.tsx index c7e57b038..f36024143 100644 --- a/src/components/icons/TagIcon.tsx +++ b/src/components/icons/TagIcon.tsx @@ -1,4 +1,4 @@ -export function TagIcon(props) { +export function TagIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/UserIcon.tsx b/src/components/icons/UserIcon.tsx index 350e3c42d..78bb8f617 100644 --- a/src/components/icons/UserIcon.tsx +++ b/src/components/icons/UserIcon.tsx @@ -1,4 +1,4 @@ -export function UserIcon(props) { +export function UserIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/icons/UsersIcon.tsx b/src/components/icons/UsersIcon.tsx index 68ef13120..aa7d13b3d 100644 --- a/src/components/icons/UsersIcon.tsx +++ b/src/components/icons/UsersIcon.tsx @@ -1,4 +1,4 @@ -export function UsersIcon(props) { +export function UsersIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 20 20" aria-hidden="true" {...props}> <path diff --git a/src/components/layout/BaseLayout.tsx b/src/components/layout/BaseLayout.tsx new file mode 100644 index 000000000..205ea7b4c --- /dev/null +++ b/src/components/layout/BaseLayout.tsx @@ -0,0 +1,28 @@ +import Link from 'next/link' + +import { Footer } from '@/components/Footer' +import { Header } from '@/components/layout/Header' +import { Logo } from '@/components/Logo' +import { Navigation } from '@/components/nav/Navigation' + +const experimentalRuntimes = ['go', 'dart'] + +const v0Runtimes = ['csharp', 'jvm'] + +export function BaseLayout({ children }: React.PropsWithChildren) { + return ( + <div className="w-full lg:ml-72 xl:ml-80"> + <header className="contents lg:pointer-events-none lg:fixed lg:inset-0 lg:z-40 lg:flex"> + <div className="contents lg:pointer-events-auto lg:mt-[calc(var(--header-height))] lg:block lg:w-72 lg:overflow-y-auto lg:border-r lg:border-zinc-900/10 lg:px-6 lg:pb-8 lg:pt-4 lg:dark:border-white/10 xl:w-80"> + <Header /> + + <Navigation className="hidden lg:block" /> + </div> + </header> + <div className="relative px-4 pt-14 sm:px-6 lg:px-8"> + {children} + <Footer /> + </div> + </div> + ) +} diff --git a/src/components/layout/DocToC.tsx b/src/components/layout/DocToC.tsx new file mode 100644 index 000000000..4fe771cfb --- /dev/null +++ b/src/components/layout/DocToC.tsx @@ -0,0 +1,72 @@ +'use client' + +import type { Doc } from '@/content' +import React, { useRef } from 'react' +import { Badge } from '../ui/badge' +import Link from 'next/link' +import { FaFacebook, FaFilePdf, FaLinkedin } from 'react-icons/fa' +import { DocTracingBeam } from './DocTracingBeam' +import { BASE_URL } from '@/lib/constants' +import { title } from 'radash' +import { Button } from '../ui/button' +import { GitHubIcon } from '../icons/GitHubIcon' + +interface Props { + doc: Doc + articleRef?: React.RefObject<HTMLDivElement> +} + +interface Toc { + url: string + value: string + depth: number +} + +const DocToC: React.FC<Props> = ({ doc }) => { + const articleRef = useRef<HTMLDivElement>(null) + + return ( + <div className="h-full min-w-52" ref={articleRef}> + <aside className="sticky top-[calc(var(--header-height)+1px+2rem)] hidden max-h-[calc(100vh-var(--header-height)-3rem)] min-w-40 space-y-6 md:block"> + {doc.toc.length ? ( + <div className="relative flex flex-col"> + <p className="mb-2 font-mono text-sm uppercase dark:text-zinc-300"> + On this page + </p> + <DocTracingBeam targetRef={articleRef}> + <ol className="flex flex-col gap-y-1 pl-4 text-sm font-medium"> + {doc.toc.map((item: Toc, i: number) => { + return ( + <li key={item.url + i}> + <Link + href={item.url} + className="text-2xs text-muted-foreground transition-colors hover:text-zinc-900 dark:hover:text-zinc-200" + > + {item.value} + </Link> + </li> + ) + })} + </ol> + </DocTracingBeam> + </div> + ) : null} + <div> + <Button asChild variant="unstyled"> + <a + href={doc.editUrl} + target="_blank" + rel="noopener noreferrer" + className="group flex items-center gap-x-2 text-xs dark:text-zinc-300 dark:hover:text-white" + > + <GitHubIcon className="h-5 w-5 fill-zinc-800 transition group-hover:fill-zinc-900 dark:fill-zinc-300 dark:group-hover:fill-white" /> + Edit this page on GitHub + </a> + </Button> + </div> + </aside> + </div> + ) +} + +export default DocToC diff --git a/src/components/layout/DocTracingBeam.tsx b/src/components/layout/DocTracingBeam.tsx new file mode 100644 index 000000000..7ccf3ca41 --- /dev/null +++ b/src/components/layout/DocTracingBeam.tsx @@ -0,0 +1,101 @@ +'use client' + +import React, { useEffect, useRef, useState } from 'react' +import { motion, useTransform, useScroll, useSpring } from 'framer-motion' +import { cn } from '@/lib/utils' + +// TODO this should set the height based off the h2 offset heights, not current scroll progress +export const DocTracingBeam = ({ + children, + className, + targetRef, +}: { + children: React.ReactNode + className?: string + targetRef: React.RefObject<HTMLDivElement> +}) => { + const { scrollYProgress } = useScroll({ + target: targetRef, + offset: ['start start', 'end end'], + }) + + const contentRef = useRef<HTMLDivElement>(null) + const [svgHeight, setSvgHeight] = useState(0) + + useEffect(() => { + if (contentRef.current) { + setSvgHeight(contentRef.current.offsetHeight) + } + }, []) + + const y1 = useSpring( + useTransform(scrollYProgress, [0, 0.8], [0, svgHeight]), + { + stiffness: 500, + damping: 90, + }, + ) + const y2 = useSpring( + useTransform(scrollYProgress, [0, 1], [0, svgHeight - 210]), + { + stiffness: 500, + damping: 90, + }, + ) + + return ( + <motion.div + className={cn('relative mx-auto h-full w-full max-w-4xl', className)} + > + <div className="absolute -left-4 top-1 mb-2 ml-1 md:-left-16"> + <svg + viewBox={`0 0 20 ${svgHeight}`} + width="20" + height={svgHeight} // Set the SVG height + className="ml-10 block" + aria-hidden="true" + > + <motion.path + d={`M 1 0V -36 l 18 24 V ${svgHeight * 0.98}`} + fill="none" + className={`stroke-zinc-400 dark:stroke-zinc-200`} + strokeOpacity="0.16" + transition={{ + duration: 10, + }} + ></motion.path> + <motion.path + d={`M 1 0V -36 l 18 24 V ${svgHeight * 0.98}`} + fill="none" + stroke="url(#gradient)" + strokeWidth="1.25" + className="motion-reduce:hidden" + transition={{ + duration: 10, + }} + ></motion.path> + <defs> + <motion.linearGradient + id="gradient" + gradientUnits="userSpaceOnUse" + x1="0" + x2="0" + y1={y1} // set y1 for gradient + y2={y2} // set y2 for gradient + > + <stop stopColor="var(--primary-500)" stopOpacity="0"></stop> + <stop stopColor="var(--primary-500)"></stop> + <stop offset="0.325" stopColor="var(--secondary-700)"></stop> + <stop + offset="1" + stopColor="var(--secondary-500)" + stopOpacity="0" + ></stop> + </motion.linearGradient> + </defs> + </svg> + </div> + <div ref={contentRef}>{children}</div> + </motion.div> + ) +} diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx new file mode 100644 index 000000000..59b83b96d --- /dev/null +++ b/src/components/layout/Header.tsx @@ -0,0 +1,115 @@ +'use client' + +import { ComponentPropsWithoutRef, forwardRef } from 'react' +import Link from 'next/link' +import clsx from 'clsx' +import { motion, useScroll, useTransform } from 'framer-motion' + +import { Logo } from '@/components/Logo' +import { + MobileNavigation, + useIsInsideMobileNavigation, +} from '@/components/nav/MobileNavigation' +import { useMobileNavigationStore } from '@/components/nav/MobileNavigation' +import { Search } from '@/components/layout/Search' +import { ThemeToggle } from '@/components/ThemeToggle' +import { cn } from '@/lib/utils' +import GitHubStarCount from '../GitHubStarCount' +import { GitHubIcon } from '../icons/GitHubIcon' + +function TopLevelNavItem({ + className, + ...props +}: ComponentPropsWithoutRef<typeof Link>) { + return ( + <li> + <Link + {...props} + className={cn( + 'text-sm font-semibold leading-5 text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white', + className, + )} + /> + </li> + ) +} + +export const Header = forwardRef< + React.ElementRef<'div'>, + React.ComponentPropsWithoutRef<typeof motion.div> +>(function Header({ className, ...props }, ref) { + let { isOpen: mobileNavIsOpen } = useMobileNavigationStore() + let isInsideMobileNavigation = useIsInsideMobileNavigation() + + let { scrollY } = useScroll() + let bgOpacityLight = useTransform(scrollY, [0, 72], [0.5, 0.9]) + let bgOpacityDark = useTransform(scrollY, [0, 72], [0.2, 0.8]) + + return ( + <motion.div + ref={ref} + className={clsx( + className, + 'fixed inset-x-0 top-0 z-50 flex h-14 items-center justify-between gap-12 px-4 transition sm:px-6 lg:z-30 lg:px-8', + !isInsideMobileNavigation && 'backdrop-blur-sm dark:backdrop-blur', + isInsideMobileNavigation + ? 'bg-white dark:bg-background' + : 'bg-white/[var(--bg-opacity-light)] dark:bg-background/[var(--bg-opacity-dark)]', + )} + style={ + { + '--bg-opacity-light': bgOpacityLight, + '--bg-opacity-dark': bgOpacityDark, + } as any + } + > + <div + className={clsx( + 'absolute inset-x-0 top-full h-px transition', + (isInsideMobileNavigation || !mobileNavIsOpen) && + 'bg-gray-800/7.5 dark:bg-white/7.5', + )} + /> + <Link href="/" aria-label="Home" className="hidden lg:block"> + <Logo className="h-6" /> + </Link> + <div className="hidden lg:block"> + <Search /> + </div> + <div className="flex items-center gap-5 lg:hidden"> + <MobileNavigation /> + <Link href="/" aria-label="Home"> + <Logo className="h-6" /> + </Link> + </div> + <div className="flex items-center gap-5"> + <nav className="hidden md:block"> + <ul role="list" className="flex items-center gap-8"> + <TopLevelNavItem + href={'https://nitric.io'} + target="_blank" + rel="noreferrer noopener" + > + Nitric.io + </TopLevelNavItem> + + <TopLevelNavItem + className="group flex items-center" + rel="noreferrer noopener" + href="https://github.com/nitrictech/nitric" + > + <GitHubIcon className="dark:fill-gray h-5 w-5 fill-current" /> + <GitHubStarCount className="ml-2 text-inherit" /> + </TopLevelNavItem> + </ul> + </nav> + <div className="flex items-center gap-4"> + <div className="lg:hidden"> + <Search /> + </div> + <ThemeToggle /> + </div> + </div> + </motion.div> + ) +}) diff --git a/src/components/Search.tsx b/src/components/layout/Search.tsx similarity index 78% rename from src/components/Search.tsx rename to src/components/layout/Search.tsx index ad88e42a9..d06c66aac 100644 --- a/src/components/Search.tsx +++ b/src/components/layout/Search.tsx @@ -1,8 +1,10 @@ +'use client' + import { useCallback, useEffect, useState } from 'react' import { createPortal } from 'react-dom' import Link from 'next/link' import { DocSearchModal, useDocSearchKeyboardEvents } from '@docsearch/react' -import { useRouter } from 'next/router' +import { useRouter } from 'next/navigation' const docSearchConfig = { appId: process.env.NEXT_PUBLIC_DOCSEARCH_APP_ID || '', @@ -19,11 +21,11 @@ const cleanUrl = (href: string) => { return url.href.replace(url.origin, '').replace(/^\/docs/, '') } -function Hit({ hit, children }) { +function Hit({ hit, children }: { hit: any; children: React.ReactNode }) { return <Link href={cleanUrl(hit.url)}>{children}</Link> } -function SearchIcon(props) { +function SearchIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg aria-hidden="true" viewBox="0 0 20 20" {...props}> <path d="M16.293 17.707a1 1 0 0 0 1.414-1.414l-1.414 1.414ZM9 14a5 5 0 0 1-5-5H2a7 7 0 0 0 7 7v-2ZM4 9a5 5 0 0 1 5-5V2a7 7 0 0 0-7 7h2Zm5-5a5 5 0 0 1 5 5h2a7 7 0 0 0-7-7v2Zm8.707 12.293-3.757-3.757-1.414 1.414 3.757 3.757 1.414-1.414ZM14 9a4.98 4.98 0 0 1-1.464 3.536l1.414 1.414A6.98 6.98 0 0 0 16 9h-2Zm-1.464 3.536A4.98 4.98 0 0 1 9 14v2a6.98 6.98 0 0 0 4.95-2.05l-1.414-1.414Z" /> @@ -48,7 +50,7 @@ export function Search() { useEffect(() => { setModifierKey( - /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform) ? '⌘' : 'Ctrl ' + /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform) ? '⌘' : 'Ctrl ', ) }, []) @@ -56,15 +58,15 @@ export function Search() { <> <button type="button" - className="lg:w-92 group hidden h-6 w-6 items-center justify-center sm:justify-start md:h-auto md:w-80 md:flex-none md:rounded-lg md:py-1 md:pl-4 md:pr-3.5 md:text-sm md:ring-1 md:ring-slate-200 md:hover:ring-slate-300 dark:md:bg-gray-700/75 dark:md:ring-inset dark:md:ring-white/5 dark:md:hover:bg-gray-700/40 dark:md:hover:ring-slate-500 lg:flex" + className="lg:w-92 group hidden h-6 w-6 items-center justify-center sm:justify-start md:h-auto md:w-80 md:flex-none md:rounded-lg md:py-1 md:pl-4 md:pr-3.5 md:text-sm md:ring-1 md:ring-zinc-200 md:hover:ring-zinc-300 dark:md:bg-zinc-800/70 dark:md:ring-inset dark:md:ring-white/5 dark:md:hover:bg-zinc-700/40 dark:md:hover:ring-zinc-500 lg:flex" onClick={onOpen} > - <SearchIcon className="h-5 w-5 flex-none fill-gray-400 group-hover:fill-gray-500 dark:fill-gray-500 md:group-hover:fill-slate-400" /> - <span className="sr-only transition-colors dark:group-hover:text-white md:not-sr-only md:ml-2 md:text-gray-500 md:dark:text-zinc-400"> - Search docs + <SearchIcon className="h-5 w-5 flex-none fill-zinc-400 group-hover:fill-zinc-500 dark:fill-zinc-500 md:group-hover:fill-zinc-400" /> + <span className="sr-only transition-colors dark:group-hover:text-white md:not-sr-only md:ml-2 md:text-zinc-500 md:dark:text-zinc-400"> + Search documentation </span> {modifierKey && ( - <kbd className="ml-auto hidden font-medium text-slate-400 dark:text-slate-500 md:block"> + <kbd className="ml-auto hidden font-medium text-zinc-400 dark:text-zinc-500 md:block"> <kbd className="font-sans">{modifierKey}</kbd> <kbd className="font-sans">K</kbd> </kbd> @@ -76,7 +78,7 @@ export function Search() { onClick={onOpen} > <span className="sr-only">Search Docs</span> - <SearchIcon className="h-5 w-5 flex-none fill-slate-400 group-hover:fill-slate-500 dark:fill-slate-500 md:group-hover:fill-slate-400" /> + <SearchIcon className="h-5 w-5 flex-none fill-zinc-400 group-hover:fill-zinc-500 dark:fill-zinc-500 md:group-hover:fill-zinc-400" /> </button> {isOpen && createPortal( @@ -87,7 +89,7 @@ export function Search() { hitComponent={Hit} getMissingResultsUrl={({ query }: { query: string }) => `https://github.com/nitrictech/docs/issues/new?title=Missing+results+for+query+%22${encodeURIComponent( - query + query, )}%22` } navigator={{ @@ -102,7 +104,7 @@ export function Search() { })) }} />, - document.body + document.body, )} </> ) diff --git a/src/components/mdx.tsx b/src/components/mdx.tsx index ce8ed9aba..48001fb52 100644 --- a/src/components/mdx.tsx +++ b/src/components/mdx.tsx @@ -1,23 +1,60 @@ import Link from 'next/link' import clsx from 'clsx' +//import { Table } from '@/components/ui/table' +import { Feedback } from '@/components/Feedback' -import { Heading } from '@/components/Heading' -import { Button } from '@/components/Button' -import { useState } from 'react' -import { MinusCircleIcon, PlusCircleIcon } from '@heroicons/react/24/outline' -import { Tag } from '@/components/Tag' +import { Prose } from '@/components/Prose' -export const a = Link -export { Button } from '@/components/Button' -export { CodeGroup, Code as code, Pre as pre } from '@/components/Code' -export { GuidesGrid, Guide } from '@/components/GuidesGrid' -export { Tag } from '@/components/Tag' +// export { +// TableHead as th, +// TableHeader as thead, +// TableRow as tr, +// TableBody as tbody, +// TableCell as td, +// TableFooter as tfoot, +// } from './ui/table' -export const h2 = function H2(props) { - return <Heading level={2} {...props} /> +// export function wrapper({ children }: { children: React.ReactNode }) { +// return ( +// <article className="flex h-full flex-col pb-10 pt-16"> +// <Prose className="flex-auto">{children}</Prose> +// <footer className="mx-auto mt-16 w-full max-w-2xl lg:max-w-5xl"> +// <Feedback /> +// </footer> +// </article> +// ) +// } + +// export const table = (props: React.ComponentPropsWithoutRef<typeof Table>) => ( +// <Table {...props} className="text-base" /> +// ) + +export function a({ + href, + children, + ...props +}: React.ComponentPropsWithoutRef<typeof Link>) { + const isExternal = href.toString().startsWith('http') + + return ( + <Link + href={href} + target={isExternal ? '_blank' : undefined} + rel={isExternal ? 'noopener noreferrer' : undefined} + {...props} + > + {children} + </Link> + ) } -function InfoIcon(props) { +export { Code } from './code/Code' + +export { CodeWithTabs } from './code/CodeWithTabs' + +export { CodeSwitcher } from './code/CodeSwitcher' + +function InfoIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( <svg viewBox="0 0 16 16" aria-hidden="true" {...props}> <circle cx="8" cy="8" r="8" strokeWidth="0" /> @@ -33,9 +70,9 @@ function InfoIcon(props) { ) } -export function Note({ children }) { +export function Note({ children }: { children: React.ReactNode }) { return ( - <div className="my-6 flex gap-2.5 rounded-2xl border border-primary-500/20 bg-primary-50/50 p-4 leading-6 text-primary-900 dark:border-primary-500/30 dark:bg-primary-500/5 dark:text-primary-200 dark:[--tw-prose-links-hover:theme(colors.primary.300)] dark:[--tw-prose-links:theme(colors.white)]"> + <div className="my-6 flex gap-2.5 rounded-2xl border border-primary-500/20 bg-primary-50/50 p-4 leading-6 text-primary-900 dark:border-primary-500/30 dark:bg-primary-500/5 dark:text-primary-200"> <InfoIcon className="mt-1 h-4 w-4 flex-none fill-primary-500 stroke-white dark:fill-primary-200/20 dark:stroke-primary-200" /> <div className="[&>:first-child]:mt-0 [&>:last-child]:mb-0"> {children} @@ -44,7 +81,7 @@ export function Note({ children }) { ) } -export function Row({ children }) { +export function Row({ children }: { children: React.ReactNode }) { return ( <div className="grid grid-cols-1 items-start gap-x-16 gap-y-10 xl:max-w-none xl:grid-cols-2"> {children} @@ -52,12 +89,18 @@ export function Row({ children }) { ) } -export function Col({ children, sticky = false }) { +export function Col({ + children, + sticky = false, +}: { + children: React.ReactNode + sticky?: boolean +}) { return ( <div className={clsx( '[&>:first-child]:mt-0 [&>:last-child]:mb-0', - sticky && 'xl:sticky xl:top-24' + sticky && 'xl:sticky xl:top-24', )} > {children} @@ -65,47 +108,28 @@ export function Col({ children, sticky = false }) { ) } -export function Properties({ children, nested }) { - const [open, setOpen] = useState(false) - - const content = ( - <ul - role="list" - className="m-0 max-w-[calc(theme(maxWidth.lg)-theme(spacing.8))] list-none divide-y divide-zinc-900/5 p-0 dark:divide-white/5" - > - {children} - </ul> - ) - - return nested ? ( - <li> - <Button - onClick={() => setOpen(!open)} - variant="outline" - className="mt-4 flex items-center gap-2" - > - {open ? ( - <MinusCircleIcon className="mt-0.5 h-5 w-5" /> - ) : ( - <PlusCircleIcon className="mt-0.5 h-5 w-5" /> - )} - {open ? 'Hide' : 'Show'} accepted values - </Button> - <div - className={clsx( - 'mt-4 rounded-lg border p-4 dark:border-zinc-600', - !open && 'sr-only' - )} +export function Properties({ children }: { children: React.ReactNode }) { + return ( + <div className="my-6"> + <ul + role="list" + className="m-0 max-w-[calc(theme(maxWidth.lg)-theme(spacing.8))] list-none divide-y divide-zinc-900/5 p-0 dark:divide-white/5" > - {content} - </div> - </li> - ) : ( - <div className={'my-6'}>{content}</div> + {children} + </ul> + </div> ) } -export function Property({ name, type, children, required }) { +export function Property({ + name, + children, + type, +}: { + name: string + children: React.ReactNode + type?: string +}) { return ( <li className="m-0 px-0 py-4 first:pt-0 last:pb-0"> <dl className="m-0 flex flex-wrap items-center gap-x-3 gap-y-2"> @@ -113,22 +137,14 @@ export function Property({ name, type, children, required }) { <dd> <code>{name}</code> </dd> - <dt className="sr-only">{required ? 'Required' : 'Optional'}</dt> - <dd> - {required ? ( - <Tag color="amber" className="rounded-md py-0.5 uppercase"> - Required - </Tag> - ) : ( - <span className="mt-0.5 font-mono text-xs text-zinc-400 dark:text-zinc-500"> - Optional - </span> - )} - </dd> - <dt className="sr-only">Type</dt> - <dd className="mt-0.5 flex font-mono text-xs text-zinc-400 dark:text-zinc-500"> - {type} - </dd> + {type && ( + <> + <dt className="sr-only">Type</dt> + <dd className="font-mono text-xs text-zinc-400 dark:text-zinc-500"> + {type} + </dd> + </> + )} <dt className="sr-only">Description</dt> <dd className="w-full flex-none [&>:first-child]:mt-0 [&>:last-child]:mb-0"> {children} @@ -137,3 +153,13 @@ export function Property({ name, type, children, required }) { </li> ) } + +export { InstallNitric } from '@/components/InstallNitric' + +export { HomeHeader } from '@/components/HomeHeader' + +export { ShowIfLang } from '@/components/ShowIfLang' + +export { Libraries } from '@/components/Libraries' + +export { ImportCode } from '@/components/code/ImportCode' diff --git a/src/components/nav/CollapsibleNavItem.tsx b/src/components/nav/CollapsibleNavItem.tsx new file mode 100644 index 000000000..a50f732ea --- /dev/null +++ b/src/components/nav/CollapsibleNavItem.tsx @@ -0,0 +1,88 @@ +'use client' + +import React from 'react' +import { + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from '../ui/collapsible' +import { ChevronDownIcon } from '@heroicons/react/24/outline' +import { cn } from '@/lib/utils' +import { NavLink } from './NavLink' +import { usePathname } from 'next/navigation' +import { Button } from '../ui/button' +import { NavigationGroup } from './NavigationGroup' +import { NavGroup } from '@/config/types' + +interface Props { + group: NavGroup + className?: string +} + +const CollapsibleNavItem: React.FC<Props> = ({ group, className }) => { + const pathname = usePathname() + + const { title, items, icon: Icon } = group + + const isActive = items.some( + (link) => 'href' in link && link.href === pathname, + ) + const [isOpen, setIsOpen] = React.useState(isActive) + + return ( + <Collapsible + open={isOpen} + onOpenChange={setIsOpen} + className={cn('space-y-2 pl-2', className)} + > + <CollapsibleTrigger asChild> + <Button + variant="link" + className={cn( + 'flex w-full justify-between gap-2 py-1 pl-0 pr-3 text-sm transition hover:no-underline', + isOpen + ? 'text-zinc-900 dark:text-white' + : 'text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white', + )} + > + <div className="flex items-center"> + {Icon && <Icon className="mr-2 h-4 w-4" />} + <span>{title}</span> + </div> + <ChevronDownIcon className={cn('h-4 w-4', isOpen && 'rotate-180')} /> + </Button> + </CollapsibleTrigger> + <CollapsibleContent className="relative mt-2 space-y-2"> + <ul role="list"> + {items.map((entry, idx) => + 'href' in entry ? ( + <li key={entry.title}> + <NavLink + isAnchorLink + key={entry.title} + href={entry.href} + active={entry.href === pathname} + > + {entry.title} + </NavLink> + </li> + ) : ( + <li key={entry.title}> + <div + aria-hidden="true" + className={cn( + 'absolute bottom-0 left-2 top-0 w-[1px]', + 'bg-zinc-300 dark:bg-zinc-700', + )} + />{' '} + <CollapsibleNavItem group={entry} className="pl-7" /> + </li> + ), + )} + </ul> + </CollapsibleContent> + </Collapsible> + ) +} + +export default CollapsibleNavItem diff --git a/src/components/nav/MobileNavigation.tsx b/src/components/nav/MobileNavigation.tsx new file mode 100644 index 000000000..6dc78f047 --- /dev/null +++ b/src/components/nav/MobileNavigation.tsx @@ -0,0 +1,148 @@ +'use client' + +import { createContext, Suspense, useContext, useEffect, useRef } from 'react' +import { usePathname, useSearchParams } from 'next/navigation' +import { + Dialog, + DialogPanel, + DialogBackdrop, + TransitionChild, +} from '@headlessui/react' +import { motion } from 'framer-motion' +import { create } from 'zustand' + +import { Header } from '@/components/layout/Header' +import { Navigation } from '@/components/nav/Navigation' + +function MenuIcon(props: React.ComponentPropsWithoutRef<'svg'>) { + return ( + <svg + viewBox="0 0 10 9" + fill="none" + strokeLinecap="round" + aria-hidden="true" + {...props} + > + <path d="M.5 1h9M.5 8h9M.5 4.5h9" /> + </svg> + ) +} + +function XIcon(props: React.ComponentPropsWithoutRef<'svg'>) { + return ( + <svg + viewBox="0 0 10 9" + fill="none" + strokeLinecap="round" + aria-hidden="true" + {...props} + > + <path d="m1.5 1 7 7M8.5 1l-7 7" /> + </svg> + ) +} + +const IsInsideMobileNavigationContext = createContext(false) + +function MobileNavigationDialog({ + isOpen, + close, +}: { + isOpen: boolean + close: () => void +}) { + let pathname = usePathname() + let searchParams = useSearchParams() + let initialPathname = useRef(pathname).current + let initialSearchParams = useRef(searchParams).current + + useEffect(() => { + if (pathname !== initialPathname || searchParams !== initialSearchParams) { + close() + } + }, [pathname, searchParams, close, initialPathname, initialSearchParams]) + + function onClickDialog(event: React.MouseEvent<HTMLDivElement>) { + if (!(event.target instanceof HTMLElement)) { + return + } + + let link = event.target.closest('a') + if ( + link && + link.pathname + link.search + link.hash === + window.location.pathname + window.location.search + window.location.hash + ) { + close() + } + } + + return ( + <Dialog + open={isOpen} + onClickCapture={onClickDialog} + onClose={close} + className="fixed inset-0 z-50 lg:hidden" + > + <DialogBackdrop + transition + className="fixed inset-0 top-14 bg-zinc-400/20 backdrop-blur-sm data-[closed]:opacity-0 data-[enter]:duration-300 data-[leave]:duration-200 data-[enter]:ease-out data-[leave]:ease-in dark:bg-black/40" + /> + + <DialogPanel> + <TransitionChild> + <Header className="data-[closed]:opacity-0 data-[enter]:duration-300 data-[leave]:duration-200 data-[enter]:ease-out data-[leave]:ease-in" /> + </TransitionChild> + + <TransitionChild> + <motion.div + layoutScroll + className="fixed bottom-0 left-0 top-14 w-full overflow-y-auto bg-white px-4 pb-4 pt-6 shadow-lg shadow-zinc-900/10 ring-1 ring-zinc-900/7.5 duration-500 ease-in-out data-[closed]:-translate-x-full dark:bg-zinc-900 dark:ring-zinc-800 min-[416px]:max-w-sm sm:px-6 sm:pb-10" + > + <Navigation /> + </motion.div> + </TransitionChild> + </DialogPanel> + </Dialog> + ) +} + +export function useIsInsideMobileNavigation() { + return useContext(IsInsideMobileNavigationContext) +} + +export const useMobileNavigationStore = create<{ + isOpen: boolean + open: () => void + close: () => void + toggle: () => void +}>()((set) => ({ + isOpen: false, + open: () => set({ isOpen: true }), + close: () => set({ isOpen: false }), + toggle: () => set((state) => ({ isOpen: !state.isOpen })), +})) + +export function MobileNavigation() { + let isInsideMobileNavigation = useIsInsideMobileNavigation() + let { isOpen, toggle, close } = useMobileNavigationStore() + let ToggleIcon = isOpen ? XIcon : MenuIcon + + return ( + <IsInsideMobileNavigationContext.Provider value={true}> + <button + type="button" + className="flex h-6 w-6 items-center justify-center rounded-md transition hover:bg-zinc-900/5 dark:hover:bg-white/5" + aria-label="Toggle navigation" + onClick={toggle} + > + <ToggleIcon className="w-2.5 stroke-zinc-900 dark:stroke-white" /> + </button> + {!isInsideMobileNavigation && ( + <Suspense fallback={null}> + <MobileNavigationDialog isOpen={isOpen} close={close} /> + </Suspense> + )} + </IsInsideMobileNavigationContext.Provider> + ) +} diff --git a/src/components/nav/NavLink.tsx b/src/components/nav/NavLink.tsx new file mode 100644 index 000000000..b4a5e5cdc --- /dev/null +++ b/src/components/nav/NavLink.tsx @@ -0,0 +1,59 @@ +import React, { PropsWithChildren } from 'react' +import Link from 'next/link' +import { cn } from '@/lib/utils' +import { Tag } from '../Tag' +import { Button } from '../ui/button' +import { NavItem } from '@/config/types' + +interface NavLinkProps extends PropsWithChildren<Omit<NavItem, 'title'>> { + href: string + tag?: string + active?: boolean + isAnchorLink?: boolean + className?: string +} + +export const NavLink: React.FC<NavLinkProps> = ({ + active, + isAnchorLink, + href, + children, + tag, + icon: Icon, + className, +}) => { + return ( + <Button variant="link" asChild> + <Link + href={href} + aria-current={active ? 'page' : undefined} + className={cn( + 'relative flex w-full justify-between gap-2 py-1 pr-3 text-sm no-underline transition hover:no-underline', + isAnchorLink ? 'pl-7' : 'pl-2', + active + ? 'bg-zinc-100/60 text-zinc-900 dark:bg-zinc-800/60 dark:text-white' + : 'text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white', + className, + )} + > + {isAnchorLink && ( + <div + aria-hidden="true" + className={cn( + 'absolute bottom-0 left-2 top-0 w-[1px]', + active ? 'bg-primary-500' : 'bg-zinc-300 dark:bg-zinc-700', + )} + /> + )} + <span className="flex items-center truncate"> + {Icon && <Icon className="mr-2 h-4 w-4" />} {children} + </span> + {tag && ( + <Tag variant="small" color="zinc"> + {tag} + </Tag> + )} + </Link> + </Button> + ) +} diff --git a/src/components/nav/Navigation.tsx b/src/components/nav/Navigation.tsx new file mode 100644 index 000000000..7657d18a4 --- /dev/null +++ b/src/components/nav/Navigation.tsx @@ -0,0 +1,37 @@ +'use client' + +import { usePathname } from 'next/navigation' + +import { NavLink } from './NavLink' +import { cn } from '@/lib/utils' +import { NavigationGroup } from './NavigationGroup' +import { navigation } from '@/config' + +export function Navigation(props: React.ComponentPropsWithoutRef<'nav'>) { + const pathname = usePathname() + + return ( + <nav {...props}> + <ul role="list"> + {navigation.map((entry, groupIndex) => + 'href' in entry ? ( + <NavLink + className={cn('pl-2', groupIndex === 0 ? 'md:mt-0' : '')} + key={entry.title} + active={entry.href === pathname} + {...entry} + > + {entry.title} + </NavLink> + ) : ( + <NavigationGroup + key={entry.title} + group={entry} + className={groupIndex === 0 ? 'md:mt-0' : ''} + /> + ), + )} + </ul> + </nav> + ) +} diff --git a/src/components/nav/NavigationGroup.tsx b/src/components/nav/NavigationGroup.tsx new file mode 100644 index 000000000..200412af4 --- /dev/null +++ b/src/components/nav/NavigationGroup.tsx @@ -0,0 +1,49 @@ +import { cn } from '@/lib/utils' +import { usePathname } from 'next/navigation' +import { NavLink } from './NavLink' +import CollapsibleNavItem from './CollapsibleNavItem' +import { NavGroup } from '@/config/types' + +export function NavigationGroup({ + group, + className, + isAnchorLinks, +}: { + group: NavGroup + className?: string + isAnchorLinks?: boolean +}) { + // If this is the mobile navigation then we always render the initial + // state, so that the state does not change during the close animation. + // The state will still update when we re-open (re-render) the navigation. + const pathname = usePathname() + + return ( + <li className={cn('relative mt-6', className)}> + <h2 className="pl-2 text-2xs font-semibold text-zinc-900 dark:text-white"> + {group.title} + </h2> + <div className="relative mt-3"> + <ul role="list" className="border-l border-transparent"> + {group.items.map((link) => + 'href' in link ? ( + <li key={link.href} className="relative"> + <NavLink + {...link} + active={link.href === pathname} + isAnchorLink={isAnchorLinks} + > + {link.title} + </NavLink> + </li> + ) : ( + <li key={link.title}> + <CollapsibleNavItem group={link} /> + </li> + ), + )} + </ul> + </div> + </li> + ) +} diff --git a/src/components/ui/accordion.tsx b/src/components/ui/accordion.tsx new file mode 100644 index 000000000..2c7be7136 --- /dev/null +++ b/src/components/ui/accordion.tsx @@ -0,0 +1,57 @@ +'use client' + +import * as React from 'react' +import * as AccordionPrimitive from '@radix-ui/react-accordion' +import { ChevronDownIcon } from '@radix-ui/react-icons' + +import { cn } from '@/lib/utils' + +const Accordion = AccordionPrimitive.Root + +const AccordionItem = React.forwardRef< + React.ElementRef<typeof AccordionPrimitive.Item>, + React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item> +>(({ className, ...props }, ref) => ( + <AccordionPrimitive.Item + ref={ref} + className={cn('border-b', className)} + {...props} + /> +)) +AccordionItem.displayName = 'AccordionItem' + +const AccordionTrigger = React.forwardRef< + React.ElementRef<typeof AccordionPrimitive.Trigger>, + React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger> +>(({ className, children, ...props }, ref) => ( + <AccordionPrimitive.Header className="flex"> + <AccordionPrimitive.Trigger + ref={ref} + className={cn( + 'flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180', + className, + )} + {...props} + > + {children} + <ChevronDownIcon className="h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200" /> + </AccordionPrimitive.Trigger> + </AccordionPrimitive.Header> +)) +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName + +const AccordionContent = React.forwardRef< + React.ElementRef<typeof AccordionPrimitive.Content>, + React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content> +>(({ className, children, ...props }, ref) => ( + <AccordionPrimitive.Content + ref={ref} + className="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down" + {...props} + > + <div className={cn('pb-4 pt-0', className)}>{children}</div> + </AccordionPrimitive.Content> +)) +AccordionContent.displayName = AccordionPrimitive.Content.displayName + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } diff --git a/src/components/ui/avatar.tsx b/src/components/ui/avatar.tsx new file mode 100644 index 000000000..77fde462c --- /dev/null +++ b/src/components/ui/avatar.tsx @@ -0,0 +1,50 @@ +'use client' + +import * as React from 'react' +import * as AvatarPrimitive from '@radix-ui/react-avatar' + +import { cn } from '@/lib/utils' + +const Avatar = React.forwardRef< + React.ElementRef<typeof AvatarPrimitive.Root>, + React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root> +>(({ className, ...props }, ref) => ( + <AvatarPrimitive.Root + ref={ref} + className={cn( + 'relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full', + className, + )} + {...props} + /> +)) +Avatar.displayName = AvatarPrimitive.Root.displayName + +const AvatarImage = React.forwardRef< + React.ElementRef<typeof AvatarPrimitive.Image>, + React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image> +>(({ className, ...props }, ref) => ( + <AvatarPrimitive.Image + ref={ref} + className={cn('aspect-square h-full w-full', className)} + {...props} + /> +)) +AvatarImage.displayName = AvatarPrimitive.Image.displayName + +const AvatarFallback = React.forwardRef< + React.ElementRef<typeof AvatarPrimitive.Fallback>, + React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback> +>(({ className, ...props }, ref) => ( + <AvatarPrimitive.Fallback + ref={ref} + className={cn( + 'flex h-full w-full items-center justify-center rounded-full bg-muted', + className, + )} + {...props} + /> +)) +AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName + +export { Avatar, AvatarImage, AvatarFallback } diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx index 0c0985cfe..19fb78ea7 100644 --- a/src/components/ui/badge.tsx +++ b/src/components/ui/badge.tsx @@ -4,23 +4,23 @@ import { cva, type VariantProps } from 'class-variance-authority' import { cn } from '@/lib/utils' const badgeVariants = cva( - 'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', + 'inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', { variants: { variant: { default: - 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80', + 'border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80', secondary: 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80', destructive: - 'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80', + 'border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80', outline: 'text-foreground', }, }, defaultVariants: { variant: 'default', }, - } + }, ) export interface BadgeProps diff --git a/src/components/ui/breadcrumb.tsx b/src/components/ui/breadcrumb.tsx new file mode 100644 index 000000000..3752ec44d --- /dev/null +++ b/src/components/ui/breadcrumb.tsx @@ -0,0 +1,115 @@ +import * as React from 'react' +import { ChevronRightIcon, DotsHorizontalIcon } from '@radix-ui/react-icons' +import { Slot } from '@radix-ui/react-slot' + +import { cn } from '@/lib/utils' + +const Breadcrumb = React.forwardRef< + HTMLElement, + React.ComponentPropsWithoutRef<'nav'> & { + separator?: React.ReactNode + } +>(({ ...props }, ref) => <nav ref={ref} aria-label="breadcrumb" {...props} />) +Breadcrumb.displayName = 'Breadcrumb' + +const BreadcrumbList = React.forwardRef< + HTMLOListElement, + React.ComponentPropsWithoutRef<'ol'> +>(({ className, ...props }, ref) => ( + <ol + ref={ref} + className={cn( + 'flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5', + className, + )} + {...props} + /> +)) +BreadcrumbList.displayName = 'BreadcrumbList' + +const BreadcrumbItem = React.forwardRef< + HTMLLIElement, + React.ComponentPropsWithoutRef<'li'> +>(({ className, ...props }, ref) => ( + <li + ref={ref} + className={cn('inline-flex items-center gap-1.5', className)} + {...props} + /> +)) +BreadcrumbItem.displayName = 'BreadcrumbItem' + +const BreadcrumbLink = React.forwardRef< + HTMLAnchorElement, + React.ComponentPropsWithoutRef<'a'> & { + asChild?: boolean + } +>(({ asChild, className, ...props }, ref) => { + const Comp = asChild ? Slot : 'a' + + return ( + <Comp + ref={ref} + className={cn('transition-colors hover:text-foreground', className)} + {...props} + /> + ) +}) +BreadcrumbLink.displayName = 'BreadcrumbLink' + +const BreadcrumbPage = React.forwardRef< + HTMLSpanElement, + React.ComponentPropsWithoutRef<'span'> +>(({ className, ...props }, ref) => ( + <span + ref={ref} + role="link" + aria-disabled="true" + aria-current="page" + className={cn('font-normal text-foreground', className)} + {...props} + /> +)) +BreadcrumbPage.displayName = 'BreadcrumbPage' + +const BreadcrumbSeparator = ({ + children, + className, + ...props +}: React.ComponentProps<'li'>) => ( + <li + role="presentation" + aria-hidden="true" + className={cn('[&>svg]:size-3.5', className)} + {...props} + > + {children ?? <ChevronRightIcon />} + </li> +) +BreadcrumbSeparator.displayName = 'BreadcrumbSeparator' + +const BreadcrumbEllipsis = ({ + className, + ...props +}: React.ComponentProps<'span'>) => ( + <span + role="presentation" + aria-hidden="true" + className={cn('flex h-9 w-9 items-center justify-center', className)} + {...props} + > + <DotsHorizontalIcon className="h-4 w-4" /> + <span className="sr-only">More</span> + </span> +) +BreadcrumbEllipsis.displayName = 'BreadcrumbElipssis' + +export { + Breadcrumb, + BreadcrumbList, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbPage, + BreadcrumbSeparator, + BreadcrumbEllipsis, +} diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx new file mode 100644 index 000000000..c34a51601 --- /dev/null +++ b/src/components/ui/button.tsx @@ -0,0 +1,63 @@ +import * as React from 'react' +import { Slot } from '@radix-ui/react-slot' +import { cva, type VariantProps } from 'class-variance-authority' + +import { cn } from '@/lib/utils' + +const buttonVariants = cva( + 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50', + { + variants: { + variant: { + default: + 'bg-primary text-primary-foreground shadow hover:bg-primary/90', + destructive: + 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90', + outline: + 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground', + secondary: + 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80', + ghost: 'hover:bg-accent hover:text-accent-foreground', + link: 'text-primary underline-offset-4 hover:underline', + unstyled: '', + }, + size: { + default: 'h-9 px-4 py-2', + sm: 'h-8 rounded-md px-3 text-xs', + lg: 'h-10 rounded-md px-8', + xl: 'h-12 rounded-md text-base px-10', + icon: 'h-9 w-9', + }, + }, + defaultVariants: { + variant: 'default', + size: 'default', + }, + }, +) + +export interface ButtonProps + extends React.ButtonHTMLAttributes<HTMLButtonElement>, + VariantProps<typeof buttonVariants> { + asChild?: boolean +} + +const Button = React.forwardRef<HTMLButtonElement, ButtonProps>( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : 'button' + + return ( + <Comp + className={cn( + variant !== 'unstyled' && buttonVariants({ variant, size }), + className, + )} + ref={ref} + {...props} + /> + ) + }, +) +Button.displayName = 'Button' + +export { Button, buttonVariants } diff --git a/src/components/ui/collapsible.tsx b/src/components/ui/collapsible.tsx new file mode 100644 index 000000000..1bbaed5a8 --- /dev/null +++ b/src/components/ui/collapsible.tsx @@ -0,0 +1,11 @@ +'use client' + +import * as CollapsiblePrimitive from '@radix-ui/react-collapsible' + +const Collapsible = CollapsiblePrimitive.Root + +const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger + +const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent + +export { Collapsible, CollapsibleTrigger, CollapsibleContent } diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx new file mode 100644 index 000000000..71b43a391 --- /dev/null +++ b/src/components/ui/dialog.tsx @@ -0,0 +1,123 @@ +'use client' + +import * as React from 'react' +import * as DialogPrimitive from '@radix-ui/react-dialog' +import { Cross2Icon } from '@radix-ui/react-icons' + +import { cn } from '@/lib/utils' +import { XMarkIcon } from '@heroicons/react/24/outline' + +const Dialog = DialogPrimitive.Root + +const DialogTrigger = DialogPrimitive.Trigger + +const DialogPortal = DialogPrimitive.Portal + +const DialogClose = DialogPrimitive.Close + +const DialogOverlay = React.forwardRef< + React.ElementRef<typeof DialogPrimitive.Overlay>, + React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay> +>(({ className, ...props }, ref) => ( + <DialogPrimitive.Overlay + ref={ref} + className={cn( + 'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0', + className, + )} + {...props} + /> +)) +DialogOverlay.displayName = DialogPrimitive.Overlay.displayName + +const DialogContent = React.forwardRef< + React.ElementRef<typeof DialogPrimitive.Content>, + React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> +>(({ className, children, ...props }, ref) => ( + <DialogPortal> + <DialogOverlay /> + <DialogPrimitive.Content + ref={ref} + className={cn( + 'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg', + className, + )} + {...props} + > + {children} + <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground"> + <XMarkIcon className="h-6 w-6 stroke-zinc-400" /> + <span className="sr-only">Close</span> + </DialogPrimitive.Close> + </DialogPrimitive.Content> + </DialogPortal> +)) +DialogContent.displayName = DialogPrimitive.Content.displayName + +const DialogHeader = ({ + className, + ...props +}: React.HTMLAttributes<HTMLDivElement>) => ( + <div + className={cn( + 'flex flex-col space-y-1.5 text-center sm:text-left', + className, + )} + {...props} + /> +) +DialogHeader.displayName = 'DialogHeader' + +const DialogFooter = ({ + className, + ...props +}: React.HTMLAttributes<HTMLDivElement>) => ( + <div + className={cn( + 'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', + className, + )} + {...props} + /> +) +DialogFooter.displayName = 'DialogFooter' + +const DialogTitle = React.forwardRef< + React.ElementRef<typeof DialogPrimitive.Title>, + React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title> +>(({ className, ...props }, ref) => ( + <DialogPrimitive.Title + ref={ref} + className={cn( + 'text-lg font-semibold leading-none tracking-tight', + className, + )} + {...props} + /> +)) +DialogTitle.displayName = DialogPrimitive.Title.displayName + +const DialogDescription = React.forwardRef< + React.ElementRef<typeof DialogPrimitive.Description>, + React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description> +>(({ className, ...props }, ref) => ( + <DialogPrimitive.Description + ref={ref} + className={cn('text-sm text-muted-foreground', className)} + {...props} + /> +)) +DialogDescription.displayName = DialogPrimitive.Description.displayName + +export { + Dialog, + DialogPortal, + DialogOverlay, + DialogTrigger, + DialogClose, + DialogContent, + DialogHeader, + DialogFooter, + DialogTitle, + DialogDescription, +} diff --git a/src/components/ui/heading.tsx b/src/components/ui/heading.tsx new file mode 100644 index 000000000..4079bf517 --- /dev/null +++ b/src/components/ui/heading.tsx @@ -0,0 +1,40 @@ +import React from 'react' +import { cva, type VariantProps } from 'class-variance-authority' +import { cn } from '@/lib/utils' + +type Level = 1 | 2 | 3 | 4 | 5 | 6 + +const headingVariants = cva('text-balance font-bold font-display', { + variants: { + level: { + 1: 'text-foreground text-3xl sm:text-4xl lg:text-5xl', + 2: 'text-foreground text-2xl sm:text-3xl font-bold lg:text-4xl', + 3: 'text-foreground text-2xl lg:text-3xl', + 4: 'text-foreground text-xl lg:text-2xl', + 5: 'text-foreground text-lg lg:text-xl', + 6: 'text-foreground text-base lg:text-lg', + }, + }, + defaultVariants: { + level: 6, + }, +}) + +interface HeadingProps + extends React.HTMLAttributes<HTMLHeadingElement>, + VariantProps<typeof headingVariants> {} + +export const Heading: React.FC<HeadingProps> = ({ + level, + className, + children, + ...props +}) => { + const Tag = `h${level}` as `h${Level}` + + return ( + <Tag {...props} className={cn(headingVariants({ level, className }))}> + {children} + </Tag> + ) +} diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx new file mode 100644 index 000000000..95dd4e051 --- /dev/null +++ b/src/components/ui/input.tsx @@ -0,0 +1,25 @@ +import * as React from 'react' + +import { cn } from '@/lib/utils' + +export interface InputProps + extends React.InputHTMLAttributes<HTMLInputElement> {} + +const Input = React.forwardRef<HTMLInputElement, InputProps>( + ({ className, type, ...props }, ref) => { + return ( + <input + type={type} + className={cn( + 'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50', + className, + )} + ref={ref} + {...props} + /> + ) + }, +) +Input.displayName = 'Input' + +export { Input } diff --git a/src/components/ui/label.tsx b/src/components/ui/label.tsx new file mode 100644 index 000000000..fb5c5454c --- /dev/null +++ b/src/components/ui/label.tsx @@ -0,0 +1,26 @@ +'use client' + +import * as React from 'react' +import * as LabelPrimitive from '@radix-ui/react-label' +import { cva, type VariantProps } from 'class-variance-authority' + +import { cn } from '@/lib/utils' + +const labelVariants = cva( + 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70', +) + +const Label = React.forwardRef< + React.ElementRef<typeof LabelPrimitive.Root>, + React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & + VariantProps<typeof labelVariants> +>(({ className, ...props }, ref) => ( + <LabelPrimitive.Root + ref={ref} + className={cn(labelVariants(), className)} + {...props} + /> +)) +Label.displayName = LabelPrimitive.Root.displayName + +export { Label } diff --git a/src/components/ui/navigation-menu.tsx b/src/components/ui/navigation-menu.tsx new file mode 100644 index 000000000..85569dcb9 --- /dev/null +++ b/src/components/ui/navigation-menu.tsx @@ -0,0 +1,128 @@ +import * as React from 'react' +import { ChevronDownIcon } from '@radix-ui/react-icons' +import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu' +import { cva } from 'class-variance-authority' + +import { cn } from '@/lib/utils' + +const NavigationMenu = React.forwardRef< + React.ElementRef<typeof NavigationMenuPrimitive.Root>, + React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Root> +>(({ className, children, ...props }, ref) => ( + <NavigationMenuPrimitive.Root + ref={ref} + className={cn( + 'relative z-10 flex max-w-max flex-1 items-center justify-center', + className, + )} + {...props} + > + {children} + <NavigationMenuViewport /> + </NavigationMenuPrimitive.Root> +)) +NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName + +const NavigationMenuList = React.forwardRef< + React.ElementRef<typeof NavigationMenuPrimitive.List>, + React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.List> +>(({ className, ...props }, ref) => ( + <NavigationMenuPrimitive.List + ref={ref} + className={cn( + 'group flex flex-1 list-none items-center justify-center space-x-1', + className, + )} + {...props} + /> +)) +NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName + +const NavigationMenuItem = NavigationMenuPrimitive.Item + +const navigationMenuTriggerStyle = cva( + 'group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50', +) + +const NavigationMenuTrigger = React.forwardRef< + React.ElementRef<typeof NavigationMenuPrimitive.Trigger>, + React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Trigger> +>(({ className, children, ...props }, ref) => ( + <NavigationMenuPrimitive.Trigger + ref={ref} + className={cn(navigationMenuTriggerStyle(), 'group', className)} + {...props} + > + {children}{' '} + <ChevronDownIcon + className="relative top-[1px] ml-1 h-3 w-3 transition duration-300 group-data-[state=open]:rotate-180" + aria-hidden="true" + /> + </NavigationMenuPrimitive.Trigger> +)) +NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName + +const NavigationMenuContent = React.forwardRef< + React.ElementRef<typeof NavigationMenuPrimitive.Content>, + React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Content> +>(({ className, ...props }, ref) => ( + <NavigationMenuPrimitive.Content + ref={ref} + className={cn( + 'left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto', + className, + )} + {...props} + /> +)) +NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName + +const NavigationMenuLink = NavigationMenuPrimitive.Link + +const NavigationMenuViewport = React.forwardRef< + React.ElementRef<typeof NavigationMenuPrimitive.Viewport>, + React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport> +>(({ className, ...props }, ref) => ( + <div className={cn('absolute left-0 top-full flex justify-center')}> + <NavigationMenuPrimitive.Viewport + className={cn( + 'origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]', + className, + )} + ref={ref} + {...props} + /> + </div> +)) +NavigationMenuViewport.displayName = + NavigationMenuPrimitive.Viewport.displayName + +const NavigationMenuIndicator = React.forwardRef< + React.ElementRef<typeof NavigationMenuPrimitive.Indicator>, + React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Indicator> +>(({ className, ...props }, ref) => ( + <NavigationMenuPrimitive.Indicator + ref={ref} + className={cn( + 'top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in', + className, + )} + {...props} + > + <div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" /> + </NavigationMenuPrimitive.Indicator> +)) +NavigationMenuIndicator.displayName = + NavigationMenuPrimitive.Indicator.displayName + +export { + navigationMenuTriggerStyle, + NavigationMenu, + NavigationMenuList, + NavigationMenuItem, + NavigationMenuContent, + NavigationMenuTrigger, + NavigationMenuLink, + NavigationMenuIndicator, + NavigationMenuViewport, +} diff --git a/src/components/ui/pagination.tsx b/src/components/ui/pagination.tsx new file mode 100644 index 000000000..e4a55b560 --- /dev/null +++ b/src/components/ui/pagination.tsx @@ -0,0 +1,145 @@ +import * as React from 'react' +import { + ChevronLeftIcon, + ChevronRightIcon, + DotsHorizontalIcon, +} from '@radix-ui/react-icons' +import Link from 'next/link' +import { cn } from '@/lib/utils' +import { Button, ButtonProps, buttonVariants } from '@/components/ui/button' + +const Pagination = ({ className, ...props }: React.ComponentProps<'nav'>) => ( + <nav + role="navigation" + aria-label="pagination" + className={cn('mx-auto flex w-full justify-center', className)} + {...props} + /> +) +Pagination.displayName = 'Pagination' + +const PaginationContent = React.forwardRef< + HTMLUListElement, + React.ComponentProps<'ul'> +>(({ className, ...props }, ref) => ( + <ul + ref={ref} + className={cn('flex flex-row items-center gap-1', className)} + {...props} + /> +)) +PaginationContent.displayName = 'PaginationContent' + +const PaginationItem = React.forwardRef< + HTMLLIElement, + React.ComponentProps<'li'> +>(({ className, ...props }, ref) => ( + <li ref={ref} className={cn('', className)} {...props} /> +)) +PaginationItem.displayName = 'PaginationItem' + +type PaginationLinkProps = { + isActive?: boolean +} & Pick<ButtonProps, 'size'> & + React.ComponentProps<typeof Link> + +const PaginationLink = ({ + className, + isActive, + size = 'icon', + ...props +}: PaginationLinkProps) => ( + <Link + aria-current={isActive ? 'page' : undefined} + className={cn( + buttonVariants({ + variant: isActive ? 'outline' : 'ghost', + size, + }), + className, + )} + {...props} + /> +) +PaginationLink.displayName = 'PaginationLink' + +const PaginationPrevious = ({ + className, + disabled, + ...props +}: React.ComponentProps<typeof PaginationLink> & { disabled: boolean }) => + disabled ? ( + <Button + aria-label="Go to previous page" + size="default" + disabled + className={'cursor-not-allowed gap-1 bg-transparent pl-2.5'} + > + <ChevronLeftIcon className="h-4 w-4" /> + <span>Previous</span> + </Button> + ) : ( + <PaginationLink + aria-label="Go to previous page" + size="default" + className={cn('gap-1 pl-2.5', className)} + {...props} + > + <ChevronLeftIcon className="h-4 w-4" /> + <span>Previous</span> + </PaginationLink> + ) +PaginationPrevious.displayName = 'PaginationPrevious' + +const PaginationNext = ({ + className, + disabled, + ...props +}: React.ComponentProps<typeof PaginationLink> & { disabled: boolean }) => + disabled ? ( + <Button + aria-label="Go to next page" + size="default" + disabled + className={'cursor-not-allowed gap-1 bg-transparent pr-2.5'} + > + <span>Next</span> + <ChevronRightIcon className="h-4 w-4" /> + </Button> + ) : ( + <PaginationLink + aria-label="Go to next page" + size="default" + className={cn('gap-1 pr-2.5', className)} + {...props} + > + <span>Next</span> + <ChevronRightIcon className="h-4 w-4" /> + </PaginationLink> + ) +PaginationNext.displayName = 'PaginationNext' + +const PaginationEllipsis = ({ + className, + ...props +}: React.ComponentProps<'span'>) => ( + <span + aria-hidden + className={cn('flex h-9 w-9 items-center justify-center', className)} + {...props} + > + <DotsHorizontalIcon className="h-4 w-4" /> + <span className="sr-only">More pages</span> + </span> +) +PaginationEllipsis.displayName = 'PaginationEllipsis' + +export { + Pagination, + PaginationContent, + PaginationLink, + PaginationItem, + PaginationPrevious, + PaginationNext, + PaginationEllipsis, +} diff --git a/src/components/ui/radio-group.tsx b/src/components/ui/radio-group.tsx new file mode 100644 index 000000000..043832c49 --- /dev/null +++ b/src/components/ui/radio-group.tsx @@ -0,0 +1,44 @@ +'use client' + +import * as React from 'react' +import { CheckIcon } from '@radix-ui/react-icons' +import * as RadioGroupPrimitive from '@radix-ui/react-radio-group' + +import { cn } from '@/lib/utils' + +const RadioGroup = React.forwardRef< + React.ElementRef<typeof RadioGroupPrimitive.Root>, + React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root> +>(({ className, ...props }, ref) => { + return ( + <RadioGroupPrimitive.Root + className={cn('grid gap-2', className)} + {...props} + ref={ref} + /> + ) +}) +RadioGroup.displayName = RadioGroupPrimitive.Root.displayName + +const RadioGroupItem = React.forwardRef< + React.ElementRef<typeof RadioGroupPrimitive.Item>, + React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item> +>(({ className, ...props }, ref) => { + return ( + <RadioGroupPrimitive.Item + ref={ref} + className={cn( + 'aspect-square h-4 w-4 rounded-full border border-primary text-primary shadow focus:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50', + className, + )} + {...props} + > + <RadioGroupPrimitive.Indicator className="flex items-center justify-center"> + <CheckIcon className="h-3.5 w-3.5 fill-primary" /> + </RadioGroupPrimitive.Indicator> + </RadioGroupPrimitive.Item> + ) +}) +RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName + +export { RadioGroup, RadioGroupItem } diff --git a/src/components/ui/scroll-area.tsx b/src/components/ui/scroll-area.tsx new file mode 100644 index 000000000..69f1f4ec6 --- /dev/null +++ b/src/components/ui/scroll-area.tsx @@ -0,0 +1,48 @@ +'use client' + +import * as React from 'react' +import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area' + +import { cn } from '@/lib/utils' + +const ScrollArea = React.forwardRef< + React.ElementRef<typeof ScrollAreaPrimitive.Root>, + React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> +>(({ className, children, ...props }, ref) => ( + <ScrollAreaPrimitive.Root + ref={ref} + className={cn('relative overflow-hidden', className)} + {...props} + > + <ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]"> + {children} + </ScrollAreaPrimitive.Viewport> + <ScrollBar /> + <ScrollAreaPrimitive.Corner /> + </ScrollAreaPrimitive.Root> +)) +ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName + +const ScrollBar = React.forwardRef< + React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>, + React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar> +>(({ className, orientation = 'vertical', ...props }, ref) => ( + <ScrollAreaPrimitive.ScrollAreaScrollbar + ref={ref} + orientation={orientation} + className={cn( + 'flex touch-none select-none transition-colors', + orientation === 'vertical' && + 'h-full w-2.5 border-l border-l-transparent p-[1px]', + orientation === 'horizontal' && + 'h-2.5 flex-col border-t border-t-transparent p-[1px]', + className, + )} + {...props} + > + <ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" /> + </ScrollAreaPrimitive.ScrollAreaScrollbar> +)) +ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName + +export { ScrollArea, ScrollBar } diff --git a/src/components/ui/select.tsx b/src/components/ui/select.tsx index ffa7b0d34..5f27337cd 100644 --- a/src/components/ui/select.tsx +++ b/src/components/ui/select.tsx @@ -1,6 +1,13 @@ +'use client' + import * as React from 'react' +import { + CaretSortIcon, + CheckIcon, + ChevronDownIcon, + ChevronUpIcon, +} from '@radix-ui/react-icons' import * as SelectPrimitive from '@radix-ui/react-select' -import { Check, ChevronDown, ChevronUp } from 'lucide-react' import { cn } from '@/lib/utils' @@ -17,14 +24,14 @@ const SelectTrigger = React.forwardRef< <SelectPrimitive.Trigger ref={ref} className={cn( - 'flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1', - className + 'flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1', + className, )} {...props} > {children} <SelectPrimitive.Icon asChild> - <ChevronDown className="h-4 w-4 opacity-50" /> + <CaretSortIcon className="h-4 w-4 opacity-50" /> </SelectPrimitive.Icon> </SelectPrimitive.Trigger> )) @@ -38,11 +45,11 @@ const SelectScrollUpButton = React.forwardRef< ref={ref} className={cn( 'flex cursor-default items-center justify-center py-1', - className + className, )} {...props} > - <ChevronUp className="h-4 w-4" /> + <ChevronUpIcon /> </SelectPrimitive.ScrollUpButton> )) SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName @@ -55,11 +62,11 @@ const SelectScrollDownButton = React.forwardRef< ref={ref} className={cn( 'flex cursor-default items-center justify-center py-1', - className + className, )} {...props} > - <ChevronDown className="h-4 w-4" /> + <ChevronDownIcon /> </SelectPrimitive.ScrollDownButton> )) SelectScrollDownButton.displayName = @@ -73,10 +80,10 @@ const SelectContent = React.forwardRef< <SelectPrimitive.Content ref={ref} className={cn( - 'relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', + 'relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', position === 'popper' && 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1', - className + className, )} position={position} {...props} @@ -86,7 +93,7 @@ const SelectContent = React.forwardRef< className={cn( 'p-1', position === 'popper' && - 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]' + 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]', )} > {children} @@ -103,7 +110,7 @@ const SelectLabel = React.forwardRef< >(({ className, ...props }, ref) => ( <SelectPrimitive.Label ref={ref} - className={cn('py-1.5 pl-2 pr-8 text-sm font-semibold', className)} + className={cn('px-2 py-1.5 text-sm font-semibold', className)} {...props} /> )) @@ -117,16 +124,15 @@ const SelectItem = React.forwardRef< ref={ref} className={cn( 'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', - className + className, )} {...props} > <span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center"> <SelectPrimitive.ItemIndicator> - <Check className="h-4 w-4" /> + <CheckIcon className="h-4 w-4" /> </SelectPrimitive.ItemIndicator> </span> - <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText> </SelectPrimitive.Item> )) diff --git a/src/components/ui/separator.tsx b/src/components/ui/separator.tsx new file mode 100644 index 000000000..7f6db4435 --- /dev/null +++ b/src/components/ui/separator.tsx @@ -0,0 +1,31 @@ +'use client' + +import * as React from 'react' +import * as SeparatorPrimitive from '@radix-ui/react-separator' + +import { cn } from '@/lib/utils' + +const Separator = React.forwardRef< + React.ElementRef<typeof SeparatorPrimitive.Root>, + React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root> +>( + ( + { className, orientation = 'horizontal', decorative = true, ...props }, + ref, + ) => ( + <SeparatorPrimitive.Root + ref={ref} + decorative={decorative} + orientation={orientation} + className={cn( + 'shrink-0 bg-border', + orientation === 'horizontal' ? 'h-[1px] w-full' : 'h-full w-[1px]', + className, + )} + {...props} + /> + ), +) +Separator.displayName = SeparatorPrimitive.Root.displayName + +export { Separator } diff --git a/src/components/ui/subheading.tsx b/src/components/ui/subheading.tsx new file mode 100644 index 000000000..a430aa296 --- /dev/null +++ b/src/components/ui/subheading.tsx @@ -0,0 +1,19 @@ +import React from 'react' +import { cn } from '@/lib/utils' + +type HeadingProps = React.HTMLAttributes<HTMLParagraphElement> + +export const Subheading: React.FC<HeadingProps> = ({ + className, + children, + ...props +}) => { + return ( + <p + {...props} + className={cn('mt-6 text-lg tracking-tight text-zinc-400', className)} + > + {children} + </p> + ) +} diff --git a/src/components/ui/table.tsx b/src/components/ui/table.tsx new file mode 100644 index 000000000..3d7ce9159 --- /dev/null +++ b/src/components/ui/table.tsx @@ -0,0 +1,120 @@ +import * as React from 'react' + +import { cn } from '@/lib/utils' + +const Table = React.forwardRef< + HTMLTableElement, + React.HTMLAttributes<HTMLTableElement> +>(({ className, ...props }, ref) => ( + <div className="relative w-full overflow-auto"> + <table + ref={ref} + className={cn('w-full caption-bottom text-sm', className)} + {...props} + /> + </div> +)) +Table.displayName = 'Table' + +const TableHeader = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes<HTMLTableSectionElement> +>(({ className, ...props }, ref) => ( + <thead ref={ref} className={cn('[&_tr]:border-b', className)} {...props} /> +)) +TableHeader.displayName = 'TableHeader' + +const TableBody = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes<HTMLTableSectionElement> +>(({ className, ...props }, ref) => ( + <tbody + ref={ref} + className={cn('[&_tr:last-child]:border-0', className)} + {...props} + /> +)) +TableBody.displayName = 'TableBody' + +const TableFooter = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes<HTMLTableSectionElement> +>(({ className, ...props }, ref) => ( + <tfoot + ref={ref} + className={cn( + 'border-t bg-muted/50 font-medium [&>tr]:last:border-b-0', + className, + )} + {...props} + /> +)) +TableFooter.displayName = 'TableFooter' + +const TableRow = React.forwardRef< + HTMLTableRowElement, + React.HTMLAttributes<HTMLTableRowElement> +>(({ className, ...props }, ref) => ( + <tr + ref={ref} + className={cn( + 'border-b transition-colors hover:bg-muted/20 data-[state=selected]:bg-muted', + className, + )} + {...props} + /> +)) +TableRow.displayName = 'TableRow' + +const TableHead = React.forwardRef< + HTMLTableCellElement, + React.ThHTMLAttributes<HTMLTableCellElement> +>(({ className, ...props }, ref) => ( + <th + ref={ref} + className={cn( + 'h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]', + className, + )} + {...props} + /> +)) +TableHead.displayName = 'TableHead' + +const TableCell = React.forwardRef< + HTMLTableCellElement, + React.TdHTMLAttributes<HTMLTableCellElement> +>(({ className, ...props }, ref) => ( + <td + ref={ref} + className={cn( + 'p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]', + className, + )} + {...props} + /> +)) +TableCell.displayName = 'TableCell' + +const TableCaption = React.forwardRef< + HTMLTableCaptionElement, + React.HTMLAttributes<HTMLTableCaptionElement> +>(({ className, ...props }, ref) => ( + <caption + ref={ref} + className={cn('mt-4 text-sm text-muted-foreground', className)} + {...props} + /> +)) +TableCaption.displayName = 'TableCaption' + +export { + Table, + TableHeader, + TableBody, + TableFooter, + TableHead, + TableRow, + TableCell, + TableCaption, +} diff --git a/src/components/ui/tabs.tsx b/src/components/ui/tabs.tsx new file mode 100644 index 000000000..00852fa0a --- /dev/null +++ b/src/components/ui/tabs.tsx @@ -0,0 +1,55 @@ +'use client' + +import * as React from 'react' +import * as TabsPrimitive from '@radix-ui/react-tabs' + +import { cn } from '@/lib/utils' + +const Tabs = TabsPrimitive.Root + +const TabsList = React.forwardRef< + React.ElementRef<typeof TabsPrimitive.List>, + React.ComponentPropsWithoutRef<typeof TabsPrimitive.List> +>(({ className, ...props }, ref) => ( + <TabsPrimitive.List + ref={ref} + className={cn( + 'inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground', + className, + )} + {...props} + /> +)) +TabsList.displayName = TabsPrimitive.List.displayName + +const TabsTrigger = React.forwardRef< + React.ElementRef<typeof TabsPrimitive.Trigger>, + React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger> +>(({ className, ...props }, ref) => ( + <TabsPrimitive.Trigger + ref={ref} + className={cn( + 'inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow', + className, + )} + {...props} + /> +)) +TabsTrigger.displayName = TabsPrimitive.Trigger.displayName + +const TabsContent = React.forwardRef< + React.ElementRef<typeof TabsPrimitive.Content>, + React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content> +>(({ className, ...props }, ref) => ( + <TabsPrimitive.Content + ref={ref} + className={cn( + 'mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2', + className, + )} + {...props} + /> +)) +TabsContent.displayName = TabsPrimitive.Content.displayName + +export { Tabs, TabsList, TabsTrigger, TabsContent } diff --git a/src/config/index.ts b/src/config/index.ts new file mode 100644 index 000000000..ac6447f01 --- /dev/null +++ b/src/config/index.ts @@ -0,0 +1,273 @@ +import { CommandLineIcon, HomeIcon } from '@heroicons/react/24/outline' +import { FaNodeJs, FaPython, FaJava, FaAws, FaGithub } from 'react-icons/fa' +import { SiDart, SiGo } from 'react-icons/si' +import { NavEntry } from './types' +import { NodeReference } from './reference/node' +import { PyReference } from './reference/python' +import { DartReference } from './reference/dart' +import { GoReference } from './reference/go' + +export const navigation: NavEntry[] = [ + { + title: 'Introduction', + href: '/', + }, + { + title: 'Concepts', + items: [ + { + title: 'Infrastructure from Code', + href: '/infrastructure-from-code', + }, + { + title: 'Project', + href: '/project', + }, + { + title: 'Service', + href: '/service', + }, + { + title: 'Resource', + href: '/resource', + }, + { + title: 'Provider', + href: '/provider', + }, + { + title: 'Stack', + href: '/stack', + }, + ], + }, + { + title: 'Basics', + items: [ + { + title: 'Installation', + href: '/getting-started/installation', + }, + { + title: 'Configuration', + href: '/getting-started/configuration', + }, + { + title: 'Project Structure', + href: '/getting-started/project-structure', + }, + { + title: 'Local Development', + href: '/getting-started/local-development', + }, + { + title: 'Security', + href: '/getting-started/security', + }, + { + title: 'Deployment', + href: '/getting-started/deploying', + }, + ], + }, + { + title: 'Get Started', + items: [ + { + title: 'Node.js', + icon: FaNodeJs, + items: [ + { + title: 'API', + href: '/getting-started/node/quick-start', + }, + { + title: 'Todo App', + href: '/getting-started/node/to-do', + }, + ], + }, + { + title: 'Python', + icon: FaPython, + items: [ + { + title: 'API', + href: '/getting-started/python/quick-start', + }, + { + title: 'Todo App', + href: '/getting-started/python/to-do', + }, + ], + }, + { + title: 'Go', + icon: SiGo, + items: [ + { + title: 'API', + href: '/getting-started/go/quick-start', + }, + { + title: 'Todo App', + href: '/getting-started/go/to-do', + }, + ], + }, + { + title: 'Dart', + icon: SiDart, + items: [ + { + title: 'API', + href: '/getting-started/dart/quick-start', + }, + { + title: 'Todo App', + href: '/getting-started/dart/to-do', + }, + ], + }, + ], + }, + { + title: 'Deployment', + items: [ + { + title: 'Intro', + href: '/getting-started/quick-start', + }, + { + title: 'AWS', + href: '/getting-started/quick-start', + }, + { + title: 'GCP', + href: '/getting-started/quick-start', + }, + { + title: 'Azure', + href: '/getting-started/quick-start', + }, + { + title: 'Custom', + href: '/getting-started/quick-start', + }, + { + title: 'CD/CD', + href: '/getting-started/quick-start', + }, + ], + }, + { + title: 'Languages', + items: [ + { + title: 'Node.js', + href: '/getting-started/quick-start', + }, + { + title: 'Python', + href: '/getting-started/quick-start', + }, + { + title: 'Go', + href: '/getting-started/quick-start', + }, + { + title: 'Dart', + href: '/getting-started/quick-start', + }, + ], + }, + { + title: 'Extension', + items: [ + { + title: 'Overview', + href: '/extension/overview', + }, + { + title: 'Provider Extension', + href: '/extension/provider-extension', + }, + { + title: 'Custom Providers', + href: '/extension/custom-providers', + }, + { + title: 'Custom Containers', + href: '/extension/custom-containers', + }, + ], + }, + { + title: 'Reference', + items: [ + { + title: 'CLI', + icon: CommandLineIcon, + items: [ + { + title: 'Overview', + href: '/reference/cli', + }, + { + title: 'Installation', + href: '/reference/cli/installation', + }, + { + title: 'Local Development', + href: '/reference/cli/local-development', + }, + { + title: 'Stacks', + href: '/reference/cli/stacks', + }, + ], + }, + NodeReference, + PyReference, + GoReference, + DartReference, + { + title: 'Env Vars', + href: '/reference/env-vars', + }, + { + title: 'Examples', + href: '/reference/examples', + }, + { + title: 'Preview Features', + href: '/reference/preview-features', + }, + ], + }, + { + title: 'FAQ', + items: [ + { + title: 'How is nitric different from Pulumi?', + href: '/faq/nitric-vs-pulumi', + }, + { + title: 'How is nitric different from Terraform?', + href: '/faq/nitric-vs-terraform', + }, + { + title: 'Comparisons with other tools/frameworks', + href: '/faq/comparisons', + }, + { + title: 'How to migrate between clouds', + href: '/faq/migrate-between-clouds', + }, + { + title: 'Ask a question', + href: '/faq/ask-a-question', + }, + ], + }, +] diff --git a/src/config/reference/dart.ts b/src/config/reference/dart.ts new file mode 100644 index 000000000..05e0f6a1f --- /dev/null +++ b/src/config/reference/dart.ts @@ -0,0 +1,251 @@ +import { NavGroup } from '../types' +import { SiDart } from 'react-icons/si' + +export const DartReference: NavGroup = { + title: 'Dart', + icon: SiDart, + items: [ + { + title: 'Overview', + href: '/reference/dart', + breadcrumbRoot: true, + }, + { + title: 'APIs', + items: [ + { + title: 'api()', + href: '/reference/dart/api/api', + }, + { + title: 'api.get()', + href: '/reference/dart/api/api-get', + }, + { + title: 'api.post()', + href: '/reference/dart/api/api-post', + }, + { + title: 'api.put()', + href: '/reference/dart/api/api-put', + }, + { + title: 'api.delete()', + href: '/reference/dart/api/api-delete', + }, + { + title: 'api.patch()', + href: '/reference/dart/api/api-patch', + }, + { + title: 'api.route()', + href: '/reference/dart/api/api-route', + }, + { + title: 'api.route.all()', + href: '/reference/dart/api/api-route-all', + }, + { + title: 'api.route.get()', + href: '/reference/dart/api/api-route-get', + }, + { + title: 'api.route.post()', + href: '/reference/dart/api/api-route-post', + }, + { + title: 'api.route.put()', + href: '/reference/dart/api/api-route-put', + }, + { + title: 'api.route.delete()', + href: '/reference/dart/api/api-route-delete', + }, + { + title: 'api.route.patch()', + href: '/reference/dart/api/api-route-patch', + }, + ], + }, + { + title: 'Key Value Stores', + items: [ + { + title: 'kv()', + href: '/reference/dart/keyvalue/keyvalue', + }, + { + title: 'kv.get()', + href: '/reference/dart/keyvalue/keyvalue-get', + }, + { + title: 'kv.set()', + href: '/reference/dart/keyvalue/keyvalue-set', + }, + { + title: 'kv.delete()', + href: '/reference/dart/keyvalue/keyvalue-delete', + }, + { + title: 'kv.keys()', + href: '/reference/dart/keyvalue/keyvalue-keys', + }, + ], + }, + { + title: 'Topics', + items: [ + { + title: 'topic()', + href: '/reference/dart/topic/topic', + }, + { + title: 'topic.publish()', + href: '/reference/dart/topic/topic-publish', + }, + { + title: 'topic.subscribe()', + href: '/reference/dart/topic/topic-subscribe', + }, + ], + }, + { + title: 'Queues', + items: [ + { + title: 'queue()', + href: '/reference/dart/queues/queue', + }, + { + title: 'queue.enqueue()', + href: '/reference/dart/queues/queue-enqueue', + }, + { + title: 'queue.dequeue()', + href: '/reference/dart/queues/queue-dequeue', + }, + ], + }, + { + title: 'Secrets', + items: [ + { + title: 'secret()', + href: '/reference/dart/secrets/secret', + }, + { + title: 'secret.put()', + href: '/reference/dart/secrets/secret-put', + }, + { + title: 'secret.version()', + href: '/reference/dart/secrets/secret-version', + }, + { + title: 'secret.latest()', + href: '/reference/dart/secrets/secret-latest', + }, + { + title: 'secret.version.access()', + href: '/reference/dart/secrets/secret-version-access', + }, + ], + }, + { + title: 'Storage', + items: [ + { + title: 'bucket()', + href: '/reference/dart/storage/bucket', + }, + { + title: 'bucket.on()', + href: '/reference/dart/storage/bucket-on', + }, + { + title: 'bucket.file()', + href: '/reference/dart/storage/bucket-file', + }, + { + title: 'bucket.files()', + href: '/reference/dart/storage/bucket-files', + }, + { + title: 'file.exists()', + href: '/reference/dart/storage/bucket-file-exists', + }, + { + title: 'file.read()', + href: '/reference/dart/storage/bucket-file-read', + }, + { + title: 'file.write()', + href: '/reference/dart/storage/bucket-file-write', + }, + { + title: 'file.delete()', + href: '/reference/dart/storage/bucket-file-delete', + }, + { + title: 'file.getDownloadUrl()', + href: '/reference/dart/storage/bucket-file-downloadurl', + }, + { + title: 'file.getUploadUrl()', + href: '/reference/dart/storage/bucket-file-uploadurl', + }, + ], + }, + { + title: 'SQL', + items: [ + { + title: 'sql()', + href: '/reference/dart/sql/sql', + }, + { + title: 'sql.connectionString()', + href: '/reference/dart/sql/sql-connection-string', + }, + ], + }, + { + title: 'Schedules', + items: [ + { + title: 'schedule()', + href: '/reference/dart/schedule/schedule', + }, + { + title: 'schedule.every()', + href: '/reference/dart/schedule/schedule-every', + }, + { + title: 'schedule.cron()', + href: '/reference/dart/schedule/schedule-cron', + }, + ], + }, + { + title: 'Websockets', + items: [ + { + title: 'websocket()', + href: '/reference/dart/websocket/websocket', + }, + { + title: 'websocket.on()', + href: '/reference/dart/websocket/websocket-on', + }, + { + title: 'websocket.send()', + href: '/reference/dart/websocket/websocket-send', + }, + { + title: 'websocket.close()', + href: '/reference/dart/websocket/websocket-close', + }, + ], + }, + ], +} diff --git a/src/config/reference/go.ts b/src/config/reference/go.ts new file mode 100644 index 000000000..a93dfd97e --- /dev/null +++ b/src/config/reference/go.ts @@ -0,0 +1,240 @@ +import { FaPython } from 'react-icons/fa' +import { NavGroup } from '../types' +import { SiGo } from 'react-icons/si' + +export const GoReference: NavGroup = { + title: 'Go', + icon: SiGo, + items: [ + { + title: 'Overview', + href: '/reference/go', + breadcrumbRoot: true, + }, + { + title: 'Resources', + items: [ + { + title: 'NewApi()', + href: '/reference/go/api/api', + }, + { + title: 'NewKv()', + href: '/reference/go/keyvalue/keyvalue', + }, + { + title: 'NewQueue()', + href: '/reference/go/queues/queue', + }, + { + title: 'NewSecret()', + href: '/reference/go/secrets/secret', + }, + { + title: 'NewBucket()', + href: '/reference/go/storage/bucket', + }, + { + title: 'NewTopic()', + href: '/reference/go/topic/topic', + }, + { + title: 'NewSchedule()', + href: '/reference/go/schedule/schedule', + }, + { + title: 'NewWebsocket()', + href: '/reference/go/websocket/websocket', + }, + ], + }, + { + title: 'APIs', + items: [ + { + title: 'Api.Get()', + href: '/reference/go/api/api-get', + }, + { + title: 'Api.Post()', + href: '/reference/go/api/api-post', + }, + { + title: 'Api.Put()', + href: '/reference/go/api/api-put', + }, + { + title: 'Api.Delete()', + href: '/reference/go/api/api-delete', + }, + { + title: 'Api.Patch()', + href: '/reference/go/api/api-patch', + }, + { + title: 'Api.NewRoute()', + href: '/reference/go/api/api-route', + }, + { + title: 'Api.Route.All()', + href: '/reference/go/api/api-route-all', + }, + { + title: 'Api.Route.Get()', + href: '/reference/go/api/api-route-get', + }, + { + title: 'Api.Route.Post()', + href: '/reference/go/api/api-route-post', + }, + { + title: 'Api.Route.Put()', + href: '/reference/go/api/api-route-put', + }, + { + title: 'Api.Route.Delete()', + href: '/reference/go/api/api-route-delete', + }, + { + title: 'Api.Route.Patch()', + href: '/reference/go/api/api-route-patch', + }, + ], + }, + { + title: 'Key Value Stores', + items: [ + { + title: 'Kv.Get()', + href: '/reference/go/keyvalue/keyvalue-get', + }, + { + title: 'Kv.Set()', + href: '/reference/go/keyvalue/keyvalue-set', + }, + { + title: 'Kv.Delete()', + href: '/reference/go/keyvalue/keyvalue-delete', + }, + { + title: 'Kv.Keys()', + href: '/reference/go/keyvalue/keyvalue-keys', + }, + ], + }, + { + title: 'Topics', + items: [ + { + title: 'Topic.Publish()', + href: '/reference/go/topic/topic-publish', + }, + { + title: 'Topic.Subscribe()', + href: '/reference/go/topic/topic-subscribe', + }, + ], + }, + { + title: 'Queues', + items: [ + { + title: 'Queue.Enqueue()', + href: '/reference/go/queues/queue-enqueue', + }, + { + title: 'Queue.Dequeue()', + href: '/reference/go/queues/queue-dequeue', + }, + ], + }, + { + title: 'Secrets', + items: [ + { + title: 'Secret.Put()', + href: '/reference/go/secrets/secret-put', + }, + { + title: 'Secret.Version()', + href: '/reference/go/secrets/secret-version', + }, + { + title: 'Secret.Latest()', + href: '/reference/go/secrets/secret-latest', + }, + { + title: 'Secret.Version.Access()', + href: '/reference/go/secrets/secret-version-access', + }, + ], + }, + { + title: 'Storage', + items: [ + { + title: 'Bucket.On()', + href: '/reference/go/storage/bucket-on', + }, + { + title: 'Bucket.File()', + href: '/reference/go/storage/bucket-file', + }, + { + title: 'Bucket.Files()', + href: '/reference/go/storage/bucket-files', + }, + { + title: 'File.Read()', + href: '/reference/go/storage/bucket-file-read', + }, + { + title: 'File.Write()', + href: '/reference/go/storage/bucket-file-write', + }, + { + title: 'File.Delete()', + href: '/reference/go/storage/bucket-file-delete', + }, + { + title: 'File.DownloadUrl()', + href: '/reference/go/storage/bucket-file-downloadurl', + }, + { + title: 'File.UploadUrl()', + href: '/reference/go/storage/bucket-file-uploadurl', + }, + ], + }, + { + title: 'Schedules', + items: [ + { + title: 'Schedule.Every()', + href: '/reference/go/schedule/schedule-every', + }, + { + title: 'Schedule.Cron()', + href: '/reference/go/schedule/schedule-cron', + }, + ], + }, + { + title: 'Websockets', + items: [ + { + title: 'Websocket.On()', + href: '/reference/go/websocket/websocket-on', + }, + { + title: 'Websocket.Send()', + href: '/reference/go/websocket/websocket-send', + }, + { + title: 'Websocket.Close()', + href: '/reference/go/websocket/websocket-close', + }, + ], + }, + ], +} diff --git a/src/config/reference/node.ts b/src/config/reference/node.ts new file mode 100644 index 000000000..ffdc88e51 --- /dev/null +++ b/src/config/reference/node.ts @@ -0,0 +1,260 @@ +import { FaNodeJs } from 'react-icons/fa' +import { NavGroup } from '../types' + +export const NodeReference: NavGroup = { + title: 'Node.js', + icon: FaNodeJs, + items: [ + { + title: 'Overview', + href: '/reference/nodejs', + breadcrumbRoot: true, + }, + { + title: 'APIs', + items: [ + { + title: 'api()', + href: '/reference/nodejs/api/api', + }, + { + title: 'api.get()', + href: '/reference/nodejs/api/api-get', + }, + { + title: 'api.post()', + href: '/reference/nodejs/api/api-post', + }, + { + title: 'api.put()', + href: '/reference/nodejs/api/api-put', + }, + { + title: 'api.delete()', + href: '/reference/nodejs/api/api-delete', + }, + { + title: 'api.patch()', + href: '/reference/nodejs/api/api-patch', + }, + { + title: 'api.route()', + href: '/reference/nodejs/api/api-route', + }, + { + title: 'api.route.all()', + href: '/reference/nodejs/api/api-route-all', + }, + { + title: 'api.route.get()', + href: '/reference/nodejs/api/api-route-get', + }, + { + title: 'api.route.post()', + href: '/reference/nodejs/api/api-route-post', + }, + { + title: 'api.route.put()', + href: '/reference/nodejs/api/api-route-put', + }, + { + title: 'api.route.delete()', + href: '/reference/nodejs/api/api-route-delete', + }, + { + title: 'api.route.patch()', + href: '/reference/nodejs/api/api-route-patch', + }, + ], + }, + { + title: 'HTTP', + items: [ + { + title: 'http()', + href: '/reference/nodejs/http/http', + }, + ], + }, + { + title: 'Key Value Stores', + items: [ + { + title: 'kv()', + href: '/reference/nodejs/keyvalue/keyvalue', + }, + { + title: 'kv.get()', + href: '/reference/nodejs/keyvalue/keyvalue-get', + }, + { + title: 'kv.set()', + href: '/reference/nodejs/keyvalue/keyvalue-set', + }, + { + title: 'kv.delete()', + href: '/reference/nodejs/keyvalue/keyvalue-delete', + }, + { + title: 'kv.keys()', + href: '/reference/nodejs/keyvalue/keyvalue-keys', + }, + ], + }, + { + title: 'Topics', + items: [ + { + title: 'topic()', + href: '/reference/nodejs/topic/topic', + }, + { + title: 'topic.publish()', + href: '/reference/nodejs/topic/topic-publish', + }, + { + title: 'topic.subscribe()', + href: '/reference/nodejs/topic/topic-subscribe', + }, + ], + }, + { + title: 'Queues', + items: [ + { + title: 'queue()', + href: '/reference/nodejs/queues/queue', + }, + { + title: 'queue.enqueue()', + href: '/reference/nodejs/queues/queue-enqueue', + }, + { + title: 'queue.dequeue()', + href: '/reference/nodejs/queues/queue-dequeue', + }, + ], + }, + { + title: 'Secrets', + items: [ + { + title: 'secret()', + href: '/reference/nodejs/secrets/secret', + }, + { + title: 'secret.put()', + href: '/reference/nodejs/secrets/secret-put', + }, + { + title: 'secret.version()', + href: '/reference/nodejs/secrets/secret-version', + }, + { + title: 'secret.latest()', + href: '/reference/nodejs/secrets/secret-latest', + }, + { + title: 'secret.version.access()', + href: '/reference/nodejs/secrets/secret-version-access', + }, + ], + }, + { + title: 'Storage', + items: [ + { + title: 'bucket()', + href: '/reference/nodejs/storage/bucket', + }, + { + title: 'bucket.on()', + href: '/reference/nodejs/storage/bucket-on', + }, + { + title: 'bucket.file()', + href: '/reference/nodejs/storage/bucket-file', + }, + { + title: 'bucket.files()', + href: '/reference/nodejs/storage/bucket-files', + }, + { + title: 'file.exists()', + href: '/reference/nodejs/storage/bucket-file-exists', + }, + { + title: 'file.read()', + href: '/reference/nodejs/storage/bucket-file-read', + }, + { + title: 'file.write()', + href: '/reference/nodejs/storage/bucket-file-write', + }, + { + title: 'file.delete()', + href: '/reference/nodejs/storage/bucket-file-delete', + }, + { + title: 'file.getDownloadUrl()', + href: '/reference/nodejs/storage/bucket-file-downloadurl', + }, + { + title: 'file.getUploadUrl()', + href: '/reference/nodejs/storage/bucket-file-uploadurl', + }, + ], + }, + { + title: 'SQL', + items: [ + { + title: 'sql()', + href: '/reference/nodejs/sql/sql', + }, + { + title: 'sql.connectionString()', + href: '/reference/nodejs/sql/sql-connection-string', + }, + ], + }, + { + title: 'Schedules', + items: [ + { + title: 'schedule()', + href: '/reference/nodejs/schedule/schedule', + }, + { + title: 'schedule.every()', + href: '/reference/nodejs/schedule/schedule-every', + }, + { + title: 'schedule.cron()', + href: '/reference/nodejs/schedule/schedule-cron', + }, + ], + }, + { + title: 'Websockets', + items: [ + { + title: 'websocket()', + href: '/reference/nodejs/websocket/websocket', + }, + { + title: 'websocket.on()', + href: '/reference/nodejs/websocket/websocket-on', + }, + { + title: 'websocket.send()', + href: '/reference/nodejs/websocket/websocket-send', + }, + { + title: 'websocket.close()', + href: '/reference/nodejs/websocket/websocket-close', + }, + ], + }, + ], +} diff --git a/src/config/reference/python.ts b/src/config/reference/python.ts new file mode 100644 index 000000000..b0935809e --- /dev/null +++ b/src/config/reference/python.ts @@ -0,0 +1,215 @@ +import { FaPython } from 'react-icons/fa' +import { NavGroup } from '../types' + +export const PyReference: NavGroup = { + title: 'Python', + icon: FaPython, + items: [ + { + title: 'Overview', + href: '/reference/python', + breadcrumbRoot: true, + }, + { + title: 'APIs', + items: [ + { + title: 'api()', + href: '/reference/python/api/api', + }, + { + title: 'api.get()', + href: '/reference/python/api/api-get', + }, + { + title: 'api.post()', + href: '/reference/python/api/api-post', + }, + { + title: 'api.put()', + href: '/reference/python/api/api-put', + }, + { + title: 'api.delete()', + href: '/reference/python/api/api-delete', + }, + { + title: 'api.patch()', + href: '/reference/python/api/api-patch', + }, + { + title: 'api.methods()', + href: '/reference/python/api/api-methods', + }, + { + title: 'api.all()', + href: '/reference/python/api/api-all', + }, + ], + }, + { + title: 'Key Value Stores', + items: [ + { + title: 'kv()', + href: '/reference/python/keyvalue/keyvalue', + }, + { + title: 'kv.get()', + href: '/reference/python/keyvalue/keyvalue-get', + }, + { + title: 'kv.set()', + href: '/reference/python/keyvalue/keyvalue-set', + }, + { + title: 'kv.delete()', + href: '/reference/python/keyvalue/keyvalue-delete', + }, + { + title: 'kv.keys()', + href: '/reference/python/keyvalue/keyvalue-keys', + }, + ], + }, + { + title: 'Sql', + items: [ + { + title: 'sql()', + href: '/reference/python/sql/sql', + }, + { + title: 'sql.connection_string()', + href: '/reference/python/sql/sql-connection-string', + }, + ], + }, + { + title: 'Topics', + items: [ + { + title: 'topic()', + href: '/reference/python/topic/topic', + }, + { + title: 'topic.publish()', + href: '/reference/python/topic/topic-publish', + }, + { + title: 'topic.subscribe()', + href: '/reference/python/topic/topic-subscribe', + }, + ], + }, + { + title: 'Queues', + items: [ + { + title: 'queue()', + href: '/reference/python/queues/queue', + }, + { + title: 'queue.enqueue()', + href: '/reference/python/queues/queue-enqueue', + }, + { + title: 'queue.dequeue()', + href: '/reference/python/queues/queue-dequeue', + }, + ], + }, + { + title: 'Secrets', + items: [ + { + title: 'secret()', + href: '/reference/python/secrets/secret', + }, + { + title: 'secret.put()', + href: '/reference/python/secrets/secret-put', + }, + { + title: 'secret.version()', + href: '/reference/python/secrets/secret-version', + }, + { + title: 'secret.latest()', + href: '/reference/python/secrets/secret-latest', + }, + { + title: 'secret.version.access()', + href: '/reference/python/secrets/secret-version-access', + }, + ], + }, + { + title: 'Storage', + items: [ + { + title: 'bucket()', + href: '/reference/python/storage/bucket', + }, + { + title: 'bucket.on()', + href: '/reference/python/storage/bucket-on', + }, + { + title: 'bucket.file()', + href: '/reference/python/storage/bucket-file', + }, + { + title: 'bucket.files()', + href: '/reference/python/storage/bucket-files', + }, + { + title: 'file.read()', + href: '/reference/python/storage/bucket-file-read', + }, + { + title: 'file.write()', + href: '/reference/python/storage/bucket-file-write', + }, + { + title: 'file.delete()', + href: '/reference/python/storage/bucket-file-delete', + }, + { + title: 'file.download_url()', + href: '/reference/python/storage/bucket-file-downloadurl', + }, + { + title: 'file.upload_url()', + href: '/reference/python/storage/bucket-file-uploadurl', + }, + ], + }, + { + title: 'Schedules', + items: [ + { + title: 'schedule()', + href: '/reference/python/schedules/schedule', + }, + ], + }, + { + title: 'Websockets', + items: [ + { + title: 'websocket()', + href: '/reference/python/websocket/websocket', + }, + { + title: 'websocket.on()', + href: '/reference/python/websocket/websocket-on', + }, + { + title: 'websocket.send()', + href: '/reference/python/websocket/websocket-send', + }, + ], + }, + ], +} diff --git a/src/config/types.ts b/src/config/types.ts new file mode 100644 index 000000000..bdc0f201c --- /dev/null +++ b/src/config/types.ts @@ -0,0 +1,16 @@ +export interface BaseNavItem { + title: string + icon?: React.ComponentType<{ className?: string }> +} + +export interface NavItem extends BaseNavItem { + href: string + items?: NavItem[] + breadcrumbRoot?: boolean +} + +export interface NavGroup extends BaseNavItem { + items: NavEntry[] +} + +export type NavEntry = NavItem | NavGroup diff --git a/src/hooks/useLang.ts b/src/hooks/useLang.ts new file mode 100644 index 000000000..49ff1b4e0 --- /dev/null +++ b/src/hooks/useLang.ts @@ -0,0 +1,94 @@ +import { useSearchParams } from 'next/navigation' +import { useCallback, useEffect } from 'react' + +export type LanguageId = + | 'javascript' + | 'typescript' + | 'dart' + | 'python' + | 'ruby' + | 'java' + | 'csharp' + | 'go' + | 'php' + | 'rust' + | 'swift' + | 'kotlin' + | 'scala' + | 'r' + | 'perl' + | 'haskell' + | 'lua' + | 'shell' + | 'sql' + | 'plaintext' + +const languages = ['javascript', 'python', 'go', 'typescript', 'dart'] + +const LOCAL_STORAGE_KEY = 'nitric.docs.selected.language' + +const useLang = () => { + const searchParams = useSearchParams() + + const queryParamLang = searchParams.get('lang') as LanguageId + + const currentLanguage = languages.includes(queryParamLang) + ? queryParamLang + : languages[0] + + const setLanguage = useCallback( + (id: LanguageId) => { + // Apparently this nonsense is necessary to update the URL. + // See: https://github.com/vercel/next.js/discussions/47583 + const currentParams = new URLSearchParams( + Array.from(searchParams.entries()), + ) + + if (!id) { + currentParams.delete('lang') + } else { + currentParams.set('lang', id) + } + + const search = currentParams.toString() + const query = search ? `?${search}` : '' + + window.history.pushState(null, '', query) + + if (query) { + // set language in local storage + try { + localStorage.setItem(LOCAL_STORAGE_KEY, id) + } catch (e) { + // ignore + } + } + }, + [searchParams], + ) + + useEffect(() => { + // add data current lang to body to style based on language, used in hide/show blocks + document.body.dataset.currentLang = currentLanguage + + // set query params from local storage if no query params are present + if (!queryParamLang) { + const localLang = localStorage.getItem(LOCAL_STORAGE_KEY) as LanguageId + if ( + localLang && + languages.includes(localLang) && + localLang !== currentLanguage + ) { + setLanguage(localLang) + } + } + }, [currentLanguage]) + + return { + languages, + currentLanguage, + setCurrentLanguage: setLanguage, + } +} + +export default useLang diff --git a/src/images/logos/go copy.svg b/src/images/logos/go copy.svg new file mode 100644 index 000000000..7f7b19de5 --- /dev/null +++ b/src/images/logos/go copy.svg @@ -0,0 +1,14 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="none"> + <g fill="#00ACD7" clip-path="url(#a)"> + <path fill-rule="evenodd" + d="M5.8 19.334c-.08 0-.093-.054-.067-.107l.4-.533a.421.421 0 0 1 .227-.08h6.893c.08 0 .094.053.067.106l-.334.507c-.04.053-.133.12-.2.12L5.8 19.32v.014Zm-2.92 1.773c-.08 0-.093-.04-.053-.107l.4-.52c.04-.053.133-.093.213-.093h8.8c.093 0 .133.053.107.12l-.16.453c-.014.08-.094.134-.174.134H2.88v.013Zm4.68 1.773c-.08 0-.107-.053-.067-.12l.267-.48c.053-.053.133-.12.2-.12h3.866c.08 0 .12.067.12.134l-.04.466c0 .08-.08.134-.133.134L7.56 22.88Zm20.053-3.906-3.24.853c-.293.08-.32.093-.56-.2-.293-.32-.506-.533-.92-.733a3.36 3.36 0 0 0-3.493.293 4.107 4.107 0 0 0-1.973 3.667 3.027 3.027 0 0 0 2.613 3.04c1.306.173 2.413-.294 3.28-1.28l.533-.707H20.12c-.4 0-.507-.267-.373-.587.253-.6.72-1.6.986-2.106a.533.533 0 0 1 .48-.307h7.04c-.04.533-.04 1.04-.12 1.573-.213 1.387-.733 2.667-1.586 3.787a8.053 8.053 0 0 1-5.507 3.28 6.839 6.839 0 0 1-5.2-1.28A6.065 6.065 0 0 1 13.386 24c-.24-2.106.374-4 1.654-5.666A8.573 8.573 0 0 1 20.44 15a6.667 6.667 0 0 1 5.12.934c1.027.666 1.76 1.6 2.253 2.733.107.173.027.267-.2.32v-.013Z" + clip-rule="evenodd" /> + <path + d="M34 29.667a7.253 7.253 0 0 1-4.707-1.707 6.066 6.066 0 0 1-2.08-3.733 7.373 7.373 0 0 1 1.56-5.827 8.107 8.107 0 0 1 5.413-3.226 7.173 7.173 0 0 1 5.507.986 6.015 6.015 0 0 1 2.72 4.307 7.467 7.467 0 0 1-2.227 6.547 8.854 8.854 0 0 1-4.626 2.48c-.534.093-1.054.106-1.547.173H34Zm4.613-7.813c-.027-.254-.027-.44-.067-.64a3.186 3.186 0 0 0-3.933-2.547 4.227 4.227 0 0 0-3.387 3.36A3.187 3.187 0 0 0 33 25.68c1.066.454 2.133.4 3.16-.133a4.227 4.227 0 0 0 2.453-3.68v-.013Z" /> + </g> + <defs> + <clipPath id="a"> + <path fill="#fff" d="M4 4h40v40H4z" /> + </clipPath> + </defs> +</svg> diff --git a/src/images/logos/node copy.svg b/src/images/logos/node copy.svg new file mode 100644 index 000000000..1d09de22b --- /dev/null +++ b/src/images/logos/node copy.svg @@ -0,0 +1,4 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="none"> + <path fill="#89D42C" + d="M23.675 39.82a2.48 2.48 0 0 1-1.19-.313l-3.764-2.236c-.568-.31-.285-.425-.114-.48.765-.256.906-.313 1.698-.765.086-.057.198-.029.284.028l2.888 1.727c.113.057.254.057.34 0l11.296-6.54c.113-.057.17-.17.17-.312v-13.05c0-.143-.057-.256-.17-.313l-11.296-6.51c-.114-.057-.256-.057-.34 0L12.18 17.567c-.114.057-.17.198-.17.311V30.93c0 .114.056.255.17.312l3.087 1.784c1.67.849 2.717-.143 2.717-1.133V19.01a.344.344 0 0 1 .34-.34h1.443a.344.344 0 0 1 .341.34v12.882c0 2.237-1.218 3.539-3.342 3.539-.65 0-1.16 0-2.604-.708l-2.975-1.698A2.39 2.39 0 0 1 10 30.959V17.904c0-.849.452-1.642 1.189-2.066l11.296-6.54a2.527 2.527 0 0 1 2.379 0l11.297 6.54a2.39 2.39 0 0 1 1.188 2.066V30.96c0 .85-.452 1.642-1.188 2.066l-11.297 6.54a2.896 2.896 0 0 1-1.189.256v-.001Zm3.482-8.976c-4.954 0-5.973-2.264-5.973-4.19a.344.344 0 0 1 .34-.34h1.472c.169 0 .311.114.311.284.226 1.5.878 2.236 3.879 2.236 2.378 0 3.397-.538 3.397-1.812 0-.736-.283-1.274-3.992-1.642-3.086-.311-5.012-.99-5.012-3.454 0-2.293 1.926-3.652 5.154-3.652 3.623 0 5.407 1.246 5.634 3.963a.459.459 0 0 1-.086.256c-.056.056-.141.113-.226.113h-1.472a.332.332 0 0 1-.311-.256c-.34-1.555-1.217-2.066-3.539-2.066-2.605 0-2.916.906-2.916 1.585 0 .821.368 1.076 3.878 1.53 3.483.452 5.124 1.104 5.124 3.539-.027 2.491-2.066 3.907-5.662 3.907Z" /> +</svg> diff --git a/src/images/logos/php copy.svg b/src/images/logos/php copy.svg new file mode 100644 index 000000000..0a9ac462a --- /dev/null +++ b/src/images/logos/php copy.svg @@ -0,0 +1,10 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="none"> + <path fill="#6181B6" fill-rule="evenodd" + d="M14.643 21.762h-1.77l-.964 4.965h1.57c1.043 0 1.82-.198 2.33-.59.51-.393.853-1.047 1.03-1.966.173-.882.095-1.503-.232-1.866-.328-.362-.98-.543-1.962-.543h-.002Z" + clip-rule="evenodd" /> + <path fill="#6181B6" + d="M24 13.29c-12.426 0-22.5 5.3-22.5 11.835 0 6.535 10.074 11.837 22.5 11.837s22.5-5.3 22.5-11.837S36.426 13.29 24 13.29Zm-6.113 13.971a4.55 4.55 0 0 1-1.718 1.032c-.63.203-1.434.308-2.41.308h-2.215l-.612 3.152H8.346l2.307-11.861h4.968c1.494 0 2.585.391 3.27 1.177.687.785.893 1.88.618 3.285a5.34 5.34 0 0 1-.57 1.588c-.28.493-.634.938-1.053 1.319h.002Zm7.546 1.34 1.018-5.247c.119-.598.073-1.005-.128-1.221-.2-.218-.63-.328-1.288-.328h-2.047l-1.32 6.799h-2.566L21.41 16.74h2.561l-.611 3.155h2.282c1.439 0 2.429.25 2.975.75.546.499.708 1.314.492 2.437l-1.073 5.52h-2.604V28.6Zm14.243-4.245a5.215 5.215 0 0 1-.571 1.586 5.356 5.356 0 0 1-1.051 1.319c-.49.467-1.078.82-1.721 1.032-.63.203-1.434.308-2.41.308H31.71l-.614 3.154h-2.581l2.305-11.862h4.968c1.495 0 2.584.393 3.27 1.177.686.784.895 1.878.62 3.285h-.002Z" /> + <path fill="#6181B6" fill-rule="evenodd" + d="M34.81 21.762h-1.765l-.968 4.965h1.571c1.044 0 1.821-.198 2.33-.59.51-.393.852-1.047 1.032-1.966.172-.882.093-1.503-.234-1.866-.326-.362-.983-.543-1.964-.543h-.002Z" + clip-rule="evenodd" /> +</svg> diff --git a/src/images/logos/python copy.svg b/src/images/logos/python copy.svg new file mode 100644 index 000000000..9bceb587a --- /dev/null +++ b/src/images/logos/python copy.svg @@ -0,0 +1,13 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="none"> + <g clip-path="url(#a)"> + <path fill="#3372A7" + d="M23.429 9.008c-7.882 0-7.39 3.418-7.39 3.418l.01 3.541h7.52v1.063H13.062s-5.043-.572-5.043 7.38c0 7.954 4.402 7.671 4.402 7.671h2.627v-3.69s-.142-4.402 4.331-4.402h7.46s4.191.068 4.191-4.05v-6.81s.637-4.12-7.6-4.12Zm-4.147 2.382a1.353 1.353 0 1 1 .001 2.706 1.353 1.353 0 0 1-.001-2.706Z" /> + <path fill="#FFD235" + d="M23.653 39.894c7.881 0 7.39-3.418 7.39-3.418l-.01-3.541h-7.52v-1.063H34.02s5.043.572 5.043-7.381-4.402-7.67-4.402-7.67h-2.627v3.69s.142 4.402-4.332 4.402h-7.46s-4.19-.068-4.19 4.05v6.81s-.637 4.12 7.6 4.12Zm4.147-2.381a1.353 1.353 0 1 1-.002-2.707 1.353 1.353 0 0 1 .002 2.706Z" /> + </g> + <defs> + <clipPath id="a"> + <path fill="#fff" d="M8 9h31.122v31H8z" /> + </clipPath> + </defs> +</svg> diff --git a/src/images/logos/ruby copy.svg b/src/images/logos/ruby copy.svg new file mode 100644 index 000000000..b22a5bf10 --- /dev/null +++ b/src/images/logos/ruby copy.svg @@ -0,0 +1,4 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="none"> + <path fill="#D91505" + d="M33.735 10.41c3.376.585 4.334 2.893 4.262 5.311l.017-.035-1.519 19.912-19.752 1.352h.017c-1.639-.069-5.294-.218-5.46-5.328l1.83-3.34 3.139 7.331.56 1.306L19.95 26.74l-.032.007.017-.034 10.302 3.29-1.555-6.044-1.101-4.341 9.817-.634-.684-.567-7.048-5.746 4.073-2.272-.004.012v-.001ZM17.01 15.966c3.963-3.932 9.079-6.256 11.044-4.274 1.96 1.98-.118 6.796-4.089 10.726-3.966 3.931-9.02 6.382-10.98 4.405-1.967-1.98.05-6.921 4.02-10.853l.005-.004Z" /> +</svg> diff --git a/src/lib/constants.ts b/src/lib/constants.ts new file mode 100644 index 000000000..af717ef2e --- /dev/null +++ b/src/lib/constants.ts @@ -0,0 +1,34 @@ +interface Language { + label: string + value: string + icon: string +} + +export const LANGUAGES: Language[] = [ + { + label: 'Node.js', + value: 'node', + icon: '/img/node-logo.svg', + }, + { label: 'Python', value: 'python', icon: '/img/python-logo.svg' }, + { label: 'Java', value: 'java', icon: '/img/java-logo.svg' }, + { label: 'Go', value: 'go', icon: '/img/go-logo.svg' }, +] + +export const isMobile = + typeof navigator !== 'undefined' && + /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( + navigator.userAgent, + ) + +export const discordChatUrl = + process.env.NEXT_PUBLIC_VERCEL_ENV === 'production' + ? 'https://nitric.io/chat' + : process.env.NEXT_PUBLIC_VERCEL_URL + ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}/chat` + : `http://localhost:3000/chat` + +export const BASE_URL = + process.env.NEXT_PUBLIC_VERCEL_ENV === 'production' + ? 'https://nitric.io' + : `https://${process.env.NEXT_PUBLIC_VERCEL_URL || 'localhost:3000'}` diff --git a/src/lib/getNavInfo.ts b/src/lib/getNavInfo.ts new file mode 100644 index 000000000..399d20e01 --- /dev/null +++ b/src/lib/getNavInfo.ts @@ -0,0 +1,53 @@ +import { navigation } from '@/config' +import { NavEntry, NavItem } from '@/config/types' +import { Doc } from '@/content' + +interface NavItemWithBreadcrumb extends NavItem { + breadcrumbParentItem?: NavEntry +} + +interface NavInfo { + prevItem: NavItemWithBreadcrumb | null + navItem: NavItemWithBreadcrumb | null + nextItem: NavItemWithBreadcrumb | null +} + +const flatten = ( + entries: NavEntry[], + rootParent?: NavEntry, + breadcrumbParentItem?: NavEntry, +): NavItemWithBreadcrumb[] => { + return entries.flatMap((entry) => { + if ('href' in entry) { + if (entry.breadcrumbRoot) { + breadcrumbParentItem = { + ...entry, + title: rootParent?.title || entry.title, // take title of parent if available + } + } + + return breadcrumbParentItem + ? { + ...entry, + breadcrumbParentItem, + } + : entry + } + return flatten(entry.items, entry, breadcrumbParentItem) + }) +} + +// This function should return an object that contains the current nav item, the previous nav item, and the next nav item. +export function getNavInfo(doc: Doc): NavInfo { + const slug = doc.slug ? `/${doc.slug}` : '/' + + const flattenedNav = flatten(navigation) + + const index = flattenedNav.findIndex((item) => item.href === slug) + + return { + navItem: flattenedNav[index] || null, + prevItem: flattenedNav[index - 1] || null, + nextItem: flattenedNav[index + 1] || null, + } +} diff --git a/src/lib/hooks/use-versions.ts b/src/lib/hooks/use-versions.ts deleted file mode 100644 index e0f1d487b..000000000 --- a/src/lib/hooks/use-versions.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Version } from '@/nav.config' -import { useRouter } from 'next/router' - -const versionRegex = /\/reference\/[^\/]+\/v\d+/ - -const SDK_LABEL_MAP = { - go: 'Go', - jvm: 'JVM', - nodejs: 'Node.js', - python: 'Python', - csharp: 'C# .NET', - dart: 'Dart', -} - -export const useVersions = (versions?: Version[]) => { - const router = useRouter() - - const latestVersion = versions ? [...versions].sort().pop() : '' - - const isReferenceDocs = router.pathname.startsWith('/reference/') - const match = router.pathname.match(versionRegex) - const isNotLatest = isReferenceDocs && !!match - const currentVersion = - !isNotLatest && versions?.length - ? latestVersion - : match - ? match[0].split('/').pop() - : undefined - const currentSdk = router.pathname.split('/reference/')[1]?.split('/')[0] - - const latestLink = `/reference/${currentSdk}` - - return { - isReferenceDocs, - currentVersion, - latestVersion, - currentSdk, - currentSdkLabel: SDK_LABEL_MAP[currentSdk], - isNotLatest, - latestLink, - } -} diff --git a/src/lib/remToPx.ts b/src/lib/remToPx.ts index 9ae9628d6..d3c3953a1 100644 --- a/src/lib/remToPx.ts +++ b/src/lib/remToPx.ts @@ -1,8 +1,8 @@ -export function remToPx(remValue) { +export function remToPx(remValue: number) { let rootFontSize = typeof window === 'undefined' ? 16 : parseFloat(window.getComputedStyle(document.documentElement).fontSize) - return parseFloat(remValue) * rootFontSize + return remValue * rootFontSize } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index d32b0fe65..fed2fe91e 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,4 +1,4 @@ -import { type ClassValue, clsx } from 'clsx' +import { clsx, type ClassValue } from 'clsx' import { twMerge } from 'tailwind-merge' export function cn(...inputs: ClassValue[]) { diff --git a/src/mdx/mdx-options.mjs b/src/mdx/mdx-options.mjs new file mode 100644 index 000000000..0582c6162 --- /dev/null +++ b/src/mdx/mdx-options.mjs @@ -0,0 +1,16 @@ +import { recmaPlugins } from './recma.mjs' +import { rehypePlugins } from './rehype.mjs' +import { remarkPlugins } from './remark.mjs' +import { recmaCodeHike, remarkCodeHike } from 'codehike/mdx' + +/** @type {import('codehike/mdx').CodeHikeConfig} */ +const chConfig = { + components: { code: 'Code' }, +} + +export const mdxOptions = { + remarkPlugins: [...remarkPlugins, [remarkCodeHike, chConfig]], + rehypePlugins, + recmaPlugins: [...recmaPlugins, [recmaCodeHike, chConfig]], + jsx: true, +} diff --git a/src/mdx/recma.mjs b/src/mdx/recma.mjs index 489011603..b88cc48d4 100644 --- a/src/mdx/recma.mjs +++ b/src/mdx/recma.mjs @@ -1,19 +1,3 @@ import { mdxAnnotations } from 'mdx-annotations' -import recmaNextjsStaticProps from 'recma-nextjs-static-props' -function recmaRemoveNamedExports() { - return (tree) => { - tree.body = tree.body.map((node) => { - if (node.type === 'ExportNamedDeclaration') { - return node.declaration - } - return node - }) - } -} - -export const recmaPlugins = [ - mdxAnnotations.recma, - recmaRemoveNamedExports, - recmaNextjsStaticProps, -] +export const recmaPlugins = [mdxAnnotations.recma] diff --git a/src/mdx/rehype.mjs b/src/mdx/rehype.mjs index 6a1793e06..7b268ef63 100644 --- a/src/mdx/rehype.mjs +++ b/src/mdx/rehype.mjs @@ -1,14 +1,10 @@ +import { slugifyWithCounter } from '@sindresorhus/slugify' +import * as acorn from 'acorn' +import { toString } from 'mdast-util-to-string' import { mdxAnnotations } from 'mdx-annotations' import { visit } from 'unist-util-visit' -import rehypeMdxTitle from 'rehype-mdx-title' -import { - createHighlighter, - createCssVariablesTheme, - getSingletonHighlighter, -} from 'shiki' -import { toString } from 'mdast-util-to-string' -import * as acorn from 'acorn' -import { slugifyWithCounter } from '@sindresorhus/slugify' +import rehypeAutolinkHeadings from 'rehype-autolink-headings' +import { fromHtmlIsomorphic } from 'hast-util-from-html-isomorphic' function rehypeParseCodeBlocks() { return (tree) => { @@ -16,68 +12,13 @@ function rehypeParseCodeBlocks() { if (node.tagName === 'code' && node.properties.className) { parentNode.properties.language = node.properties.className[0]?.replace( /^language-/, - '' + '', ) } }) } } -function rehypeShiki() { - return async (tree) => { - const cssTheme = createCssVariablesTheme({ - name: 'css-variables', - variablePrefix: '--shiki-', - variableDefaults: {}, - fontStyle: true, - }) - - const highlighter = await getSingletonHighlighter({ - themes: [cssTheme], - langs: [ - 'javascript', - 'typescript', - 'php', - 'python', - 'ruby', - 'shellscript', - 'csharp', - 'text', - 'java', - 'kotlin', - 'terraform', - 'make', - 'hcl', - 'dart', - 'go', - 'yaml', - 'bicep', - 'dockerfile', - 'json', - 'prisma', - 'toml', - 'graphql', - ], - }) - - visit(tree, 'element', (node) => { - if (node.tagName === 'pre' && node.children[0]?.tagName === 'code') { - let codeNode = node.children[0] - let textNode = codeNode.children[0] - - node.properties.code = textNode.value - - if (node.properties.language) { - textNode.value = highlighter.codeToHtml(textNode.value, { - lang: node.properties.language, - theme: 'css-variables', - }) - } - } - }) - } -} - function rehypeSlugify() { return (tree) => { let slugify = slugifyWithCounter() @@ -137,16 +78,36 @@ function getSections(node) { return sections } +const icon = fromHtmlIsomorphic( + ` + <span class="content-header-link"> + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" className="w-5 h-5 linkicon"> + <path d="M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z" /> + <path d="M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z" /> + </svg> + </span> +`, + { fragment: true }, +) + export const rehypePlugins = [ mdxAnnotations.rehype, rehypeParseCodeBlocks, - rehypeShiki, rehypeSlugify, - rehypeMdxTitle, [ rehypeAddMDXExports, (tree) => ({ sections: `[${getSections(tree).join()}]`, }), ], + [ + rehypeAutolinkHeadings, + { + behavior: 'append', + headingProperties: { + className: ['md-content-header group'], + }, + content: icon, + }, + ], ] diff --git a/src/mdx/remark-toc-headings.mjs b/src/mdx/remark-toc-headings.mjs new file mode 100644 index 000000000..fcb6d09fd --- /dev/null +++ b/src/mdx/remark-toc-headings.mjs @@ -0,0 +1,41 @@ +import { visit } from 'unist-util-visit' +import { toString } from 'mdast-util-to-string' +import { remark } from 'remark' +import slugify from 'slugify' + +/** + * Extracts TOC headings from markdown file and adds it to the file's data object. + */ +export function remarkTocHeadings() { + return (tree, file) => { + const toc = [] + visit(tree, 'heading', (node) => { + if (node.depth !== 2) return // ignore h1 and h3+ + + const textContent = toString(node) + toc.push({ + value: textContent, + url: + '#' + + slugify(textContent, { + lower: true, + strict: true, + }), + depth: node.depth, + }) + }) + file.data.toc = toc + } +} + +/** + * Passes markdown file through remark to extract TOC headings + * + * @param {string} markdown + * @return {*} {Promise<Toc>} + */ +export async function extractTocHeadings(markdown) { + const vfile = await remark().use(remarkTocHeadings).process(markdown) + // @ts-ignore + return vfile.data.toc +} diff --git a/src/mdx/remark.mjs b/src/mdx/remark.mjs index 6052b4aa7..e523464b4 100644 --- a/src/mdx/remark.mjs +++ b/src/mdx/remark.mjs @@ -1,5 +1,4 @@ import { mdxAnnotations } from 'mdx-annotations' import remarkGfm from 'remark-gfm' -import codeImport from 'remark-code-import' -export const remarkPlugins = [mdxAnnotations.remark, remarkGfm, codeImport] +export const remarkPlugins = [mdxAnnotations.remark, remarkGfm] diff --git a/src/mdx/search.mjs b/src/mdx/search.mjs index 06a29fae7..813070c27 100644 --- a/src/mdx/search.mjs +++ b/src/mdx/search.mjs @@ -1,14 +1,14 @@ -import { createLoader } from 'simple-functional-loader' +import { slugifyWithCounter } from '@sindresorhus/slugify' import glob from 'fast-glob' -import { remark } from 'remark' -import remarkMdx from 'remark-mdx' -import * as url from 'url' -import * as path from 'path' import * as fs from 'fs' -import { visit, SKIP } from 'unist-util-visit' -import { slugifyWithCounter } from '@sindresorhus/slugify' import { toString } from 'mdast-util-to-string' +import * as path from 'path' +import { remark } from 'remark' +import remarkMdx from 'remark-mdx' +import { createLoader } from 'simple-functional-loader' import { filter } from 'unist-util-filter' +import { SKIP, visit } from 'unist-util-visit' +import * as url from 'url' const __filename = url.fileURLToPath(import.meta.url) const processor = remark().use(remarkMdx).use(extractSections) @@ -44,7 +44,7 @@ function extractSections() { } } -export default function (nextConfig = {}) { +export default function Search(nextConfig = {}) { let cache = new Map() return Object.assign({}, nextConfig, { @@ -53,14 +53,13 @@ export default function (nextConfig = {}) { test: __filename, use: [ createLoader(function () { - let pagesDir = path.resolve('./src/pages') - this.addContextDependency(pagesDir) + let appDir = path.resolve('./src/app') + this.addContextDependency(appDir) - let files = glob.sync('**/*.mdx', { cwd: pagesDir }) + let files = glob.sync('**/*.mdx', { cwd: appDir }) let data = files.map((file) => { - let url = - file === 'index.mdx' ? '/' : `/${file.replace(/\.mdx$/, '')}` - let mdx = fs.readFileSync(path.join(pagesDir, file), 'utf8') + let url = '/' + file.replace(/(^|\/)page\.mdx$/, '') + let mdx = fs.readFileSync(path.join(appDir, file), 'utf8') let sections = [] diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx deleted file mode 100644 index 7602321ee..000000000 --- a/src/pages/_app.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import Head from 'next/head' -import { Router, useRouter } from 'next/router' -import { MDXProvider } from '@mdx-js/react' -import * as Fathom from 'fathom-client' - -import { Layout } from '@/components/Layout' -import * as mdxComponents from '@/components/mdx' -import { useMobileNavigationStore } from '@/components/MobileNavigation' - -import '@/styles/tailwind.css' -import 'focus-visible' -import { useEffect } from 'react' -import { useVersions } from '@/lib/hooks/use-versions' - -function onRouteChange() { - useMobileNavigationStore.getState().close() -} - -Router.events.on('routeChangeStart', onRouteChange) -Router.events.on('hashChangeStart', onRouteChange) - -// Record a pageview when route changes -Router.events.on('routeChangeComplete', (url: string, routeProps) => { - if (!routeProps.shallow && process.env.NEXT_PUBLIC_FATHOM_SITE_ID) { - Fathom.trackPageview({ url }) - } -}) - -export default function App({ Component, pageProps }) { - const router = useRouter() - - // Initialize Fathom when the app loads - useEffect(() => { - Fathom.load(`${process.env.NEXT_PUBLIC_FATHOM_SITE_ID}`, { - // disable for preview branches in Vercel - excludedDomains: ['vercel.app'], - }) - }, []) - - const { isNotLatest, isReferenceDocs, currentVersion } = useVersions() - - const titleSuffix = - isReferenceDocs && isNotLatest - ? `Nitric ${currentVersion} Documentation` - : 'Nitric Documentation' - - const title = - router.pathname === '/' - ? 'Nitric Documentation' - : `${pageProps.title_meta || pageProps.title} - ${titleSuffix}` - const description = - pageProps.description || - 'Documentation for the Nitric cloud application framework.' - - const baseUrl = - process.env.NEXT_PUBLIC_VERCEL_ENV === 'production' - ? 'https://nitric.io' - : `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` - - const cleanedPath = router.asPath.split('#')[0].split('?')[0] - - const ogTitle = - router.pathname === '/' ? 'Nitric Docs' : title.split(' - ')[0] - - return ( - <> - <Head> - <title>{title} - - - - - - - - - - - - - - - - - - - - - - - - - ) -} diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx deleted file mode 100644 index 0cca938c6..000000000 --- a/src/pages/_document.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Head, Html, Main, NextScript } from 'next/document' - -const modeScript = ` - let darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)') - - updateMode() - darkModeMediaQuery.addEventListener('change', updateModeWithoutTransitions) - window.addEventListener('storage', updateModeWithoutTransitions) - - function updateMode() { - let isSystemDarkMode = darkModeMediaQuery.matches - let isDarkMode = window.localStorage.isDarkMode === 'true' || (!('isDarkMode' in window.localStorage) && isSystemDarkMode) - - if (isDarkMode) { - document.documentElement.classList.add('dark') - } else { - document.documentElement.classList.remove('dark') - } - - if (isDarkMode === isSystemDarkMode) { - delete window.localStorage.isDarkMode - } - } - - function disableTransitionsTemporarily() { - document.documentElement.classList.add('[&_*]:!transition-none') - window.setTimeout(() => { - document.documentElement.classList.remove('[&_*]:!transition-none') - }, 0) - } - - function updateModeWithoutTransitions() { - disableTransitionsTemporarily() - updateMode() - } -` - -export default function Document() { - return ( - - -

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ÝGE{5Ud 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 diff --git a/src/actions/sendFeedback.ts b/src/actions/sendFeedback.ts new file mode 100644 index 000000000..7eb236266 --- /dev/null +++ b/src/actions/sendFeedback.ts @@ -0,0 +1,41 @@ +'use server' + +import { PrismaClient } from '@prisma/client' + +const prisma = new PrismaClient() + +export async function sendFeedback(prevState: any, formData: FormData) { + const answer = formData.get('choice') || '' + const comment = formData.get('comment') || '' + const ua = formData.get('ua') || '' + const url = formData.get('url') || '' + + console.log('sendFeedback', { answer, comment, ua, url }) + + // disable on non prod + if (process.env.NEXT_PUBLIC_VERCEL_ENV !== 'production') { + return { message: 'Not available on production' } + } + + // validate answer + if (!['yes', 'no', 'feedback'].includes(answer?.toString())) { + return { message: 'invalid' } + } + + try { + await prisma.feedback.create({ + data: { + url: url?.toString(), + answer: answer?.toString(), + comment: comment?.toString(), + label: 'is docs page helpful', + ua: ua?.toString(), + }, + }) + + return { message: 'Feedback sent!' } + } catch (error) { + console.error(error) + return { message: 'failed to store feedback' } + } +} diff --git a/src/app/(sitemaps)/sitemap-0.xml/route.ts b/src/app/(sitemaps)/sitemap-0.xml/route.ts new file mode 100644 index 000000000..46cf36a86 --- /dev/null +++ b/src/app/(sitemaps)/sitemap-0.xml/route.ts @@ -0,0 +1,46 @@ +import { allDocs } from '@/content' + +const URL = 'https://nitric.io/docs' + +interface SitemapItem { + loc: string + lastmod: string + changefreq: string + priority: number +} + +// Function to construct the XML structure of the sitemap index. +export async function GET() { + const pages: SitemapItem[] = allDocs.map((page) => ({ + loc: page.slug === '' ? URL : `${URL}/${page.slug}`, + lastmod: new Date(page.lastModified).toISOString(), + changefreq: 'daily', + priority: 0.7, + })) + + const allPagesSorted = [...pages].sort((a, b) => (a.loc < b.loc ? -1 : 1)) + + const sitemapIndexXML = buildSitemap(allPagesSorted) + + // Return the sitemap index XML with the appropriate content type. + return new Response(sitemapIndexXML, { + headers: { + 'Content-Type': 'application/xml', + }, + }) +} + +function buildSitemap(items: SitemapItem[]) { + let xml = '' + xml += '' + + for (const pageURL of items) { + xml += '' + xml += `${pageURL.loc}` + xml += `${pageURL.lastmod}` // Set the to the current date in IST + xml += '' + } + + xml += '' + return xml +} diff --git a/src/app/(sitemaps)/sitemap.xml/route.ts b/src/app/(sitemaps)/sitemap.xml/route.ts new file mode 100644 index 000000000..076746419 --- /dev/null +++ b/src/app/(sitemaps)/sitemap.xml/route.ts @@ -0,0 +1,30 @@ +// Function to construct the XML structure of the sitemap index. +export async function GET() { + const sitemapIndexXML = buildSitemapIndex([ + 'https://nitric.io/docs/sitemap-0.xml', + ]) + + // Return the sitemap index XML with the appropriate content type. + return new Response(sitemapIndexXML, { + headers: { + 'Content-Type': 'application/xml', + }, + }) +} + +function buildSitemapIndex(sitemaps: string[]) { + // XML declaration and opening tag for the sitemap index. + let xml = '' + xml += '' + + // Iterate over each sitemap URL and add it to the sitemap index. + for (const sitemapURL of sitemaps) { + xml += '' + xml += `${sitemapURL}` // Location tag specifying the URL of a sitemap file. + xml += '' + } + + // Closing tag for the sitemap index. + xml += '' + return xml +} diff --git a/src/app/Fathom.tsx b/src/app/Fathom.tsx new file mode 100644 index 000000000..e1496cc4e --- /dev/null +++ b/src/app/Fathom.tsx @@ -0,0 +1,50 @@ +// Fathom.tsx +'use client' + +import { load, trackPageview } from 'fathom-client' +import { useEffect, Suspense } from 'react' +import { usePathname, useSearchParams } from 'next/navigation' + +const SITE_ID = process.env.NEXT_PUBLIC_FATHOM_SITE_ID + +const enabled = !!SITE_ID + +function TrackPageView() { + const pathname = usePathname() + const searchParams = useSearchParams() + + // Load the Fathom script on mount + useEffect(() => { + if (!enabled) { + console.error('Fathom is not enabled') + + return + } + + load(SITE_ID, { + auto: false, + // disable for preview branches in Vercel + excludedDomains: ['vercel.app'], + }) + }, []) + + // Record a pageview when route changes + useEffect(() => { + if (!pathname || !enabled) return + + trackPageview({ + url: pathname + searchParams?.toString(), + referrer: document.referrer, + }) + }, [pathname, searchParams]) + + return null +} + +export default function Fathom() { + return ( + + + + ) +} diff --git a/src/app/[[...slug]]/layout.tsx b/src/app/[[...slug]]/layout.tsx new file mode 100644 index 000000000..0cb795d3c --- /dev/null +++ b/src/app/[[...slug]]/layout.tsx @@ -0,0 +1,63 @@ +import { Prose } from '@/components/Prose' + +import React from 'react' +import { allDocs } from '@/content' +import DocToc from '@/components/layout/DocToC' +import { Feedback } from '@/components/Feedback' +import { Button } from '@/components/ui/button' +import { GitHubIcon } from '@/components/icons/GitHubIcon' +import Breadcrumbs from '@/components/Breadcrumbs' +import FeedbackForm from '@/components/FeedbackForm' + +export default function DocLayout({ + children, + params, +}: { + children: React.ReactNode + params: { slug: string[] } +}) { + const slug = params.slug ? decodeURI(params.slug.join('/')) : '' + const doc = allDocs.find((p) => p.slug === slug) + + if (!doc) { + return <>{children} + } + + return ( +