diff --git a/src/utils/isElementVisible.ts b/src/utils/isElementVisible.ts index 27aa0cfd4..f2394ee9e 100644 --- a/src/utils/isElementVisible.ts +++ b/src/utils/isElementVisible.ts @@ -19,18 +19,34 @@ function isStyleVisible(element: T) { ) } -function isAttributeVisible(element: T) { - return ( - !element.hasAttribute('hidden') && - (element.nodeName === 'DETAILS' ? element.hasAttribute('open') : true) - ) +function isAttributeVisible( + element: T, + childElement?: Element +) { + if (element.hasAttribute('hidden')) return false + + // A closed
renders only its : the
itself is + // visible, the is visible, but other descendants are not. + if ( + element.nodeName === 'DETAILS' && + !element.hasAttribute('open') && + childElement && + childElement.nodeName !== 'SUMMARY' + ) { + return false + } + + return true } -export function isElementVisible(element: T): boolean { +export function isElementVisible( + element: T, + childElement?: Element +): boolean { return ( element.nodeName !== '#comment' && isStyleVisible(element) && - isAttributeVisible(element) && - (!element.parentElement || isElementVisible(element.parentElement)) + isAttributeVisible(element, childElement) && + (!element.parentElement || isElementVisible(element.parentElement, element)) ) } diff --git a/tests/isVisible.spec.ts b/tests/isVisible.spec.ts index 2de407a61..fc8ff9bf9 100644 --- a/tests/isVisible.spec.ts +++ b/tests/isVisible.spec.ts @@ -117,6 +117,50 @@ describe('isVisible', () => { expect(wrapper.html()).not.toContain('Item: 2') }) + describe('details element', () => { + const Comp = defineComponent({ + props: { + open: { type: Boolean, default: false } + }, + template: ` +
+ Toggle +

Content

+
+ ` + }) + + it('details, summary and content are visible when open', () => { + const wrapper = mount(Comp, { props: { open: true } }) + + expect(wrapper.get('details').isVisible()).toBe(true) + expect(wrapper.get('summary').isVisible()).toBe(true) + expect(wrapper.get('p.content').isVisible()).toBe(true) + }) + + it('details and summary stay visible when closed, content is hidden', () => { + const wrapper = mount(Comp, { props: { open: false } }) + + expect(wrapper.get('details').isVisible()).toBe(true) + expect(wrapper.get('summary').isVisible()).toBe(true) + expect(wrapper.get('p.content').isVisible()).toBe(false) + }) + + it('non-summary descendants of a closed details are hidden even when nested', () => { + const Nested = defineComponent({ + template: ` +
+ Toggle +
Deep
+
+ ` + }) + const wrapper = mount(Nested) + + expect(wrapper.get('span.deep').isVisible()).toBe(false) + }) + }) + it('should take css into account', async () => { const style = document.createElement('style') style.type = 'text/css'