Skip to content

Commit

Permalink
fix: correctly apply panel classes (#201)
Browse files Browse the repository at this point in the history
  • Loading branch information
gadenbuie authored May 20, 2024
1 parent 2e93378 commit 5e14923
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 135 deletions.
4 changes: 3 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# xaringanExtra (development version)

* Fixed an issue that caused panelset to incorrectly apply classes from the `.panel` markup container (#200).

# xaringanExtra 0.8.0

This release focuses entirely on improving the **panelset** feature, especially
Expand Down Expand Up @@ -37,7 +39,7 @@ computation engine.

Unlike in R Markdown, where you always need to place panelset chunks in a
`::: {.panelset}` div, in Quarto, panelset code chunks automatically create
their own panelsets with two tabs (code and output). Use the
their own panelsets with two tabs (code and output). Use the
`::: {.panelset}` syntax to add more than one panelset code chunk to the same
panelset (#196).

Expand Down
2 changes: 1 addition & 1 deletion _extensions/panelset/_extension.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
title: Panelset
author: Garrick Aden-Buie
version: 0.3.0
version: 0.3.1
quarto-required: '>=1.3.0'
contributes:
filters:
Expand Down
141 changes: 79 additions & 62 deletions _extensions/panelset/panelset.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* https://opensource.org/licenses/MIT
*/

/* VERSION: 0.3.0 */
/* VERSION: 0.3.1 */

/* global slideshow */
;(function () {
Expand Down Expand Up @@ -143,11 +143,9 @@

function getElementAttributes (el) {
return {
classes: Array.from(el.classList)
.filter(c => !/^level\d$/.test(c))
.toString(),
classes: Array.from(el.classList).filter(c => !/^level\d$/.test(c)),
style: el.style.cssText,
dataset: el.dataset
dataset: el.dataset,
}
}

Expand All @@ -172,7 +170,7 @@
active:
item.dataset &&
['', 'true'].includes(item.dataset.active?.toLowerCase()),
...getElementAttributes(item)
...getElementAttributes(item),
}
}

Expand Down Expand Up @@ -237,7 +235,9 @@
*/
const reflowPanelSet = (panels, { id, classes, style, dataset }) => {
const res = document.createElement('div')
res.classList = 'panelset' + (classes ? ' ' + classes : '')
if (classes.length) {
classes.forEach(cls => res.classList.add(cls))
}
res.id = uniquePanelsetId(id)
res.style.cssText = style
if (dataset) {
Expand Down Expand Up @@ -295,7 +295,10 @@
const thisPanelIsActive = panelSelected === p.id
const panelTag = inRevealjs() ? 'div' : 'section'
const panelContent = document.createElement(panelTag)
panelContent.classList = p.classes ? 'panel ' + p.classes : 'panel'
panelContent.classList.add('panel')
if (p.classes.length) {
p.classes.forEach(cls => panelContent.classList.add(cls))
}
panelContent.style.cssText = p.style
panelContent.classList.toggle('panel-active', thisPanelIsActive)
panelContent.id = p.id
Expand Down Expand Up @@ -505,7 +508,7 @@
panelset.dispatchEvent(
new window.CustomEvent('panelset:group', {
bubbles: true,
detail: { group, panel }
detail: { group, panel },
})
)
}
Expand Down Expand Up @@ -552,7 +555,9 @@
* @returns {HTMLElement} - The new panelset element.
*/
const initPanelSet = panelset => {
let panels = Array.from(panelset.querySelectorAll(':scope > .panel'))
let panels = Array.from(
panelset.querySelectorAll(':scope > .panel, :scope > .cell > .panel')
)

const pandocSectionSelector = ':is(section, .section)[class*="level"]'
if (!panels.length) {
Expand Down Expand Up @@ -600,7 +605,7 @@
const panelsetAttrs = getElementAttributes(panelset)
const newPanelSet = reflowPanelSet(contents, {
id: panelset.id,
...panelsetAttrs
...panelsetAttrs,
})
newPanelSet.classList = panelset.classList

Expand Down Expand Up @@ -691,9 +696,16 @@
}

// initialize panels
document
.querySelectorAll('[data-panelset="true"]')
.forEach(el => el.classList.add('panelset'))
document.querySelectorAll('[data-panelset="true"]').forEach(el => {
const isCell = el.classList.contains('cell')
const hasParentPanelset = el.parentElement.classList.contains('panelset')
if (!isCell || !hasParentPanelset) {
// We let `data-panelset="true"` create a new panelset, unless it's on
// a code cell that's already inside a panelset, in which case the
// panels will be folded into the parent panelset.
el.classList.add('panelset')
}
})

const panelsets = { atomic: [], nested: [] }
Array.from(document.querySelectorAll('.panelset')).forEach(el => {
Expand Down Expand Up @@ -722,7 +734,7 @@
return {
panel,
panelId: panel.children[0].getAttribute('aria-controls'),
panelSetId: panel.parentNode.parentNode.id
panelSetId: panel.parentNode.parentNode.id,
}
})
}
Expand All @@ -733,7 +745,7 @@

// clear search query for panelsets in current slide
const params = [
...document.querySelectorAll('.remark-visible .panelset')
...document.querySelectorAll('.remark-visible .panelset'),
].reduce(function (params, panelset) {
return updateSearchParams(panelset.id, null, params)
}, new URLSearchParams(window.location.search))
Expand Down Expand Up @@ -761,57 +773,62 @@
}

if (inRevealjs()) {
window.Reveal.on('slidechanged', function ({ currentSlide, previousSlide, ...data }) {
// clear focus from any active panel-tab in the previous slide
const previousActive = previousSlide.querySelector('.panelset .panel-tab:focus')
if (previousActive) {
previousActive.blur()
previousActive.removeAttribute('tabindex')
}

const previousPanelsets = previousSlide.querySelectorAll('.panelset')
if (previousPanelsets.length) {
// clear search query for panelsets in previous slide
const params = [
...previousSlide.querySelectorAll('.panelset')
].reduce(function (params, panelset) {
return updateSearchParams(panelset.id, null, params)
}, new URLSearchParams(window.location.search))

updateUrl(params)
}

const firstPanelset = currentSlide.querySelector('.panelset')
if (!firstPanelset) return

const panelIdFromUrl = getCurrentPanelFromUrl(firstPanelset.id)
const panelFromUrl = !panelIdFromUrl
? null
: firstPanelset
.querySelector(`[aria-controls="${panelIdFromUrl}"]`)
?.parentElement
window.Reveal.on(
'slidechanged',
function ({ currentSlide, previousSlide, ...data }) {
// clear focus from any active panel-tab in the previous slide
const previousActive = previousSlide.querySelector(
'.panelset .panel-tab:focus'
)
if (previousActive) {
previousActive.blur()
previousActive.removeAttribute('tabindex')
}

const firstPanel = panelIdFromUrl
? panelFromUrl
: firstPanelset.querySelector('.panel-tab-active')
const previousPanelsets = previousSlide.querySelectorAll('.panelset')
if (previousPanelsets.length) {
// clear search query for panelsets in previous slide
const params = [
...previousSlide.querySelectorAll('.panelset'),
].reduce(function (params, panelset) {
return updateSearchParams(panelset.id, null, params)
}, new URLSearchParams(window.location.search))

if (!firstPanel) return
firstPanel.setAttribute('tabindex', '-1')
firstPanel.focus()
updateUrl(params)
}

// update url for all panels on this slide
const params = [
...currentSlide.querySelectorAll('.panelset')
].reduce(function (params, panelset) {
return updateSearchParams(
panelset.id,
panelset.querySelector('.panel-active').id,
params
const firstPanelset = currentSlide.querySelector('.panelset')
if (!firstPanelset) return

const panelIdFromUrl = getCurrentPanelFromUrl(firstPanelset.id)
const panelFromUrl = !panelIdFromUrl
? null
: firstPanelset.querySelector(`[aria-controls="${panelIdFromUrl}"]`)
?.parentElement

const firstPanel = panelIdFromUrl
? panelFromUrl
: firstPanelset.querySelector('.panel-tab-active')

if (!firstPanel) return
firstPanel.setAttribute('tabindex', '-1')
firstPanel.focus()

// update url for all panels on this slide
const params = [...currentSlide.querySelectorAll('.panelset')].reduce(
function (params, panelset) {
return updateSearchParams(
panelset.id,
panelset.querySelector('.panel-active').id,
params
)
},
new URLSearchParams(window.location.search)
)
}, new URLSearchParams(window.location.search))

updateUrl(params)
})
updateUrl(params)
}
)
}
})
})()
Loading

0 comments on commit 5e14923

Please sign in to comment.