diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 0362ca6..fd46b8e 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -2,7 +2,7 @@ blank_issues_enabled: false contact_links: - name: Community Discussion url: https://coretalk.space/tags/cip - about: Share your CIP comments in Talk \#CIP + about: Share your CIP comments in Core Talk — CIP - name: Security Bugs url: https://dev.coreblockchain.net/report-bug/ about: Please report security vulnerabilities here. diff --git a/README.md b/README.md index a903440..73fc2c0 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ You can begin by opening your proposal under the [issues section of this reposit ### Review -- [What is CIP](/docs/what-is-cip) +- [What is a CIP](/docs/what-is-cip) - [CIP rationale](/docs/cip-rationale) - [CIP categories](/docs/cip-categories) - [CIP workflow](/docs/cip-workflow) @@ -17,8 +17,12 @@ You can begin by opening your proposal under the [issues section of this reposit ### How to start -1. Review the template [cip-0](https://github.com/core-coin/cip/blob/master/cip/docs/cip-0.md) -2. [Create a CIP in the Online Editor](https://github.com/core-coin/cip/new/master?filename=cip/cip-0.md&message=CIP%20Proposal&description=CIP%20Proposal%20Draft&value=---%0Acip%3A%20%0Atitle%3A%20%0Aauthor%3A%20%0Alang%3A%20en-US%0Atag%3A%20draft%0Acategory%3A%20%0Adate%3A%202022-12-01%0A---%0A%3C%21--Introduction--%3E%0A%0A%3C%21--truncate--%3E%0A%0A%23%23%20Abstract%0A%0A%0A%0A%23%23%20Motivation%0A%0A%0A%0A%23%23%20Specification%0A%0A%0A%0A%23%23%20Rationale%0A%0A%0A%0A%23%23%20Backwards%20Compatibility%0A%0A%0A%0A%23%23%20Test%20Cases%0A%0A%0A%0A%23%23%20Implementation%0A%0A%0A%0A%23%23%20Security%20Considerations%0A%0A%0A%0A%23%23%20Copyright%0A%0ACopyright%20and%20related%20rights%20waived%20via%20%5BCC0%5D%28https%3A%2F%2Fcreativecommons.org%2Fpublicdomain%2Fzero%2F1.0%2F%29.%0A) +Begin by contributing to the [issues section of this repository](https://github.com/core-coin/cip/issues/new/choose). Once done, you'll be able to draft a CIP using the associated issue number (if available). + +**Next steps:** + +1. Review the template [cip-0](/docs/cip-0.md) +2. [Create a CIP in the Online Editor](https://github.com/core-coin/cip/new/master?filename=cip/cip-0.md&message=CIP%20Proposal&description=CIP%20Proposal%20Draft&value=---%0Acip%3A%20%0Atitle%3A%20%0Adescription%3A%20%0Akeywords%3A%20%5B%5D%0Aauthor%3A%20%0Alang%3A%20en-US%0Atags%3A%20%5Bdraft%5D%0Acategories%3A%20%5B%5D%0Adate%3A%202022-12-01%0Adiscussions-to%3A%20%0A---%0A%3C%21--Introduction--%3E%0A%0A%3C%21--truncate--%3E%0A%0A%23%23%20Abstract%0A%0A%0A%0A%23%23%20Motivation%0A%0A%0A%0A%23%23%20Specification%0A%0A%0A%0A%23%23%20Rationale%0A%0A%0A%0A%23%23%20Backwards%20Compatibility%0A%0A%0A%0A%23%23%20Test%20Cases%0A%0A%0A%0A%23%23%20Implementation%0A%0A%0A%0A%23%23%20Security%20Considerations%0A%0A%0A%0A%23%23%20Copyright%0A%0ACopyright%20and%20related%20rights%20waived%20via%20%5BCC0%5D%28https%3A%2F%2Fcreativecommons.org%2Fpublicdomain%2Fzero%2F1.0%2F%29.%0A) Or @@ -50,11 +54,3 @@ CIPs are categorized into various types, each with its own list: - [Core ◆ Talk](https://coretalk.space/tags/cip) - [GH Issues](https://github.com/core-coin/cip/issues) - -## License of the content - -[CC0 “No Rights Reserved”](https://creativecommons.org/share-your-work/public-domain/cc0/) - -## License of the app - -[CORE License](LICENSE) diff --git a/cip/cbc/.gitkeep b/cip/cbc/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/cip/cip-100.md b/cip/cbc/cip-100.md similarity index 96% rename from cip/cip-100.md rename to cip/cbc/cip-100.md index bbdb07e..f36390f 100644 --- a/cip/cip-100.md +++ b/cip/cbc/cip-100.md @@ -1,12 +1,13 @@ --- cip: 100 title: ICAN +description: International Crypto Account Number +keywords: [cip, cip-100, ican, international, crypto, account, number] author: Rastislav Vašička (@rastislav@coretalk.space) lang: en-US -tag: final -category: cbc +tags: [final] +categories: [cbc] date: 2022-01-02 -star: true --- We are introducing a standard for crypto addresses — ICAN — with HRP and checksum, similar to what we are all using for current financial transactions. ICAN stands for International Crypto Account Number. Only hexadecimal characters are used to minimize the size of the address in the Blockchain storage. diff --git a/cip/cip-20.md b/cip/cbc/cip-20.md similarity index 97% rename from cip/cip-20.md rename to cip/cbc/cip-20.md index b8bf2ac..a70b7f3 100644 --- a/cip/cip-20.md +++ b/cip/cbc/cip-20.md @@ -1,12 +1,13 @@ --- cip: 20 title: Token Standard +description: A standard interface for tokens. +keywords: [cip, cip-20, token, standard] author: Mojtaba lang: en-US -tag: final -category: cbc +tags: [final] +categories: [cbc] date: 2022-05-28 -star: true --- A standard interface for tokens. @@ -27,6 +28,7 @@ A standard interface allows any tokens on Core to be re-used by other applicatio #### Methods **NOTES**: + - The following specifications use syntax from Ylem `0.8.4` (or above). - Callers MUST handle `false` from `returns (bool success)`. They MUST NOT assume that `false` is never returned! diff --git a/cip/core/.gitkeep b/cip/core/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/cip/cip-98.md b/cip/core/cip-98.md similarity index 84% rename from cip/cip-98.md rename to cip/core/cip-98.md index 3f793ef..0b233b8 100644 --- a/cip/cip-98.md +++ b/cip/core/cip-98.md @@ -1,10 +1,12 @@ --- cip: 98 title: Core Cryptography Scheme +description: The cryptography scheme employed in the Core Blockchain. +keywords: [cip, cip-98, cryptography, scheme, core, blockchain] author: Dmitry (@todesstile) lang: en-US -tag: final -category: core +tags: [final] +categories: [core] date: 2022-06-16 --- This standard details the cryptography scheme employed in the Core Blockchain. @@ -45,22 +47,22 @@ If the most significant bit of the last byte (little endian) of the private key Given that the `privateKey` is represented by `byte[57]`, the overarching scheme can be elucidated as follows: -``` +```go if (privateKey[56] & 0x80 == 0x00) { - // Most significant bit of the last byte equals 0, process as usual: - output = SHAKE256(privateKey, 114) - left = output[0:57] - right = output[57:114] - // .... + // Most significant bit of the last byte equals 0, process as usual: + output = SHAKE256(privateKey, 114) + left = output[0:57] + right = output[57:114] + // .... } else { - // Most significant bit of the last byte equals 1: - scalar = privateKey - scalar[0] &= 0xfc - scalar[56] = 0 - scalar[55] |= 0x80 - left = scalar - right = scalar - // then proceed as usual + // Most significant bit of the last byte equals 1: + scalar = privateKey + scalar[0] &= 0xfc + scalar[56] = 0 + scalar[55] |= 0x80 + left = scalar + right = scalar + // then proceed as usual } ``` diff --git a/cip/cip-99.md b/cip/core/cip-99.md similarity index 95% rename from cip/cip-99.md rename to cip/core/cip-99.md index b55078e..47fb08d 100644 --- a/cip/cip-99.md +++ b/cip/core/cip-99.md @@ -1,10 +1,12 @@ --- cip: 99 title: Core HD-Wallet Scheme +description: The HD-wallet derivation scheme for Core Coin. +keywords: [cip, cip-99, hd-wallet, scheme, core, coin] author: Dmitry (@todesstile) lang: en-US -tag: final -category: core +tags: [final] +categories: [core] date: 2022-06-16 --- This standard outlines the HD-wallet derivation scheme for Core Coin. @@ -39,7 +41,7 @@ An extended key is represented by a [114]byte array. It is derived from `chainco The master key forms the root of the HD-derivation tree. It can be derived from mnemonics using a slightly modified version of the BIP39 scheme. You should adhere to this scheme until obtaining the seed (BIP39 Seed). The master key can then be derived as: -``` +```go chain = H(seed, "mnemonicforthechain") key = H(seed, "mnemonicforthekey") masterKey = chain || key @@ -47,7 +49,7 @@ masterKey = chain || key For enhanced security, you should: -``` +```txt set the most significant bit of the last byte to 1 (masterKey[113] |= 0x80) set the most significant bit of the next-to-last byte to 1 (masterKey[112] |= 0x80) clear the second significant bit of the next-to-last byte (masterKey[112] &= 0xbf) @@ -61,14 +63,14 @@ You can always generate `pubKey` from `privKey`. This operation will be denoted Child chaincode generation varies between usual and hardened keys. For a usual key: -``` +```go pubKey = private2public(privKey) childChain = H(0x03 || pubKey || i , chain), where i < 2^31 ``` For a hardened key: -``` +```go childChain = H(0x01 || privKey || i , chain), where i >= 2^31 ``` @@ -76,20 +78,20 @@ childChain = H(0x01 || privKey || i , chain), where i >= 2^31 Child private key generation also differs between usual and hardened keys. For a usual key: -``` +```go pubKey = private2public(privKey) template = H(0x02 || pubKey || i , chain), where i < 2^31 ``` For a hardened key: -``` +```go template = H(0x00 || privKey || i , chain), where i >= 2^31 ``` Next, nullify the top 4 bytes and the last 2 bits of the template for security reasons, resulting in the `clampedTemplate = clamp(template)`. Then, the child `privKey` can be computed as: -``` +```go childPrivKey = privKey + clampedTemplate ``` @@ -105,14 +107,14 @@ It is impossible to generate a child public key from a hardened public key, whic However, usual child public keys can be derived from a usual parent public key. First, calculate the `clampedTemplate` as described above: -``` +```go template = H(0x02 || publicKey || i , chain), where i < 2^31 template -> clampedTemplate ``` Next, compute a point on Ed448 corresponding to the `clampedTemplate` and add it to the `publicKey` using point addition for Ed448: -``` +```go point = private2public(clampedTemplate) childPublicKey = publicKey +++ point ``` diff --git a/cip/informational/.gitkeep b/cip/informational/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/cip/interface/.gitkeep b/cip/interface/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/cip/meta/.gitkeep b/cip/meta/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/cip/networking/.gitkeep b/cip/networking/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docs/cip-0.md b/docs/cip-0.md index a4c9d3c..b2b697b 100755 --- a/docs/cip-0.md +++ b/docs/cip-0.md @@ -1,14 +1,30 @@ --- +title: CIP-0 example +description: CIP-0 example template +author: Core Foundation +comment: false +date: 2022-01-01 +sidebar_position: 7 +--- +**Frontmatter:** + +```yaml +--- cip: 0 title: CIP-0 example +description: CIP-0 example template +keywords: [cip, cip-0, example, template] author: Author (@author@server.pod) lang: en-US -tag: draft -category: example +tags: [draft] +categories: [example] date: 2022-01-01 -sidebar_position: 7 +discussions-to: +requires: # Only required when you reference an CIP in the `Specification` section. Otherwise, remove this field. --- -> This is the suggested template for new CIPs. Note that a CIP number will be assigned by an editor. When opening a pull request to submit your CIP, please use an abbreviated title in the filename, `cip-ID.md`, where "ID" is the CIP ID. The title should be 44 characters or fewer. +``` + +> This is the suggested template for new CIPs. Note that a CIP number will be assigned by an editor. When opening a pull request to submit your CIP, please, use an abbreviated title in the filename, `cip-ID.md`, where "ID" is the CIP ID. The title should be 44 characters or fewer. > Provide a simplified and layperson-accessible explanation of the CIP. @@ -44,7 +60,7 @@ sidebar_position: 7 ## Security Considerations -> All CIPs must contain a section discussing the security implications and considerations relevant to the proposed change. This section should provide details important for security discussions, highlight potential risks, and be referenced throughout the lifecycle of the proposal. CIP submissions lacking the "Security Considerations" section will be rejected. A CIP cannot proceed to "Final" status without a Security Considerations discussion deemed satisfactory by the reviewers. +> All CIPs must contain a section discussing the security implications and considerations relevant to the proposed change. This section should provide details important for security discussions, highlight potential risks, and be referenced throughout the lifecycle of the proposal. CIP submissions lacking the "Security Considerations" section will be rejected. A CIP cannot proceed to the "Final" status without a Security Considerations discussion deemed satisfactory by the reviewers. ## Copyright diff --git a/docs/cip-categories.md b/docs/cip-categories.md index 642307e..f853acc 100755 --- a/docs/cip-categories.md +++ b/docs/cip-categories.md @@ -1,12 +1,7 @@ --- title: CIP Categories -isOriginal: true author: Core Foundation date: 2022-01-01 -category: - - tutorial -tag: - - tutorial comment: false sidebar_position: 4 --- diff --git a/docs/cip-editors.md b/docs/cip-editors.md index 0360c6d..161ba0c 100755 --- a/docs/cip-editors.md +++ b/docs/cip-editors.md @@ -1,12 +1,7 @@ --- title: CIP Editors -isOriginal: true author: Core Foundation date: 2022-01-01 -category: - - tutorial -tag: - - tutorial comment: false sidebar_position: 6 --- diff --git a/docs/cip-rationale.md b/docs/cip-rationale.md index 08ea9cd..aeeb411 100755 --- a/docs/cip-rationale.md +++ b/docs/cip-rationale.md @@ -1,12 +1,7 @@ --- title: CIP Rationale -isOriginal: true author: Core Foundation date: 2022-01-01 -category: - - tutorial -tag: - - tutorial comment: false sidebar_position: 3 --- diff --git a/docs/cip-workflow.md b/docs/cip-workflow.md index 8f8e0c7..83b4f61 100755 --- a/docs/cip-workflow.md +++ b/docs/cip-workflow.md @@ -1,12 +1,7 @@ --- title: CIP Work Flow -isOriginal: true author: Core Foundation date: 2022-01-01 -category: - - tutorial -tag: - - tutorial comment: false sidebar_position: 5 --- @@ -53,11 +48,11 @@ Every stage transition requires the CIP author's request and subsequent approval - **Deferred**: For core CIPs postponed for an upcoming hard fork. - **Rejected**: Either a fundamentally flawed CIP or a Core CIP declined by Core Devs. - **Active**: Similar to Final, but can undergo updates without changing the CIP number. -- **Superseded**: A once-final CIP no longer represents the zenith. Another "Final" CIP references the outdated one. +- **Superseeded**: A once-final CIP no longer represents the zenith. Another "Final" CIP references the outdated one. ## Pillars of a Successful CIP -Each CIP should encapsulate +Each CIP should encapsulate: - **Preamble**: RFC 822 headers detailing CIP metadata. - **Simple Summary**: An easy-to-understand synopsis. diff --git a/docs/cip.md b/docs/cip.md index 15ff517..682bdda 100755 --- a/docs/cip.md +++ b/docs/cip.md @@ -1,12 +1,7 @@ --- title: Core Improvement Proposals -isOriginal: true author: Core Foundation date: 2022-01-01 -category: - - tutorial -tag: - - tutorial comment: false sidebar_position: 1 --- @@ -20,7 +15,7 @@ You can begin by opening your proposal under the [issues section of this reposit ### Review -- [What is CIP](/docs/what-is-cip) +- [What is a CIP](/docs/what-is-cip) - [CIP rationale](/docs/cip-rationale) - [CIP categories](/docs/cip-categories) - [CIP workflow](/docs/cip-workflow) @@ -29,8 +24,12 @@ You can begin by opening your proposal under the [issues section of this reposit ### How to start -1. Review the template [cip-0](https://github.com/core-coin/cip/blob/master/cip/docs/cip-0.md) -2. [Create a CIP in the Online Editor](https://github.com/core-coin/cip/new/master?filename=cip/cip-0.md&message=CIP%20Proposal&description=CIP%20Proposal%20Draft&value=---%0Acip%3A%20%0Atitle%3A%20%0Aauthor%3A%20%0Alang%3A%20en-US%0Atag%3A%20draft%0Acategory%3A%20%0Adate%3A%202022-12-01%0A---%0A%3C%21--Introduction--%3E%0A%0A%3C%21--truncate--%3E%0A%0A%23%23%20Abstract%0A%0A%0A%0A%23%23%20Motivation%0A%0A%0A%0A%23%23%20Specification%0A%0A%0A%0A%23%23%20Rationale%0A%0A%0A%0A%23%23%20Backwards%20Compatibility%0A%0A%0A%0A%23%23%20Test%20Cases%0A%0A%0A%0A%23%23%20Implementation%0A%0A%0A%0A%23%23%20Security%20Considerations%0A%0A%0A%0A%23%23%20Copyright%0A%0ACopyright%20and%20related%20rights%20waived%20via%20%5BCC0%5D%28https%3A%2F%2Fcreativecommons.org%2Fpublicdomain%2Fzero%2F1.0%2F%29.%0A) +Begin by contributing to the [issues section of this repository](https://github.com/core-coin/cip/issues/new/choose). Once done, you'll be able to draft a CIP using the associated issue number (if available). + +**Next steps:** + +1. Review the template [cip-0](/docs/cip-0.md) +2. [Create a CIP in the Online Editor](https://github.com/core-coin/cip/new/master?filename=cip/cip-0.md&message=CIP%20Proposal&description=CIP%20Proposal%20Draft&value=---%0Acip%3A%20%0Atitle%3A%20%0Adescription%3A%20%0Akeywords%3A%20%5B%5D%0Aauthor%3A%20%0Alang%3A%20en-US%0Atags%3A%20%5Bdraft%5D%0Acategories%3A%20%5B%5D%0Adate%3A%202022-12-01%0Adiscussions-to%3A%20%0A---%0A%3C%21--Introduction--%3E%0A%0A%3C%21--truncate--%3E%0A%0A%23%23%20Abstract%0A%0A%0A%0A%23%23%20Motivation%0A%0A%0A%0A%23%23%20Specification%0A%0A%0A%0A%23%23%20Rationale%0A%0A%0A%0A%23%23%20Backwards%20Compatibility%0A%0A%0A%0A%23%23%20Test%20Cases%0A%0A%0A%0A%23%23%20Implementation%0A%0A%0A%0A%23%23%20Security%20Considerations%0A%0A%0A%0A%23%23%20Copyright%0A%0ACopyright%20and%20related%20rights%20waived%20via%20%5BCC0%5D%28https%3A%2F%2Fcreativecommons.org%2Fpublicdomain%2Fzero%2F1.0%2F%29.%0A) Or diff --git a/docs/what-is-cip.md b/docs/what-is-cip.md index 655b659..6932895 100755 --- a/docs/what-is-cip.md +++ b/docs/what-is-cip.md @@ -1,12 +1,7 @@ --- title: What is a CIP -isOriginal: true author: Core Foundation date: 2022-01-01 -category: - - tutorial -tag: - - tutorial comment: false sidebar_position: 2 --- diff --git a/docusaurus.config.js b/docusaurus.config.js deleted file mode 100644 index a807795..0000000 --- a/docusaurus.config.js +++ /dev/null @@ -1,178 +0,0 @@ -// @ts-check -// Note: type annotations allow type checking and IDEs autocompletion - -const lightCodeTheme = require('prism-react-renderer/themes/github'); -const darkCodeTheme = require('prism-react-renderer/themes/dracula'); - -/** @type {import('@docusaurus/types').Config} */ -const config = { - title: 'CIP', - tagline: 'Core Imporvement Proposal', - favicon: 'img/favicon.png', - - // Set the production url of your site here - url: 'https://cip.coreblockchain.net', - // Set the // pathname under which your site is served - // For GitHub pages deployment, it is often '//' - baseUrl: '/', - - // GitHub pages deployment config. - // If you aren't using GitHub pages, you don't need these. - organizationName: 'Core Foundation', // Usually your GitHub org/user name. - projectName: 'cip', // Usually your repo name. - - onBrokenLinks: 'throw', - onBrokenMarkdownLinks: 'warn', - - // Even if you don't use internalization, you can use this field to set useful - // metadata like html lang. For example, if your site is Chinese, you may want - // to replace "en" with "zh-Hans". - i18n: { - defaultLocale: 'en', - locales: ['en'], - }, - - presets: [ - [ - 'classic', - /** @type {import('@docusaurus/preset-classic').Options} */ - ({ - docs: { - sidebarPath: require.resolve('./sidebars.js'), - editUrl: - 'https://github.com/core-coin/cip/tree/master/docs/', - }, - blog: { - showReadingTime: true, - editUrl: - 'https://github.com/core-coin/cip/tree/master/cip/', - path: 'cip', - routeBasePath: 'cip', - blogSidebarCount: 0, - blogTitle: 'CIP Register', - postsPerPage: 5, - feedOptions: { - type: 'all', - copyright: `Core Foundation ⛬ Copyright and related rights waived via CC0`, - createFeedItems: async (params) => { - const {blogPosts, defaultCreateFeedItems, ...rest} = params; - return defaultCreateFeedItems({ - blogPosts: blogPosts.filter((item, index) => index < 10), - ...rest, - }); - }, - }, - }, - theme: { - customCss: require.resolve('./src/css/custom.css'), - }, - }), - ], - ], - - themeConfig: - /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ - ({ - // Replace with your project's social card - image: 'img/social-card.jpg', - metadata: [ - { name: 'description', content: 'Core Improvement Proposals' }, - { property: 'og:title', content: 'CIP' }, - { property: 'og:description', content: 'Core Improvement Proposals' }, - { property: 'og:type', content: 'website' }, - { - "name": "keywords", - "content": "author, categories, champion, cip, cips, consensus, core, design, document, each, editor, editors, encompassing, features, flow, fork, github, have, improvement, improvements, information, intended, key, mechanisms, members, new, offers, platform, primary, proposal, proposing, protocol, rationale, require, responsibilities, serve, sets, six, specifications, stakeholders, standards, stands, team, we, what, work, you", - }, - { property: 'ican:xcb', content: 'cb57bbbb54cdf60fa666fd741be78f794d4608d67109' }, - ], - navbar: { - title: 'CIP', - logo: { - alt: 'CIP', - src: 'img/logo.svg', - }, - items: [ - {to: '/cip', label: 'CIPs', position: 'left'}, - { - type: 'docSidebar', - sidebarId: 'tutorialSidebar', - position: 'left', - label: 'Tutorial', - }, - { - href: 'https://github.com/core-coin', - label: 'GitHub', - position: 'right', - }, - ], - }, - footer: { - style: 'dark', - links: [ - { - title: 'Docs', - items: [ - { - label: 'CIPs', - to: '/cip', - }, - { - label: 'Tutorial', - to: '/docs/cip', - }, - ], - }, - { - title: 'Ecosystem', - items: [ - { - label: 'Core Website', - href: 'https://coreblockchain.net', - }, - { - label: 'Core Blog', - href: 'https://blog.coreblockchain.net', - }, - { - label: 'Dev Portal', - href: 'https://dev.coreblockchain.net', - }, - ], - }, - { - title: 'Community', - items: [ - { - label: 'Core ◆ Talk', - href: 'https://coretalk.space', - }, - { - label: 'GitHub', - href: 'https://github.com/core-coin', - }, - { - label: '𝕏', - href: 'https://x.com/corecoincc', - }, - ], - }, - ], - copyright: `Core Foundation ⛬ Copyright and related rights waived via CC0.`, - }, - prism: { - theme: lightCodeTheme, - darkTheme: darkCodeTheme, - }, - algolia: { - appId: '6BNEFFU7K3', - apiKey: 'c149ac2035f0b47db92d69b9bfa4f227', - indexName: 'cip-coreblockchain-net', - searchParameters: { - facetFilters: ['tags:en'], - }, - }, - }), -}; - -module.exports = config; diff --git a/docusaurus.config.ts b/docusaurus.config.ts new file mode 100644 index 0000000..1a0c36c --- /dev/null +++ b/docusaurus.config.ts @@ -0,0 +1,201 @@ +import {themes as prismThemes} from 'prism-react-renderer'; +import type {Config} from '@docusaurus/types'; +import type * as Preset from '@docusaurus/preset-classic'; + +const config: Config = { + title: 'CIP', + tagline: 'Core Improvement Proposals', + favicon: 'img/favicon.png', + + // Set the production url of your site here + url: 'https://cip.coreblockchain.net', + // Set the // pathname under which your site is served + // For GitHub pages deployment, it is often '//' + baseUrl: '/', + + // GitHub pages deployment config. + // If you aren't using GitHub pages, you don't need these. + organizationName: 'Core Foundation', // Usually your GitHub org/user name. + projectName: 'cip', // Usually your repo name. + + onBrokenLinks: 'throw', + onBrokenMarkdownLinks: 'warn', + + // Even if you don't use internationalization, you can use this field to set + // useful metadata like html lang. For example, if your site is Chinese, you + // may want to replace "en" with "zh-Hans". + i18n: { + defaultLocale: 'en', + locales: ['en'], + }, + + presets: [ + [ + 'classic', + { + docs: { + sidebarPath: './sidebars.ts', + // Please change this to your repo. + // Remove this to remove the "edit this page" links. + editUrl: + 'https://github.com/core-coin/cip/tree/master/docs/', + }, + blog: { + showReadingTime: true, + // Please change this to your repo. + // Remove this to remove the "edit this page" links. + editUrl: + 'https://github.com/core-coin/cip/tree/master/cip/', + path: 'cip', + routeBasePath: 'cip', + blogSidebarCount: 0, + blogTitle: 'CIP Register', + postsPerPage: 6, + blogListComponent: '@site/src/components/BlogListPage', + blogPostComponent: '@site/src/components/BlogPostPage', + feedOptions: { + type: 'all', + copyright: `Core Foundation ⛬ Copyright and related rights waived via CC0`, + createFeedItems: async (params) => { + const {blogPosts, defaultCreateFeedItems, ...rest} = params; + return defaultCreateFeedItems({ + blogPosts: blogPosts.filter((item, index) => index < 10), + ...rest, + }); + }, + }, + }, + theme: { + customCss: './src/css/custom.css', + }, + } satisfies Preset.Options, + ], + ], + + themeConfig: { + // Replace with your project's social card + image: 'img/social-card.png', + metadata: [ + { name: 'description', content: 'Core Improvement Proposals' }, + { property: 'og:title', content: 'CIP' }, + { property: 'og:description', content: 'Core Improvement Proposals' }, + { property: 'og:type', content: 'website' }, + { + "name": "keywords", + "content": "author, categories, champion, cip, cips, consensus, core, design, document, each, editor, editors, encompassing, features, flow, fork, github, have, improvement, improvements, information, intended, key, mechanisms, members, new, offers, platform, primary, proposal, proposing, protocol, rationale, require, responsibilities, serve, sets, six, specifications, stakeholders, standards, stands, team, we, what, work, you", + }, + { property: 'ican:xcb', content: 'cb57bbbb54cdf60fa666fd741be78f794d4608d67109' }, + ], + colorMode: { + defaultMode: 'light', + disableSwitch: false, + respectPrefersColorScheme: true, + }, + navbar: { + title: 'CIP', + logo: { + alt: 'CIP', + src: 'img/logo.svg', + }, + items: [ + {to: '/cip', label: 'CIPs', position: 'left'}, + { + type: 'docSidebar', + sidebarId: 'tutorialSidebar', + position: 'left', + label: 'Tutorial', + }, + { + href: 'https://github.com/core-coin', + position: 'right', + className: 'header-github-link', + 'aria-label': 'GitHub repository', + }, + ], + }, + footer: { + style: 'dark', + links: [ + { + title: 'Docs', + items: [ + { + label: 'CIPs', + to: '/cip', + }, + { + label: 'Tutorial', + to: '/docs/cip', + }, + { + label: 'Tags', + to: '/cip/tags', + }, + ], + }, + { + title: 'Ecosystem', + items: [ + { + label: 'Core Website', + href: 'https://coreblockchain.net', + }, + { + label: 'Core Blog', + href: 'https://blog.coreblockchain.net', + }, + { + label: 'Dev Portal', + href: 'https://dev.coreblockchain.net', + }, + { + label: 'Blockindex', + href: 'https://blockindex.net', + }, + { + label: 'Payto', + href: 'https://payto.money', + }, + ], + }, + { + title: 'Community', + items: [ + { + label: 'Core ◆ Talk', + href: 'https://coretalk.space', + }, + { + label: 'GitHub', + href: 'https://github.com/core-coin', + }, + { + label: 'Discord', + href: 'https://discord.com/invite/SCxmFr5Pwp', + }, + { + label: 'Reddit', + href: 'https://www.reddit.com/r/CoreCoinCC', + }, + { + label: '𝕏', + href: 'https://x.com/corecoincc', + }, + ], + }, + ], + copyright: `Core Foundation ⛬ Copyright and related rights waived via CC0.`, + }, + prism: { + theme: prismThemes.github, + darkTheme: prismThemes.dracula, + }, + algolia: { + appId: '6BNEFFU7K3', + apiKey: 'c149ac2035f0b47db92d69b9bfa4f227', + indexName: 'cip-coreblockchain-net', + }, + } satisfies Preset.ThemeConfig, +}; + +export default config; diff --git a/package.json b/package.json index 7abb8bf..bf07c9d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cip", - "version": "2.0.0", + "version": "3.0.0", "private": true, "scripts": { "docusaurus": "docusaurus", @@ -15,19 +15,20 @@ "typecheck": "tsc" }, "dependencies": { - "@docusaurus/core": "2.4.3", - "@docusaurus/preset-classic": "2.4.3", - "@mdx-js/react": "^1.6.22", - "clsx": "^1.2.1", - "prism-react-renderer": "^1.3.5", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "unist-util-visit": "^5.0.0" + "@docusaurus/core": "3.0.0", + "@docusaurus/preset-classic": "3.0.0", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "cryptocons": "^1.3.3", + "prism-react-renderer": "^2.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0" }, "devDependencies": { - "@docusaurus/module-type-aliases": "2.4.3", - "@tsconfig/docusaurus": "^1.0.5", - "typescript": "^4.7.4" + "@docusaurus/module-type-aliases": "^3.0.0", + "@docusaurus/tsconfig": "^3.0.0", + "@docusaurus/types": "^3.0.0", + "typescript": "^5.2.2" }, "browserslist": { "production": [ @@ -36,12 +37,12 @@ "not op_mini all" ], "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" + "last 3 chrome version", + "last 3 firefox version", + "last 5 safari version" ] }, "engines": { - "node": ">=16.14" + "node": ">=18.0" } } diff --git a/sidebars.js b/sidebars.ts similarity index 83% rename from sidebars.js rename to sidebars.ts index 9ab54c2..acc7685 100644 --- a/sidebars.js +++ b/sidebars.ts @@ -1,3 +1,5 @@ +import type {SidebarsConfig} from '@docusaurus/plugin-content-docs'; + /** * Creating a sidebar enables you to: - create an ordered group of docs @@ -8,11 +10,7 @@ Create as many sidebars as you want. */ - -// @ts-check - -/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ -const sidebars = { +const sidebars: SidebarsConfig = { // By default, Docusaurus generates a sidebar from the docs folder structure tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], @@ -30,4 +28,4 @@ const sidebars = { */ }; -module.exports = sidebars; +export default sidebars; diff --git a/src/components/BlogListPage/index.tsx b/src/components/BlogListPage/index.tsx new file mode 100644 index 0000000..522ede6 --- /dev/null +++ b/src/components/BlogListPage/index.tsx @@ -0,0 +1,53 @@ +import React from 'react'; +import clsx from 'clsx'; + +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import { + PageMetadata, + HtmlClassNameProvider, + ThemeClassNames, +} from '@docusaurus/theme-common'; +import BlogLayout from '@theme/BlogLayout'; +import BlogListPaginator from '@theme/BlogListPaginator'; +import SearchMetadata from '@theme/SearchMetadata'; +import type {Props} from '@theme/BlogListPage'; +import BlogPostItems from '@site/src/components/BlogPostItems'; + +function BlogListPageMetadata(props: Props): JSX.Element { + const {metadata} = props; + const { + siteConfig: {title: siteTitle}, + } = useDocusaurusContext(); + const {blogDescription, blogTitle, permalink} = metadata; + const isBlogOnlyMode = permalink === '/'; + const title = isBlogOnlyMode ? siteTitle : blogTitle; + return ( + <> + + + + ); +} + +function BlogListPageContent(props: Props): JSX.Element { + const {metadata, items, sidebar} = props; + return ( + + + + + ); +} + +export default function BlogListPage(props: Props): JSX.Element { + return ( + + + + + ); +} diff --git a/src/components/BlogPostItem/Container/index.tsx b/src/components/BlogPostItem/Container/index.tsx new file mode 100755 index 0000000..05c12d3 --- /dev/null +++ b/src/components/BlogPostItem/Container/index.tsx @@ -0,0 +1,41 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import {useBaseUrlUtils} from '@docusaurus/useBaseUrl'; +import {useBlogPost} from '@docusaurus/theme-common/internal'; +import type {Props} from '@theme/BlogPostItem/Container'; + +export default function BlogPostItemContainer({ + children, + className, +}: Props): JSX.Element { + const { + frontMatter, + assets, + metadata: {description}, + } = useBlogPost(); + const {withBaseUrl} = useBaseUrlUtils(); + const image = assets.image ?? frontMatter.image; + const keywords = frontMatter.keywords ?? []; + return ( +
+ {description && } + {image && ( + + )} + {keywords.length > 0 && ( + + )} + {children} +
+ ); +} diff --git a/src/components/BlogPostItem/Content/index.tsx b/src/components/BlogPostItem/Content/index.tsx new file mode 100755 index 0000000..592df27 --- /dev/null +++ b/src/components/BlogPostItem/Content/index.tsx @@ -0,0 +1,29 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import clsx from 'clsx'; +import {blogPostContainerID} from '@docusaurus/utils-common'; +import {useBlogPost} from '@docusaurus/theme-common/internal'; +import MDXContent from '@theme/MDXContent'; +import type {Props} from '@theme/BlogPostItem/Content'; + +export default function BlogPostItemContent({ + children, + className, +}: Props): JSX.Element { + const {isBlogPostPage} = useBlogPost(); + return ( +
+ {children} +
+ ); +} diff --git a/src/components/BlogPostItem/Footer/ReadMoreLink/index.tsx b/src/components/BlogPostItem/Footer/ReadMoreLink/index.tsx new file mode 100755 index 0000000..75f725c --- /dev/null +++ b/src/components/BlogPostItem/Footer/ReadMoreLink/index.tsx @@ -0,0 +1,44 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import Translate, {translate} from '@docusaurus/Translate'; +import Link from '@docusaurus/Link'; +import type {Props} from '@theme/BlogPostItem/Footer/ReadMoreLink'; + +function ReadMoreLabel() { + return ( + + + Read More + + + ); +} + +export default function BlogPostItemFooterReadMoreLink( + props: Props, +): JSX.Element { + const {blogPostTitle, ...linkProps} = props; + return ( + + + + ); +} diff --git a/src/components/BlogPostItem/Footer/index.tsx b/src/components/BlogPostItem/Footer/index.tsx new file mode 100755 index 0000000..253faef --- /dev/null +++ b/src/components/BlogPostItem/Footer/index.tsx @@ -0,0 +1,60 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import clsx from 'clsx'; +import {useBlogPost} from '@docusaurus/theme-common/internal'; +import EditThisPage from '@theme/EditThisPage'; +import TagsListInline from '@theme/TagsListInline'; +import ReadMoreLink from '@theme/BlogPostItem/Footer/ReadMoreLink'; + +import styles from './styles.module.css'; + +export default function BlogPostItemFooter(): JSX.Element | null { + const {metadata, isBlogPostPage} = useBlogPost(); + const {tags, title, editUrl, hasTruncateMarker} = metadata; + + // A post is truncated if it's in the "list view" and it has a truncate marker + const truncatedPost = !isBlogPostPage && hasTruncateMarker; + + const tagsExists = tags.length > 0; + + const renderFooter = tagsExists || truncatedPost || editUrl; + + if (!renderFooter) { + return null; + } + + return ( +
+ {tagsExists && ( +
+ +
+ )} + + {isBlogPostPage && editUrl && ( +
+ +
+ )} + + {truncatedPost && ( +
+ +
+ )} +
+ ); +} diff --git a/src/components/BlogPostItem/Footer/styles.module.css b/src/components/BlogPostItem/Footer/styles.module.css new file mode 100755 index 0000000..f9272fb --- /dev/null +++ b/src/components/BlogPostItem/Footer/styles.module.css @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.blogPostFooterDetailsFull { + flex-direction: column; +} diff --git a/src/components/BlogPostItem/Header/Author/index.tsx b/src/components/BlogPostItem/Header/Author/index.tsx new file mode 100755 index 0000000..5f2eb1d --- /dev/null +++ b/src/components/BlogPostItem/Header/Author/index.tsx @@ -0,0 +1,60 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import clsx from 'clsx'; +import Link, {type Props as LinkProps} from '@docusaurus/Link'; + +import type {Props} from '@theme/BlogPostItem/Header/Author'; + +function MaybeLink(props: LinkProps): JSX.Element { + if (props.href) { + return ; + } + return <>{props.children}; +} + +export default function BlogPostItemHeaderAuthor({ + author, + className, +}: Props): JSX.Element { + const {name, title, url, imageURL, email} = author; + const link = url || (email && `mailto:${email}`) || undefined; + return ( +
+ {imageURL && ( + + {name} + + )} + + {name && ( + + )} +
+ ); +} diff --git a/src/components/BlogPostItem/Header/Authors/index.tsx b/src/components/BlogPostItem/Header/Authors/index.tsx new file mode 100755 index 0000000..d1ed5bb --- /dev/null +++ b/src/components/BlogPostItem/Header/Authors/index.tsx @@ -0,0 +1,53 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import clsx from 'clsx'; +import {useBlogPost} from '@docusaurus/theme-common/internal'; +import BlogPostItemHeaderAuthor from '@theme/BlogPostItem/Header/Author'; +import type {Props} from '@theme/BlogPostItem/Header/Authors'; +import styles from './styles.module.css'; + +// Component responsible for the authors layout +export default function BlogPostItemHeaderAuthors({ + className, +}: Props): JSX.Element | null { + const { + metadata: {authors}, + assets, + } = useBlogPost(); + const authorsCount = authors.length; + if (authorsCount === 0) { + return null; + } + const imageOnly = authors.every(({name}) => !name); + return ( +
+ {authors.map((author, idx) => ( +
+ +
+ ))} +
+ ); +} diff --git a/src/components/BlogPostItem/Header/Authors/styles.module.css b/src/components/BlogPostItem/Header/Authors/styles.module.css new file mode 100755 index 0000000..b1bd110 --- /dev/null +++ b/src/components/BlogPostItem/Header/Authors/styles.module.css @@ -0,0 +1,21 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.authorCol { + max-width: inherit !important; + flex-grow: 1 !important; +} + +.imageOnlyAuthorRow { + display: flex; + flex-flow: row wrap; +} + +.imageOnlyAuthorCol { + margin-left: 0.3rem; + margin-right: 0.3rem; +} diff --git a/src/components/BlogPostItem/Header/Info/index.tsx b/src/components/BlogPostItem/Header/Info/index.tsx new file mode 100755 index 0000000..90e648d --- /dev/null +++ b/src/components/BlogPostItem/Header/Info/index.tsx @@ -0,0 +1,125 @@ +import React from 'react'; +import clsx from 'clsx'; +import {translate} from '@docusaurus/Translate'; +import {usePluralForm} from '@docusaurus/theme-common'; +import {useBlogPost} from '@docusaurus/theme-common/internal'; +import type {Props} from '@theme/BlogPostItem/Header/Info'; +import Link from '@docusaurus/Link'; + +import styles from './styles.module.css'; + +// Very simple pluralization: probably good enough for now +function useReadingTimePlural() { + const {selectMessage} = usePluralForm(); + return (readingTimeFloat: number) => { + const readingTime = Math.ceil(readingTimeFloat); + return selectMessage( + readingTime, + translate( + { + id: 'theme.blog.post.readingTime.plurals', + description: + 'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)', + message: 'One min read|{readingTime} min read', + }, + {readingTime}, + ), + ); + }; +} + +function ReadingTime({readingTime}: {readingTime: number}) { + const readingTimePlural = useReadingTimePlural(); + return <>{readingTimePlural(readingTime)}; +} + +function Date({date, formattedDate}: {date: string; formattedDate: string}) { + return ( + + ); +} + +function Spacer() { + return <>{' ● '}; +} + +export default function BlogPostItemHeaderInfo({ + className, +}: Props): JSX.Element { + const {metadata} = useBlogPost(); + const {date, formattedDate, readingTime, frontMatter} = metadata; + + const renderCategory = () => { + if (Array.isArray(frontMatter.categories)) { + const categories = (frontMatter.categories as string[]).map((cat, index, arr) => ( + + + {cat.toUpperCase()} + + {index !== arr.length - 1 && ', '} + + )); + return <>{categories}; + } + return + {(frontMatter.categories as string).toUpperCase()} + ; + }; + + const renderTag = () => { + if (Array.isArray(frontMatter.tags)) { + const tags = (frontMatter.tags as string[]).map((tag, index, arr) => ( + + + {tag.toUpperCase()} + + {index !== arr.length - 1 && ', '} + + )); + return <>{tags}; + } + return + {(frontMatter.tags as string).toUpperCase()} + ; + }; + + return ( +
+ {frontMatter.cip && ( + <> + CIP-{frontMatter.cip} + + + )} + {frontMatter.categories && ( + <> + Category: {renderCategory()} + + + )} + {frontMatter.tags && ( + <> + Tag: {renderTag()} + + + )} + + {typeof readingTime !== 'undefined' && ( + <> + + + + )} + {frontMatter['discussion-to'] && ( + <> + + + Discussion + + + )} +
+ ); +} diff --git a/src/components/BlogPostItem/Header/Info/styles.module.css b/src/components/BlogPostItem/Header/Info/styles.module.css new file mode 100755 index 0000000..796b0f1 --- /dev/null +++ b/src/components/BlogPostItem/Header/Info/styles.module.css @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.container { + font-size: 0.9rem; +} diff --git a/src/components/BlogPostItem/Header/Title/index.tsx b/src/components/BlogPostItem/Header/Title/index.tsx new file mode 100755 index 0000000..ea40c2e --- /dev/null +++ b/src/components/BlogPostItem/Header/Title/index.tsx @@ -0,0 +1,33 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; +import {useBlogPost} from '@docusaurus/theme-common/internal'; +import type {Props} from '@theme/BlogPostItem/Header/Title'; + +import styles from './styles.module.css'; + +export default function BlogPostItemHeaderTitle({ + className, +}: Props): JSX.Element { + const {metadata, isBlogPostPage} = useBlogPost(); + const {permalink, title} = metadata; + const TitleHeading = isBlogPostPage ? 'h1' : 'h2'; + return ( + + {isBlogPostPage ? ( + title + ) : ( + + {title} + + )} + + ); +} diff --git a/src/components/BlogPostItem/Header/Title/styles.module.css b/src/components/BlogPostItem/Header/Title/styles.module.css new file mode 100755 index 0000000..29a29b7 --- /dev/null +++ b/src/components/BlogPostItem/Header/Title/styles.module.css @@ -0,0 +1,19 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.title { + font-size: 2rem; +} + +/** + Blog post title should be smaller on smaller devices +**/ +@media (max-width: 576px) { + .title { + font-size: 1.3rem; + } +} diff --git a/src/components/BlogPostItem/Header/index.tsx b/src/components/BlogPostItem/Header/index.tsx new file mode 100755 index 0000000..cb46782 --- /dev/null +++ b/src/components/BlogPostItem/Header/index.tsx @@ -0,0 +1,21 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import BlogPostItemHeaderTitle from '@site/src/components/BlogPostItem/Header/Title'; +import BlogPostItemHeaderInfo from '@site/src/components/BlogPostItem/Header/Info'; +import BlogPostItemHeaderAuthors from '@site/src/components/BlogPostItem/Header/Authors'; + +export default function BlogPostItemHeader(): JSX.Element { + return ( +
+ + + +
+ ); +} diff --git a/src/components/BlogPostItem/index.tsx b/src/components/BlogPostItem/index.tsx new file mode 100755 index 0000000..ce131c0 --- /dev/null +++ b/src/components/BlogPostItem/index.tsx @@ -0,0 +1,35 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import clsx from 'clsx'; +import {useBlogPost} from '@docusaurus/theme-common/internal'; +import BlogPostItemContainer from '@site/src/components/BlogPostItem/Container'; +import BlogPostItemHeader from '@site/src/components/BlogPostItem/Header'; +import BlogPostItemContent from '@site/src/components/BlogPostItem/Content'; +import BlogPostItemFooter from '@site/src/components/BlogPostItem/Footer'; +import type {Props} from '@theme/BlogPostItem'; + +// apply a bottom margin in list view +function useContainerClassName() { + const {isBlogPostPage} = useBlogPost(); + return !isBlogPostPage ? 'margin-bottom--xl' : undefined; +} + +export default function BlogPostItem({ + children, + className, +}: Props): JSX.Element { + const containerClassName = useContainerClassName(); + return ( + + + {children} + + + ); +} diff --git a/src/components/BlogPostItems/index.tsx b/src/components/BlogPostItems/index.tsx new file mode 100644 index 0000000..02b2b78 --- /dev/null +++ b/src/components/BlogPostItems/index.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import {BlogPostProvider} from '@docusaurus/theme-common/internal'; +import BlogPostItem from '@site/src/components/BlogPostItem'; +import type {Props} from '@theme/BlogPostItems'; + +export default function BlogPostItems({ + items, + component: BlogPostItemComponent = BlogPostItem, +}: Props): JSX.Element { + return ( + <> + {items.map(({content: BlogPostContent}) => ( + + + + + + ))} + + ); +} diff --git a/src/components/BlogPostPage/Metadata/index.tsx b/src/components/BlogPostPage/Metadata/index.tsx new file mode 100755 index 0000000..515e104 --- /dev/null +++ b/src/components/BlogPostPage/Metadata/index.tsx @@ -0,0 +1,44 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import {PageMetadata} from '@docusaurus/theme-common'; +import {useBlogPost} from '@docusaurus/theme-common/internal'; + +export default function BlogPostPageMetadata(): JSX.Element { + const {assets, metadata} = useBlogPost(); + const {title, description, date, tags, authors, frontMatter} = metadata; + + const {keywords} = frontMatter; + const image = assets.image ?? frontMatter.image; + return ( + + + + {/* TODO double check those article meta array syntaxes, see https://ogp.me/#array */} + {authors.some((author) => author.url) && ( + author.url) + .filter(Boolean) + .join(',')} + /> + )} + {tags.length > 0 && ( + tag.label).join(',')} + /> + )} + + ); +} diff --git a/src/components/BlogPostPage/index.tsx b/src/components/BlogPostPage/index.tsx new file mode 100755 index 0000000..aacd383 --- /dev/null +++ b/src/components/BlogPostPage/index.tsx @@ -0,0 +1,73 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React, {type ReactNode} from 'react'; +import clsx from 'clsx'; +import {HtmlClassNameProvider, ThemeClassNames} from '@docusaurus/theme-common'; +import {BlogPostProvider, useBlogPost} from '@docusaurus/theme-common/internal'; +import BlogLayout from '@theme/BlogLayout'; +import BlogPostItem from '@site/src/components/BlogPostItem'; +import BlogPostPaginator from '@theme/BlogPostPaginator'; +import BlogPostPageMetadata from '@theme/BlogPostPage/Metadata'; +import TOC from '@theme/TOC'; +import type {Props} from '@theme/BlogPostPage'; +import Unlisted from '@theme/Unlisted'; +import type {BlogSidebar} from '@docusaurus/plugin-content-blog'; + +function BlogPostPageContent({ + sidebar, + children, +}: { + sidebar: BlogSidebar; + children: ReactNode; +}): JSX.Element { + const {metadata, toc} = useBlogPost(); + const {nextItem, prevItem, frontMatter, unlisted} = metadata; + const { + hide_table_of_contents: hideTableOfContents, + toc_min_heading_level: tocMinHeadingLevel, + toc_max_heading_level: tocMaxHeadingLevel, + } = frontMatter; + return ( + 0 ? ( + + ) : undefined + }> + {unlisted && } + {children} + + {(nextItem || prevItem) && ( + + )} + + ); +} + +export default function BlogPostPage(props: Props): JSX.Element { + const BlogPostContent = props.content; + return ( + + + + + + + + + ); +} diff --git a/src/components/HomepageFeatures/index.tsx b/src/components/HomepageFeatures/index.tsx index e576ca2..6f2803e 100644 --- a/src/components/HomepageFeatures/index.tsx +++ b/src/components/HomepageFeatures/index.tsx @@ -1,5 +1,5 @@ -import React from 'react'; import clsx from 'clsx'; +import Heading from '@theme/Heading'; import styles from './styles.module.css'; type FeatureItem = { @@ -51,9 +51,9 @@ function Feature({title, Img, link, description}: FeatureItem) {
-

+ {title} -

+

{description}

diff --git a/src/css/custom.css b/src/css/custom.css index bb20cb6..3987aaf 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -42,3 +42,18 @@ .footer { background-color: #18181F; } + +a.header-github-link { + background-image: url('/img/github.svg'); + background-repeat: no-repeat; + background-size: contain; + background-position: center; + width: 24px; + height: 24px; + display: inline-block; + margin: 4px; +} + +a.header-github-link > svg { + display: none; +} diff --git a/src/pages/index.module.css b/src/pages/index.module.css index 9ea9399..ca34cb5 100644 --- a/src/pages/index.module.css +++ b/src/pages/index.module.css @@ -3,7 +3,7 @@ * and scoped locally. */ -.heroBanner { + .heroBanner { background-position: center center; background-color: #18181F; color: var(--ifm-color-primary); diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 5153017..10e5459 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,9 +1,9 @@ -import React from 'react'; import clsx from 'clsx'; import Link from '@docusaurus/Link'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import Layout from '@theme/Layout'; import HomepageFeatures from '@site/src/components/HomepageFeatures'; +import Heading from '@theme/Heading'; import styles from './index.module.css'; @@ -12,7 +12,7 @@ function HomepageHeader() { return (
-

{siteConfig.title}

+ {siteConfig.title}

{siteConfig.tagline}

+ + + diff --git a/static/img/social-card.jpg b/static/img/social-card.jpg deleted file mode 100644 index 9996a70..0000000 Binary files a/static/img/social-card.jpg and /dev/null differ diff --git a/static/img/social-card.png b/static/img/social-card.png new file mode 100644 index 0000000..9186c13 Binary files /dev/null and b/static/img/social-card.png differ diff --git a/tsconfig.json b/tsconfig.json index 6f47569..314eab8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { // This file is not used in compilation. It is here just for a nice editor experience. - "extends": "@tsconfig/docusaurus/tsconfig.json", + "extends": "@docusaurus/tsconfig", "compilerOptions": { "baseUrl": "." }