mirror of
https://github.com/nunocoracao/blowfish.git
synced 2026-01-30 16:31:52 +01:00
Merge pull request #2713 from ZhenShuo2021/feat/tabs
✨ Feat(tabs): add icon, group, and default options
This commit is contained in:
47
.vscode/blowfish.code-snippets
vendored
47
.vscode/blowfish.code-snippets
vendored
@@ -178,6 +178,53 @@
|
||||
],
|
||||
"description": "Output a set of up to three different colors. Blowfish swatches Shortcode. Documentation: https://blowfish.page/docs/shortcodes/#swatches ",
|
||||
},
|
||||
"Tabs - Basic": {
|
||||
"prefix": "tabs",
|
||||
"body": [
|
||||
"{{< tabs >}}",
|
||||
"",
|
||||
" {{< tab label=\"${1:Tab 1}\" >}}",
|
||||
" $2",
|
||||
" {{< /tab >}}",
|
||||
"",
|
||||
" {{< tab label=\"${3:Tab 2}\" >}}",
|
||||
" $4",
|
||||
" {{< /tab >}}",
|
||||
"",
|
||||
"{{< /tabs >}}"
|
||||
],
|
||||
"description": "Insert Hugo tabs shortcode"
|
||||
},
|
||||
"Tabs - Full Options": {
|
||||
"prefix": "tabsfull",
|
||||
"body": [
|
||||
"{{< tabs group=\"${1:group-name}\" default=\"${2:Default Tab}\" >}}",
|
||||
"",
|
||||
" {{< tab label=\"${3:Tab 1}\" icon=\"${4:code}\" >}}",
|
||||
" $5",
|
||||
" {{< /tab >}}",
|
||||
"",
|
||||
" {{< tab label=\"${2:Default Tab}\" icon=\"${6:sun}\" >}}",
|
||||
" $7",
|
||||
" {{< /tab >}}",
|
||||
"",
|
||||
" {{< tab label=\"${8:Tab 3}\" icon=\"${9:moon}\" >}}",
|
||||
" $0",
|
||||
" {{< /tab >}}",
|
||||
"",
|
||||
"{{< /tabs >}}"
|
||||
],
|
||||
"description": "Insert Hugo tabs with group, default, and icons"
|
||||
},
|
||||
"Tab": {
|
||||
"prefix": "tab",
|
||||
"body": [
|
||||
"{{< tab label=\"${1:Tab Label}\" >}}",
|
||||
"$2",
|
||||
"{{< /tab >}}"
|
||||
],
|
||||
"description": "Insert Hugo tab item"
|
||||
},
|
||||
"timeline": {
|
||||
"prefix": ["BFS-timeline", "HSC-timeline", "timeline"],
|
||||
"body": [
|
||||
|
||||
@@ -5,7 +5,25 @@ function initTabs() {
|
||||
|
||||
const container = button.closest(".tab__container");
|
||||
const tabIndex = parseInt(button.dataset.tabIndex);
|
||||
activateTab(container, tabIndex);
|
||||
const tabLabel = button.dataset.tabLabel;
|
||||
const group = container.dataset.tabGroup;
|
||||
|
||||
if (group) {
|
||||
const allGroupContainers = document.querySelectorAll(`.tab__container[data-tab-group="${group}"]`);
|
||||
|
||||
allGroupContainers.forEach((groupContainer) => {
|
||||
const targetButton = Array.from(groupContainer.querySelectorAll(".tab__button")).find(
|
||||
(btn) => btn.dataset.tabLabel === tabLabel,
|
||||
);
|
||||
|
||||
if (targetButton) {
|
||||
const targetIndex = parseInt(targetButton.dataset.tabIndex);
|
||||
activateTab(groupContainer, targetIndex);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
activateTab(container, tabIndex);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("click", tabClickHandler);
|
||||
|
||||
@@ -753,7 +753,14 @@ You can see some additional Mermaid examples on the [diagrams and flowcharts sam
|
||||
|
||||
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**
|
||||
| Parameter | Description |
|
||||
| --------- | -------------------------------------------------------- |
|
||||
| `group` | **Optional.** Group name for synchronized tab switching. All tabs with the same group name will switch together. |
|
||||
| `default` | **Optional.** Label of the tab to be active by default. If not set, the first tab will be active. |
|
||||
| `label` | **Required.** The text label displayed on the tab button. |
|
||||
| `icon` | **Optional.** Icon name to display before the label. |
|
||||
|
||||
**Example 1: Basic Usage**
|
||||
|
||||
`````md
|
||||
{{</* tabs */>}}
|
||||
@@ -815,6 +822,94 @@ The `tabs` shortcode is commonly used to present different variants of a particu
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
**Example 2: With Group, Default, and Icon**
|
||||
|
||||
`````md
|
||||
{{</* tabs group="lang" default="Python" */>}}
|
||||
{{</* tab label="JavaScript" icon="code" */>}}
|
||||
```javascript
|
||||
console.log("Hello");
|
||||
```
|
||||
{{</* /tab */>}}
|
||||
|
||||
{{</* tab label="Python" icon="sun" */>}}
|
||||
```python
|
||||
print("Hello")
|
||||
```
|
||||
{{</* /tab */>}}
|
||||
|
||||
{{</* tab label="Go" icon="moon" */>}}
|
||||
```go
|
||||
fmt.Println("Hello")
|
||||
```
|
||||
{{</* /tab */>}}
|
||||
{{</* /tabs */>}}
|
||||
|
||||
{{</* tabs group="lang" default="Python" */>}}
|
||||
{{</* tab label="JavaScript" icon="code" */>}}
|
||||
```javascript
|
||||
const add = (a, b) => a + b;
|
||||
```
|
||||
{{</* /tab */>}}
|
||||
|
||||
{{</* tab label="Python" icon="sun" */>}}
|
||||
```python
|
||||
def add(a, b): return a + b
|
||||
```
|
||||
{{</* /tab */>}}
|
||||
|
||||
{{</* tab label="Go" icon="moon" */>}}
|
||||
```go
|
||||
func add(a, b int) int { return a + b }
|
||||
```
|
||||
{{</* /tab */>}}
|
||||
{{</* /tabs */>}}
|
||||
`````
|
||||
|
||||
**Output**
|
||||
|
||||
{{< tabs group="lang" default="Python" >}}
|
||||
{{< tab label="JavaScript" icon="code" >}}
|
||||
```javascript
|
||||
console.log("Hello");
|
||||
```
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab label="Python" icon="sun" >}}
|
||||
```python
|
||||
print("Hello")
|
||||
```
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab label="Go" icon="moon" >}}
|
||||
```go
|
||||
fmt.Println("Hello")
|
||||
```
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
{{< tabs group="lang" default="Python" >}}
|
||||
{{< tab label="JavaScript" icon="code" >}}
|
||||
```javascript
|
||||
const add = (a, b) => a + b;
|
||||
```
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab label="Python" icon="sun" >}}
|
||||
```python
|
||||
def add(a, b): return a + b
|
||||
```
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab label="Go" icon="moon" >}}
|
||||
```go
|
||||
func add(a, b int) int { return a + b }
|
||||
```
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
In this example, both tab groups share the same `group="lang"` parameter, so clicking any tab will synchronize both groups. The `default="Python"` parameter makes Python the initially active tab, and `icon="code"` adds an icon before each label.
|
||||
|
||||
<br/><br/><br/>
|
||||
|
||||
## Timeline
|
||||
|
||||
@@ -763,7 +763,14 @@ B-->C[Profit]
|
||||
|
||||
`tabs` 简码常用于呈现某个步骤的不同变体。例如,可用于展示在不同平台上安装 VS Code 的方式。
|
||||
|
||||
**示例**
|
||||
| 参数 | 描述 |
|
||||
| --------- | --------------------------------------- |
|
||||
| `group` | **可选。** 用于同步切换标签页的组名。具有相同组名的所有标签页将一起切换。 |
|
||||
| `default` | **可选。** 默认激活的标签页的标签。如果未设置,默认激活第一个标签页。 |
|
||||
| `label` | **必填。** 显示在标签按钮上的文本标签。 |
|
||||
| `icon` | **可选。** 在标签前显示的图标名称。 |
|
||||
|
||||
**示例 1:基本用法**
|
||||
|
||||
````md
|
||||
{{</* tabs */>}}
|
||||
@@ -825,6 +832,94 @@ B-->C[Profit]
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
**示例 2:使用 Group、Default 和 Icon**
|
||||
|
||||
`````md
|
||||
{{</* tabs group="lang" default="Python" */>}}
|
||||
{{</* tab label="JavaScript" icon="code" */>}}
|
||||
```javascript
|
||||
console.log("Hello");
|
||||
```
|
||||
{{</* /tab */>}}
|
||||
|
||||
{{</* tab label="Python" icon="sun" */>}}
|
||||
```python
|
||||
print("Hello")
|
||||
```
|
||||
{{</* /tab */>}}
|
||||
|
||||
{{</* tab label="Go" icon="moon" */>}}
|
||||
```go
|
||||
fmt.Println("Hello")
|
||||
```
|
||||
{{</* /tab */>}}
|
||||
{{</* /tabs */>}}
|
||||
|
||||
{{</* tabs group="lang" default="Python" */>}}
|
||||
{{</* tab label="JavaScript" icon="code" */>}}
|
||||
```javascript
|
||||
const add = (a, b) => a + b;
|
||||
```
|
||||
{{</* /tab */>}}
|
||||
|
||||
{{</* tab label="Python" icon="sun" */>}}
|
||||
```python
|
||||
def add(a, b): return a + b
|
||||
```
|
||||
{{</* /tab */>}}
|
||||
|
||||
{{</* tab label="Go" icon="moon" */>}}
|
||||
```go
|
||||
func add(a, b int) int { return a + b }
|
||||
```
|
||||
{{</* /tab */>}}
|
||||
{{</* /tabs */>}}
|
||||
`````
|
||||
|
||||
**Output**
|
||||
|
||||
{{< tabs group="lang" default="Python" >}}
|
||||
{{< tab label="JavaScript" icon="code" >}}
|
||||
```javascript
|
||||
console.log("Hello");
|
||||
```
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab label="Python" icon="sun" >}}
|
||||
```python
|
||||
print("Hello")
|
||||
```
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab label="Go" icon="moon" >}}
|
||||
```go
|
||||
fmt.Println("Hello")
|
||||
```
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
{{< tabs group="lang" default="Python" >}}
|
||||
{{< tab label="JavaScript" icon="code" >}}
|
||||
```javascript
|
||||
const add = (a, b) => a + b;
|
||||
```
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab label="Python" icon="sun" >}}
|
||||
```python
|
||||
def add(a, b): return a + b
|
||||
```
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab label="Go" icon="moon" >}}
|
||||
```go
|
||||
func add(a, b int) int { return a + b }
|
||||
```
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
在这个示例中,两个标签组都使用了相同的 `group="lang"` 参数,因此点击任意一个标签时,两个标签组都会同步切换。`default="Python"` 参数用于指定 Python 为初始激活的标签,而 `icon="code"` 会在每个标签标题前添加一个图标。
|
||||
|
||||
<br/><br/><br/>
|
||||
|
||||
## 时间线
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{{- $label := .Get "label" -}}
|
||||
{{- $icon := .Get "icon" -}}
|
||||
{{- $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 "tabs" ($tabs | append (dict "label" $label "icon" $icon "content" $content)) -}}
|
||||
{{- .Parent.Store.Set "tab-index" (add 1 $index) -}}
|
||||
|
||||
@@ -1,26 +1,50 @@
|
||||
{{- .Store.Set "tab-index" 0 -}}
|
||||
{{- $noop := .Inner -}}
|
||||
|
||||
{{- $group := .Get "group" -}}
|
||||
{{- $default := .Get "default" -}}
|
||||
|
||||
<div class="tab__container w-full">
|
||||
|
||||
<div
|
||||
class="tab__container w-full"
|
||||
{{ with $group }}data-tab-group="{{ . }}"{{ end }}
|
||||
{{ with $default }}data-default-tab="{{ . }}"{{ end }}>
|
||||
<div class="tab__nav" role="tablist">
|
||||
<div class="flex gap-1 overflow-x-auto">
|
||||
<div class="flex flex-wrap gap-1">
|
||||
{{- range $nTabs, $_ := .Store.Get "tabs" -}}
|
||||
{{- $isActive := false -}}
|
||||
{{- if $default -}}
|
||||
{{- $isActive = eq $default (index . "label") -}}
|
||||
{{- else -}}
|
||||
{{- $isActive = eq $nTabs 0 -}}
|
||||
{{- end -}}
|
||||
<button
|
||||
class="tab__button px-3 py-2 text-sm font-semibold border-b-2 border-transparent rounded-t-md hover:bg-neutral-200 dark:hover:bg-neutral-700 {{ if eq $nTabs 0 }}
|
||||
class="tab__button px-3 py-2 text-sm font-semibold border-b-2 border-transparent rounded-t-md hover:bg-neutral-200 dark:hover:bg-neutral-700 {{ if $isActive -}}
|
||||
tab--active
|
||||
{{ end }}"
|
||||
{{- end }}"
|
||||
role="tab"
|
||||
aria-selected="{{ cond (eq $nTabs 0) "true" "false" }}"
|
||||
data-tab-index="{{ $nTabs }}">
|
||||
{{ index . "label" }}
|
||||
aria-selected="{{ cond $isActive `true` `false` }}"
|
||||
data-tab-index="{{ $nTabs }}"
|
||||
data-tab-label="{{ index . "label" }}">
|
||||
<span class="flex items-center gap-1">
|
||||
{{ with index . "icon" }}
|
||||
{{ partial "icon.html" . }}
|
||||
{{ end }}
|
||||
{{ index . "label" }}
|
||||
</span>
|
||||
</button>
|
||||
{{- end -}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab__content mt-4">
|
||||
{{- range $nTabs, $_ := .Store.Get "tabs" -}}
|
||||
<div class="tab__panel {{ if eq $nTabs 0 }}tab--active{{ end }}" data-tab-index="{{ $nTabs }}">
|
||||
{{- $isActive := false -}}
|
||||
{{- if $default -}}
|
||||
{{- $isActive = eq $default (index . "label") -}}
|
||||
{{- else -}}
|
||||
{{- $isActive = eq $nTabs 0 -}}
|
||||
{{- end -}}
|
||||
<div class="tab__panel {{ if $isActive }}tab--active{{ end }}" data-tab-index="{{ $nTabs }}">
|
||||
{{ index . "content" }}
|
||||
</div>
|
||||
{{- end -}}
|
||||
|
||||
Reference in New Issue
Block a user