diff --git a/website/app/components/doc/table-of-contents/collapsible-item.hbs b/website/app/components/doc/table-of-contents/collapsible-item.hbs
new file mode 100644
index 0000000000..55b1597633
--- /dev/null
+++ b/website/app/components/doc/table-of-contents/collapsible-item.hbs
@@ -0,0 +1,12 @@
+
+
+ {{#if this.isOpen}}
+
+ {{/if}}
+
\ No newline at end of file
diff --git a/website/app/components/doc/table-of-contents/collapsible-item.js b/website/app/components/doc/table-of-contents/collapsible-item.js
new file mode 100644
index 0000000000..cb8803f25a
--- /dev/null
+++ b/website/app/components/doc/table-of-contents/collapsible-item.js
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) HashiCorp, Inc.
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
+import Component from '@glimmer/component';
+import { guidFor } from '@ember/object/internals';
+import { tracked } from '@glimmer/tracking';
+import { action } from '@ember/object';
+export default class DocTocCollapsibleItemComponent extends Component {
+ @tracked isOpen = this.args.item.isOpen;
+ @action toggleIsOpen() {
+ this.isOpen = !this.isOpen;
+ }
+
+ contentId = 'content-' + guidFor(this);
+
+ get classNames() {
+ const classes = ['doc-table-of-contents__button'];
+ if (this.isOpen) {
+ classes.push('doc-table-of-contents__button--open');
+ }
+ return classes.join(' ');
+ }
+}
diff --git a/website/app/components/doc/table-of-contents/index.hbs b/website/app/components/doc/table-of-contents/index.hbs
index c79c232f44..0628a2007f 100644
--- a/website/app/components/doc/table-of-contents/index.hbs
+++ b/website/app/components/doc/table-of-contents/index.hbs
@@ -5,7 +5,7 @@
{{! template-lint-configure no-inline-styles {"allowDynamicStyles": true} }}
-
+
{{#each-in @structuredPageTree as |key item|}}
-
{{#if item.pageURL}}
@@ -32,10 +32,7 @@
{{humanize key}}
{{else}}
-
- {{humanize key}}
-
-
+
{{/if}}
{{/if}}
diff --git a/website/app/styles/doc-components/table-of-contents.scss b/website/app/styles/doc-components/table-of-contents.scss
index dccb56ccbd..cec352d465 100644
--- a/website/app/styles/doc-components/table-of-contents.scss
+++ b/website/app/styles/doc-components/table-of-contents.scss
@@ -38,7 +38,7 @@ $doc-toc-item-inset: 8px;
padding: 0 $doc-toc-item-inset 12px $doc-toc-item-inset;
}
-.doc-table-of-contents__summary {
+.doc-table-of-contents__button {
@include doc-font-style-navigation();
display: block;
width: 100%;
@@ -57,8 +57,7 @@ $doc-toc-item-inset: 8px;
display: none;
}
- // it's using a `` HMTL tag
- [open] > & {
+ &.doc-table-of-contents__button--open {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' viewBox='0 0 16 16'%3E%3Cpath fill='%23727374' fill-rule='evenodd' d='M3.235 5.205a.75.75 0 011.06.03L8 9.158l3.705-3.923a.75.75 0 011.09 1.03l-4.25 4.5a.75.75 0 01-1.09 0l-4.25-4.5a.75.75 0 01.03-1.06z' clip-rule='evenodd'/%3E%3C/svg%3E");
}
}
diff --git a/website/tests/acceptance/sidebar-test.js b/website/tests/acceptance/sidebar-test.js
index 24b496c669..861f665952 100644
--- a/website/tests/acceptance/sidebar-test.js
+++ b/website/tests/acceptance/sidebar-test.js
@@ -4,7 +4,7 @@
*/
import { module, test } from 'qunit';
-import { fillIn, visit } from '@ember/test-helpers';
+import { fillIn, visit, click } from '@ember/test-helpers';
import { setupApplicationTest } from 'website/tests/helpers';
module('Acceptance | Sidebar filter', function (hooks) {
@@ -29,15 +29,23 @@ module('Acceptance | Sidebar filter', function (hooks) {
test('should show the "Checkbox" link in the sidebar (under an opened parent container) if filtering using its "page title" (case insensitive)', async function (assert) {
await visit('/components');
- let link = this.element.querySelector(
- '.doc-page-sidebar__table-of-contents a[href="/components/form/checkbox"]'
- );
- assert.dom(link).exists();
- assert.dom('.doc-table-of-contents__folder[open]').exists({ count: 0 });
+ assert
+ .dom(
+ '.doc-page-sidebar__table-of-contents a[href="/components/form/checkbox"]'
+ )
+ .exists({ count: 0 });
+ assert
+ .dom('.doc-table-of-contents__button.doc-table-of-contents__button--open')
+ .exists({ count: 0 });
await fillIn('.doc-page-sidebar__filter input[type="search"]', 'ChEcKbOx');
- assert.dom(link).exists();
- // notice: we can't use `.hasAttribute('open')` here because it returns always false
- assert.dom('.doc-table-of-contents__folder[open]').exists({ count: 1 });
+ assert
+ .dom(
+ '.doc-page-sidebar__table-of-contents a[href="/components/form/checkbox"]'
+ )
+ .exists();
+ assert
+ .dom('.doc-table-of-contents__button.doc-table-of-contents__button--open')
+ .exists({ count: 1 });
});
test('should still show the filter input after filtering', async function (assert) {
@@ -74,15 +82,64 @@ module('Acceptance | Sidebar filter', function (hooks) {
.exists();
});
+ test('should expand subsection when click a parent container', async function (assert) {
+ await visit('/components');
+
+ assert.dom('.doc-table-of-contents__folder').exists({ count: 3 });
+ assert.dom('.doc-table-of-contents__button').exists({ count: 3 });
+ assert
+ .dom('.doc-table-of-contents__button')
+ .hasAttribute('aria-expanded', 'false');
+
+ assert
+ .dom('.doc-table-of-contents__button.doc-table-of-contents__button--open')
+ .exists({ count: 0 });
+
+ assert
+ .dom(
+ '.doc-page-sidebar__table-of-contents a[href="/components/copy/button"]'
+ )
+ .exists({ count: 0 });
+
+ await click('.doc-table-of-contents__button');
+ assert
+ .dom('.doc-table-of-contents__button')
+ .hasAttribute('aria-expanded', 'true');
+ assert
+ .dom(
+ '.doc-page-sidebar__table-of-contents a[href="/components/copy/button"]'
+ )
+ .exists();
+
+ await click('.doc-table-of-contents__button');
+ assert
+ .dom('.doc-table-of-contents__button')
+ .hasAttribute('aria-expanded', 'false');
+ assert
+ .dom(
+ '.doc-page-sidebar__table-of-contents a[href="/components/copy/button"]'
+ )
+ .exists({ count: 0 });
+ });
+
// QUERY PARAMS
test('all "folder" containers should be closed by default if the "current route" link is not inside any of them', async function (assert) {
await visit('/components/alert');
- assert.dom('.doc-table-of-contents__folder[open]').exists({ count: 0 });
+ assert
+ .dom('.doc-table-of-contents__button.doc-table-of-contents__button--open')
+ .exists({ count: 0 });
});
test('the "folder" container of the "current route" link should be opened by default', async function (assert) {
await visit('/components/form/radio-card');
- assert.dom('.doc-table-of-contents__folder[open]').exists({ count: 1 });
+ assert
+ .dom('.doc-table-of-contents__button.doc-table-of-contents__button--open')
+ .exists({ count: 1 });
+ assert
+ .dom(
+ '.doc-page-sidebar__table-of-contents a[href="/components/form/radio-card"]'
+ )
+ .exists();
});
});