As a developer I use different programming language to write code. It will be very helpful to have query that will put multiple pages/blocks in tabs
Tiddlywiki provide that feature using
<<tabs "SampleTabOne SampleTabTwo SampleTabThree SampleTabFour" "SampleTabOne" "$:/state/tab1">>
Does anyone know how to add tabs on pages ? ( like query on properties adds table view )
2 Likes
This got me interested and I started to play around trying to find a css
only solution. Unfortunately however, to no success. The concept I’ve been playing with would be quite easy to implement if we could use the :has
pseudo-selector.
Anyways, it would look something like this:
div[data-refs-self*="p-tab-view"] .block-children .ls-block {
display: none;
}
div[data-refs-self*="p-tab-view"]:has(input[value="1"]:checked) .block-children .ls-block:nth-of-type(1) {
display: block;
}
div[data-refs-self*="p-tab-view"]:has(input[value="2"]:checked) .block-children .ls-block:nth-of-type(2) {
display: block;
}
...
And the markdown like this:
- #p-tab-vieXX
[:span [:input {:type "radio" :name "ptv" :id "1" :value "1"} [:label {:for "1"} " First Tab "]] [:input {:type "radio" :id "2" :name "ptv" :value "2"} [:label {:for "2"} " Second Tab "]] [:input {:type "radio" :id "3" :name "ptv" :value "3"} [:label {:for "3"} " Third Tab "]] ]
Which does not work as intended, of course.
Trying to inject a data-ref
will also not be picked up by the parent block, e.g. when replacing the “First Tab” label text with the following: [:a {:tabindex "0" :data-ref "ptv1" :class "tag"} "First Tab"]
Unless someone knows how to emulate a css parent selector, you’ll have to whip up some javascript
@devs Why is the :has
pseudo-selector not available?
1 Like
Thanks for reply. But may be it can be solved using {{ query }} , But implementation need to done for it . I have very less knowledge on js/cljs . Anyone from community might help
Olivia
February 9, 2024, 10:44am
4
Anyone know some JavaScript (custom.js) solution for this?
As of recently, :has
has become available.
I just came across this old thread, and presto : :has
really was all that was missing.
Thanks so much for this. This is really elegant as a solution!
1 Like
Hi I can use this modification to insert a tab inside a page, however I am unable to add multiple lines / blocks under each tab:
After pressing enter, the caret disappears and I cannot add new line / block (I actually cannot type anything on the page)
The steps that I implemented are the following:
I pasted the following code snipped to the custom.css file:
div[data-refs-self*="p-tab-view"] .block-children .ls-block {
display: none;
}
div[data-refs-self*="p-tab-view"]:has(input[value="1"]:checked) .block-children .ls-block:nth-of-type(1) {
display: block;
}
div[data-refs-self*="p-tab-view"]:has(input[value="2"]:checked) .block-children .ls-block:nth-of-type(2) {
display: block;
}
Then I added the following code snipped to the daily journal page:
#p-tab-view
[:span [:input {:type "radio" :name "ptv" :id "1" :value "1" :checked true}[:label {:for "1"} " First Tab "]] [:input {:type "radio" :id "2" :name "ptv" :value "2"}[:label {:for "2"} " Second Tab "]]]
Any help appreciated, thanks!
Try pasting this into your custom.css
file:
/* =============================================================================
RADIO BUTTON TAB GROUP - v2025.05.24
- Author: <https://github.com/zeitlings>
- Reference: <https://discuss.logseq.com/t/tabs-inside-pages/12952>
============================================================================= */
div[data-refs-self*="p-tab-view"] .block-children .ls-block {
display: none;
}
div[data-refs-self*="p-tab-view"]:has(input[value="1"]:checked) .block-children .ls-block:nth-of-type(1),
div[data-refs-self*="p-tab-view"]:has(input[value="1"]:checked) .block-children .ls-block:nth-of-type(1) .ls-block {
display: block;
}
div[data-refs-self*="p-tab-view"]:has(input[value="2"]:checked) .block-children .ls-block:nth-of-type(2),
div[data-refs-self*="p-tab-view"]:has(input[value="2"]:checked) .block-children .ls-block:nth-of-type(2) .ls-block {
display: block;
}
div[data-refs-self*="p-tab-view"]:has(input[value="3"]:checked) .block-children .ls-block:nth-of-type(3),
div[data-refs-self*="p-tab-view"]:has(input[value="3"]:checked) .block-children .ls-block:nth-of-type(3) .ls-block {
display: block;
}
div[data-refs-self*="p-tab-view"]:has(input[value="4"]:checked) .block-children .ls-block:nth-of-type(4),
div[data-refs-self*="p-tab-view"]:has(input[value="4"]:checked) .block-children .ls-block:nth-of-type(4) .ls-block {
display: block;
}
div[data-refs-self*="p-tab-view"]:has(input[value="5"]:checked) .block-children .ls-block:nth-of-type(5),
div[data-refs-self*="p-tab-view"]:has(input[value="5"]:checked) .block-children .ls-block:nth-of-type(5) .ls-block {
display: block;
}
div[data-refs-self*="p-tab-view"]:has(input[value="6"]:checked) .block-children .ls-block:nth-of-type(6),
div[data-refs-self*="p-tab-view"]:has(input[value="6"]:checked) .block-children .ls-block:nth-of-type(6) .ls-block {
display: block;
}
/* Tab Group styling */
input[type="radio"][name="ptv"] {
opacity: 100%;
width: 15pt;
height: 15pt;
margin-right: 6px;
margin-left: 6px;
/* color: var(--ls-active-secondary-color); */
}
input[type="radio"][name="ptv"] + label {
display: inline-flex;
padding: 6px 12px;
margin: 0;
border: 1px solid var(--ls-border-color);
background-color: var(--ls-tertiary-background-color);
color: var(--ls-primary-text-color);
cursor: pointer;
transition: all 0.2s ease;
border-radius: 4px 4px 0 0;
border-bottom: none;
position: relative;
top: 1px;
user-select: contain;
}
input[type="radio"][name="ptv"] + label {
border-bottom: 1px solid var(--ls-border-color);
top: 0;
}
input[type="radio"][name="ptv"]:checked + label {
background-color: var(--ls-primary-background-color);
border-bottom: 1px solid var(--ls-primary-background-color);
top: 1px;
font-weight: bold;
}
input[type="radio"][name="ptv"] + label:hover {
background-color: var(--ls-secondary-background-color);
}
span:has(input[name="ptv"]) {
display: inline-block;
border-bottom: 1px solid var(--ls-border-color);
padding-bottom: 0;
}
/* =============================================================================
RADIO BUTTON TAB GROUP END
============================================================================= */
That supports up to to 6 tabs. To enable more tabs, just add more of these:
div[data-refs-self*="p-tab-view"]:has(input[value="7"]:checked) .block-children .ls-block:nth-of-type(7),
div[data-refs-self*="p-tab-view"]:has(input[value="7"]:checked) .block-children .ls-block:nth-of-type(7) .ls-block {
display: block;
}
etc.
And in your journal template, try this:
- ## Tabs
- #p-tab-view
[:span [:input {:type "radio" :name "ptv" :id "1" :value "1" :checked true}[:label {:for "1"} " First Tab "]] [:input {:type "radio" :id "2" :name "ptv" :value "2"}[:label {:for "2"} " Second Tab "]] [:input {:type "radio" :name "ptv" :id "3" :value "3"}[:label {:for "3"} " Third Tab "]]]
- **Fist Header**
-
- **Second Header**
-
- **Third Header**
-
You have to pre-populate what comes after the declaration with correlating headers and one empty child bullet, then you can edit directly within each self contained tab. For more tabs, again just extend the hiccup and add the fourth, fifth, etc. header.
2 Likes
Thank you very much @zeitlings ! I really appreciate the time for sharing this code snippet with me!
1 Like
Thanks so much! Help a lot!
1 Like