From 05ccd4fab0b991ad0f385a9f8092ac9ef77a170c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Garc=C3=ADa?= Date: Mon, 8 Nov 2021 14:00:16 -0300 Subject: [PATCH] Autoformat entire codebase (#152) Co-authored-by: Snehan Kekre --- README.md | 98 +- algolia/index_config.json | 27 +- components/blocks/autofunction.js | 399 +- components/blocks/button.js | 12 +- components/blocks/code.js | 128 +- components/blocks/codeTile.js | 13 +- components/blocks/headers.js | 46 +- components/blocks/iconHeader.js | 35 +- components/blocks/image.js | 169 +- components/blocks/important.js | 90 +- components/blocks/inlineCallout.js | 35 +- components/blocks/newsEntry.js | 42 +- components/blocks/note.js | 75 +- components/blocks/noteSplit.js | 70 +- components/blocks/noted.js | 94 +- components/blocks/refCard.js | 14 +- components/blocks/table.js | 129 +- components/blocks/tile.js | 165 +- components/blocks/tip.js | 101 +- components/blocks/warning.js | 90 +- components/blocks/youTube.js | 62 +- components/layouts/component.js | 22 +- components/layouts/flex.js | 10 +- components/layouts/globalTemplate.js | 32 +- components/layouts/inlineCalloutContainer.js | 10 +- components/layouts/masonry.js | 83 +- components/layouts/newsContainer.js | 8 +- components/layouts/row.js | 8 +- components/layouts/tileContainer.js | 8 +- components/navigation/arrowLink.js | 138 +- components/navigation/arrowLinkContainer.js | 8 +- components/navigation/footer.js | 169 +- components/navigation/header.js | 112 +- components/navigation/mobileNav.js | 91 +- components/navigation/sideBar.js | 192 +- components/summaryTiles.js | 6 +- components/utilities/breadCrumbs.js | 157 +- components/utilities/download.js | 6 +- components/utilities/floatingNav.js | 332 +- components/utilities/gdpr.js | 40 +- components/utilities/headerLink.js | 57 +- components/utilities/helpful.js | 343 +- components/utilities/psa.js | 28 +- components/utilities/search.js | 439 +- components/utilities/socialCallout.js | 212 +- components/utilities/spacer.js | 4 +- components/utilities/suggestEdits.js | 24 +- components/utilities/themeToggle.js | 22 +- content/gdpr-banner.md | 4 +- content/index.md | 12 +- .../kb/components/add-component-sidebar.md | 2 +- ...treamlit-components-differ-base-package.md | 2 +- content/kb/components/index.md | 4 +- .../not-possibe-streamlit-components.md | 2 +- content/kb/dependencies/index.md | 2 +- content/kb/dependencies/libgl.md | 2 +- .../kb/dependencies/module-not-found-error.md | 7 +- .../dependencies/no-matching-distribution.md | 5 +- .../deployments/authentication-without-sso.md | 5 +- ...ple-streamlit-apps-different-subdomains.md | 2 +- .../deploy-streamlit-domain-port-80.md | 4 +- ...eploy-streamlit-heroku-aws-google-cloud.md | 2 +- .../does-streamlit-support-wsgi-protocol.md | 2 +- content/kb/deployments/index.md | 2 +- content/kb/deployments/remote-start.md | 2 +- content/kb/deployments/resource-limits.md | 3 +- content/kb/error-messages/index.md | 1 - content/kb/tutorials/databases/tigergraph.md | 6 +- content/kb/tutorials/index.md | 2 +- .../kb/using-streamlit/animate-elements.md | 2 +- content/kb/using-streamlit/caching-issues.md | 1 - .../how-download-file-streamlit.md | 29 +- .../how-download-pandas-dataframe-csv.md | 18 +- content/kb/using-streamlit/index.md | 2 +- .../path-streamlit-config-toml.md | 4 +- .../pydeck-chart-custom-mapbox-styles.md | 2 +- .../remove-streamlit-app-title.md | 3 +- .../retrieve-filename-uploaded.md | 11 +- content/kb/using-streamlit/sanity-checks.md | 1 - ...tch-changes-other-modules-importing-app.md | 2 +- .../kb/using-streamlit/supported-browsers.md | 2 +- .../where-file-uploader-store-when-deleted.md | 5 +- .../advanced-features/configuration.md | 2 +- content/library/advanced-features/index.md | 9 +- .../advanced-features/prerelease-features.md | 2 +- .../advanced-features/session-state.md | 1 - content/library/advanced-features/theming.md | 1 - content/library/api-cheat-sheet.md | 27 +- content/library/api/api-reference.md | 14 - content/library/api/charts/altair_chart.md | 2 +- content/library/api/charts/area_chart.md | 2 +- content/library/api/charts/bar_chart.md | 2 +- content/library/api/charts/bokeh_chart.md | 2 +- content/library/api/charts/graphviz_chart.md | 2 +- content/library/api/charts/line_chart.md | 2 +- content/library/api/charts/map.md | 2 +- content/library/api/charts/plotly_chart.md | 2 +- content/library/api/charts/pydeck_chart.md | 2 +- content/library/api/charts/pyplot.md | 2 +- content/library/api/charts/vega_lite_chart.md | 2 +- content/library/api/code/code.md | 1 - .../library/api/control-flow/control-flow.md | 1 - content/library/api/control-flow/form.md | 2 +- .../api/control-flow/form_submit_button.md | 2 +- content/library/api/control-flow/stop.md | 2 +- content/library/api/data/data.md | 2 - content/library/api/data/dataframe.md | 2 +- content/library/api/data/json.md | 2 +- content/library/api/data/metric.md | 2 +- content/library/api/data/table.md | 2 +- content/library/api/layout/columns.md | 2 +- content/library/api/layout/container.md | 2 +- content/library/api/layout/empty.md | 2 +- content/library/api/layout/expander.md | 2 +- content/library/api/layout/layout.md | 2 - content/library/api/media/audio.md | 2 +- content/library/api/media/image.md | 2 +- content/library/api/media/video.md | 2 +- .../api/performance/experimental-memo.md | 2 +- .../api/performance/experimental-singleton.md | 2 +- content/library/api/state/state.md | 3 +- content/library/api/status/balloons.md | 2 +- content/library/api/status/error.md | 2 +- content/library/api/status/exception.md | 2 +- content/library/api/status/info.md | 2 +- content/library/api/status/progress.md | 2 +- content/library/api/status/spinner.md | 2 +- content/library/api/status/status.md | 2 - content/library/api/status/success.md | 2 +- content/library/api/status/warning.md | 2 +- content/library/api/text/caption.md | 2 +- content/library/api/text/code.md | 2 +- content/library/api/text/header.md | 2 +- content/library/api/text/latex.md | 2 +- content/library/api/text/markdown.md | 2 +- content/library/api/text/subheader.md | 2 +- content/library/api/text/text.md | 2 +- content/library/api/text/title.md | 2 +- content/library/api/utilities/help.md | 2 +- .../library/api/utilities/set_page_config.md | 2 +- content/library/api/utilities/utilities.md | 1 - content/library/api/widgets/button.md | 2 +- content/library/api/widgets/checkbox.md | 2 +- content/library/api/widgets/color_picker.md | 2 +- content/library/api/widgets/date_input.md | 2 +- .../library/api/widgets/download_button.md | 2 +- content/library/api/widgets/file_uploader.md | 2 +- content/library/api/widgets/multiselect.md | 2 +- content/library/api/widgets/number_input.md | 2 +- content/library/api/widgets/radio.md | 2 +- content/library/api/widgets/select_slider.md | 2 +- content/library/api/widgets/selectbox.md | 2 +- content/library/api/widgets/slider.md | 2 +- content/library/api/widgets/text_area.md | 2 +- content/library/api/widgets/text_input.md | 2 +- content/library/api/widgets/time_input.md | 2 +- content/library/api/widgets/widgets.md | 2 - .../library/api/write-magic/write-magic.md | 2 +- content/library/api/write-magic/write.md | 2 +- content/library/changelog.md | 35 +- content/library/components/components-api.md | 1 - content/library/components/components.md | 14 +- .../library/components/publish-component.md | 7 +- content/library/get-started/create-an-app.md | 16 +- content/library/get-started/index.md | 1 - content/library/get-started/installation.md | 2 +- content/library/get-started/main-concepts.md | 3 +- content/library/index.md | 2 +- content/menu.md | 6 - .../streamlit-cloud/additional-features.md | 2 +- .../community/deploy-app-streamlit-cloud.md | 8 +- content/streamlit-cloud/enterprise/billing.md | 4 +- .../enterprise/single-sign-on-sso.md | 2 +- .../streamlit-cloud/enterprise/sso_adfs.md | 14 +- .../streamlit-cloud/enterprise/sso_azure.md | 12 +- .../streamlit-cloud/enterprise/sso_generic.md | 14 +- .../streamlit-cloud/enterprise/sso_okta.md | 10 +- .../enterprise/streamlit_cloud_enterprise.md | 34 +- .../deploy-an-app/app-dependencies.md | 6 +- .../connect-data-sources/index.md | 4 +- .../secrets-management.md | 37 +- .../get-started/deploy-an-app/index.md | 6 +- content/streamlit-cloud/get-started/index.md | 8 +- .../get-started/manage-your-app.md | 12 +- .../get-started/share-your-app/index.md | 40 +- .../share-your-app/single-sign-on/index.md | 3 +- .../share-your-app/single-sign-on/sso_adfs.md | 14 +- .../single-sign-on/sso_auth0.md | 10 +- .../single-sign-on/sso_azure.md | 12 +- .../single-sign-on/sso_generic.md | 14 +- .../share-your-app/single-sign-on/sso_okta.md | 10 +- content/streamlit-cloud/index.md | 2 +- content/streamlit-cloud/troubleshooting.md | 39 +- lib/api.js | 149 +- lib/bus.js | 4 +- lib/utils.cjs | 133 +- next-sitemap.js | 2 +- next.config.js | 8 +- pages/404.js | 116 +- pages/[...slug].js | 708 +- pages/_app.js | 46 +- pages/_document.js | 35 +- pages/index.js | 122 +- pages/style-guide.js | 686 +- public/admin/config.yml | 264 +- public/admin/index.html | 24 +- public/sw.js | 19 +- python/.vscode/launch.json | 30 +- python/compose.yml | 4 +- python/streamlit.json | 43951 +++++++++++++++- scripts/build-search-index.js | 276 +- styles/colors.scss | 45 +- styles/components/blocks/autofunction.scss | 219 +- styles/components/blocks/code.scss | 371 +- styles/components/blocks/codeTile.scss | 81 +- styles/components/blocks/documentation.scss | 3 +- styles/components/blocks/iconHeader.scss | 36 +- styles/components/blocks/image.scss | 216 +- styles/components/blocks/inlineCallout.scss | 44 +- styles/components/blocks/markdownTable.scss | 34 +- styles/components/blocks/newsEntry.scss | 55 +- styles/components/blocks/note.scss | 59 +- styles/components/blocks/noteSplit.scss | 54 +- styles/components/blocks/refCard.scss | 121 +- styles/components/blocks/table.scss | 117 +- styles/components/blocks/tile.scss | 115 +- styles/components/blocks/youTube.scss | 30 +- styles/components/layout/article.scss | 20 +- styles/components/layout/component.scss | 54 +- .../layout/inlineCalloutContainer.scss | 16 +- styles/components/layout/masonry.scss | 6 +- styles/components/layout/newsContainer.scss | 16 +- styles/components/layout/row.scss | 59 +- styles/components/layout/tileContainer.scss | 62 +- styles/components/navigation/arrowLinks.scss | 96 +- styles/components/navigation/footer.scss | 229 +- styles/components/navigation/header.scss | 197 +- .../components/navigation/offScreenNav.scss | 30 +- styles/components/navigation/sideBar.scss | 486 +- styles/components/utilities/breadcrumbs.scss | 30 +- styles/components/utilities/floatingNav.scss | 198 +- styles/components/utilities/gdpr.scss | 58 +- styles/components/utilities/headerLink.scss | 64 +- styles/components/utilities/helpful.scss | 164 +- styles/components/utilities/loading.scss | 24 +- styles/components/utilities/psa.scss | 26 +- styles/components/utilities/search.scss | 367 +- .../components/utilities/socialCallouts.scss | 134 +- styles/components/utilities/suggestEdits.scss | 33 +- styles/fonts.scss | 8 +- styles/global/color_classes.scss | 135 +- styles/global/dark.scss | 580 +- styles/global/fonts.scss | 825 +- styles/global/global.scss | 191 +- styles/global/light.scss | 490 +- styles/global/styles.scss | 104 +- styles/global/templates.scss | 25 +- styles/main.scss | 94 +- styles/utilities.scss | 22 +- 259 files changed, 51652 insertions(+), 6576 deletions(-) diff --git a/README.md b/README.md index 448ab54cd..c6296a052 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ The directory structure of `content/` does not matter as the files will be recur ### Add a new page -Do you want to add a new page to the docs? +Do you want to add a new page to the docs? 1. First, decide which section the page should live in (Streamlit Library, Streamlit Cloud, or Knowledge Base). @@ -67,7 +67,7 @@ Now that you've decided where the file should live and have named the file, it's **File format**: -Every `.md` file has front matter at the very top that defines the page title which appears in the browser tab bar, and the URL slug which appears after the slash in `docs.streamlit.io/` and `localhost:3000/`. +Every `.md` file has front matter at the very top that defines the page title which appears in the browser tab bar, and the URL slug which appears after the slash in `docs.streamlit.io/` and `localhost:3000/`. E.g. For a page titled "Create a component" that should exist at `docs.streamlit.io/library/components/create`, the front matter at the top of `create-component.md` is: @@ -96,7 +96,7 @@ This is a **note** that links to our [website](https://docs.streamlit.io/). **Embed code:** -Enclose code within \` \` to embed it inline. E.g. +Enclose code within \` \` to embed it inline. E.g. ```markdown Create a header with `st.header`. @@ -104,13 +104,13 @@ Create a header with `st.header`. Embed code blocks like so: -```markdown +````markdown ```python import streamlit as st st.text("Hello world") ``` -``` +```` We support syntax highlighting for Python, Bash, TOML, SQL, and JSX. @@ -122,39 +122,37 @@ Use standard Markdown to link to other pages in the docs. E.g. Add an inline lin Learn how to [Create an app](/library/get-started/create-an-app). ``` - - **Add images:** Store images you want to display in `/public/images/`. There are two ways to display images. 1. To display a single image, use regular Markdown. Make sure to start the path of your images from `/images/` instead of `/public/images/`. E.g.: - ```markdown - ![Secrets manager screenshot](/images/databases/edit-secrets.png) - ``` + ```markdown + ![Secrets manager screenshot](/images/databases/edit-secrets.png) + ``` 2. To display multiple images on the same line, add an `` tag containing the alt text and path to the image, for each image, and enclose all of them within `` `` tags. E.g. To display 3 images stored in `/public/images/databases/` : - ```markdown - - Bigquery screenshot 7 - Bigquery screenshot 8 - Bigquery screenshot 9 - - ``` + ```markdown + + Bigquery screenshot 7 + Bigquery screenshot 8 + Bigquery screenshot 9 + + ``` **Discoverability:** All it takes for a new page to be available at a URL is to create a Markdown file in the format described above, containing the title and slug in the front matter. -However, a user has to know the URL to visit the page. The page is therefore *reachable but not discoverable*. The next section describes how to add pages to the docs Menu so that users can find your page. +However, a user has to know the URL to visit the page. The page is therefore _reachable but not discoverable_. The next section describes how to add pages to the docs Menu so that users can find your page. ### Add pages to the Menu How do you make the page you created appear in the Menu? Edit the special markdown file `content/menu.md`. All it has is front matter in YAML. -Suppose you have created an "Installation" page that is available at `docs.streamlit.io/library/get-started/installation`. You want to it to appear in the Menu within the "Streamlit Library" section, nested under the "Get Started" page. +Suppose you have created an "Installation" page that is available at `docs.streamlit.io/library/get-started/installation`. You want to it to appear in the Menu within the "Streamlit Library" section, nested under the "Get Started" page. To do so, find the lines that define the `category` and `url` for "Get Started" in `menu.md` and add two new lines below it, containing: @@ -184,23 +182,23 @@ Suppose a new Streamlit release includes a `st.my_chart` function that you want 2. Create Markdown file (`my_chart.md`) in `content/library/api/charts/` 3. Add the following to `my_chart.md`: - ```markdown - --- - title: st.my_chart - slug: /library/api-reference/charts/st.my_chart - --- + ```markdown + --- + title: st.my_chart + slug: /library/api-reference/charts/st.my_chart + --- - - ``` + + ``` 4. Add the following under the "Chart elements" heading in `content/library/api/api-reference.md`: - 1. A RefCard MDX function containing the URL slug defined in `my_chart.md` . This is the card that will appear on the API Reference landing page. - 2. An Image MDX function containing alt text and the location of the image to be displayed on the card. - 3. A bold heading that will appear on the card (`#### Heading`). It appears below the card image. - 4. A brief description of the `st.my_chart` . It appears below the card heading. - 5. A code block illustrating how to use `st.my_chart`. It appears below the card description and has a Copy icon that when clicked copies the code block to the users' clipboard. + 1. A RefCard MDX function containing the URL slug defined in `my_chart.md` . This is the card that will appear on the API Reference landing page. + 2. An Image MDX function containing alt text and the location of the image to be displayed on the card. + 3. A bold heading that will appear on the card (`#### Heading`). It appears below the card image. + 4. A brief description of the `st.my_chart` . It appears below the card heading. + 5. A code block illustrating how to use `st.my_chart`. It appears below the card description and has a Copy icon that when clicked copies the code block to the users' clipboard. -```markdown +````markdown Tux, the Linux mascot @@ -213,14 +211,14 @@ Suppose a new Streamlit release includes a `st.my_chart` function that you want ``` -``` +```` 5. Add the following 2 new lines to `menu.md` so that `st.my_chart` appears in the Menu: - ```YAML - - category: Streamlit Library / API Reference / Chart elements / st.my_chart - url: /library/api-reference/charts/st.my_chart - ``` + ```YAML + - category: Streamlit Library / API Reference / Chart elements / st.my_chart + url: /library/api-reference/charts/st.my_chart + ``` 6. Save your changes and refresh the browser tab. If all went well, you should see a new entry in the Menu, a new card in the API Reference, and a new page for `st.my_chart`. @@ -239,21 +237,23 @@ If you know the answer to a Streamlit user's pain point and want to add it to th 1. Decide which of the above sections your article belongs to 2. Navigate to the relevant section's folder in `kb/` and 3. Create a `.md` file in the above specified format containing your article - - Make sure the title in the front matter and the file header in Markdown are identical. E.g. - ```markdown - --- - title: How do I add a Component to the sidebar? - slug: /knowledge-base/components/add-component-sidebar - --- + - Make sure the title in the front matter and the file header in Markdown are identical. E.g. + + ```markdown + --- + title: How do I add a Component to the sidebar? + slug: /knowledge-base/components/add-component-sidebar + --- + + # How do I add a Component to the sidebar? + ``` - # How do I add a Component to the sidebar? - ``` 4. Add a line to the existing `index.md` file in the same folder as your article. It should contain the title and URL slug specified in your article's front matter. This step ensures that users are able to discover your article in the index page of the relevant KB section. E.g. - ```markdown - - [How do I add a Component to the sidebar?](/knowledge-base/components/add-component-sidebar) - ``` + ```markdown + - [How do I add a Component to the sidebar?](/knowledge-base/components/add-component-sidebar) + ``` ## Publishing @@ -263,4 +263,4 @@ To publish your changes to the docs site: 2. Create a Pull Request and mark Snehan and Randy as reviewers. 3. Once the checks have completed, checkout the Preview build. 4. Snehan and Randy will review your changes and merge your changes into the `main` branch. -5. Once merged, your changes will be live at [https://docs.streamlit.io/](https://docs.streamlit.io/). \ No newline at end of file +5. Once merged, your changes will be live at [https://docs.streamlit.io/](https://docs.streamlit.io/). diff --git a/algolia/index_config.json b/algolia/index_config.json index 1ade2b432..8afe5a63b 100644 --- a/algolia/index_config.json +++ b/algolia/index_config.json @@ -4,27 +4,15 @@ "minWordSizefor2Typos": 8, "hitsPerPage": 20, "maxValuesPerFacet": 100, - "searchableAttributes": [ - "keywords", - "title", - "content" - ], + "searchableAttributes": ["keywords", "title", "content"], "numericAttributesToIndex": null, "attributesToRetrieve": null, "replaceSynonymsInHighlight": true, "unretrievableAttributes": null, "optionalWords": null, - "attributesForFaceting": [ - "filterOnly(version)" - ], - "attributesToSnippet": [ - "content:15" - ], - "attributesToHighlight": [ - "category", - "content", - "title" - ], + "attributesForFaceting": ["filterOnly(version)"], + "attributesToSnippet": ["content:15"], + "attributesToHighlight": ["category", "content", "title"], "paginationLimitedTo": 1000, "attributeForDistinct": null, "exactOnSingleWordQuery": "attribute", @@ -45,11 +33,8 @@ "highlightPreTag": "", "highlightPostTag": "", "snippetEllipsisText": "", - "alternativesAsExact": [ - "ignorePlurals", - "singleWordSynonym" - ] + "alternativesAsExact": ["ignorePlurals", "singleWordSynonym"] }, "rules": [], "synonyms": [] -} \ No newline at end of file +} diff --git a/components/blocks/autofunction.js b/components/blocks/autofunction.js index d838bfdea..822777d86 100644 --- a/components/blocks/autofunction.js +++ b/components/blocks/autofunction.js @@ -1,203 +1,240 @@ -import reverse from 'lodash/reverse' -import React from "react" -import Table from "./table" -import { H2 } from './headers' -import Warning from "./warning" - -import { withRouter } from 'next/router' - -import Prism from 'prismjs' -import 'prismjs/components/prism-python' -import 'prismjs/plugins/line-numbers/prism-line-numbers' -import 'prismjs/plugins/line-highlight/prism-line-highlight' -import 'prismjs/plugins/line-highlight/prism-line-highlight.css' -import 'prismjs/plugins/toolbar/prism-toolbar' -import 'prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard' -import 'prismjs/plugins/normalize-whitespace/prism-normalize-whitespace' +import reverse from "lodash/reverse"; +import React from "react"; +import Table from "./table"; +import { H2 } from "./headers"; +import Warning from "./warning"; + +import { withRouter } from "next/router"; + +import Prism from "prismjs"; +import "prismjs/components/prism-python"; +import "prismjs/plugins/line-numbers/prism-line-numbers"; +import "prismjs/plugins/line-highlight/prism-line-highlight"; +import "prismjs/plugins/line-highlight/prism-line-highlight.css"; +import "prismjs/plugins/toolbar/prism-toolbar"; +import "prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard"; +import "prismjs/plugins/normalize-whitespace/prism-normalize-whitespace"; function cleanHref(name) { - return String(name).replace('.', '').replace(' ', '-') + return String(name).replace(".", "").replace(" ", "-"); } class Autofunction extends React.Component { - constructor(props) { - super(props) - this.highlighted = false - this.blockRef = React.createRef() - this.handleSelectVersion = this.handleSelectVersion.bind(this) - const versions = props.versions - const current_version = props.version ? props.version : versions[versions.length - 1] - this.state = { current_version: current_version, max_version: versions[versions.length - 1], function: props.function }; + constructor(props) { + super(props); + this.highlighted = false; + this.blockRef = React.createRef(); + this.handleSelectVersion = this.handleSelectVersion.bind(this); + const versions = props.versions; + const current_version = props.version + ? props.version + : versions[versions.length - 1]; + this.state = { + current_version: current_version, + max_version: versions[versions.length - 1], + function: props.function, + }; + } + + Heading(props) {} + + componentDidMount() { + this.highlightWithPrism(); + } + + highlightWithPrism() { + if (this.highlighted) { + return; } - - Heading(props) { - + if (!this.blockRef.current) { + return; } - componentDidMount() { - this.highlightWithPrism() + const pres = Array.prototype.slice.call( + this.blockRef.current.getElementsByTagName("pre") + ); + + pres.forEach((ele) => { + const codeText = ele.innerHTML; + const preTag = ele.cloneNode(true); + const codeWrap = document.createElement("div"); + codeWrap.setAttribute("class", "block-code"); + const codeTag = document.createElement("code"); + codeTag.setAttribute("class", "language-python"); + preTag.classList.add("line-numbers"); + codeTag.innerHTML = codeText; + preTag.textContent = null; + preTag.appendChild(codeTag); + codeWrap.appendChild(preTag); + ele.replaceWith(codeWrap); + }); + + Prism.highlightAllUnder(this.blockRef.current); + + this.highlighted = true; + } + + handleSelectVersion(event) { + const props = this.props; + + const func_obj = props.streamlit[props.function]; + const name = cleanHref(`st.${func_obj.name}`); + const slug = props.slug.slice(); + + if (event.target.value !== this.state.current_version) { + this.setState({ current_version: event.target.value }); + if (event.target.value !== this.state.max_version) { + let isnum = /^[\d\.]+$/.test(slug[0]); + if (isnum) { + slug[0] = event.target.value; + } else { + slug.unshift(event.target.value); + } + } } - highlightWithPrism() { - if (this.highlighted) { return } - if (!this.blockRef.current) { return } - - const pres = Array.prototype.slice.call(this.blockRef.current.getElementsByTagName('pre')) - - pres.forEach((ele) => { - const codeText = ele.innerHTML - const preTag = ele.cloneNode(true) - const codeWrap = document.createElement('div') - codeWrap.setAttribute('class', 'block-code') - const codeTag = document.createElement('code') - codeTag.setAttribute('class', 'language-python') - preTag.classList.add('line-numbers') - codeTag.innerHTML = codeText - preTag.textContent = null - preTag.appendChild(codeTag) - codeWrap.appendChild(preTag) - ele.replaceWith(codeWrap) - }) - - Prism.highlightAllUnder(this.blockRef.current) - - this.highlighted = true + props.router.push(`/${slug.join("/")}#${name}`); + } + + render() { + const props = this.props; + + const footers = []; + const args = []; + const versions = props.versions; + const current_version = props.version + ? props.version + : versions[versions.length - 1]; + const version_list = reverse(props.versions.slice()); + + let func_obj; + let func_description; + let header; + let body; + + if (props.function in props.streamlit) { + func_obj = props.streamlit[props.function]; + if (func_obj.description !== undefined && func_obj.description) { + func_description = { __html: func_obj.description }; + } + } else { + return ( +
+
+

{props.function}

+
+ +

+ This method did not exist in version{" "} + {current_version} of Streamlit. +

+
+
+ ); } - handleSelectVersion(event) { - const props = this.props - - const func_obj = props.streamlit[props.function] - const name = cleanHref(`st.${func_obj.name}`) - const slug = props.slug.slice() - - if ( event.target.value !== this.state.current_version) { - this.setState( { current_version: event.target.value } ); - if (event.target.value !== this.state.max_version) { - let isnum = /^[\d\.]+$/.test(slug[0]) - if (isnum) { - slug[0] = event.target.value - } else { - slug.unshift( event.target.value ) - } - } - } - - props.router.push(`/${slug.join('/')}#${name}`) + if (props.hide_header !== undefined && props.hide_header) { + header = ""; + } else { + const name = `st.${func_obj.name}`; + const selectClass = + current_version !== version_list[0] + ? "version-select old-version" + : "version-select"; + header = ( +
+
+

{name}

+
+ +
+
+
+
+ ); } - render() { - const props = this.props - - const footers = [] - const args = [] - const versions = props.versions - const current_version = props.version ? props.version : versions[versions.length - 1] - const version_list = reverse(props.versions.slice()) - - let func_obj - let func_description - let header - let body - - if (props.function in props.streamlit) { - func_obj = props.streamlit[props.function] - if (func_obj.description !== undefined && func_obj.description) { - func_description = { __html: func_obj.description } - } - } else { - return ( -
-
-

{props.function}

-
- -

This method did not exist in version {current_version} of Streamlit.

-
-
- ) - } - - - if (props.hide_header !== undefined && props.hide_header) { - header = '' - } else { - const name = `st.${func_obj.name}` - const selectClass = current_version !== version_list[0] ? 'version-select old-version' : 'version-select' - header = ( -
-
-

{name}

-
- -
-
-
-
- ) - } - - if ('example' in func_obj) { - footers.push({ 'title': 'Example', 'body': func_obj.example }) - } - - if ('examples' in func_obj) { - footers.push({ 'title': 'Examples', 'body': func_obj.examples }) - } + if ("example" in func_obj) { + footers.push({ title: "Example", body: func_obj.example }); + } - if ('notes' in func_obj) { - footers.push({ 'title': 'Notes', 'body': func_obj.notes }) - } + if ("examples" in func_obj) { + footers.push({ title: "Examples", body: func_obj.examples }); + } - if ('warning' in func_obj) { - footers.push({ 'title': 'Warning', 'body': func_obj.warning }) - } + if ("notes" in func_obj) { + footers.push({ title: "Notes", body: func_obj.notes }); + } - for (const index in func_obj.args) { - const row = {} - const param = func_obj.args[index] - const description = param.description ? param.description : `

No description

` + if ("warning" in func_obj) { + footers.push({ title: "Warning", body: func_obj.warning }); + } - if (param.is_optional) { - row['title'] = `

${param.name} (${param.type_name})

` - row['body'] = `${description}` - } else { - row['title'] = `

${param.name} (${param.type_name})

` - row['body'] = `${description}` - } + for (const index in func_obj.args) { + const row = {}; + const param = func_obj.args[index]; + const description = param.description + ? param.description + : `

No description

`; + + if (param.is_optional) { + row[ + "title" + ] = `

${param.name} (${param.type_name})

`; + row["body"] = `${description}`; + } else { + row[ + "title" + ] = `

${param.name} (${param.type_name})

`; + row["body"] = `${description}`; + } + + args.push(row); + } - args.push(row) + body = ( + ${func_obj.signature}

`, + }} + body={ + args.length + ? { + title: "Parameters", + } + : null } - - body = ( -
${func_obj.signature}

` - }} - body={args.length? { - title: 'Parameters' - } : null} - rows={args.length ? args : null} - addtionalClass='full-width' - footers={footers} - /> - ) - - return ( -
- {header} - {body} -
- ) - } + rows={args.length ? args : null} + addtionalClass="full-width" + footers={footers} + /> + ); + + return ( +
+ {header} + {body} +
+ ); + } } -export default withRouter(Autofunction) +export default withRouter(Autofunction); diff --git a/components/blocks/button.js b/components/blocks/button.js index 31cc9dbe8..866276d6f 100644 --- a/components/blocks/button.js +++ b/components/blocks/button.js @@ -1,7 +1,9 @@ -import Link from 'next/link' +import Link from "next/link"; export default function IconHeader({ children, link }) { - return ( - - ) -} \ No newline at end of file + return ( + + + + ); +} diff --git a/components/blocks/code.js b/components/blocks/code.js index da67f22f9..49dc1149a 100644 --- a/components/blocks/code.js +++ b/components/blocks/code.js @@ -1,75 +1,77 @@ -import React, { Children, useEffect } from "react" +import React, { Children, useEffect } from "react"; -import Prism from 'prismjs' -import "prismjs/components/prism-jsx" -import 'prismjs/components/prism-python' -import 'prismjs/components/prism-toml' -import 'prismjs/components/prism-bash' -import 'prismjs/components/prism-sql' -import 'prismjs/plugins/line-numbers/prism-line-numbers' -import 'prismjs/plugins/line-highlight/prism-line-highlight' -import 'prismjs/plugins/line-highlight/prism-line-highlight.css' -import 'prismjs/plugins/toolbar/prism-toolbar' -import 'prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard' -import 'prismjs/plugins/normalize-whitespace/prism-normalize-whitespace' +import Prism from "prismjs"; +import "prismjs/components/prism-jsx"; +import "prismjs/components/prism-python"; +import "prismjs/components/prism-toml"; +import "prismjs/components/prism-bash"; +import "prismjs/components/prism-sql"; +import "prismjs/plugins/line-numbers/prism-line-numbers"; +import "prismjs/plugins/line-highlight/prism-line-highlight"; +import "prismjs/plugins/line-highlight/prism-line-highlight.css"; +import "prismjs/plugins/toolbar/prism-toolbar"; +import "prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard"; +import "prismjs/plugins/normalize-whitespace/prism-normalize-whitespace"; import Image from "./image"; export default class Code extends React.Component { + constructor(props) { + super(props); + this.state = { + sticky: false, + }; + } - constructor(props) { - super(props) - this.state = { - sticky: false, - }; + componentDidMount() { + if (!window.initial.prism) { + window.initial.prism = true; + Prism.highlightAll(); } + } + componentWillUnmount() { + window.initial.prism = false; + } - componentDidMount() { - if (!window.initial.prism) { - window.initial.prism = true; - Prism.highlightAll(); - } - } - componentWillUnmount() { - window.initial.prism = false; - } - - render() { - - const props = this.props + render() { + const props = this.props; - let ConditionalRendering - let code = props.code !== undefined ? props.code : props.children - let languageClass = `language-${props.language}` + let ConditionalRendering; + let code = props.code !== undefined ? props.code : props.children; + let languageClass = `language-${props.language}`; - if (props.children !== undefined && props.children.props !== undefined) { - code = props.children.props.children - languageClass = props.children.props.className - } - - if (props.img) { - ConditionalRendering = ( -
- -
{code}
-
- ) - } - else if (props.lines) { - ConditionalRendering = ( -
-
{code}
-
- ) - } - else { - ConditionalRendering = ( -
-
{code}
-
- ) - } + if (props.children !== undefined && props.children.props !== undefined) { + code = props.children.props.children; + languageClass = props.children.props.className; + } - return ConditionalRendering + if (props.img) { + ConditionalRendering = ( +
+ +
+            {code}
+          
+
+ ); + } else if (props.lines) { + ConditionalRendering = ( +
+
+            {code}
+          
+
+ ); + } else { + ConditionalRendering = ( +
+
+            {code}
+          
+
+ ); } -} \ No newline at end of file + + return ConditionalRendering; + } +} diff --git a/components/blocks/codeTile.js b/components/blocks/codeTile.js index 9bdd86c99..4e399fe67 100644 --- a/components/blocks/codeTile.js +++ b/components/blocks/codeTile.js @@ -1,9 +1,10 @@ - // Used in cheatsheet. export default function CodeTile({ children, size, featured }) { - return ( -
- {children} -
- ) + return ( +
+ {children} +
+ ); } diff --git a/components/blocks/headers.js b/components/blocks/headers.js index ee913c676..a7f1a5fbc 100644 --- a/components/blocks/headers.js +++ b/components/blocks/headers.js @@ -1,23 +1,22 @@ -import HeaderLink from '../utilities/headerLink' - +import HeaderLink from "../utilities/headerLink"; export const H1 = (props) => ( {getBody(props)} -) +); export const H2 = (props) => ( {getBody(props)} -) +); export const H3 = (props) => ( {getBody(props)} -) +); function getBody(props) { const length = Object.keys(props).length; @@ -27,46 +26,53 @@ function getBody(props) { } else { let body = ( <> - + {props.children} - ) + ); return body; } } export function cleanHref(name) { - const clean = String(name).replace('.', '').replace(' ', '-'); + const clean = String(name).replace(".", "").replace(" ", "-"); return clean; } function getName(props) { if (props.name) { - return props.name + return props.name; } - let nodesToTraverse = Array.isArray(props.children) ? - Array.from(props.children) : [props.children] + let nodesToTraverse = Array.isArray(props.children) + ? Array.from(props.children) + : [props.children]; while (nodesToTraverse.length) { - const node = nodesToTraverse.pop() + const node = nodesToTraverse.pop(); - if (typeof (node) === "string") { - return node + if (typeof node === "string") { + return node; } if (Array.isArray(node) && node.length > 0) { - nodesToTraverse = nodesToTraverse.concat(node) - continue + nodesToTraverse = nodesToTraverse.concat(node); + continue; } if (node?.props?.children) { - nodesToTraverse.push(node.props.children) - continue + nodesToTraverse.push(node.props.children); + continue; } - break + break; } - return undefined + return undefined; } diff --git a/components/blocks/iconHeader.js b/components/blocks/iconHeader.js index 4d35fb932..98c3979ee 100644 --- a/components/blocks/iconHeader.js +++ b/components/blocks/iconHeader.js @@ -1,13 +1,22 @@ -export default function IconHeader({ children, icon, rotate, title, background, color }) { - return ( -
- {icon} -

{title}

-
- ) -} \ No newline at end of file +export default function IconHeader({ + children, + icon, + rotate, + title, + background, + color, +}) { + return ( +
+ + {icon} + +

{title}

+
+ ); +} diff --git a/components/blocks/image.js b/components/blocks/image.js index 85888ed5e..6e10d51ae 100644 --- a/components/blocks/image.js +++ b/components/blocks/image.js @@ -1,91 +1,98 @@ import React from "react"; -import TransitionGroup from 'react-transition-group'; +import TransitionGroup from "react-transition-group"; -import Note from './note' +import Note from "./note"; export default class Image extends React.Component { - constructor(props) { - super(props); - this.openModal = this.openModal.bind(this); - this.closeModal = this.closeModal.bind(this); - this.state = { - opened: false - }; - } - - openModal() { - this.setState({ opened: true }) - } - closeModal() { - this.setState({ opened: false }) - } + constructor(props) { + super(props); + this.openModal = this.openModal.bind(this); + this.closeModal = this.closeModal.bind(this); + this.state = { + opened: false, + }; + } - render() { - const props = this.props - const state = this.state - let block; - let caption; - let captionClass; + openModal() { + this.setState({ opened: true }); + } + closeModal() { + this.setState({ opened: false }); + } - if (props.caption) { - captionClass = 'has-caption'; - caption =

{props.caption}

; - } - if (props.pure) { - block = ( - {props.alt} - ) - } else if (state.opened) { - block = ( -
- -
- {props.alt} - {caption} -
-
+ render() { + const props = this.props; + const state = this.state; + let block; + let caption; + let captionClass; -
- -
- {props.alt} - {caption} -
-
-
- ) - } else if (props.clean) { - block = ( -
-
- {props.alt} - {caption} -
-
- ) - } else { - block = ( -
- -
- {props.alt} - {caption} -
-
-
- // - //
- // - //
- // - //

{{ caption }}

- //
- //
- //
- ) - - } + if (props.caption) { + captionClass = "has-caption"; + caption =

{props.caption}

; + } + if (props.pure) { + block = {props.alt}; + } else if (state.opened) { + block = ( +
+ +
+ {props.alt} + {caption} +
+
- return block +
+ +
+ {props.alt} + {caption} +
+
+
+ ); + } else if (props.clean) { + block = ( +
+
+ {props.alt} + {caption} +
+
+ ); + } else { + block = ( +
+ +
+ {props.alt} + {caption} +
+
+
+ // + //
+ // + //
+ // + //

{{ caption }}

+ //
+ //
+ //
+ ); } + + return block; + } } diff --git a/components/blocks/important.js b/components/blocks/important.js index 4339af0f5..7a364aabc 100644 --- a/components/blocks/important.js +++ b/components/blocks/important.js @@ -1,48 +1,60 @@ import React from "react"; -import IconHeader from '../blocks/iconHeader' +import IconHeader from "../blocks/iconHeader"; export default class Important extends React.Component { - constructor(props) { - super(props); - this.handleTheme = this.handleTheme.bind(this); - this.state = { - theme: 'light-mode' - }; - } + constructor(props) { + super(props); + this.handleTheme = this.handleTheme.bind(this); + this.state = { + theme: "light-mode", + }; + } - async componentDidMount() { - window.addEventListener('ChangeTheme', this.handleTheme); - } + async componentDidMount() { + window.addEventListener("ChangeTheme", this.handleTheme); + } - componentWillUnmount() { - window.removeEventListener('ChangeTheme', this.handleTheme); - } + componentWillUnmount() { + window.removeEventListener("ChangeTheme", this.handleTheme); + } - handleTheme() { - this.setState({ theme: document.body.dataset.theme }) - } - - render() { - const props = this.props - const state = this.state - let block; - if (state.theme == 'dark-mode') { - block = ( -
- - {props.children} -
- ) - } else { - block = ( -
- - {props.children} -
- ) - } + handleTheme() { + this.setState({ theme: document.body.dataset.theme }); + } - return block + render() { + const props = this.props; + const state = this.state; + let block; + if (state.theme == "dark-mode") { + block = ( +
+ + {props.children} +
+ ); + } else { + block = ( +
+ + {props.children} +
+ ); } -} \ No newline at end of file + + return block; + } +} diff --git a/components/blocks/inlineCallout.js b/components/blocks/inlineCallout.js index 31b3129f5..5baa947e8 100644 --- a/components/blocks/inlineCallout.js +++ b/components/blocks/inlineCallout.js @@ -1,22 +1,21 @@ import Link from "next/link"; export default function InlineCallout({ children, icon, color, bold, href }) { - return ( -
- - - {icon} - - -
-

- - {bold} - - {" "} - {children} -

-
-
- ) + return ( +
+ + + {icon} + + +
+

+ + {bold} + {" "} + {children} +

+
+
+ ); } diff --git a/components/blocks/newsEntry.js b/components/blocks/newsEntry.js index 044b4f384..9b238cefa 100644 --- a/components/blocks/newsEntry.js +++ b/components/blocks/newsEntry.js @@ -1,17 +1,29 @@ -import ArrowLink from "../navigation/arrowLink" +import ArrowLink from "../navigation/arrowLink"; export default function NewsEntry({ children, date, title, text, link }) { - function niceDate(date) { - let cleanDate = new Date(date); - // let date = new Date(this.date); - return cleanDate.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' }); - } - return ( -
- -

{title}

-

{text}

- -
- ) -} \ No newline at end of file + function niceDate(date) { + let cleanDate = new Date(date); + // let date = new Date(this.date); + return cleanDate.toLocaleDateString("en-US", { + month: "long", + day: "numeric", + year: "numeric", + }); + } + return ( +
+ +

{title}

+

{text}

+ +
+ ); +} diff --git a/components/blocks/note.js b/components/blocks/note.js index cfd7b9d18..133166858 100644 --- a/components/blocks/note.js +++ b/components/blocks/note.js @@ -1,44 +1,47 @@ import React from "react"; export default class Note extends React.Component { - constructor(props) { - super(props); - this.handleTheme = this.handleTheme.bind(this); - this.state = { - theme: 'light-mode' - }; - } + constructor(props) { + super(props); + this.handleTheme = this.handleTheme.bind(this); + this.state = { + theme: "light-mode", + }; + } - async componentDidMount() { - window.addEventListener('ChangeTheme', this.handleTheme); - } + async componentDidMount() { + window.addEventListener("ChangeTheme", this.handleTheme); + } - componentWillUnmount() { - window.removeEventListener('ChangeTheme', this.handleTheme); - } + componentWillUnmount() { + window.removeEventListener("ChangeTheme", this.handleTheme); + } - handleTheme() { - this.setState({ theme: document.body.dataset.theme }) + handleTheme() { + this.setState({ theme: document.body.dataset.theme }); + } + render() { + const props = this.props; + const state = this.state; + let block; + if (props.dark && state.theme == "dark-mode") { + block = ( +
+ {props.children} +
+ ); + } else { + block = ( +
+ {props.children} +
+ ); } - render() { - const props = this.props - const state = this.state - let block; - if (props.dark && state.theme == 'dark-mode') { - block = ( -
- {props.children} -
- ) - } else { - block = ( -
- {props.children} -
- ) - } - - return block - } -} \ No newline at end of file + return block; + } +} diff --git a/components/blocks/noteSplit.js b/components/blocks/noteSplit.js index 85062a3e5..ae749bb86 100644 --- a/components/blocks/noteSplit.js +++ b/components/blocks/noteSplit.js @@ -1,45 +1,45 @@ import React from "react"; import Note from "./note"; -import Button from './button' +import Button from "./button"; import Image from "./image"; export default class NoteSplit extends React.Component { - constructor(props) { - super(props); - this.handleTheme = this.handleTheme.bind(this); - this.state = { - theme: 'light-mode' - }; - } + constructor(props) { + super(props); + this.handleTheme = this.handleTheme.bind(this); + this.state = { + theme: "light-mode", + }; + } - async componentDidMount() { - window.addEventListener('ChangeTheme', this.handleTheme); - } + async componentDidMount() { + window.addEventListener("ChangeTheme", this.handleTheme); + } - componentWillUnmount() { - window.removeEventListener('ChangeTheme', this.handleTheme); - } + componentWillUnmount() { + window.removeEventListener("ChangeTheme", this.handleTheme); + } - handleTheme() { - this.setState({ theme: document.body.dataset.theme }) - } - render() { - const props = this.props - const state = this.state - let block = ( -
- -
-

{props.title}

-

{props.copy}

- -
- -
-
- ); + handleTheme() { + this.setState({ theme: document.body.dataset.theme }); + } + render() { + const props = this.props; + const state = this.state; + let block = ( +
+ +
+

{props.title}

+

{props.copy}

+ +
+ +
+
+ ); - return block - } -} \ No newline at end of file + return block; + } +} diff --git a/components/blocks/noted.js b/components/blocks/noted.js index 26d499c32..ca1d41e56 100644 --- a/components/blocks/noted.js +++ b/components/blocks/noted.js @@ -1,49 +1,61 @@ import React from "react"; -import IconHeader from './iconHeader' +import IconHeader from "./iconHeader"; export default class Note extends React.Component { - constructor(props) { - super(props); - this.handleTheme = this.handleTheme.bind(this); - this.state = { - theme: 'light-mode' - } - } + constructor(props) { + super(props); + this.handleTheme = this.handleTheme.bind(this); + this.state = { + theme: "light-mode", + }; + } - async componentDidMount() { - window.addEventListener('ChangeTheme', this.handleTheme) - } + async componentDidMount() { + window.addEventListener("ChangeTheme", this.handleTheme); + } - componentWillUnmount() { - window.removeEventListener('ChangeTheme', this.handleTheme) - } + componentWillUnmount() { + window.removeEventListener("ChangeTheme", this.handleTheme); + } - handleTheme() { - this.setState({ theme: document.body.dataset.theme }) - } - render() { - const props = this.props - const state = this.state - - let block; - - if (state.theme == 'dark-mode') { - block = ( -
- - {props.children} -
- ) - } else { - block = ( -
- - {props.children} -
- ) - } - - return block + handleTheme() { + this.setState({ theme: document.body.dataset.theme }); + } + render() { + const props = this.props; + const state = this.state; + + let block; + + if (state.theme == "dark-mode") { + block = ( +
+ + {props.children} +
+ ); + } else { + block = ( +
+ + {props.children} +
+ ); } -} \ No newline at end of file + + return block; + } +} diff --git a/components/blocks/refCard.js b/components/blocks/refCard.js index f6b394e66..4667d64b7 100644 --- a/components/blocks/refCard.js +++ b/components/blocks/refCard.js @@ -1,11 +1,9 @@ -import Link from 'next/link' +import Link from "next/link"; export default function RefCard({ children, size, href }) { - return ( - - - {children} - - - ) + return ( + + {children} + + ); } diff --git a/components/blocks/table.js b/components/blocks/table.js index 33e7ba97d..2b5dde451 100644 --- a/components/blocks/table.js +++ b/components/blocks/table.js @@ -1,59 +1,82 @@ -import React from "react" +import React from "react"; -export default function Table({ children, head, body, rows, addtionalClass, footers = [] }) { - function createMarkup(html) { - return { __html: html }; - } - function createTress(rows) { +export default function Table({ + children, + head, + body, + rows, + addtionalClass, + footers = [], +}) { + function createMarkup(html) { + return { __html: html }; + } + function createTress(rows) { + return

{rows}

; + } - return

{rows}

- } + let trees; + let tbody; - let trees - let tbody + trees = createTress(rows); - trees = createTress(rows); + if (body && body.title) { + tbody = ( + + + + + {rows.map((row, index) => ( + + + + + ))} + + ); + } - if (body && body.title) { - tbody = ( - - - - - {rows.map((row, index) => ( - - - - - ))} - - ) - } - - return ( -
-
+ {body.title} +
+
{" "} +
+
+
{body.title}
- - - - - - - - - {tbody} - -
{head.title}
-
- {footers.map((footer, index) => { - const body = footer.jsx ? footer.body : (
) - return ( -
-

{footer.title}

- {body} -
-
) - })} -
- ) + return ( +
+ + + + + + + + + {tbody} +
+ {head.title} +
+
+ {footers.map((footer, index) => { + const body = footer.jsx ? ( + footer.body + ) : ( +
+ ); + return ( + +
+

+ {footer.title} +

+ {body} +
+
+ ); + })} +
+ ); } diff --git a/components/blocks/tile.js b/components/blocks/tile.js index 46c1dbdd0..5e810e553 100644 --- a/components/blocks/tile.js +++ b/components/blocks/tile.js @@ -1,77 +1,106 @@ import React from "react"; -import Link from 'next/link'; +import Link from "next/link"; export default class Tile extends React.Component { - constructor(props) { - super(props); - this.handleTheme = this.handleTheme.bind(this); - this.state = { - theme: 'light-mode' - }; - } + constructor(props) { + super(props); + this.handleTheme = this.handleTheme.bind(this); + this.state = { + theme: "light-mode", + }; + } - async componentDidMount() { - window.addEventListener('ChangeTheme', this.handleTheme); - } + async componentDidMount() { + window.addEventListener("ChangeTheme", this.handleTheme); + } - componentWillUnmount() { - window.removeEventListener('ChangeTheme', this.handleTheme); - } + componentWillUnmount() { + window.removeEventListener("ChangeTheme", this.handleTheme); + } - handleTheme() { - this.setState({ theme: document.body.dataset.theme }) + handleTheme() { + this.setState({ theme: document.body.dataset.theme }); + } + render() { + const props = this.props; + const state = this.state; + let img; + if (props.img) { + img = ; + } else if (props.dark) { + img = ( + + {props.icon || "downloading"} + + ); + } else { + img = ( + + {props.icon || "downloading"} + + ); } - render() { - const props = this.props - const state = this.state - let img; - if (props.img) { - img = ( - - ) - } else if (props.dark) { - img = ( - {props.icon || "downloading"} - ) - } else { - img = ( - {props.icon || "downloading"} - ) - } - let block; - if (props.dark && state.theme == 'dark-mode') { - block = ( - - ) - } else { - block = ( - - ) - - } - - return block + let block; + if (props.dark && state.theme == "dark-mode") { + block = ( + + ); + } else { + block = ( + + ); } -} \ No newline at end of file + + return block; + } +} diff --git a/components/blocks/tip.js b/components/blocks/tip.js index 7a665fb6e..c9c8c8471 100644 --- a/components/blocks/tip.js +++ b/components/blocks/tip.js @@ -1,51 +1,62 @@ -import React from "react" +import React from "react"; -import IconHeader from '../blocks/iconHeader' +import IconHeader from "../blocks/iconHeader"; export default class Tip extends React.Component { - constructor(props) { - super(props); - this.handleTheme = this.handleTheme.bind(this) - this.state = { - theme: 'light-mode' - } + constructor(props) { + super(props); + this.handleTheme = this.handleTheme.bind(this); + this.state = { + theme: "light-mode", + }; + } + + async componentDidMount() { + window.addEventListener("ChangeTheme", this.handleTheme); + } + + componentWillUnmount() { + window.removeEventListener("ChangeTheme", this.handleTheme); + } + + handleTheme() { + this.setState({ theme: document.body.dataset.theme }); + } + + render() { + const props = this.props; + const state = this.state; + + let block; + + if (state.theme == "dark-mode") { + block = ( +
+ + {props.children} +
+ ); + } else { + block = ( +
+ + {props.children} +
+ ); } - async componentDidMount() { - window.addEventListener('ChangeTheme', this.handleTheme) - } - - componentWillUnmount() { - window.removeEventListener('ChangeTheme', this.handleTheme) - } - - handleTheme() { - this.setState({ theme: document.body.dataset.theme }) - } - - render() { - const props = this.props - const state = this.state - - let block; - - if (state.theme == 'dark-mode') { - block = ( -
- - {props.children} -
- ) - } else { - block = ( -
- - {props.children} -
- ) - - } - - return block - } + return block; + } } diff --git a/components/blocks/warning.js b/components/blocks/warning.js index 44c7e835d..32fbc9b00 100644 --- a/components/blocks/warning.js +++ b/components/blocks/warning.js @@ -1,48 +1,60 @@ import React from "react"; -import IconHeader from './iconHeader' +import IconHeader from "./iconHeader"; export default class Warning extends React.Component { - constructor(props) { - super(props); - this.handleTheme = this.handleTheme.bind(this); - this.state = { - theme: 'light-mode' - }; - } + constructor(props) { + super(props); + this.handleTheme = this.handleTheme.bind(this); + this.state = { + theme: "light-mode", + }; + } - async componentDidMount() { - window.addEventListener('ChangeTheme', this.handleTheme); - } + async componentDidMount() { + window.addEventListener("ChangeTheme", this.handleTheme); + } - componentWillUnmount() { - window.removeEventListener('ChangeTheme', this.handleTheme); - } + componentWillUnmount() { + window.removeEventListener("ChangeTheme", this.handleTheme); + } - handleTheme() { - this.setState({ theme: document.body.dataset.theme }) - } - - render() { - const props = this.props - const state = this.state - let block; - if (state.theme == 'dark-mode') { - block = ( -
- - {props.children} -
- ) - } else { - block = ( -
- - {props.children} -
- ) - } + handleTheme() { + this.setState({ theme: document.body.dataset.theme }); + } - return block + render() { + const props = this.props; + const state = this.state; + let block; + if (state.theme == "dark-mode") { + block = ( +
+ + {props.children} +
+ ); + } else { + block = ( +
+ + {props.children} +
+ ); } -} \ No newline at end of file + + return block; + } +} diff --git a/components/blocks/youTube.js b/components/blocks/youTube.js index 902a4e084..8dd34df6f 100644 --- a/components/blocks/youTube.js +++ b/components/blocks/youTube.js @@ -1,28 +1,42 @@ import React from "react"; export default class YouTube extends React.Component { - render() { - const props = this.props - let YouTubeBlock; - - if (props.caption) { - YouTubeBlock = ( -
-
- -
-

{props.caption}

-
- ) - } else { - YouTubeBlock = ( -
-
- -
-
- ) - } - return YouTubeBlock + render() { + const props = this.props; + let YouTubeBlock; + + if (props.caption) { + YouTubeBlock = ( +
+
+ +
+
+

{props.caption}

+
+
+ ); + } else { + YouTubeBlock = ( +
+
+ +
+
+ ); } -} \ No newline at end of file + return YouTubeBlock; + } +} diff --git a/components/layouts/component.js b/components/layouts/component.js index dbcc9f177..37540c98f 100644 --- a/components/layouts/component.js +++ b/components/layouts/component.js @@ -1,16 +1,16 @@ -import HeaderLink from '../utilities/headerLink' +import HeaderLink from "../utilities/headerLink"; export default function Component({ children, label }) { - return ( -
-
- -

{label}

-
-
-
{children}
-
- ) + return ( +
+
+ +

{label}

+
+
+
{children}
+
+ ); } // export default Component diff --git a/components/layouts/flex.js b/components/layouts/flex.js index 30894d68e..e3706f10e 100644 --- a/components/layouts/flex.js +++ b/components/layouts/flex.js @@ -1,10 +1,6 @@ // Simple horizontal flex container used for MDX. const Flex = ({ children }) => { - return ( -
- {children} -
- ) -} + return
{children}
; +}; -export default Flex +export default Flex; diff --git a/components/layouts/globalTemplate.js b/components/layouts/globalTemplate.js index 34445e987..29779aacd 100644 --- a/components/layouts/globalTemplate.js +++ b/components/layouts/globalTemplate.js @@ -1,20 +1,18 @@ -import React from 'react'; -import Header from '../navigation/header' -import Footer from '../navigation/footer' -import Button from '../blocks/button' - +import React from "react"; +import Header from "../navigation/header"; +import Footer from "../navigation/footer"; +import Button from "../blocks/button"; // export default class Header extends React.Component export default class Layout extends React.Component { - - render() { - const props = this.props; - return ( -
-
- {props.children} -
-
- ) - } -} \ No newline at end of file + render() { + const props = this.props; + return ( +
+
+ {props.children} +
+
+ ); + } +} diff --git a/components/layouts/inlineCalloutContainer.js b/components/layouts/inlineCalloutContainer.js index 0dc2fbf3e..8cfb39bac 100644 --- a/components/layouts/inlineCalloutContainer.js +++ b/components/layouts/inlineCalloutContainer.js @@ -1,7 +1,5 @@ export default function InlineCalloutContainer({ children }) { - return ( -
- {children} -
- ) -} \ No newline at end of file + return ( +
{children}
+ ); +} diff --git a/components/layouts/masonry.js b/components/layouts/masonry.js index 8214beec2..fe10381aa 100644 --- a/components/layouts/masonry.js +++ b/components/layouts/masonry.js @@ -1,48 +1,51 @@ import React from "react"; export default class Masonry extends React.Component { - constructor(props) { - super(props); - this.updateMaxheight = this.updateMaxheight.bind(this) - this.state = { - height: 2000 - }; - } - maxColumnHeight() { - const childrenDOMElements = document.querySelectorAll(".masonry > *"); - let columnHeights = [0, 0, 0]; + constructor(props) { + super(props); + this.updateMaxheight = this.updateMaxheight.bind(this); + this.state = { + height: 2000, + }; + } + maxColumnHeight() { + const childrenDOMElements = document.querySelectorAll(".masonry > *"); + let columnHeights = [0, 0, 0]; - for (let index = 0; index < childrenDOMElements.length; index++) { - let row = index % 3; - columnHeights[row] = columnHeights[row] + childrenDOMElements[index].offsetHeight; - if (index == 0) { - childrenDOMElements[index].classList.add('top-left'); - } else if (index == 2) { - childrenDOMElements[index].classList.add('top-right'); - } - } - return Math.max(...columnHeights) + 5; + for (let index = 0; index < childrenDOMElements.length; index++) { + let row = index % 3; + columnHeights[row] = + columnHeights[row] + childrenDOMElements[index].offsetHeight; + if (index == 0) { + childrenDOMElements[index].classList.add("top-left"); + } else if (index == 2) { + childrenDOMElements[index].classList.add("top-right"); + } } + return Math.max(...columnHeights) + 5; + } - updateMaxheight() { - this.setState({ height: this.maxColumnHeight() }); - - } + updateMaxheight() { + this.setState({ height: this.maxColumnHeight() }); + } - componentDidMount() { - this.updateMaxheight(); - window.addEventListener('resize', this.updateMaxheight); - } - componentWillUnmount() { - window.removeEventListener('resize', this.updateMaxheight()); - } + componentDidMount() { + this.updateMaxheight(); + window.addEventListener("resize", this.updateMaxheight); + } + componentWillUnmount() { + window.removeEventListener("resize", this.updateMaxheight()); + } - render() { - let props = this.props; - return ( -
- {props.children} -
- ) - } -} \ No newline at end of file + render() { + let props = this.props; + return ( +
+ {props.children} +
+ ); + } +} diff --git a/components/layouts/newsContainer.js b/components/layouts/newsContainer.js index fae44e2dc..4f92a2dc6 100644 --- a/components/layouts/newsContainer.js +++ b/components/layouts/newsContainer.js @@ -1,7 +1,3 @@ export default function NewsContainer({ children }) { - return ( -
- {children} -
- ) -} \ No newline at end of file + return
{children}
; +} diff --git a/components/layouts/row.js b/components/layouts/row.js index 899bb6956..3fb4be37f 100644 --- a/components/layouts/row.js +++ b/components/layouts/row.js @@ -1,7 +1,3 @@ export default function Row({ children }) { - return ( -
- {children} -
- ) -} \ No newline at end of file + return
{children}
; +} diff --git a/components/layouts/tileContainer.js b/components/layouts/tileContainer.js index 0653dfd7b..adf943723 100644 --- a/components/layouts/tileContainer.js +++ b/components/layouts/tileContainer.js @@ -1,7 +1,3 @@ export default function TilesContainer({ children }) { - return ( -
- {children} -
- ) -} \ No newline at end of file + return
{children}
; +} diff --git a/components/navigation/arrowLink.js b/components/navigation/arrowLink.js index 386798fe2..f28675a47 100644 --- a/components/navigation/arrowLink.js +++ b/components/navigation/arrowLink.js @@ -1,49 +1,95 @@ -import Link from 'next/link' +import Link from "next/link"; export default function ArrowLink({ children, link, type, content, clean }) { - function ArrowType() { - if (type == 'back' && !clean) { - return ( - - - - Previous: - {content} - - - ) - } else if (type == 'next' && !clean) { - return ( - - - Next: - - {content} - - - ) - } else if (type == 'back' && clean) { - return ( - - - - Previous: - {content} - - - ) - } else if (type == 'next' && clean) { - return ( - - - {content} - - - - ) - } + function ArrowType() { + if (type == "back" && !clean) { + return ( + + + + + + + Previous:{" "} + + {content} + + + ); + } else if (type == "next" && !clean) { + return ( + + + Next: + + + + {content} + + + ); + } else if (type == "back" && clean) { + return ( + + + + + + + Previous:{" "} + + {content} + + + ); + } else if (type == "next" && clean) { + return ( + + + {content} + + + + + + ); } - return ( - - ) -} \ No newline at end of file + } + return ; +} diff --git a/components/navigation/arrowLinkContainer.js b/components/navigation/arrowLinkContainer.js index a8a210a70..e484997d3 100644 --- a/components/navigation/arrowLinkContainer.js +++ b/components/navigation/arrowLinkContainer.js @@ -1,9 +1,5 @@ export default function ArrowLinkContainer({ children }) { - return ( -
- {children} -
- ) + return
{children}
; } -// export default Component \ No newline at end of file +// export default Component diff --git a/components/navigation/footer.js b/components/navigation/footer.js index eda1328b0..151019062 100644 --- a/components/navigation/footer.js +++ b/components/navigation/footer.js @@ -1,34 +1,141 @@ -import Link from "next/link" +import Link from "next/link"; export default function Footer({ revision }) { - return ( - - ) + return ( + + ); } diff --git a/components/navigation/header.js b/components/navigation/header.js index e919924d8..bb37662f2 100644 --- a/components/navigation/header.js +++ b/components/navigation/header.js @@ -1,70 +1,72 @@ -// import Navigation from -import React from 'react'; +// import Navigation from +import React from "react"; -import Link from 'next/link' +import Link from "next/link"; import dynamic from "next/dynamic"; -import MobileNav from './mobileNav'; +import MobileNav from "./mobileNav"; +const ThemeToggle = dynamic(() => import("../utilities/themeToggle"), { + ssr: false, +}); -const ThemeToggle = dynamic(() => import("../utilities/themeToggle"), { ssr: false, }); - -import Search from '../utilities/search'; +import Search from "../utilities/search"; export default class Header extends React.Component { - constructor(props) { - super(props); - this.handleScroll = this.handleScroll.bind(this); - this.handleResize = this.handleResize.bind(this); - this.state = { - sticky: false, - }; - } + constructor(props) { + super(props); + this.handleScroll = this.handleScroll.bind(this); + this.handleResize = this.handleResize.bind(this); + this.state = { + sticky: false, + }; + } - componentDidMount() { - window.addEventListener('scroll', this.handleScroll) - window.addEventListener('resize', this.handleResize) - this.handleResize() - } + componentDidMount() { + window.addEventListener("scroll", this.handleScroll); + window.addEventListener("resize", this.handleResize); + this.handleResize(); + } - handleResize() { - this.setState({ windowWidth: window.innerWidth }) - } + handleResize() { + this.setState({ windowWidth: window.innerWidth }); + } - componentWillUnmount() { - window.removeEventListener('scroll', this.handleScroll) - window.removeEventListener('resize', this.handleResize) - } + componentWillUnmount() { + window.removeEventListener("scroll", this.handleScroll); + window.removeEventListener("resize", this.handleResize); + } - handleScroll() { - let top = window.scrollY; - (top > 20 ? this.setState({ sticky: true }) : this.setState({ sticky: false })) - } - - render() { + handleScroll() { + let top = window.scrollY; + top > 20 + ? this.setState({ sticky: true }) + : this.setState({ sticky: false }); + } - let mobileNav; + render() { + let mobileNav; - if (this.state.windowWidth <= 1024) { - mobileNav = - } - - return ( -
- -
- ) + if (this.state.windowWidth <= 1024) { + mobileNav = ; } + + return ( +
+ +
+ ); + } } diff --git a/components/navigation/mobileNav.js b/components/navigation/mobileNav.js index 2d6e744b4..80e770e2a 100644 --- a/components/navigation/mobileNav.js +++ b/components/navigation/mobileNav.js @@ -1,53 +1,52 @@ -import React from "react" -import bus from '../../lib/bus' -import router, { withRouter } from 'next/router' - +import React from "react"; +import bus from "../../lib/bus"; +import router, { withRouter } from "next/router"; export default class MobileNav extends React.Component { - constructor(props) { - super(props); - this.state = { - nav: false - }; - this.toggleMobileNav = this.toggleMobileNav.bind(this); - this.handleRouteChange = this.handleRouteChange.bind(this); - } + constructor(props) { + super(props); + this.state = { + nav: false, + }; + this.toggleMobileNav = this.toggleMobileNav.bind(this); + this.handleRouteChange = this.handleRouteChange.bind(this); + } - toggleMobileNav() { - bus.emit( this.state.nav ? 'streamlit_nav_closed' : 'streamlit_nav_open') - if ( this.state.nav ) { - document.documentElement.classList.remove( 'nav-open' ) - } else { - document.documentElement.classList.add( 'nav-open' ) - } - this.setState({ nav: !this.state.nav }) - } - - handleRouteChange() { - if (this.state.nav) { - bus.emit( this.state.nav ? 'streamlit_nav_closed' : 'streamlit_nav_open') - if ( this.state.nav ) { - document.documentElement.classList.remove( 'nav-open' ) - } else { - document.documentElement.classList.add( 'nav-open' ) - } - this.setState({ nav: false }) - } + toggleMobileNav() { + bus.emit(this.state.nav ? "streamlit_nav_closed" : "streamlit_nav_open"); + if (this.state.nav) { + document.documentElement.classList.remove("nav-open"); + } else { + document.documentElement.classList.add("nav-open"); } + this.setState({ nav: !this.state.nav }); + } - componentDidMount() { - router.events.on('routeChangeComplete', this.handleRouteChange) + handleRouteChange() { + if (this.state.nav) { + bus.emit(this.state.nav ? "streamlit_nav_closed" : "streamlit_nav_open"); + if (this.state.nav) { + document.documentElement.classList.remove("nav-open"); + } else { + document.documentElement.classList.add("nav-open"); + } + this.setState({ nav: false }); } + } - render() { - let mobileNav; - - mobileNav = ( - - ) - - return mobileNav; - } -} \ No newline at end of file + componentDidMount() { + router.events.on("routeChangeComplete", this.handleRouteChange); + } + + render() { + let mobileNav; + + mobileNav = ( + + ); + + return mobileNav; + } +} diff --git a/components/navigation/sideBar.js b/components/navigation/sideBar.js index f14f2db75..d354f5be4 100644 --- a/components/navigation/sideBar.js +++ b/components/navigation/sideBar.js @@ -1,104 +1,110 @@ import React from "react"; import { connectScrollTo } from "react-instantsearch-dom"; -import bus from '../../lib/bus' - - -import NavItem from '../navigation/navItem' +import bus from "../../lib/bus"; +import NavItem from "../navigation/navItem"; export default class SideBar extends React.Component { - constructor(props) { - super(props); - - this.state = { - condensed: false, - loading: true, - depth: 1, - sticky: false, - over: false, - open: false, - theme: 'light-mode', - menu: props.menu, - }; - - this.checkExpanded = this.checkExpanded.bind(this) - this.handleMouseEnter = this.handleMouseEnter.bind(this) - this.handleMouseLeave = this.handleMouseLeave.bind(this) - this.handleTheme = this.handleTheme.bind(this) - } - - handleTheme() { - this.setState({ theme: document.body.dataset.theme }) - } - - handleScroll() { - let top = window.scrollY; - (top > 20 ? this.setState({ sticky: true }) : this.setState({ sticky: false })) - } - - handleMouseEnter() { - if (window.innerWidth < 1250 && window.innerWidth > 1024) { - this.setState({ condensed: false }) - this.setState({ over: true }) - } - } - - handleMouseLeave() { - if (window.innerWidth < 1250 && window.innerWidth > 1024) { - this.setState({ condensed: true }) - this.setState({ over: false }) - } - } - - checkExpanded() { - if (window.innerWidth < 1250 && window.innerWidth > 1024) { - this.setState({ condensed: true }) - } else { - this.setState({ condensed: false }) - } - } - - componentDidMount() { - window.addEventListener('resize', this.checkExpanded) - window.addEventListener('ChangeTheme', this.handleTheme) - - bus.on('streamlit_nav_open', () => this.setState({ open: true })) - bus.on('streamlit_nav_closed', () => this.setState({ open: false })) - - this.checkExpanded() - this.setState({ slug: window.location.href }) + constructor(props) { + super(props); + + this.state = { + condensed: false, + loading: true, + depth: 1, + sticky: false, + over: false, + open: false, + theme: "light-mode", + menu: props.menu, + }; + + this.checkExpanded = this.checkExpanded.bind(this); + this.handleMouseEnter = this.handleMouseEnter.bind(this); + this.handleMouseLeave = this.handleMouseLeave.bind(this); + this.handleTheme = this.handleTheme.bind(this); + } + + handleTheme() { + this.setState({ theme: document.body.dataset.theme }); + } + + handleScroll() { + let top = window.scrollY; + top > 20 + ? this.setState({ sticky: true }) + : this.setState({ sticky: false }); + } + + handleMouseEnter() { + if (window.innerWidth < 1250 && window.innerWidth > 1024) { + this.setState({ condensed: false }); + this.setState({ over: true }); } + } - componentWillUnmount() { - window.removeEventListener('ChangeTheme', this.handleTheme); + handleMouseLeave() { + if (window.innerWidth < 1250 && window.innerWidth > 1024) { + this.setState({ condensed: true }); + this.setState({ over: false }); } + } - render() { - const props = this.props - const state = this.state - - let navItems - navItems = props.menu.map((page, index) => ( - - )) - - return ( -
- -
- ) + checkExpanded() { + if (window.innerWidth < 1250 && window.innerWidth > 1024) { + this.setState({ condensed: true }); + } else { + this.setState({ condensed: false }); } + } + + componentDidMount() { + window.addEventListener("resize", this.checkExpanded); + window.addEventListener("ChangeTheme", this.handleTheme); + + bus.on("streamlit_nav_open", () => this.setState({ open: true })); + bus.on("streamlit_nav_closed", () => this.setState({ open: false })); + + this.checkExpanded(); + this.setState({ slug: window.location.href }); + } + + componentWillUnmount() { + window.removeEventListener("ChangeTheme", this.handleTheme); + } + + render() { + const props = this.props; + const state = this.state; + + let navItems; + navItems = props.menu.map((page, index) => ( + + )); + + return ( +
+ +
+ ); + } } diff --git a/components/summaryTiles.js b/components/summaryTiles.js index 8ede801aa..db547291e 100644 --- a/components/summaryTiles.js +++ b/components/summaryTiles.js @@ -1,5 +1,5 @@ -import TileContainer from '../components/layouts/tileContainer' -import Tile from '../components/blocks/tile' +import TileContainer from "../components/layouts/tileContainer"; +import Tile from "../components/blocks/tile"; export default function SummaryTiles() { return ( @@ -28,5 +28,5 @@ export default function SummaryTiles() { link="https://streamlit.io/gallery" /> - ) + ); } diff --git a/components/utilities/breadCrumbs.js b/components/utilities/breadCrumbs.js index 1c5155a1d..8feee243d 100644 --- a/components/utilities/breadCrumbs.js +++ b/components/utilities/breadCrumbs.js @@ -1,95 +1,94 @@ -import React from "react" -import { breadcrumbsForSlug } from '../../lib/utils.cjs' -import Link from "next/link" +import React from "react"; +import { breadcrumbsForSlug } from "../../lib/utils.cjs"; +import Link from "next/link"; export default class BreadCrumbs extends React.Component { - constructor(props) { - super(props) - } + constructor(props) { + super(props); + } - formatedTitle(title) { - return `${title}` - .replace(/\-/g, ' ') - .replace(/\bapi\b/, 'API') - } + formatedTitle(title) { + return `${title}`.replace(/\-/g, " ").replace(/\bapi\b/, "API"); + } - createCrumb(crumb, index, slug) { - let formatedCrumb - if (index == slug.length) { - formatedCrumb = ( - - {crumb.title} - - ) - } else { - formatedCrumb = ( - <> - - {crumb.title} - - / - - ) - } - return formatedCrumb + createCrumb(crumb, index, slug) { + let formatedCrumb; + if (index == slug.length) { + formatedCrumb = ( + + {crumb.title} + + ); + } else { + formatedCrumb = ( + <> + + {crumb.title} + + / + + ); } + return formatedCrumb; + } + render() { + const props = this.props; + const breadcrumbs = []; - render() { - const props = this.props - const breadcrumbs = [] + if (props.slug === undefined) { + return ""; + } - if ( props.slug === undefined ) { return '' } - - let paths = props.slug.join('/') + let paths = props.slug.join("/"); - breadcrumbs.push({ - link: '/', - title: 'Home' - }) + breadcrumbs.push({ + link: "/", + title: "Home", + }); - const isnum = /^[\d\.]+$/.test(props.slug[0]) - if (isnum) { - paths = props.slug.slice(1).join('/') - breadcrumbs.push({ - link: '#', - title: props.slug[0] - }) - } + const isnum = /^[\d\.]+$/.test(props.slug[0]); + if (isnum) { + paths = props.slug.slice(1).join("/"); + breadcrumbs.push({ + link: "#", + title: props.slug[0], + }); + } - // Find the menu with the current slug - const location = `/${paths}` - const path = breadcrumbsForSlug(props.menu, location, []) + // Find the menu with the current slug + const location = `/${paths}`; + const path = breadcrumbsForSlug(props.menu, location, []); - path.forEach(obj => { - if (obj.url === location) { - breadcrumbs.push({ - link: location, - title: this.formatedTitle(obj.name) - }) - } else { - breadcrumbs.push({ - link: obj.url, - title: this.formatedTitle(obj.name) - }) - } + path.forEach((obj) => { + if (obj.url === location) { + breadcrumbs.push({ + link: location, + title: this.formatedTitle(obj.name), }); + } else { + breadcrumbs.push({ + link: obj.url, + title: this.formatedTitle(obj.name), + }); + } + }); - if ( breadcrumbs.length === 1 ) { - breadcrumbs.push({ - link: location, - title: paths - }) - } - - return ( - - ) + if (breadcrumbs.length === 1) { + breadcrumbs.push({ + link: location, + title: paths, + }); } + + return ( + + ); + } } diff --git a/components/utilities/download.js b/components/utilities/download.js index 011abd4e1..3895fe7ad 100644 --- a/components/utilities/download.js +++ b/components/utilities/download.js @@ -4,7 +4,7 @@ const Download = ({ href, children }) => { {children} - ) -} + ); +}; -export default Download +export default Download; diff --git a/components/utilities/floatingNav.js b/components/utilities/floatingNav.js index 537733657..d70577748 100644 --- a/components/utilities/floatingNav.js +++ b/components/utilities/floatingNav.js @@ -1,172 +1,204 @@ -import findIndex from 'lodash/findIndex'; -import pullAt from 'lodash/pullAt' +import findIndex from "lodash/findIndex"; +import pullAt from "lodash/pullAt"; import React from "react"; -import { breadcrumbsForSlug } from '../../lib/utils.cjs' +import { breadcrumbsForSlug } from "../../lib/utils.cjs"; -import { withRouter } from 'next/router' +import { withRouter } from "next/router"; class FloatingNav extends React.Component { + constructor(props) { + super(props); - constructor(props) { - super(props) - - this.handleTheme = this.handleTheme.bind(this) - this.handleIntersection = this.handleIntersection.bind(this) - this.calculateTarget = this.calculateTarget.bind(this) - this.generateMenu = this.generateMenu.bind(this) - this.handleRouteChange = this.handleRouteChange.bind(this) - - const options = { threshold: 1.0, rootMargin: "0px 0px -200px 0px" } - - this.state = { - target: false, - observer: false, - headers: [], - menu: [], - slug: props.slug.join('/'), - theme: 'light-mode', - highest: {}, - intersected: [], - options: options - } - } + this.handleTheme = this.handleTheme.bind(this); + this.handleIntersection = this.handleIntersection.bind(this); + this.calculateTarget = this.calculateTarget.bind(this); + this.generateMenu = this.generateMenu.bind(this); + this.handleRouteChange = this.handleRouteChange.bind(this); - handleIntersection(entries, observer) { - let intersected = this.state.intersected.slice() - for (const index in entries) { - const entry = entries[index] - const existing = findIndex(intersected, (obj) => obj.target === entry.target ) - if (entry.isIntersecting && existing < 0) { - intersected.push(entry) - } - else if (entry.isIntersecting && existing > -1) { - intersected[existing] = entry - } - else if (!entry.isIntersecting && existing > -1) { - pullAt(intersected, existing) - } - } - this.setState({ intersected: intersected }) - this.calculateTarget(); - - } + const options = { threshold: 1.0, rootMargin: "0px 0px -200px 0px" }; - calculateTarget() { - let highest = 0 - const intersected = this.state.intersected - for (const index in intersected) { - const entry = intersected[index] - const hrefs = entry.target.getElementsByTagName('a') - const top = hrefs[0].offsetTop - if (top < highest || highest === 0) { - highest = top - if (hrefs.length > 0) { - const link = hrefs[0].getAttribute('href') - this.setState({ target: link }) - } - } - } - } + this.state = { + target: false, + observer: false, + headers: [], + menu: [], + slug: props.slug.join("/"), + theme: "light-mode", + highest: {}, + intersected: [], + options: options, + }; + } - async generateMenu() { - if (this.state.headers.length > 0) { this.closeMenu() } - const tocMenu = [] - const headers = Array.prototype.slice.apply(document.querySelectorAll('article.leaf-page h1, article.leaf-page h2, article.leaf-page h3, article.leaf-page h4, article.leaf-page h5, article.leaf-page h6')) - const observer = this.state.observer - for (const index in headers) { - const ele = headers[index] - if (ele.getElementsByTagName === undefined) { continue; } - const hrefs = ele.getElementsByTagName('a') - if (hrefs.length > 0) { - const target = hrefs[0].getAttribute('href') - tocMenu.push({ - label: ele.innerText, - target: target, - level: ele.tagName - }) - observer.observe(ele) - } - } - this.setState({ menu: tocMenu, headers: headers }) + handleIntersection(entries, observer) { + let intersected = this.state.intersected.slice(); + for (const index in entries) { + const entry = entries[index]; + const existing = findIndex( + intersected, + (obj) => obj.target === entry.target + ); + if (entry.isIntersecting && existing < 0) { + intersected.push(entry); + } else if (entry.isIntersecting && existing > -1) { + intersected[existing] = entry; + } else if (!entry.isIntersecting && existing > -1) { + pullAt(intersected, existing); + } } + this.setState({ intersected: intersected }); + this.calculateTarget(); + } - closeMenu() { - for (const index in this.state.headers) { - const ele = this.state.headers[index] - this.state.observer.unobserve(ele) + calculateTarget() { + let highest = 0; + const intersected = this.state.intersected; + for (const index in intersected) { + const entry = intersected[index]; + const hrefs = entry.target.getElementsByTagName("a"); + const top = hrefs[0].offsetTop; + if (top < highest || highest === 0) { + highest = top; + if (hrefs.length > 0) { + const link = hrefs[0].getAttribute("href"); + this.setState({ target: link }); } - this.setState({ menu: [], headers: [] }) + } } + } - async componentDidMount() { - const observer = new IntersectionObserver(this.handleIntersection, this.state.options) - await this.setState({ observer: observer, menu: [], headers: [] }) - this.props.router.events.on('routeChangeComplete', this.handleRouteChange) - window.addEventListener('ChangeTheme', this.handleTheme) - - this.generateMenu() + async generateMenu() { + if (this.state.headers.length > 0) { + this.closeMenu(); } - - handleRouteChange() { - this.closeMenu() - this.generateMenu() + const tocMenu = []; + const headers = Array.prototype.slice.apply( + document.querySelectorAll( + "article.leaf-page h1, article.leaf-page h2, article.leaf-page h3, article.leaf-page h4, article.leaf-page h5, article.leaf-page h6" + ) + ); + const observer = this.state.observer; + for (const index in headers) { + const ele = headers[index]; + if (ele.getElementsByTagName === undefined) { + continue; + } + const hrefs = ele.getElementsByTagName("a"); + if (hrefs.length > 0) { + const target = hrefs[0].getAttribute("href"); + tocMenu.push({ + label: ele.innerText, + target: target, + level: ele.tagName, + }); + observer.observe(ele); + } } + this.setState({ menu: tocMenu, headers: headers }); + } - componentWillUnmount() { - this.closeMenu() - window.removeEventListener('ChangeTheme', this.handleTheme) - this.props.router.events.off('routeChangeComplete', this.handleRouteChange) + closeMenu() { + for (const index in this.state.headers) { + const ele = this.state.headers[index]; + this.state.observer.unobserve(ele); } + this.setState({ menu: [], headers: [] }); + } - handleTheme() { - this.setState({ theme: document.body.dataset.theme }) - } + async componentDidMount() { + const observer = new IntersectionObserver( + this.handleIntersection, + this.state.options + ); + await this.setState({ observer: observer, menu: [], headers: [] }); + this.props.router.events.on("routeChangeComplete", this.handleRouteChange); + window.addEventListener("ChangeTheme", this.handleTheme); - render() { - let color - let svgColor = (this.state.theme === 'light-mode') ? 'black' : 'white' - const props = this.props - const menu = this.state.menu - const target = this.state.target - const isnum = /^[\d\.]+$/.test(props.slug[0]); - const slug = isnum ? props.slug.slice(1).join('/') : this.state.slug - const location = this.state.slug.split('/')[0] - - // Get the Root Object and find the appropriate color - const breadCrumbs = breadcrumbsForSlug(props.menu, `/${slug}`) - - if (breadCrumbs.length) { - const rootElement = breadCrumbs[0] - const darkColor = rootElement.color - color = darkColor - if (this.state.theme === 'light-mode') { - const colorParts = darkColor.split('-') - let lightMode = colorParts.length > 1 ? Number(colorParts[1]) - 50 : 10 - if (lightMode < 10 || isNaN(lightMode)) lightMode = 10 - color = `${colorParts.slice(0, -1).join('-')}-${lightMode}` - svgColor = darkColor - } - } - - let svg = ( - - ) - - return ( - menu.length > 1 ? -
-
-
    -
  1. Contents
  2. - {menu.map((item, index) => { - const active = item.target == target ? 'active' : '' - return (
  3. {svg}{item.label}
  4. ) - })} -
-
- : '' - ) + this.generateMenu(); + } + + handleRouteChange() { + this.closeMenu(); + this.generateMenu(); + } + + componentWillUnmount() { + this.closeMenu(); + window.removeEventListener("ChangeTheme", this.handleTheme); + this.props.router.events.off("routeChangeComplete", this.handleRouteChange); + } + + handleTheme() { + this.setState({ theme: document.body.dataset.theme }); + } + + render() { + let color; + let svgColor = this.state.theme === "light-mode" ? "black" : "white"; + const props = this.props; + const menu = this.state.menu; + const target = this.state.target; + const isnum = /^[\d\.]+$/.test(props.slug[0]); + const slug = isnum ? props.slug.slice(1).join("/") : this.state.slug; + const location = this.state.slug.split("/")[0]; + + // Get the Root Object and find the appropriate color + const breadCrumbs = breadcrumbsForSlug(props.menu, `/${slug}`); + + if (breadCrumbs.length) { + const rootElement = breadCrumbs[0]; + const darkColor = rootElement.color; + color = darkColor; + if (this.state.theme === "light-mode") { + const colorParts = darkColor.split("-"); + let lightMode = colorParts.length > 1 ? Number(colorParts[1]) - 50 : 10; + if (lightMode < 10 || isNaN(lightMode)) lightMode = 10; + color = `${colorParts.slice(0, -1).join("-")}-${lightMode}`; + svgColor = darkColor; + } } + + let svg = ( + + + + ); + + return menu.length > 1 ? ( +
+
+
    +
  1. Contents
  2. + {menu.map((item, index) => { + const active = item.target == target ? "active" : ""; + return ( +
  3. + {svg} + {item.label} +
  4. + ); + })} +
+
+ ) : ( + "" + ); + } } -export default withRouter(FloatingNav) \ No newline at end of file +export default withRouter(FloatingNav); diff --git a/components/utilities/gdpr.js b/components/utilities/gdpr.js index 69532c8ae..93db66783 100644 --- a/components/utilities/gdpr.js +++ b/components/utilities/gdpr.js @@ -1,6 +1,6 @@ // Global Imports import { useState, useEffect } from "react"; -import { MDXRemote } from 'next-mdx-remote' +import { MDXRemote } from "next-mdx-remote"; // The first timezone in Europe is UTC+0. const EUROPE_TZ_OFFSET_WEST = 0; @@ -13,10 +13,9 @@ const EUROPE_TZ_OFFSET_EAST = -3 * 60; const KEY = "InsertAnalyticsCode"; export default function GDPRBanner(gdrp_data) { - - const title = gdrp_data.title - const content = ( gdrp_data.content ) - const data = gdrp_data.data + const title = gdrp_data.title; + const content = gdrp_data.content; + const data = gdrp_data.data; const currentTzOffset = new Date().getTimezoneOffset(); @@ -36,7 +35,7 @@ export default function GDPRBanner(gdrp_data) { // Only show banner if not in europe and banner wasn't already shown. const showBanner = mayBeInEurope && !localStorageIsSetUp; - + const [isVisible, setIsVisible] = useState(showBanner); const [insertAnalyticsCode, setInsertAnalyticsCode] = useState( localStorage.getItem(KEY) == "true" @@ -62,25 +61,26 @@ export default function GDPRBanner(gdrp_data) { if (insertAnalyticsCode) { insertAnalytics(); } - }, [ insertAnalyticsCode ]); + }, [insertAnalyticsCode]); + + if (!isVisible) { + return ""; + } - if (!isVisible) { return ''; } - return (
-
-
-

{title}

- -
-
- - -
+
+
+

{title}

+
+
+ + +
+
); - } function insertAnalytics() { @@ -145,4 +145,4 @@ function insertAnalytics() { analytics.page(); } })(); -} \ No newline at end of file +} diff --git a/components/utilities/headerLink.js b/components/utilities/headerLink.js index da4670ded..9edd111ac 100644 --- a/components/utilities/headerLink.js +++ b/components/utilities/headerLink.js @@ -1,45 +1,45 @@ -import React from "react" +import React from "react"; -import slugify from 'slugify' -import classNames from 'classnames' +import slugify from "slugify"; +import classNames from "classnames"; export default class HeaderLink extends React.Component { constructor(props) { - super(props) - this.hash = props.name ? - slugify(props.name, { remove: /[^A-Za-z0-9_\s]/g, lower: true }) : - "" + super(props); + this.hash = props.name + ? slugify(props.name, { remove: /[^A-Za-z0-9_\s]/g, lower: true }) + : ""; this.state = { - copied: false - } + copied: false, + }; - this.copyLink = this.copyLinkUnbound.bind(this) + this.copyLink = this.copyLinkUnbound.bind(this); } componentDidMount() { if (window.location.hash !== `#${this.hash}`) { - return + return; } - const el = document.querySelector(`[name=${this.hash}]`) + const el = document.querySelector(`[name=${this.hash}]`); if (el) { - el.scrollIntoView(true) + el.scrollIntoView(true); } } async copyLinkUnbound() { - const link = `${window.location.host}${window.location.pathname}#${this.hash}` - await navigator.clipboard.writeText(link) - window.location.hash = this.hash + const link = `${window.location.host}${window.location.pathname}#${this.hash}`; + await navigator.clipboard.writeText(link); + window.location.hash = this.hash; - this.setState({ copied: true }) - window.setTimeout(() => this.setState({ copied: false }), 2000) + this.setState({ copied: true }); + window.setTimeout(() => this.setState({ copied: false }), 2000); } render() { - const { children, level } = this.props - const Header = `h${level}` + const { children, level } = this.props; + const Header = `h${level}`; return ( <> @@ -53,11 +53,24 @@ export default class HeaderLink extends React.Component {
) : (
- + + +
)} - ) + ); } } diff --git a/components/utilities/helpful.js b/components/utilities/helpful.js index 02c0cb4df..22bf78cb8 100644 --- a/components/utilities/helpful.js +++ b/components/utilities/helpful.js @@ -3,162 +3,219 @@ import pull from "lodash/pull"; import SuggestEdits from "./suggestEdits"; -import router, { withRouter } from 'next/router'; +import router, { withRouter } from "next/router"; export default class Helpful extends React.Component { - - constructor(props) { - super(props) - this.formRef = React.createRef() - - this.handleStep = this.handleStep.bind(this) - this.handleOther = this.handleOther.bind(this) - this.submitForm = this.submitForm.bind(this) - this.handleRouteChange = this.handleRouteChange.bind(this) - this.handleImprovement = this.handleImprovement.bind(this) - this.handleNoteChange = this.handleNoteChange.bind(this) - - this.state = { - step: 0, - other: false, - helpful: true, - improvements: [], - notes: '', - improvementsString: '', - moreExamples: false, - clearerSteps: false, - moreInformation: false, - other: false - } + constructor(props) { + super(props); + this.formRef = React.createRef(); + + this.handleStep = this.handleStep.bind(this); + this.handleOther = this.handleOther.bind(this); + this.submitForm = this.submitForm.bind(this); + this.handleRouteChange = this.handleRouteChange.bind(this); + this.handleImprovement = this.handleImprovement.bind(this); + this.handleNoteChange = this.handleNoteChange.bind(this); + + this.state = { + step: 0, + other: false, + helpful: true, + improvements: [], + notes: "", + improvementsString: "", + moreExamples: false, + clearerSteps: false, + moreInformation: false, + other: false, + }; + } + + handleStep(newStep) { + this.setState({ step: newStep }); + if (newStep == 1) { + this.setState({ helpful: false }); } + if (newStep == 2) { + this.submitForm(); + } + } + + submitForm() { + if (this.formRef && this.formRef.current) { + const data = new FormData(this.formRef.current); + fetch("/", { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + body: new URLSearchParams(data).toString(), + }); + } + } + + handleOther() { + this.setState({ other: !this.state.other }); + } - handleStep(newStep) { - this.setState({ step: newStep }) - if (newStep == 1) { - this.setState({ helpful: false }) - } - if (newStep == 2) { - this.submitForm() - } + handleImprovement(event) { + const improvements = this.state.improvements.slice(); + const target = event.target; + const value = target.type === "checkbox" ? target.checked : target.value; + const name = target.name; + + if (value && !improvements.includes(name)) { + improvements.push(name); } - submitForm() { - if (this.formRef && this.formRef.current) { - const data = new FormData(this.formRef.current) - fetch('/', { - method: 'POST', - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body: new URLSearchParams(data).toString() - }) - } + if (!value && improvements.includes(name)) { + pull(improvements, name); } - handleOther() { - this.setState({ other: !this.state.other }) + this.setState({ [name]: value }); + this.setState({ improvements: improvements }); + this.setState({ improvementsString: improvements.join(",") }); + } + + handleNoteChange(event) { + this.setState({ notes: event.target.value }); + } + + handleRouteChange() { + this.setState({ + step: 0, + helpful: true, + improvements: [], + improvementsString: "", + }); + } + + componentDidMount() { + router.events.on("routeChangeComplete", this.handleRouteChange); + } + + render() { + let slug = "/"; + const state = this.state; + const props = this.props; + if (props.slug) { + slug = `/${props.slug.join("/")}`; } - handleImprovement(event) { - const improvements = this.state.improvements.slice() - const target = event.target; - const value = target.type === 'checkbox' ? target.checked : target.value; - const name = target.name; - - if (value && !improvements.includes(name)) { - improvements.push(name) - } - - if (!value && improvements.includes(name)) { - pull(improvements, name) - } - - this.setState({ [name]: value }); - this.setState({ improvements: improvements }); - this.setState({ improvementsString: improvements.join(',') }); + let otherText; + if (state.other) { + otherText = ( +