From 81b81ca95a19da78591dee3c4273583641f204ed Mon Sep 17 00:00:00 2001 From: Silas Berger Date: Sat, 6 Jan 2024 14:44:03 +0100 Subject: [PATCH] Sketch idea for tabs component and plugin. --- .../Components-Gallery/09-Tab-Container.mdx | 22 ++++++++ docusaurus.config.ts | 2 + src/components/Tabs/TabBody.tsx | 0 src/components/Tabs/TabHeader.tsx | 0 src/components/Tabs/Tabs.module.scss | 53 +++++++++++++++++++ src/components/Tabs/Tabs.tsx | 25 +++++++++ src/plugins/remark-tabs.ts | 47 ++++++++++++++++ 7 files changed, 149 insertions(+) create mode 100644 content/material/Components-Gallery/09-Tab-Container.mdx create mode 100644 src/components/Tabs/TabBody.tsx create mode 100644 src/components/Tabs/TabHeader.tsx create mode 100644 src/components/Tabs/Tabs.module.scss create mode 100644 src/components/Tabs/Tabs.tsx create mode 100644 src/plugins/remark-tabs.ts diff --git a/content/material/Components-Gallery/09-Tab-Container.mdx b/content/material/Components-Gallery/09-Tab-Container.mdx new file mode 100644 index 00000000..1edbdaf8 --- /dev/null +++ b/content/material/Components-Gallery/09-Tab-Container.mdx @@ -0,0 +1,22 @@ +# Tabs +Here you can find all necessary instructions for your operating system. + +::Tabs +:Tab :mdi-microsoft-windows: Windows +Here's how to do it in Windows. + +:Tab :mdi-apple: macOS + +These are the required steps for macOS. + +:Tab :mdi-linux: Linux +
+ Do you really want to try? +
+ If you're brave enough to use Linux (hats off to you), here's how to get it working (maybe probably). +
+
+ +::EndTabs + +We use this text to trigger rebuilds... diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 6d260f39..b846750b 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -7,6 +7,7 @@ import {SCRIPTS_ROOT} from "./config/builder-config"; import * as osPath from "path"; import { Logger } from './src/builder/util/logger'; import remarkMdi from "./src/plugins/remark-mdi"; +import remarkTabs from "./src/plugins/remark-tabs"; const siteConfig = loadSiteConfig(); Logger.instance.info(`🔧 Building site '${siteConfig.siteId}'`); @@ -23,6 +24,7 @@ const docsConfigs = scriptRoots.map((scriptRoot, index) => { routeBasePath: `${scriptRoot}`, sidebarPath: `./config/sidebars/${siteConfig.siteId}.sidebars.ts`, remarkPlugins: [ + remarkTabs, remarkMdi, ] } diff --git a/src/components/Tabs/TabBody.tsx b/src/components/Tabs/TabBody.tsx new file mode 100644 index 00000000..e69de29b diff --git a/src/components/Tabs/TabHeader.tsx b/src/components/Tabs/TabHeader.tsx new file mode 100644 index 00000000..e69de29b diff --git a/src/components/Tabs/Tabs.module.scss b/src/components/Tabs/Tabs.module.scss new file mode 100644 index 00000000..594e2ce4 --- /dev/null +++ b/src/components/Tabs/Tabs.module.scss @@ -0,0 +1,53 @@ +$outside-padding: 0.7rem; + +.tabContainer { + width: 100%; + display: flex; + flex-direction: column; + border-radius: var(--ifm-pagination-nav-border-radius); + overflow: hidden; + box-shadow: var(--custom-global-shadow-lw); +} + +.tabContainer .tabHeader { + width: 100%; + display: flex; + flex-direction: row; + // background: linear-gradient(to top, #f5f5f5, #ffffff 40%); + + //border-bottom: var(--ifm-hr-height) solid var(--ifm-hr-background-color); + + .tab { + padding: $outside-padding; + cursor: pointer; + flex-grow: 1; + display: flex; + justify-content: center; + font-weight: bold; + font-size: 1.05rem; + background: none; + box-shadow: inset var(--custom-global-shadow-lw); + border: none; + border-right: var(--ifm-hr-height) solid var(--ifm-hr-background-color); + transition: color var(--ifm-transition-fast), box-shadow var(--ifm-transition-fast); + + &:last-child { + border-right: none; + } + + &:hover { + color: var(--ifm-color-primary) + } + + &.active { + color: var(--ifm-color-primary); + box-shadow: none; + } + } +} + +.tabContainer .tabBody { + width: 100%; + display: flex; + padding: $outside-padding; +} diff --git a/src/components/Tabs/Tabs.tsx b/src/components/Tabs/Tabs.tsx new file mode 100644 index 00000000..8982b16c --- /dev/null +++ b/src/components/Tabs/Tabs.tsx @@ -0,0 +1,25 @@ +import React, {Children, ReactNode} from "react"; +import styles from "./Tabs.module.scss"; +import clsx from "clsx"; + +export interface Props { + children?: React.ReactNode // TODO: Type to +} + +interface TabElement { + title: string; + node: ReactNode; +} + +export default function ({children}: Props): React.ReactNode { + return ( +
+
+ +
+
+ Here is some text about macOS. +
+
+ ); +}; diff --git a/src/plugins/remark-tabs.ts b/src/plugins/remark-tabs.ts new file mode 100644 index 00000000..30746676 --- /dev/null +++ b/src/plugins/remark-tabs.ts @@ -0,0 +1,47 @@ +import {Transformer} from "unified"; + +import {Node, Parent} from "unist"; +import {visit} from "unist-util-visit"; +import {Directives} from "mdast-util-directive"; + + +/** @type {import('unified').Plugin<[], MdastRoot>} */ +export default function remarkTabs(): Transformer { + return (mdast: Node) => { + console.log(mdast); + + let tabsParent: Parent; + let tabsNode: Directives; + let endTabsNode: Directives; + + visit( + mdast, + (node) => node.type === 'textDirective' || node.type === 'leafDirective', + (node: Directives, _, parent) => { + const tag = node.name.toLowerCase(); + if (tag === 'tabs' || tag === 'endtabs') { + if (tabsParent && parent !== tabsParent) { + throw 'Unexpected tree: ::Tabs and ::EndTabs do not have the same parent.'; + } + tabsParent = parent; + } + if (tag === 'tabs') { + tabsNode = node; + } else if (tag === 'endtabs') { + endTabsNode = node; + } + }); + + if (!(tabsNode && endTabsNode)) { + return; + } + + const tabsIndex = tabsParent.children.indexOf(tabsNode); + const endTabsIndex = tabsParent.children.indexOf(endTabsNode); + const tabsContentRoot: Parent = { + type: 'root', + children: [...tabsParent.children].slice(tabsIndex + 1, endTabsIndex) + } + console.log(tabsContentRoot); + } +}