diff --git a/assets/css/compiled/main.css b/assets/css/compiled/main.css
index c6e734d1..6f571a93 100644
--- a/assets/css/compiled/main.css
+++ b/assets/css/compiled/main.css
@@ -1373,6 +1373,9 @@
.justify-center {
justify-content: center;
}
+ .gap-1 {
+ gap: calc(var(--spacing) * 1);
+ }
.gap-4 {
gap: calc(var(--spacing) * 4);
}
@@ -1497,6 +1500,10 @@
border-top-left-radius: var(--radius-lg);
border-top-right-radius: var(--radius-lg);
}
+ .rounded-t-md {
+ border-top-left-radius: var(--radius-md);
+ border-top-right-radius: var(--radius-md);
+ }
.rounded-b-lg {
border-bottom-right-radius: var(--radius-lg);
border-bottom-left-radius: var(--radius-lg);
@@ -2427,6 +2434,13 @@
}
}
}
+ .hover\:bg-neutral-200 {
+ &:hover {
+ @media (hover: hover) {
+ background-color: rgba(var(--color-neutral-200), 1);
+ }
+ }
+ }
.hover\:bg-primary-100 {
&:hover {
@media (hover: hover) {
@@ -3252,6 +3266,15 @@
}
}
}
+ .dark\:hover\:bg-neutral-700 {
+ &:is(.dark *) {
+ &:hover {
+ @media (hover: hover) {
+ background-color: rgba(var(--color-neutral-700), 1);
+ }
+ }
+ }
+ }
.dark\:hover\:bg-primary-400 {
&:is(.dark *) {
&:hover {
@@ -3860,6 +3883,17 @@
}
}
}
+@layer utilities {
+ .tab__button.tab--active {
+ border-bottom: 2px solid rgb(var(--color-primary-500));
+ }
+ .tab__panel {
+ display: none;
+ }
+ .tab__panel.tab--active {
+ display: block;
+ }
+}
#zen-mode-button {
cursor: pointer;
}
diff --git a/assets/css/components/tabs.css b/assets/css/components/tabs.css
new file mode 100644
index 00000000..7bc7548d
--- /dev/null
+++ b/assets/css/components/tabs.css
@@ -0,0 +1,9 @@
+.tab__button.tab--active {
+ border-bottom: 2px solid rgb(var(--color-primary-500));
+}
+.tab__panel {
+ display: none;
+}
+.tab__panel.tab--active {
+ display: block;
+}
diff --git a/assets/css/main.css b/assets/css/main.css
index 8c19a5d5..46550a2d 100644
--- a/assets/css/main.css
+++ b/assets/css/main.css
@@ -4,6 +4,7 @@
@import "tailwindcss";
@import "./components/chroma.css" layer(utilities);
+@import "./components/tabs.css" layer(utilities);
@import "./components/zen-mode.css";
@import "./components/a11y.css";
diff --git a/assets/js/shortcodes/tabs.js b/assets/js/shortcodes/tabs.js
new file mode 100644
index 00000000..a08c4601
--- /dev/null
+++ b/assets/js/shortcodes/tabs.js
@@ -0,0 +1,41 @@
+function initTabs() {
+ tabClickHandler = (event) => {
+ const button = event.target.closest(".tab__button");
+ if (!button) return;
+
+ const container = button.closest(".tab__container");
+ const tabIndex = parseInt(button.dataset.tabIndex);
+ activateTab(container, tabIndex);
+ };
+
+ document.addEventListener("click", tabClickHandler);
+}
+
+function activateTab(container, activeIndex) {
+ const buttons = container.querySelectorAll(".tab__button");
+ const panels = container.querySelectorAll(".tab__panel");
+
+ buttons.forEach((btn, index) => {
+ if (index === activeIndex) {
+ btn.classList.add("tab--active");
+ btn.setAttribute("aria-selected", "true");
+ } else {
+ btn.classList.remove("tab--active");
+ btn.setAttribute("aria-selected", "false");
+ }
+ });
+
+ panels.forEach((panel, index) => {
+ if (index === activeIndex) {
+ panel.classList.add("tab--active");
+ } else {
+ panel.classList.remove("tab--active");
+ }
+ });
+}
+
+if (document.readyState === "loading") {
+ document.addEventListener("DOMContentLoaded", initTabs);
+} else {
+ initTabs();
+}
diff --git a/exampleSite/content/docs/shortcodes/index.it.md b/exampleSite/content/docs/shortcodes/index.it.md
index 3034d038..aa78e0ef 100644
--- a/exampleSite/content/docs/shortcodes/index.it.md
+++ b/exampleSite/content/docs/shortcodes/index.it.md
@@ -714,6 +714,74 @@ You can see some additional Mermaid examples on the [diagrams and flowcharts sam
+## Tabs
+
+The `tabs` shortcode is commonly used to present different variants of a particular step. For example, it can be used to show how to install VS Code on different platforms.
+
+**Example**
+
+`````md
+{{* tabs */>}}
+
+ {{* tab label="Windows" */>}}
+ Install using Chocolatey:
+
+ ```pwsh
+ choco install vscode.install
+ ```
+
+ or install using WinGet
+
+ ```pwsh
+ winget install -e --id Microsoft.VisualStudioCode
+ ```
+ {{* /tab */>}}
+
+ {{* tab label="macOS" */>}}
+ ```bash
+ brew install --cask visual-studio-code
+ ```
+ {{* /tab */>}}
+
+ {{* tab label="Linux" */>}}
+ See [documentation](https://code.visualstudio.com/docs/setup/linux#_install-vs-code-on-linux).
+ {{* /tab */>}}
+
+{{* /tabs */>}}
+`````
+
+**Output**
+
+{{< tabs >}}
+
+ {{< tab label="Windows" >}}
+ Install using Chocolatey:
+
+ ```pwsh
+ choco install vscode.install
+ ```
+
+ or install using WinGet
+
+ ```pwsh
+ winget install -e --id Microsoft.VisualStudioCode
+ ```
+ {{< /tab >}}
+
+ {{< tab label="macOS" >}}
+ ```bash
+ brew install --cask visual-studio-code
+ ```
+ {{< /tab >}}
+
+ {{< tab label="Linux" >}}
+ See [documentation](https://code.visualstudio.com/docs/setup/linux#_install-vs-code-on-linux).
+ {{< /tab >}}
+
+{{< /tabs >}}
+
+
+
## Timeline
The `timeline` creates a visual timeline that can be used in different use-cases, e.g. professional experience, a project's achievements, etc. The `timeline` shortcode relies on the `timelineItem` sub-shortcode to define each item within the main timeline. Each item can have the following properties.
diff --git a/exampleSite/content/docs/shortcodes/index.ja.md b/exampleSite/content/docs/shortcodes/index.ja.md
index 221770f9..95e3ff0f 100644
--- a/exampleSite/content/docs/shortcodes/index.ja.md
+++ b/exampleSite/content/docs/shortcodes/index.ja.md
@@ -711,6 +711,74 @@ B-->C[利益]
+## Tabs
+
+`tabs` ショートコードは、特定の手順における異なるバリアントを提示する際によく使用される。例えば、VS Code を各種プラットフォームにインストールする方法を示す場合などに利用できる。
+
+**例**
+
+````md
+{{* tabs */>}}
+
+ {{* tab label="Windows" */>}}
+ Chocolatey を使用してインストール:
+
+ ```pwsh
+ choco install vscode.install
+ ```
+
+ または WinGet を使用してインストール
+
+ ```pwsh
+ winget install -e --id Microsoft.VisualStudioCode
+ ```
+ {{* /tab */>}}
+
+ {{* tab label="macOS" */>}}
+ ```bash
+ brew install --cask visual-studio-code
+ ```
+ {{* /tab */>}}
+
+ {{* tab label="Linux" */>}}
+ [ドキュメント](https://code.visualstudio.com/docs/setup/linux#_install-vs-code-on-linux)を参照。
+ {{* /tab */>}}
+
+{{* /tabs */>}}
+````
+
+**出力**
+
+{{< tabs >}}
+
+ {{< tab label="Windows" >}}
+ Chocolatey を使用してインストール:
+
+ ```pwsh
+ choco install vscode.install
+ ```
+
+ または WinGet を使用してインストール
+
+ ```pwsh
+ winget install -e --id Microsoft.VisualStudioCode
+ ```
+ {{< /tab >}}
+
+ {{< tab label="macOS" >}}
+ ```bash
+ brew install --cask visual-studio-codeqweqwe
+ ```
+ {{< /tab >}}
+
+ {{< tab label="Linux" >}}
+ [ドキュメント](https://code.visualstudio.com/docs/setup/linux#_install-vs-code-on-linux)を参照。
+ {{< /tab >}}
+
+{{< /tabs >}}
+
+
+
## タイムライン
`timeline` は、さまざまなユースケース (例: 職務経歴、プロジェクトの成果など) で使用できる視覚的なタイムラインを作成します。`timeline` ショートコードは、メインタイムライン内の各アイテムを定義するために `timelineItem` サブショートコードに依存しています。各アイテムには、次のプロパティを設定できます。
diff --git a/exampleSite/content/docs/shortcodes/index.md b/exampleSite/content/docs/shortcodes/index.md
index 0b72c969..c1e36f42 100644
--- a/exampleSite/content/docs/shortcodes/index.md
+++ b/exampleSite/content/docs/shortcodes/index.md
@@ -720,6 +720,74 @@ You can see some additional Mermaid examples on the [diagrams and flowcharts sam
+## Tabs
+
+The `tabs` shortcode is commonly used to present different variants of a particular step. For example, it can be used to show how to install VS Code on different platforms.
+
+**Example**
+
+`````md
+{{* tabs */>}}
+
+ {{* tab label="Windows" */>}}
+ Install using Chocolatey:
+
+ ```pwsh
+ choco install vscode.install
+ ```
+
+ or install using WinGet
+
+ ```pwsh
+ winget install -e --id Microsoft.VisualStudioCode
+ ```
+ {{* /tab */>}}
+
+ {{* tab label="macOS" */>}}
+ ```bash
+ brew install --cask visual-studio-code
+ ```
+ {{* /tab */>}}
+
+ {{* tab label="Linux" */>}}
+ See [documentation](https://code.visualstudio.com/docs/setup/linux#_install-vs-code-on-linux).
+ {{* /tab */>}}
+
+{{* /tabs */>}}
+`````
+
+**Output**
+
+{{< tabs >}}
+
+ {{< tab label="Windows" >}}
+ Install using Chocolatey:
+
+ ```pwsh
+ choco install vscode.install
+ ```
+
+ or install using WinGet
+
+ ```pwsh
+ winget install -e --id Microsoft.VisualStudioCode
+ ```
+ {{< /tab >}}
+
+ {{< tab label="macOS" >}}
+ ```bash
+ brew install --cask visual-studio-code
+ ```
+ {{< /tab >}}
+
+ {{< tab label="Linux" >}}
+ See [documentation](https://code.visualstudio.com/docs/setup/linux#_install-vs-code-on-linux).
+ {{< /tab >}}
+
+{{< /tabs >}}
+
+
+
## Timeline
The `timeline` creates a visual timeline that can be used in different use-cases, e.g. professional experience, a project's achievements, etc. The `timeline` shortcode relies on the `timelineItem` sub-shortcode to define each item within the main timeline. Each item can have the following properties.
diff --git a/exampleSite/content/docs/shortcodes/index.zh-cn.md b/exampleSite/content/docs/shortcodes/index.zh-cn.md
index 17ccc2a3..f1df003d 100644
--- a/exampleSite/content/docs/shortcodes/index.zh-cn.md
+++ b/exampleSite/content/docs/shortcodes/index.zh-cn.md
@@ -724,6 +724,74 @@ B-->C[Profit]
+## Tabs
+
+`tabs` 简码常用于呈现某个步骤的不同变体。例如,可用于展示在不同平台上安装 VS Code 的方式。
+
+**示例**
+
+````md
+{{* tabs */>}}
+
+ {{* tab label="Windows" */>}}
+ 使用 Chocolatey 安装:
+
+ ```pwsh
+ choco install vscode.install
+ ```
+
+ 或使用 WinGet 安装
+
+ ```pwsh
+ winget install -e --id Microsoft.VisualStudioCode
+ ```
+ {{* /tab */>}}
+
+ {{* tab label="macOS" */>}}
+ ```bash
+ brew install --cask visual-studio-code
+ ```
+ {{* /tab */>}}
+
+ {{* tab label="Linux" */>}}
+ 参见[文档](https://code.visualstudio.com/docs/setup/linux#_install-vs-code-on-linux)。
+ {{* /tab */>}}
+
+{{* /tabs */>}}
+````
+
+**输出**
+
+{{< tabs >}}
+
+ {{< tab label="Windows" >}}
+ 使用 Chocolatey 安装:
+
+ ```pwsh
+ choco install vscode.install
+ ```
+
+ 或使用 WinGet 安装
+
+ ```pwsh
+ winget install -e --id Microsoft.VisualStudioCode
+ ```
+ {{< /tab >}}
+
+ {{< tab label="macOS" >}}
+ ```bash
+ brew install --cask visual-studio-code
+ ```
+ {{< /tab >}}
+
+ {{< tab label="Linux" >}}
+ 参见[文档](https://code.visualstudio.com/docs/setup/linux#_install-vs-code-on-linux)。
+ {{< /tab >}}
+
+{{< /tabs >}}
+
+
+
## 时间线
`timeline` 创建了一个可视化时间线,用于展示专业经验、项目成就等。 `timeline` 简码依赖于 `timelineItem` 子简码来定义主时间线中的每个项目。每个项目可以具有以下属性。
diff --git a/layouts/partials/vendor.html b/layouts/partials/vendor.html
index 31872d08..66b6a9c0 100644
--- a/layouts/partials/vendor.html
+++ b/layouts/partials/vendor.html
@@ -145,3 +145,11 @@
}}
{{ end }}
+
+{{/* tabs */}}
+{{ if .Page.HasShortcode "tabs" }}
+ {{ $tabJS := resources.Get "js/shortcodes/tabs.js" }}
+ {{ with $tabJS | minify | resources.Fingerprint (.Site.Params.fingerprintAlgorithm | default "sha512") }}
+
+ {{ end }}
+{{ end }}
diff --git a/layouts/shortcodes/tab.html b/layouts/shortcodes/tab.html
new file mode 100644
index 00000000..338ccc52
--- /dev/null
+++ b/layouts/shortcodes/tab.html
@@ -0,0 +1,7 @@
+{{- $label := .Get "label" -}}
+{{- $index := .Parent.Store.Get "tab-index" | default 0 -}}
+{{- $content := .InnerDeindent | strings.TrimSpace | .Page.RenderString -}}
+
+{{- $tabs := .Parent.Store.Get "tabs" | default slice -}}
+{{- .Parent.Store.Set "tabs" ($tabs | append (dict "label" $label "content" $content)) -}}
+{{- .Parent.Store.Set "tab-index" (add 1 $index) -}}
diff --git a/layouts/shortcodes/tabs.html b/layouts/shortcodes/tabs.html
new file mode 100644
index 00000000..07fe2695
--- /dev/null
+++ b/layouts/shortcodes/tabs.html
@@ -0,0 +1,28 @@
+{{- .Store.Set "tab-index" 0 -}}
+{{- $noop := .Inner -}}
+
+
+