Skip to content

Commit

Permalink
website: replace details/summary in side nav with button and list
Browse files Browse the repository at this point in the history
  • Loading branch information
shleewhite authored Jul 15, 2024
2 parents e5ea033 + 42b8194 commit 86fdd79
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 19 deletions.
12 changes: 12 additions & 0 deletions website/app/components/doc/table-of-contents/collapsible-item.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<div class="doc-table-of-contents__folder">
<button
type="button"
aria-controls={{if this.isOpen this.contentId: ""}}
aria-expanded={{if this.isOpen "true" "false"}}
class={{this.classNames}}
{{on "click" this.toggleIsOpen}}
>{{@name}}</button>
{{#if this.isOpen}}
<Doc::TableOfContents @structuredPageTree={{@item.children}} @depth={{@depth}} id={{this.contentId}} />
{{/if}}
</div>
25 changes: 25 additions & 0 deletions website/app/components/doc/table-of-contents/collapsible-item.js
Original file line number Diff line number Diff line change
@@ -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(' ');
}
}
7 changes: 2 additions & 5 deletions website/app/components/doc/table-of-contents/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

{{! template-lint-configure no-inline-styles {"allowDynamicStyles": true} }}

<ul class="doc-table-of-contents" role="list">
<ul class="doc-table-of-contents" role="list" ...attributes>
{{#each-in @structuredPageTree as |key item|}}
<li class="doc-table-of-contents__item doc-table-of-contents__item--depth-{{@depth}}">
{{#if item.pageURL}}
Expand All @@ -32,10 +32,7 @@
<div class="doc-table-of-contents__heading">{{humanize key}}</div>
<Doc::TableOfContents @structuredPageTree={{item}} @depth={{add @depth 1}} />
{{else}}
<details class="doc-table-of-contents__folder" open={{item.isOpen}}>
<summary class="doc-table-of-contents__summary">{{humanize key}}</summary>
<Doc::TableOfContents @structuredPageTree={{item.children}} @depth={{add @depth 1}} />
</details>
<Doc::TableOfContents::CollapsibleItem @item={{item}} @depth={{add @depth 1}} @name={{humanize key}} />
{{/if}}
{{/if}}
</li>
Expand Down
5 changes: 2 additions & 3 deletions website/app/styles/doc-components/table-of-contents.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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%;
Expand All @@ -57,8 +57,7 @@ $doc-toc-item-inset: 8px;
display: none;
}

// it's using a `<detail>` 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");
}
}
Expand Down
79 changes: 68 additions & 11 deletions website/tests/acceptance/sidebar-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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();
});
});

0 comments on commit 86fdd79

Please sign in to comment.