diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md deleted file mode 100644 index c6f1d3b8..00000000 --- a/docs/getting-started/quickstart.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -title: Quickstart -sidebar_label: Quickstart -description: See CodeRabbit in action, using a live GitHub repository. -sidebar_position: 1 ---- - -# Quickstart - -This tutorial gives you a hands-on demonstration of CodeRabbit, using a real, GitHub-based repository. It guides you through the following tasks: - -1. Integrate CodeRabbit into a GitHub-based repository that you own. -1. Observe CodeRabbit perform a code review of a pull request that you initiate. -1. Converse with CodeRabbit about the code review. -1. Prompt CodeRabbit to generate its own improvements to the pull request. - -When you complete this tutorial, you'll have seen CodeRabbit's code-review feature in action, and glimpsed a few of its other AI-driven abilities as well. - -For a more general overview of CodeRabbit, see [Introduction](/). - -:::note -While this tutorial focuses on GitHub, CodeRabbit also works with GitLab, Azure DevOps, and Bitbucket. For more information, see [Integrate with Git platforms](/platforms/). -::: - -## Before you begin - -Create a new, private repository on GitHub. Name the new repository `coderabbit-test`, and let it have otherwise default GitHub settings. - -## Integrate CodeRabbit with your GitHub account - -To integrate CodeRabbit with your GitHub account, follow these steps: - -1. Visit [the CodeRabbit login page](https://app.coderabbit.ai/login?free-trial). -1. Click **Login with GitHub**. -1. Click **Authorize coderabbitai**. - -CodeRabbit takes a moment to set up the integration. After it finishes, the CodeRabbit dashboard appears. - -## Add CodeRabbit to your repository - -To add CodeRabbit to your test repository, follow these steps: - -1. On the CodeRabbit dashboard, click **Add Repositories**. A GitHub repository-access dialog appears. -1. Select the **Only select repositories** radio button. -1. From the **Select repositories** menu, select the `coderabbit-test` repository that you created earlier in this Quickstart. -1. Click **Install & Authorize**. - :::note - CodeRabbit requests read and write access to your repository in order for its code review, issue management, and pull request generation features to work. CodeRabbit never stores your code. For more information, see [the CodeRabbit Trust Center](https://trust.coderabbit.ai). - ::: -1. If a CodeRabbit **Complete your signup** dialog appears, then fill it out with the requested information before continuing. - -CodeRabbit is now ready to use with your test repository. The next steps demonstrate its core code-review features. - -## Let CodeRabbit perform a code review - -The following steps initiate a pull request to add a tiny and somewhat flawed Python library to your repository, triggering analysis and review from CodeRabbit. - -Use your usual Git workflow to perform the following steps in the `coderabbit-test` repository: - -1. Create a branch named `add-utils`. - -1. In that new `add-utils` branch, create a new file called `simple_utils.py`, with the following content: - - ```python - # simple_utils.py - A tiny utility library - - def reverse_string(text): - """Reverses the characters in a string.""" - return text[::-1] - - def count_words(sentence): - return len(sentence.split()) - - def celsius_to_fahrenheit(celsius): - return (celsius * 9/5) + 32 - ``` - -1. Commit the added file to the `add-utils` branch. Use any text you want for the commit message. - -1. Create a pull request that proposes to merge the `add-utils` branch into the `main` branch. Use any text you want for the pull request message. - -After a few moments, CodeRabbit responds to the pull request using the `@coderabbitai` GitHub account. It performs the following actions, all of which are visible on the pull request's page on GitHub: - -- If you didn't write a pull request summary, then CodeRabbit adds a new summary to the pull request. -- CodeRabbit posts a comment titled **Walkthrough** containing analysis and commentary about the content of the pull request. -- CodeRabbit attaches a detailed code review to the pull request as another comment. - -Part of the review resembles the following screenshot: - -![An example code review comment](/img/getting-started/quickstart-comment.png) - -This shows that CodeRabbit has noticed some flaws with this Python library, including a lack of docstrings and input validation. The review comment identifies these flaws, and suggests how you might improve them. - -## Ask CodeRabbit for more information - -After CodeRabbit reviews a pull request, you can converse with it about its review. You can also give CodeRabbit special commands to request it to perform specific functions, such as generating appropriate code changes for you. - -1. Post the following as a new GitHub comment attached to the pull request: - - ```text - @coderabbitai Why do all of these functions need docstrings? Isn't it obvious enough what they do? - ``` - - After a few moments, CodeRabbit posts its reply, explaining its motivations for its recommendation. The reply might resemble the following: - - > You're right that these functions are quite self-explanatory from their names alone. Docstrings aren't strictly necessary for every function, especially in smaller projects with clear function names. - > - > While docstrings do provide benefits (IDE tooltips, documentation generation, help for future developers), they can sometimes feel redundant for very straightforward functions. It's ultimately a matter of coding style and project requirements. - > - > If you prefer to skip docstrings for obvious utility functions in this project, that's perfectly reasonable. Would you like me to adjust my review approach regarding documentation for this repository? - - In this case, CodeRabbit is offering to adjust its future behavior when reviewing changes to this repository. Instead, follow the next step to ask CodeRabbit to implement part of its suggestions. - -1. Post the following as another new comment: - - ```text - @coderabbitai generate docstrings - ``` - - After a few moments, CodeRabbit does the following: - - - CodeRabbit creates a new branch, based on `add-utils`. - - CodeRabbit commits changes to the branch that adds suggested docstrings to `add-utils`. - - CodeRabbit opens a new pull request between the new branch and `add-utils`. - -## Clean up - -Continue experimenting with CodeRabbit in your test repository for as long as you like. When you're finished, you can delete the repository. - -You are now ready to add CodeRabbit to other repositories that you own, and let it review some real pull requests. - -## What's next - -- [Integrate CodeRabbit](/platforms/) with your repositories on GitHub, GitLab, Azure DevOps, or Bitbucket. -- [Configure CodeRabbit](/getting-started/configure-coderabbit) beyond its default settings. -- [Add custom review instructions](/guides/review-instructions). -- [Get support for CodeRabbit](/getting-started/support). -- [Learn more about how CodeRabbit works](/overview/why-coderabbit). diff --git a/docs/getting-started/quickstart.mdx b/docs/getting-started/quickstart.mdx new file mode 100644 index 00000000..8f6190db --- /dev/null +++ b/docs/getting-started/quickstart.mdx @@ -0,0 +1,184 @@ +--- +title: Quickstart +sidebar_label: Quickstart +description: See CodeRabbit in action, using a live GitHub repository. +sidebar_position: 1 +--- + +import CodeBlock from "@theme/CodeBlock" +import ChatBubble from "../../src/components/ChatBubble" +import DarkCodeBlock from "../../src/components/DarkCodeBlock" +import InfoBox from "../../src/components/InfoBox" +import ListItems from "../../src/components/ListItems" +import Note from "../../src/components/Note" + +# Quickstart + +This tutorial gives you a hands-on demonstration of CodeRabbit, using a real, GitHub-based repository. It guides you through the following tasks: + + + +When you complete this tutorial, you'll have seen CodeRabbit's code-review feature in action, and glimpsed a few of its other AI-driven abilities as well. + + + For a more general overview of CodeRabbit, see Introduction. + + + + While this tutorial focuses on GitHub, CodeRabbit also works with GitLab, + Azure DevOps, and Bitbucket. For more information, see{" "} + Integrate with Git platforms. + + +## Before you begin + +Create a new, private repository on GitHub. Name the new repository `coderabbit-test`, and let it have otherwise default GitHub settings. + +## Integrate CodeRabbit with your GitHub account + +To integrate CodeRabbit with your GitHub account, follow these steps: + + + Visit{" "} + + the CodeRabbit login page + + . + , + <> + Click Login with GitHub. + , + <> + Click Authorize coderabbitai. + , + ]} +/> + +CodeRabbit takes a moment to set up the integration. After it finishes, the CodeRabbit dashboard appears. + +## Add CodeRabbit to your repository + +To add CodeRabbit to your test repository, follow these steps: + +On the CodeRabbit dashboard, click Add Repositories., + <>Select the Only select repositories radio button., + <>From the Select repositories menu, select the coderabbit-test repository that you created earlier in this Quickstart., + <> + Click Install & Authorize. + + CodeRabbit requests read and write access to your repository in order for its code review, issue management, and pull request generation features to work. CodeRabbit never stores your code. For more information, see the CodeRabbit Trust Center. + + , + <>If a CodeRabbit Complete your signup dialog appears, then fill it out with the requested information before continuing., + ]} +/> + +CodeRabbit is now ready to use with your test repository. The next steps demonstrate its core code-review features. + +## Let CodeRabbit perform a code review + +The following steps initiate a pull request to add a tiny and somewhat flawed Python library to your repository, triggering analysis and review from CodeRabbit. + +Use your usual Git workflow to perform the following steps in the `coderabbit-test` repository: + + + In that new add-utils branch, create a new file called simple_utils.py, with the following content: + {`# simple_utils.py - A tiny utility library + +def reverse_string(text): + """Reverses the characters in a string.""" + return text[::-1] + +def count_words(sentence): + return len(sentence.split()) + +def celsius_to_fahrenheit(celsius): + return (celsius * 9/5) + 32 +`} + , + "Commit the added file to the `add-utils`branch. Use any text you want for the commit message.", + "Create a pull request that proposes to merge the`add-utils`branch into the`main` branch. Use any text you want for the pull request message.", +]} +/> + +After a few moments, CodeRabbit responds to the pull request using the `@coderabbitai` GitHub account. It performs the following actions, all of which are visible on the pull request's page on GitHub: + +If you didn't write a pull request summary, then CodeRabbit adds a new summary to the pull request., + <>CodeRabbit posts a comment titled Walkthrough containing analysis and commentary about the content of the pull request., + <>CodeRabbit attaches a detailed code review to the pull request as another comment., + ]} +/> + +Part of the review resembles the following screenshot: + +![An example code review comment](/img/getting-started/quickstart-comment.png) + +This shows that CodeRabbit has noticed some flaws with this Python library, including a lack of docstrings and input validation. The review comment identifies these flaws, and suggests how you might improve them. + +## Ask CodeRabbit for more information + +After CodeRabbit reviews a pull request, you can converse with it about its review. You can also give CodeRabbit special commands to request it to perform specific functions, such as generating appropriate code changes for you. + +1. Post the following as a new GitHub comment attached to the pull request: + +@coderabbitai Why do all of these functions need docstrings? Isn't it obvious enough what they do? + +After a few moments, CodeRabbit posts its reply, explaining its motivations for its recommendation. The reply might resemble the following: + + +{`You're right that these functions are quite self-explanatory from their names alone. Docstrings aren't strictly necessary for every function, especially in smaller projects with clear function names. + + While docstrings do provide benefits (IDE tooltips, documentation generation, help for future developers), they can sometimes feel redundant for very straightforward functions. It's ultimately a matter of coding style and project requirements. + + If you prefer to skip docstrings for obvious utility functions in this project, that's perfectly reasonable. Would you like me to adjust my review approach regarding documentation for this repository?`} + + +In this case, CodeRabbit is offering to adjust its future behavior when reviewing changes to this repository. Instead, follow the next step to ask CodeRabbit to implement part of its suggestions. + +2. Post the following as another new comment: + +@coderabbitai generate docstrings + +After a few moments, CodeRabbit does the following: + +CodeRabbit creates a new branch, based on `add-utils`., + <>CodeRabbit commits changes to the branch that adds suggested docstrings to `add-utils`., + <>CodeRabbit opens a new pull request between the new branch and `add-utils`., +]} /> + +## Clean up + +Continue experimenting with CodeRabbit in your test repository for as long as you like. When you're finished, you can delete the repository. + +You are now ready to add CodeRabbit to other repositories that you own, and let it review some real pull requests. + +## What's next + +Integrate CodeRabbit with your repositories on GitHub, GitLab, Azure DevOps, or Bitbucket., + <>Configure CodeRabbit beyond its default settings., + <>Add custom review instructions., + <>Get support for CodeRabbit., + <>Learn more about how CodeRabbit works., +]} /> diff --git a/docs/overview/introduction.md b/docs/overview/introduction.mdx similarity index 56% rename from docs/overview/introduction.md rename to docs/overview/introduction.mdx index f937ac67..45c6b796 100644 --- a/docs/overview/introduction.md +++ b/docs/overview/introduction.mdx @@ -9,6 +9,11 @@ description: slug: "/" --- +import ListItems from "../../src/components/ListItems" +import InfoBox from "../../src/components/InfoBox" +import PlatformGrid from "../../src/components/PlatformGrid" +import PlatformCard from "../../src/components/PlatformCard" + # Introduction This page provides a conceptual introduction to CodeRabbit. For a hands-on tutorial, see [Quickstart](/getting-started/quickstart/). @@ -18,21 +23,32 @@ This page provides a conceptual introduction to CodeRabbit. For a hands-on tutor Developers can interact directly with the CodeRabbit bot within their existing Git platform's pull request interface to add context, ask questions, or even have the bot generate code. Over time, CodeRabbit learns from user input and improves its suggestions.
- +
## Core features Core CodeRabbit features include the following: -- Integrates rapidly with popular Git platforms and workflows. -- Applies dozens of open-source, industry-standard code analyzers to every commit. -- Implements code reviews as familiar pull-request comments. -- Works with contributors through natural-language conversation in comments. -- Learns and adapts to your team's code style and review preferences. -- Provides an observability dashboard of code-contribution activity. -- Practices strong privacy and security, with no retention of analyzed code. -- Offers free use for public repositories, and flexible pricing for private codebases. + ## Seamless workflow integration @@ -58,52 +74,93 @@ No matter how you tune and customize CodeRabbit, its default settings make it us CodeRabbit integrates in just a few clicks with many popular Git platforms: -- GitHub, GitHub Enterprise Cloud, GitHub Enterprise Server, -- GitLab, GitLab Self-Managed -- Azure DevOps -- Bitbucket Cloud - -For more information, see [Supported Git Platforms](/platforms/). + + + + + + + + For more information, see Supported Git Platforms. + ### Issue-management integration You can integrate CodeRabbit with issue-management platforms. This lets you ask CodeRabbit to create tickets during code reviews, or chat with CodeRabbit about your code from within issue comments. Compatible platforms include the following: -- GitHub Issues -- GitLab Issues -- Jira -- Linear + + + + + + -For more information, see [Issue Creation](/guides/issue-creation) and [Issue Chat](/guides/issue-chat). + + For more information, see Issue Creation{" "} + and Issue Chat. + ## Data privacy and security CodeRabbit collects only the minimum amount of information needed to provide you with our code review services. Our privacy and security posture centers around protecting your data through ephemerality: -- All queries to large language models (LLMs) exist in-memory only, with zero retention after each query completes. -- We don't use your code, code reviews, or other collected data to train LLMs. -- CodeRabbit doesn't share any collected customer data with third parties. -- We keep all customer data confidential, and isolated by organization. -- Our data collection and storage practices comply with SOC 2 and GDPR standards. - -For more information about how we protect your data, see [the CodeRabbit Trust Center](https://trust.coderabbit.ai). + + + + For more information about how we protect your data, see{" "} + the CodeRabbit Trust Center. + ## Flexible pricing, free for public repositories Public repositories can use the Pro tier of CodeRabbit at no charge, including all of the code-review features described on this page. Rate limits might apply. -For private repositories, a number of pricing tiers are available. These range from a Free tier that offers unlimited code-change summaries, to an Enterprise tier with access to advanced features and SLA support. For more information, see [Pricing](https://www.coderabbit.ai/pricing). +For private repositories, a number of pricing tiers are available. These range from a Free tier that offers unlimited code-change summaries, to an Enterprise tier with access to advanced features and SLA support. + + + For more information, see{" "} + Pricing. + ## Review local changes from within VSCode As a separate, free product, CodeRabbit offers a VSCode extension that brings a subset of core CodeRabbit features to VSCode. This lets you use the power of CodeRabbit to tune and tidy your code changes locally before pushing your changes into a formal pull request for more thorough reviews. -For more information, see [Review local changes](/code-editors). + + For more information, see Review local changes. + ## What's next -- [Quickstart](/getting-started/quickstart/) lets you experience your first CodeRabbit code review first-hand. - -- [Review local changes](/code-editors) guides you through installing and using a subset of CodeRabbit features directly from your code editor. - -- [Why CodeRabbit?](/overview/why-coderabbit) dives further into the philosophies and technologies that drive CodeRabbit. + + Quickstart lets you experience + your first CodeRabbit code review first-hand. + , + <> + Review local changes guides you through + installing and using a subset of CodeRabbit features directly from your + code editor. + , + <> + Why CodeRabbit? dives further into + the philosophies and technologies that drive CodeRabbit. + , + ]} +/> diff --git a/docusaurus.config.ts b/docusaurus.config.ts index f4cd07ca..721da114 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -273,8 +273,8 @@ const config: Config = { ], }, prism: { - theme: prismThemes.github, - darkTheme: prismThemes.dracula, + theme: prismThemes.nightOwl, + darkTheme: prismThemes.nightOwl, }, algolia: { // The application ID provided by Algolia diff --git a/src/components/ChatBubble/ChatBubble.module.css b/src/components/ChatBubble/ChatBubble.module.css new file mode 100644 index 00000000..61f961ce --- /dev/null +++ b/src/components/ChatBubble/ChatBubble.module.css @@ -0,0 +1,11 @@ +.chatBubble { + background: var(--imf-text-button-color-bg); + color: var(--imf-text-color); + border-radius: 6px; + padding: 1em 1.2em; + margin: 1em 0; + font-family: "Fira Mono", "Menlo", "Monaco", "Consolas", monospace; + font-size: 0.98em; + white-space: pre-wrap; + word-break: break-word; +} diff --git a/src/components/ChatBubble/ChatBubble.tsx b/src/components/ChatBubble/ChatBubble.tsx new file mode 100644 index 00000000..02850637 --- /dev/null +++ b/src/components/ChatBubble/ChatBubble.tsx @@ -0,0 +1,10 @@ +import React from "react" +import styles from "./ChatBubble.module.css" + +export default function ChatBubble({ + children, +}: { + children: React.ReactNode +}) { + return
{children}
+} diff --git a/src/components/ChatBubble/index.ts b/src/components/ChatBubble/index.ts new file mode 100644 index 00000000..919031d1 --- /dev/null +++ b/src/components/ChatBubble/index.ts @@ -0,0 +1 @@ +export { default } from "./ChatBubble" diff --git a/src/components/DarkCodeBlock/DarkCodeBlock.module.css b/src/components/DarkCodeBlock/DarkCodeBlock.module.css new file mode 100644 index 00000000..e424a52c --- /dev/null +++ b/src/components/DarkCodeBlock/DarkCodeBlock.module.css @@ -0,0 +1,131 @@ +.codeBlock { + margin: 1rem 0; + border-radius: 8px; + overflow: hidden; + background-color: #1a1a1a; + border: none; + font-family: 'Consolas', 'Monaco', 'Lucida Console', monospace; + position: relative; +} + +.codeHeader { + background-color: #1a1a1a; + padding: 0.75rem 1rem; + border-bottom: 1px solid #333; + color: #888; + font-size: 0.875rem; + font-weight: 400; + font-style: italic; +} + +.codeTitle { + color: #888; + font-style: italic; +} + +.codeContainer { + position: relative; + background-color: #1a1a1a; +} + +.codeContent { + margin: 0; + padding: 1rem; + padding-bottom: 2rem; + background-color: transparent; + color: #e6e6e6; + font-size: 0.875rem; + line-height: 1.6; + overflow-x: auto; + white-space: pre; +} + +.codeLine { + display: block; + min-height: 1.6rem; +} + +.copyButtonContainer { + background-color: #1a1a1a; + padding: 0.75rem 1rem; + display: flex; + justify-content: flex-end; + cursor: pointer; +} + +.copyButton { + background-color: #333; + color: #fff; + border: 1px solid #333; + border-radius: 4px; + padding: 0.5rem 0.75rem; + font-size: 0.75rem; + cursor: pointer; + display: flex; + align-items: center; + gap: 0.5rem; + transition: all 0.2s ease; + font-family: inherit; + width: 100%; + justify-content: flex-end; +} + +.copyButton:hover { + background-color: #333; + color: #fff; + border-color: #666; +} + +.copyButton:active { + transform: scale(0.98); +} + +.copyButton svg { + width: 14px; + height: 14px; +} + +.codeContent :global(.keyword) { + color: #4fc1ff; + font-weight: 400; +} + +.codeContent :global(.comment) { + color: #6a9955; + font-style: italic; +} + +.codeContent :global(.string) { + color: #ff6b9d; +} + +.codeContent :global(.function) { + color: #ffab70; + font-weight: 400; +} + +.codeContent :global(.number) { + color: #53FFE8; +} + +.codeContent :global(.header) { + color: #e6e6e6; + font-style: italic; +} + +@media (max-width: 768px) { + .codeContent { + font-size: 0.8rem; + padding: 0.75rem; + padding-bottom: 3rem; + } + + .copyButton { + font-size: 0.7rem; + padding: 0.4rem 0.6rem; + } + + .copyButtonContainer { + padding: 0.5rem 0.75rem; + } +} diff --git a/src/components/DarkCodeBlock/DarkCodeBlock.tsx b/src/components/DarkCodeBlock/DarkCodeBlock.tsx new file mode 100644 index 00000000..47a4775c --- /dev/null +++ b/src/components/DarkCodeBlock/DarkCodeBlock.tsx @@ -0,0 +1,182 @@ +import React, { useState, useMemo } from 'react'; +import styles from './DarkCodeBlock.module.css'; + +interface DarkCodeBlockProps { + children: string; + language?: string; + title?: string; +} + +const DarkCodeBlock: React.FC = ({ + children, + language = 'python', + title +}) => { + const [copied, setCopied] = useState(false); + + const handleCopy = async () => { + try { + await navigator.clipboard.writeText(children); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } catch (err) { + console.error('Failed to copy text: ', err); + } + }; + + const KEYWORDS = useMemo(() => ['def', 'return', 'if', 'else', 'elif', 'for', 'while', 'class', 'import', 'from', 'as', 'try', 'except', 'finally', 'with', 'pass', 'break', 'continue', 'and', 'or', 'not', 'in', 'is', 'lambda', 'yield', 'global', 'nonlocal', 'assert', 'del', 'raise', 'True', 'False', 'None'], []); + + const highlightedCode = useMemo(() => { + const highlightCode = (code: string, lang: string) => { + const lines = code.trim().split('\n'); + + return lines.map((line, index) => { + if (lang === 'python') { + const tokens = []; + let i = 0; + const text = line; + + while (i < text.length) { + if (/\s/.test(text[i])) { + let start = i; + while (i < text.length && /\s/.test(text[i])) i++; + tokens.push({ type: 'whitespace', value: text.substring(start, i) }); + continue; + } + + if (text[i] === '#') { + const commentText = text.substring(i); + if (index === 0 && commentText.includes('.py')) { + tokens.push({ type: 'header', value: commentText }); + } else { + tokens.push({ type: 'comment', value: commentText }); + } + break; + } + + if (text.substring(i, i + 3) === '"""' || text.substring(i, i + 3) === "'''") { + const quote = text.substring(i, i + 3); + let end = i + 3; + while (end < text.length - 2 && text.substring(end, end + 3) !== quote) { + end++; + } + if (end < text.length - 2) end += 3; + tokens.push({ type: 'string', value: text.substring(i, end) }); + i = end; + continue; + } + + if (text[i] === '"' || text[i] === "'") { + const quote = text[i]; + let end = i + 1; + while (end < text.length && text[end] !== quote) { + if (text[end] === '\\') end += 2; + else end++; + } + if (end < text.length) end++; + tokens.push({ type: 'string', value: text.substring(i, end) }); + i = end; + continue; + } + + if (/\d/.test(text[i])) { + let start = i; + while (i < text.length && /[\d.]/.test(text[i])) i++; + tokens.push({ type: 'number', value: text.substring(start, i) }); + continue; + } + + if (/[a-zA-Z_]/.test(text[i])) { + let start = i; + while (i < text.length && /[a-zA-Z0-9_]/.test(text[i])) i++; + const word = text.substring(start, i); + + if (KEYWORDS.includes(word)) { + tokens.push({ type: 'keyword', value: word }); + } else { + const prevKeywordToken = tokens.filter(t => t.type !== 'whitespace').pop(); + if (prevKeywordToken && prevKeywordToken.value === 'def') { + tokens.push({ type: 'function', value: word }); + } else { + tokens.push({ type: 'identifier', value: word }); + } + } + continue; + } + + tokens.push({ type: 'operator', value: text[i] }); + i++; + } + + const htmlParts = tokens.map(token => { + switch (token.type) { + case 'keyword': + return `${token.value}`; + case 'string': + return `${token.value}`; + case 'function': + return `${token.value}`; + case 'number': + return `${token.value}`; + case 'comment': + return `${token.value}`; + case 'header': + return `${token.value}`; + case 'whitespace': + case 'operator': + case 'identifier': + default: + return token.value; + } + }); + + return ( +
+ +
+ ); + } + + return ( +
+ {line} +
+ ); + }); + }; + + return highlightCode(children, language); + }, [children, language, KEYWORDS]); + + return ( +
+ {title && ( +
+ {title} +
+ )} +
+
+          
+            {highlightedCode}
+          
+        
+
+ +
+
+
+ ); +}; + +export default DarkCodeBlock; diff --git a/src/components/DarkCodeBlock/index.ts b/src/components/DarkCodeBlock/index.ts new file mode 100644 index 00000000..ee453e50 --- /dev/null +++ b/src/components/DarkCodeBlock/index.ts @@ -0,0 +1 @@ +export { default } from './DarkCodeBlock'; \ No newline at end of file diff --git a/src/components/InfoBox/InfoBox.module.css b/src/components/InfoBox/InfoBox.module.css new file mode 100644 index 00000000..afa9212b --- /dev/null +++ b/src/components/InfoBox/InfoBox.module.css @@ -0,0 +1,19 @@ +.infoBox { + border: 2px solid var(--imf-color-border-orange); + border-radius: 12px; + background: var(--imf-color-background-orange-light); + padding: 0.7em; +} + +.infoBox p { + margin: 0rem; +} + +.infoBox a { + color: var(--ifm-color-primary); + text-decoration: none; +} + +.infoBox a:hover { + text-decoration: underline; +} diff --git a/src/components/InfoBox/InfoBox.tsx b/src/components/InfoBox/InfoBox.tsx new file mode 100644 index 00000000..988d193f --- /dev/null +++ b/src/components/InfoBox/InfoBox.tsx @@ -0,0 +1,15 @@ +import React from "react" +import styles from "./InfoBox.module.css" + +interface InfoBoxProps { + children: React.ReactNode + className?: string +} + +export const InfoBox: React.FC = ({ children, className }) => { + return ( +
{children}
+ ) +} + +export default InfoBox diff --git a/src/components/InfoBox/index.ts b/src/components/InfoBox/index.ts new file mode 100644 index 00000000..7e71df22 --- /dev/null +++ b/src/components/InfoBox/index.ts @@ -0,0 +1 @@ +export { default, InfoBox } from "./InfoBox" diff --git a/src/components/ListItems/ListItems.module.css b/src/components/ListItems/ListItems.module.css new file mode 100644 index 00000000..e671f8cb --- /dev/null +++ b/src/components/ListItems/ListItems.module.css @@ -0,0 +1,74 @@ +.crFeatureCard { + background: var(--imf-list-card-background-color); + border-radius: 8px; + padding: 1.3rem; + margin: 0.8rem 0; + border: 2px solid var(--ifm-background-color-secondary); +} + +.crFeatureList { + list-style: none; + margin: 0; + padding: 0; +} + +.crOrderedList { + list-style: decimal; + margin: 0; + padding-left: 1.5em; +} + +.crFeatureList li { + position: relative; + padding-left: 1.7em; + margin-bottom: 1em; + font-size: 1.08rem; + line-height: 1.6; +} + +.crFeatureList li:last-child { + margin-bottom: 0; +} + +.crOrderedList li { + margin-bottom: 1em; + font-size: 1.08rem; + line-height: 1.6; + padding-left: 0.3em; +} + +.crOrderedList li:last-child { + margin-bottom: 0; +} + +.crFeatureList li:before { + content: ""; + position: absolute; + left: 0.3em; + top: 0.5em; + width: 0.6em; + height: 0.6em; + background: var(--imf-list-bullets-color); + border-radius: 50%; + display: inline-block; +} + +.crFeatureList li a { + color: var(--ifm-color-primary, orange); + text-decoration: none; + font-weight: 500; +} + +.crOrderedList li a { + color: var(--ifm-color-primary, orange); + text-decoration: none; + font-weight: 500; +} + +.crFeatureList li a:hover { + text-decoration: underline; +} + +.crOrderedList li a:hover { + text-decoration: underline; +} diff --git a/src/components/ListItems/ListItems.tsx b/src/components/ListItems/ListItems.tsx new file mode 100644 index 00000000..6f87105f --- /dev/null +++ b/src/components/ListItems/ListItems.tsx @@ -0,0 +1,31 @@ +import React from "react" +import styles from "./ListItems.module.css" + +interface ListItemsProps { + items: React.ReactNode[] + className?: string + orderedList?: boolean +} + +export const ListItems: React.FC = ({ + items, + className, + orderedList = false, +}) => { + const ListTag = orderedList ? "ol" : "ul" + const listClassName = orderedList + ? styles.crOrderedList + : styles.crFeatureList + + return ( +
+ + {items.map((item, index) => ( +
  • {item}
  • + ))} +
    +
    + ) +} + +export default ListItems diff --git a/src/components/ListItems/index.ts b/src/components/ListItems/index.ts new file mode 100644 index 00000000..e4d4326c --- /dev/null +++ b/src/components/ListItems/index.ts @@ -0,0 +1 @@ +export { default, ListItems } from "./ListItems" diff --git a/src/components/Note/Note.module.css b/src/components/Note/Note.module.css new file mode 100644 index 00000000..e4f27ae6 --- /dev/null +++ b/src/components/Note/Note.module.css @@ -0,0 +1,42 @@ +.note { + display: flex; + flex-direction: column; + align-items: flex-start; + background: var(--imf-note-background-color); + border: 2px solid var(--imf-note-border-color); + border-radius: 8px; + padding: 1rem 1.2rem; + margin: 1.2rem 0; + font-size: 1rem; +} + +.header { + display: flex; + align-items: center; + margin-bottom: 0.3em; +} + +.icon { + width: 1.5em; + height: 1.5em; + margin-right: 0.5em; + flex-shrink: 0; +} + +.title { + font-weight: 600; + color: var(--imf-note-text-color); +} + +.text { + margin-top: 0.2em; +} +.note.text p { + margin: 0px; +} +.note a { + color: var(--imf-note-text-color); +} +.note p { + margin: 0rem; +} diff --git a/src/components/Note/Note.tsx b/src/components/Note/Note.tsx new file mode 100644 index 00000000..10ce1247 --- /dev/null +++ b/src/components/Note/Note.tsx @@ -0,0 +1,18 @@ +import React from "react" +import styles from "./Note.module.css" + +interface NoteProps { + children: React.ReactNode +} + +const Note: React.FC = ({ children }) => ( +
    +
    + Note + Note +
    +
    {children}
    +
    +) + +export default Note diff --git a/src/components/Note/index.ts b/src/components/Note/index.ts new file mode 100644 index 00000000..dd6db3eb --- /dev/null +++ b/src/components/Note/index.ts @@ -0,0 +1 @@ +export { default } from "./Note" diff --git a/src/components/OrderedSteps.tsx b/src/components/OrderedSteps.tsx new file mode 100644 index 00000000..505ed5c8 --- /dev/null +++ b/src/components/OrderedSteps.tsx @@ -0,0 +1,11 @@ +import React from "react" + +export default function OrderedSteps({ children }) { + return ( +
      + {React.Children.map(children, (child, idx) => ( +
    1. {child}
    2. + ))} +
    + ) +} diff --git a/src/components/PlatformCard/PlatformCard.module.css b/src/components/PlatformCard/PlatformCard.module.css new file mode 100644 index 00000000..8b710ed5 --- /dev/null +++ b/src/components/PlatformCard/PlatformCard.module.css @@ -0,0 +1,18 @@ +.platformCard { + display: flex; + align-items: center; + background: var(--imf-list-card-background-color); + border-radius: 8px; + padding: 1.3rem; + border: 2px solid var(--ifm-background-color-secondary); +} + +.platformIcon { + width: 32px; + height: 32px; + margin-right: 16px; +} + +[data-theme="dark"] .platformIcon { + filter: invert(1); +} diff --git a/src/components/PlatformCard/PlatformCard.tsx b/src/components/PlatformCard/PlatformCard.tsx new file mode 100644 index 00000000..d94b7ff0 --- /dev/null +++ b/src/components/PlatformCard/PlatformCard.tsx @@ -0,0 +1,23 @@ +import React from "react" +import styles from "./PlatformCard.module.css" + +interface PlatformCardProps { + imageSrc: string + name: string + className?: string +} + +export const PlatformCard: React.FC = ({ + imageSrc, + name, + className, +}) => { + return ( +
    + {name} + {name} +
    + ) +} + +export default PlatformCard diff --git a/src/components/PlatformCard/index.ts b/src/components/PlatformCard/index.ts new file mode 100644 index 00000000..ca2c1258 --- /dev/null +++ b/src/components/PlatformCard/index.ts @@ -0,0 +1 @@ +export { PlatformCard, default } from "./PlatformCard" diff --git a/src/components/PlatformGrid/PlatformGrid.module.css b/src/components/PlatformGrid/PlatformGrid.module.css new file mode 100644 index 00000000..dcef77a3 --- /dev/null +++ b/src/components/PlatformGrid/PlatformGrid.module.css @@ -0,0 +1,6 @@ +.platformGrid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1rem; + margin: 1.5rem 0; +} diff --git a/src/components/PlatformGrid/PlatformGrid.tsx b/src/components/PlatformGrid/PlatformGrid.tsx new file mode 100644 index 00000000..706d006a --- /dev/null +++ b/src/components/PlatformGrid/PlatformGrid.tsx @@ -0,0 +1,20 @@ +import React from "react" +import styles from "./PlatformGrid.module.css" + +interface PlatformGridProps { + children: React.ReactNode + className?: string +} + +export const PlatformGrid: React.FC = ({ + children, + className, +}) => { + return ( +
    + {children} +
    + ) +} + +export default PlatformGrid diff --git a/src/components/PlatformGrid/index.ts b/src/components/PlatformGrid/index.ts new file mode 100644 index 00000000..843327a1 --- /dev/null +++ b/src/components/PlatformGrid/index.ts @@ -0,0 +1 @@ +export { PlatformGrid, default } from "./PlatformGrid" diff --git a/src/css/custom.css b/src/css/custom.css index 7365089e..27d4e5b3 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -41,6 +41,16 @@ --ifm-background-color-primary: #f6f6f1; --ifm-background-color-secondary: #e8e8e8; --ifm-breadcrumb-item-background-active: #ffe9e2; + --imf-list-card-background-color: #ffffff; + --imf-list-bullets-color: #25bab1; + --imf-color-background-orange-light: #fffcfb; + --imf-color-border-orange: #ffceb6; + --imf-note-border-color: #25bab1; + --imf-note-background-color: #f1fffe; + --imf-note-text-color: #208682; + --imf-text-color-bg: #e8e8e8; + --imf-text-color: #171717; + --imf-text-button-color-bg: #e8e8e8; } [data-theme="dark"] { @@ -55,6 +65,15 @@ --ifm-background-color-primary: #171717; --ifm-background-color-secondary: #232323; --ifm-breadcrumb-item-background-active: #3f322e; + --imf-list-card-background-color: #232323; + --imf-list-bullets-color: #208682; + --imf-color-background-orange-light: #232323; + --imf-color-border-orange: #232323; + --imf-note-border-color: #208682; + --imf-note-background-color: #252828; + --imf-text-color-bg: #232323; + --imf-text-color: #f5f5f5; + --imf-text-button-color-bg: #232323; } #__docusaurus { @@ -73,27 +92,6 @@ a[docid="docs"] > svg { display: none; } -/* Adjustments for mobile view */ -@media (max-width: 768px) { - /* Reduce the logo size for smaller screens */ - .navbar__logo img { - height: 32px; - align-items: center; - } - - /* Reduce the padding around the logo for smaller screens */ - .navbar__logo { - padding: 2px; /* Adjust the padding for smaller screens */ - } -} - -/* Center the Discord link within its parent */ -.navbar__items.navbar__items--right { - display: flex; - justify-content: center; - align-items: center; -} - [data-theme="light"] img[src$="#gh-dark-mode-only"], [data-theme="dark"] img[src$="#gh-light-mode-only"] { display: none; @@ -129,7 +127,14 @@ a[docid="docs"] > svg { display: none; } -/* Adjustments for mobile view */ +/* Center the Discord link within its parent */ +.navbar__items.navbar__items--right { + display: flex; + justify-content: center; + align-items: center; +} + +/* Consolidated mobile view adjustments */ @media (max-width: 768px) { /* Reduce the logo size for smaller screens */ .navbar__logo img { @@ -139,15 +144,13 @@ a[docid="docs"] > svg { /* Reduce the padding around the logo for smaller screens */ .navbar__logo { - padding: 2px; /* Adjust the padding for smaller screens */ + padding: 2px; } -} -/* Center the Discord link within its parent */ -.navbar__items.navbar__items--right { - display: flex; - justify-content: center; - align-items: center; + /* Content padding for mobile */ + .markdown { + padding-left: 1rem; + } } /* Light mode Discord icon */ @@ -304,6 +307,17 @@ a[docid="docs"] > svg { .pagination-nav { display: none; } +.language-text { + background-color: var(--imf-text-color-bg) !important; +} +.language-text .token-line { + color: var(--imf-text-color) !important; +} +.language-text [class*="buttonGroup"] button { + background-color: var(--imf-text-color-bg) !important; + color: var(--imf-text-color) !important; + border-radius: 4px; +} /* ===== MARKDOWN STYLES ===== */ .theme-doc-markdown.markdown { line-height: 1.8rem; @@ -335,3 +349,19 @@ a[docid="docs"] > svg { cursor: default; background-color: var(--ifm-breadcrumb-item-background-active); } + +/* Add left spacing to main content */ +.markdown { + padding-left: 1.5rem; +} + +/* Align numbered lists with other content */ +.markdown ol { + padding-left: 1.2rem; + margin-left: 0; +} + +.markdown ol > li { + margin-left: 0; + padding-left: 0.5rem; +} diff --git a/static/img/Icons/Icons.png b/static/img/Icons/Icons.png new file mode 100644 index 00000000..4fd5b868 Binary files /dev/null and b/static/img/Icons/Icons.png differ diff --git a/static/img/overview/Azure.png b/static/img/overview/Azure.png new file mode 100644 index 00000000..6e8b02ee Binary files /dev/null and b/static/img/overview/Azure.png differ diff --git a/static/img/overview/Bitbucket.png b/static/img/overview/Bitbucket.png new file mode 100644 index 00000000..0f349913 Binary files /dev/null and b/static/img/overview/Bitbucket.png differ diff --git a/static/img/overview/Github.png b/static/img/overview/Github.png new file mode 100644 index 00000000..cfe4be2e Binary files /dev/null and b/static/img/overview/Github.png differ diff --git a/static/img/overview/Gitlab.png b/static/img/overview/Gitlab.png new file mode 100644 index 00000000..9ed9a1a8 Binary files /dev/null and b/static/img/overview/Gitlab.png differ diff --git a/static/img/overview/Jira.png b/static/img/overview/Jira.png new file mode 100644 index 00000000..abb1c8b1 Binary files /dev/null and b/static/img/overview/Jira.png differ diff --git a/static/img/overview/Linear.png b/static/img/overview/Linear.png new file mode 100644 index 00000000..8960789c Binary files /dev/null and b/static/img/overview/Linear.png differ