diff --git a/src/components/NcAppNavigationCaption/NcAppNavigationCaption.vue b/src/components/NcAppNavigationCaption/NcAppNavigationCaption.vue
index 505e53d410..c7d6164f1b 100644
--- a/src/components/NcAppNavigationCaption/NcAppNavigationCaption.vue
+++ b/src/components/NcAppNavigationCaption/NcAppNavigationCaption.vue
@@ -148,6 +148,14 @@ export default {
default: false,
},
+ /**
+ * If `isHeading` is set, this defines the heading level that should be used
+ */
+ headingLevel: {
+ type: Number,
+ default: 2,
+ },
+
/**
* Any [NcActions](#/Components/NcActions?id=ncactions-1) prop
*/
@@ -161,7 +169,9 @@ export default {
return this.isHeading ? 'div' : 'li'
},
captionTag() {
- return this.isHeading ? 'h2' : 'span'
+ // Limit to at least h2 as h1 is considered invalid and reserved
+ const headingLevel = Math.max(2, this.headingLevel)
+ return this.isHeading ? `h${headingLevel}` : 'span'
},
// Check if the actions slot is populated
hasActions() {
diff --git a/tests/unit/components/NcAppNavigation/NcAppNavigationCaption.spec.ts b/tests/unit/components/NcAppNavigation/NcAppNavigationCaption.spec.ts
new file mode 100644
index 0000000000..b15151a216
--- /dev/null
+++ b/tests/unit/components/NcAppNavigation/NcAppNavigationCaption.spec.ts
@@ -0,0 +1,74 @@
+import { describe, expect } from '@jest/globals'
+import { shallowMount } from '@vue/test-utils'
+import NcAppNavigationCaption from '../../../../src/components/NcAppNavigationCaption/NcAppNavigationCaption.vue'
+
+describe('NcAppNavigationCaption.vue', () => {
+ test('attributes are passed to actions', async () => {
+ const wrapper = shallowMount(NcAppNavigationCaption, {
+ propsData: {
+ name: 'The name',
+ },
+ attrs: {
+ forceMenu: 'true',
+ },
+ slots: {
+ actions: [
+ 'Button 1',
+ 'Button 2',
+ ],
+ },
+ })
+
+ expect(wrapper.findComponent({ name: 'NcActions' }).attributes('forcemenu')).toBe('true')
+ })
+
+ test('component is a list entry by default', async () => {
+ const wrapper = shallowMount(NcAppNavigationCaption, {
+ propsData: {
+ name: 'The name',
+ },
+ })
+
+ expect(wrapper.element.tagName).toBe('LI')
+ expect(wrapper.find('h2').exists()).toBe(false)
+ expect(wrapper.find('span').exists()).toBe(true)
+ })
+
+ test('component tags are adjusted when used as heading', async () => {
+ const wrapper = shallowMount(NcAppNavigationCaption, {
+ propsData: {
+ name: 'The name',
+ isHeading: true,
+ },
+ })
+
+ expect(wrapper.element.tagName).toBe('DIV')
+ expect(wrapper.find('h2').exists()).toBe(true)
+ })
+
+ test('can set the heading level', async () => {
+ const wrapper = shallowMount(NcAppNavigationCaption, {
+ propsData: {
+ name: 'The name',
+ isHeading: true,
+ headingLevel: 3,
+ },
+ })
+
+ expect(wrapper.contains('h3')).toBe(true)
+ expect(wrapper.contains('h2')).toBe(false)
+ })
+
+ test('does not set the heading level to h1', async () => {
+ const wrapper = shallowMount(NcAppNavigationCaption, {
+ propsData: {
+ name: 'The name',
+ isHeading: true,
+ headingLevel: 1,
+ },
+ })
+
+ expect(wrapper.contains('h2')).toBe(true)
+ expect(wrapper.contains('h1')).toBe(false)
+ })
+})