forked from drowl87/hextra_mirror
feat: add tabs implementation
chore: use filename by default in sidebar
This commit is contained in:
parent
e71887d00e
commit
b6e0ab0872
20
assets/js/tabs.js
Normal file
20
assets/js/tabs.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
document.querySelectorAll('.tabs-toggle').forEach(function (button) {
|
||||||
|
button.addEventListener('click', function (e) {
|
||||||
|
// set parent tabs to unselected
|
||||||
|
const tabs = Array.from(e.target.parentElement.querySelectorAll('.tabs-toggle'));
|
||||||
|
tabs.map(tab => tab.setAttribute('data-state', ''));
|
||||||
|
|
||||||
|
// set current tab to selected
|
||||||
|
e.target.setAttribute('data-state', 'selected');
|
||||||
|
|
||||||
|
// set all panels to unselected
|
||||||
|
const panelsContainer = e.target.parentElement.nextElementSibling;
|
||||||
|
Array.from(panelsContainer.children).forEach(function (panel) {
|
||||||
|
panel.setAttribute('data-state', '');
|
||||||
|
});
|
||||||
|
|
||||||
|
const panelId = e.target.getAttribute('aria-controls');
|
||||||
|
const panel = panelsContainer.querySelector(`#${panelId}`);
|
||||||
|
panel.setAttribute('data-state', 'selected');
|
||||||
|
});
|
||||||
|
});
|
51
content/docs/components/tabs.md
Normal file
51
content/docs/components/tabs.md
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
title: Tabs
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
{{< tabs items="JSON,YAML,TOML" >}}
|
||||||
|
|
||||||
|
{{< tab >}}**JSON**: JavaScript Object Notation (JSON) is a standard text-based format for representing structured data based on JavaScript object syntax.{{< /tab >}}
|
||||||
|
{{< tab >}}**YAML**: YAML is a human-readable data serialization language.{{< /tab >}}
|
||||||
|
{{< tab >}}**TOML**: TOML aims to be a minimal configuration file format that's easy to read due to obvious semantics.{{< /tab >}}
|
||||||
|
|
||||||
|
{{< /tabs >}}
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Default
|
||||||
|
|
||||||
|
```
|
||||||
|
{{</* tabs items="JSON,YAML,TOML" */>}}
|
||||||
|
|
||||||
|
{{</* tab */>}}**JSON**: JavaScript Object Notation (JSON) is a standard text-based format for representing structured data based on JavaScript object syntax.{{</* /tab */>}}
|
||||||
|
{{</* tab */>}}**YAML**: YAML is a human-readable data serialization language.{{</* /tab */>}}
|
||||||
|
{{</* tab */>}}**TOML**: TOML aims to be a minimal configuration file format that's easy to read due to obvious semantics.{{</* /tab */>}}
|
||||||
|
|
||||||
|
{{</* /tabs */>}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Specify Selected Index
|
||||||
|
|
||||||
|
Use `defaultIndex` property to specify the selected tab. The index starts from 0.
|
||||||
|
|
||||||
|
```
|
||||||
|
{{</* tabs items="JSON,YAML,TOML" defaultIndex="1" */>}}
|
||||||
|
|
||||||
|
{{</* tab */>}}**JSON**: JavaScript Object Notation (JSON) is a standard text-based format for representing structured data based on JavaScript object syntax.{{</* /tab */>}}
|
||||||
|
{{</* tab */>}}**YAML**: YAML is a human-readable data serialization language.{{</* /tab */>}}
|
||||||
|
{{</* tab */>}}**TOML**: TOML aims to be a minimal configuration file format that's easy to read due to obvious semantics.{{</* /tab */>}}
|
||||||
|
|
||||||
|
{{</* /tabs */>}}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `YAML` tab will be selected by default.
|
||||||
|
|
||||||
|
{{< tabs items="JSON,YAML,TOML" defaultIndex="1" >}}
|
||||||
|
|
||||||
|
{{< tab >}}**JSON**: JavaScript Object Notation (JSON) is a standard text-based format for representing structured data based on JavaScript object syntax.{{< /tab >}}
|
||||||
|
{{< tab >}}**YAML**: YAML is a human-readable data serialization language.{{< /tab >}}
|
||||||
|
{{< tab >}}**TOML**: TOML aims to be a minimal configuration file format that's easy to read due to obvious semantics.{{< /tab >}}
|
||||||
|
|
||||||
|
{{< /tabs >}}
|
@ -13,6 +13,11 @@
|
|||||||
</script>
|
</script>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if .HasShortcode "tabs" }}
|
||||||
|
{{ $tabsJS := resources.Get "js/tabs.js" }}
|
||||||
|
<script src="{{ $tabsJS.RelPermalink }}"></script>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
{{ if .Page.Params.math }}
|
{{ if .Page.Params.math }}
|
||||||
<!-- TODO: embed katex in the theme -->
|
<!-- TODO: embed katex in the theme -->
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css" integrity="sha384-GvrOXuhMATgEsSwCs4smul74iXGOixntILdUW9XmUC6+HX0sLNAK3q71HotJqlAn" crossorigin="anonymous" />
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css" integrity="sha384-GvrOXuhMATgEsSwCs4smul74iXGOixntILdUW9XmUC6+HX0sLNAK3q71HotJqlAn" crossorigin="anonymous" />
|
||||||
|
@ -1,26 +1,28 @@
|
|||||||
<aside class="flex flex-col print:hidden md:top-16 md:shrink-0 md:w-64 md:sticky md:self-start max-md:[transform:translate3d(0,-100%,0)]">
|
<aside class="flex flex-col print:hidden md:top-16 md:shrink-0 md:w-64 md:sticky md:self-start max-md:[transform:translate3d(0,-100%,0)]">
|
||||||
<div class="overflow-y-auto overflow-x-hidden p-4 grow md:h-[calc(100vh-4rem)]">
|
<div class="overflow-y-auto overflow-x-hidden p-4 grow md:h-[calc(100vh-4rem-3.75rem)]">
|
||||||
<ul class="flex flex-col gap-1 max-md:hidden">
|
<ul class="flex flex-col gap-1 max-md:hidden">
|
||||||
{{ $s := .FirstSection }}
|
{{- $s := .FirstSection -}}
|
||||||
{{ $topLevelItems := union $s.RegularPages $s.Sections }}
|
{{- $topLevelItems := union $s.RegularPages $s.Sections -}}
|
||||||
{{ $currentUrl := .RelPermalink }}
|
{{- $currentUrl := .RelPermalink -}}
|
||||||
|
|
||||||
{{ range $topLevelItems.ByWeight }}
|
{{- range $topLevelItems.ByWeight -}}
|
||||||
{{ $isCurrent := eq $currentUrl .RelPermalink }}
|
{{- $isCurrent := eq $currentUrl .RelPermalink -}}
|
||||||
|
{{- $title := .LinkTitle | default .File.BaseFileName -}}
|
||||||
<li class="open">
|
<li class="open">
|
||||||
{{ if $isCurrent }}
|
{{- if $isCurrent -}}
|
||||||
<a
|
<a
|
||||||
class="flex cursor-pointer items-center justify-between gap-2 rounded bg-primary-100 px-2 py-1.5 text-sm font-semibold text-primary-800 transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word] contrast-more:border contrast-more:border-primary-500 dark:bg-primary-400/10 dark:text-primary-600 contrast-more:dark:border-primary-500"
|
class="flex cursor-pointer items-center justify-between gap-2 rounded bg-primary-100 px-2 py-1.5 text-sm font-semibold text-primary-800 transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word] contrast-more:border contrast-more:border-primary-500 dark:bg-primary-400/10 dark:text-primary-600 contrast-more:dark:border-primary-500"
|
||||||
href="{{ .RelPermalink }}"
|
href="{{ .RelPermalink }}"
|
||||||
>{{ .LinkTitle }}</a
|
|
||||||
>
|
>
|
||||||
|
{{- $title -}}
|
||||||
|
</a>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<a
|
<a
|
||||||
class="flex cursor-pointer items-center justify-between gap-2 rounded px-2 py-1.5 text-sm text-gray-500 transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word] hover:bg-gray-100 hover:text-gray-900 contrast-more:border contrast-more:border-transparent contrast-more:text-gray-900 contrast-more:hover:border-gray-900 dark:text-neutral-400 dark:hover:bg-primary-100/5 dark:hover:text-gray-50 contrast-more:dark:text-gray-50 contrast-more:dark:hover:border-gray-50"
|
class="flex cursor-pointer items-center justify-between gap-2 rounded px-2 py-1.5 text-sm text-gray-500 transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word] hover:bg-gray-100 hover:text-gray-900 contrast-more:border contrast-more:border-transparent contrast-more:text-gray-900 contrast-more:hover:border-gray-900 dark:text-neutral-400 dark:hover:bg-primary-100/5 dark:hover:text-gray-50 contrast-more:dark:text-gray-50 contrast-more:dark:hover:border-gray-50"
|
||||||
href="{{ .RelPermalink }}"
|
href="{{ .RelPermalink }}"
|
||||||
>{{ .LinkTitle }}
|
>{{- $title -}}
|
||||||
</a>
|
</a>
|
||||||
{{ end }}
|
{{- end -}}
|
||||||
</li>
|
</li>
|
||||||
{{ $secondLevelItems := union .RegularPages .Sections }}
|
{{ $secondLevelItems := union .RegularPages .Sections }}
|
||||||
{{ with $secondLevelItems }}
|
{{ with $secondLevelItems }}
|
||||||
@ -38,7 +40,7 @@
|
|||||||
{{ end }}"
|
{{ end }}"
|
||||||
href="{{ .RelPermalink }}"
|
href="{{ .RelPermalink }}"
|
||||||
>
|
>
|
||||||
{{ .LinkTitle }}
|
{{ .LinkTitle | default .File.BaseFileName }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
11
layouts/shortcodes/tab.html
Normal file
11
layouts/shortcodes/tab.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{{- $defaultIndex := int ((.Parent.Get "defaultIndex") | default "0") -}}
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="tabs-panel rounded pt-6 hidden data-[state=selected]:block"
|
||||||
|
id="tabs-panel-{{ .Ordinal }}"
|
||||||
|
role="tabpanel"
|
||||||
|
{{ if eq .Ordinal $defaultIndex }}tabindex="0"{{ end }}
|
||||||
|
{{ if eq .Ordinal $defaultIndex }}data-state="selected"{{ end }}
|
||||||
|
>
|
||||||
|
{{ .InnerDeindent | markdownify }}
|
||||||
|
</div>
|
26
layouts/shortcodes/tabs.html
Normal file
26
layouts/shortcodes/tabs.html
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{{- $items := split (.Get "items") "," -}}
|
||||||
|
{{- $defaultIndex := int ((.Get "defaultIndex") | default "0") -}}
|
||||||
|
|
||||||
|
{{- if not $items -}}
|
||||||
|
{{ errorf "no items provided" }}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="mt-4 flex w-max min-w-full border-b border-gray-200 pb-px dark:border-neutral-800">
|
||||||
|
{{- range $i, $item := $items -}}
|
||||||
|
<button
|
||||||
|
class="tabs-toggle data-[state=selected]:border-primary-500 data-[state=selected]:text-primary-600 mr-2 rounded-t p-2 font-medium leading-5 transition-colors -mb-0.5 select-none border-b-2 border-transparent text-gray-600 hover:border-gray-200 hover:text-black dark:text-gray-200 dark:hover:border-neutral-800 dark:hover:text-white"
|
||||||
|
role="tab"
|
||||||
|
type="button"
|
||||||
|
aria-controls="tabs-panel-{{ $i }}"
|
||||||
|
{{ if eq $i $defaultIndex }}aria-selected="true"{{ end }}
|
||||||
|
{{ if eq $i $defaultIndex }}tabindex="0"{{ end }}
|
||||||
|
{{ if eq $i $defaultIndex }}data-state="selected"{{ end }}
|
||||||
|
>
|
||||||
|
{{- $item -}}
|
||||||
|
</button>
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{ .Inner }}
|
||||||
|
</div>
|
Loading…
x
Reference in New Issue
Block a user