Skip to content

Commit 8f93461

Browse files
authored
feat: Better nav for generic modules (#355)
Closes #353
1 parent 116ba91 commit 8f93461

File tree

11 files changed

+173
-26
lines changed

11 files changed

+173
-26
lines changed

addon/components/api/x-import-path/component.js

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,19 @@ import hbs from 'htmlbars-inline-precompile';
44
export default Component.extend({
55
tagName: '',
66
layout: hbs`
7-
<div class="import-path docs-mb-6 docs-font-mono" data-test-import-path>
8-
<span class="hljs-keyword">import</span>
7+
<div class="import-path docs-mb-6" data-test-import-path>
8+
<pre class="docs-md__code docs-whitespace-no-wrap">
9+
<span class="hljs-keyword">import</span>
910
10-
{{#if (eq item.exportType "default")}}
11-
{{item.name}}
12-
{{else}}
13-
{ {{item.name}} }
14-
{{/if}}
11+
{{#if (eq item.exportType "default")}}
12+
{{item.name}}
13+
{{else}}
14+
{ {{item.name}} }
15+
{{/if}}
1516
16-
<span class="hljs-keyword">from</span>
17-
<span class="hljs-string">'{{item.file}}'</span>;
17+
<span class="hljs-keyword">from</span>
18+
<span class="hljs-string">'{{item.file}}'</span>;
19+
</pre>
1820
</div>
1921
`,
2022
});
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import Component from '@ember/component';
2+
import { inject as service } from '@ember/service';
3+
import { computed } from '@ember/object';
4+
import layout from './template';
5+
import { readOnly } from '@ember/object/computed';
6+
import { set as _set } from 'lodash';
7+
8+
export default Component.extend({
9+
layout,
10+
tagName: '',
11+
store: service(),
12+
13+
sections: readOnly('project.navigationIndex'),
14+
15+
/*
16+
Autogenerated sections include "resolved types", by which we mean things like
17+
Components and Helpers, as well as generic "modules", which is any other
18+
public JavaScript export from this library.
19+
20+
These are the sections for the resolved types.
21+
*/
22+
resolvedTypeSections: computed(function() {
23+
return this.get('sections').filter(section => section.type !== 'modules');
24+
}),
25+
26+
/*
27+
Autogenerated sections include "resolved types", by which we mean things like
28+
Components and Helpers, as well as generic "modules", which is any other
29+
public JavaScript export from this library.
30+
31+
This is the index of nodes for generic modules. We transform the raw array
32+
of modules that look like this
33+
34+
```
35+
[
36+
{id: "ember-cli-addon-docs/keyboard-config", path: "modules/ember-cli-addon-docs/keyboard-config", name: "ember-cli-addon-docs/keyboard-config"}
37+
{id: "ember-cli-addon-docs/router", path: "modules/ember-cli-addon-docs/router", name: "ember-cli-addon-docs/router"}
38+
{id: "ember-cli-addon-docs/utils/compile-markdown", path: "modules/ember-cli-addon-docs/utils/compile-markdown", name: "ember-cli-addon-docs/utils/compile-markdown"}
39+
]
40+
```
41+
42+
into a nested data structure resembling the filesystem:
43+
44+
```
45+
{
46+
name: '@ember-cli-addon-docs',
47+
children: [
48+
{ name: 'keyboard-config', path: "modules/ember-cli-addon-docs/keyboard-config" },
49+
{ name: 'router', children: [], path: "modules/ember-cli-addon-docs/router" },
50+
{
51+
name: 'utils',
52+
children: [
53+
{ name: 'compile-markdown', children: [], path: "modules/ember-cli-addon-docs/utils/compile-markdown" },
54+
]
55+
},
56+
]
57+
};
58+
```
59+
*/
60+
moduleIndex: computed(function() {
61+
let modules = this.get('sections').filter(section => section.type === 'modules')[0].items;
62+
63+
/*
64+
Intermediate data structure:
65+
66+
```
67+
{
68+
'@ember-cli-addon-docs': {
69+
'keyboard-config': {},
70+
'router': {},
71+
'utils': {
72+
'compile-markdown': {}
73+
}
74+
}
75+
};
76+
```
77+
*/
78+
let index = {};
79+
modules.forEach(module => {
80+
let parts = module.id.split('/');
81+
_set(index, parts, {});
82+
});
83+
84+
let transform = (obj, id) => Object.keys(obj)
85+
.map(key => {
86+
let node = {
87+
name: key
88+
};
89+
let children = transform(obj[key], id ? `${id}/${key}` : key);
90+
if (children.length) {
91+
node.children = children;
92+
} else {
93+
node.id = `${id}/${key}`;
94+
}
95+
96+
return node;
97+
});
98+
99+
return transform(index)[0];
100+
})
101+
102+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Component from '@ember/component';
2+
import layout from './template';
3+
4+
/*
5+
A component used to recursively render a nested structure of module nodes.
6+
*/
7+
export default Component.extend({
8+
layout,
9+
tagName: ''
10+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{{#docs-viewer/x-nav-list class='docs-ml-4' as |subnav|}}
2+
{{#docs-viewer/x-section style='subsection'}}
3+
{{this.node.name}}
4+
{{/docs-viewer/x-section}}
5+
6+
{{#each this.node.children as |child|}}
7+
{{#if child.children}}
8+
{{docs-viewer/x-autogenerated-api-docs/module-nav node=child root=root}}
9+
{{else}}
10+
11+
{{subnav.item child.name (concat root '.api.item') (concat 'modules/' child.id)}}
12+
{{/if}}
13+
{{/each}}
14+
{{/docs-viewer/x-nav-list}}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{{#if (gt project.modules.length 0)}}
2+
{{docs-viewer/x-section 'API Reference' style='large'}}
3+
4+
{{#each this.resolvedTypeSections as |section|}}
5+
{{docs-viewer/x-section section.type}}
6+
7+
{{#each section.items as |item|}}
8+
{{docs-viewer/x-nav-item (break-on item.name '/') (concat root '.api.item') item.path}}
9+
{{/each}}
10+
{{/each}}
11+
12+
{{docs-viewer/x-section 'Modules'}}
13+
14+
{{docs-viewer/x-autogenerated-api-docs/module-nav node=this.moduleIndex root=root}}
15+
16+
{{/if}}

addon/components/docs-viewer/x-nav/component.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ export default Component.extend({
2424
return classify(projectName.replace(`${logo}-`, ''));
2525
}),
2626

27+
/*
28+
This is overwritten for the Sandbox.
29+
*/
2730
project: computed(function() {
2831
return this.get('store').peekRecord('project', projectName);
2932
})

addon/components/docs-viewer/x-nav/template.hbs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,7 @@
3333
subnav=(component 'docs-viewer/x-nav-list' class='docs-ml-4')
3434
)}}
3535

36-
{{!-- Autogenerated API docs --}}
37-
{{#if (gt project.modules.length 0)}}
38-
{{docs-viewer/x-section 'API Reference' style='large'}}
39-
40-
{{#each project.navigationIndex as |section|}}
41-
{{docs-viewer/x-section section.type}}
42-
43-
{{#each section.items as |item|}}
44-
{{docs-viewer/x-nav-item (break-on item.name '/') (concat root '.api.item') item.path}}
45-
{{/each}}
46-
{{/each}}
47-
{{/if}}
36+
{{docs-viewer/x-autogenerated-api-docs root=root project=project}}
4837
{{/docs-viewer/x-nav-list}}
4938

5039
<div class="docs-mt-16 lg:docs-mb-16 docs-mr-2 docs-text-xxs docs-rounded">

addon/components/docs-viewer/x-section/component.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import layout from './template';
33

44
export default Component.extend({
55
layout,
6-
tagName: ''
6+
tagName: '',
7+
style: 'regular'
78
}).reopenClass({
89

910
positionalParams: [ 'label' ]
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1-
<li class='docs-mt-8
2-
{{if (eq style 'large') 'docs--mb-4 docs-text-xs docs-uppercase' 'docs-capitalize'}}
1+
<li class='
2+
{{if (eq style 'regular') 'docs-mt-8 docs-capitalize'}}
3+
{{if (eq style 'large') 'docs-mt-8 docs--mb-4 docs-text-xs docs-uppercase'}}
4+
{{if (eq style 'subsection') 'docs-mt-2 docs-text-sm'}}
35
'>
4-
{{label}}
6+
{{#if hasBlock}}
7+
{{yield}}
8+
{{else}}
9+
{{label}}
10+
{{/if}}
511
</li>

addon/keyboard-config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
const TAGNAMES_THAT_WHEN_FOCUSED_PREVENT_KEYBOARD_SHORTCUTS = [ 'INPUT', 'SELECT', 'TEXTAREA' ];
22

3+
/**
4+
@function formElementHasFocus
5+
@hide
6+
*/
37
export function formElementHasFocus() {
48
return TAGNAMES_THAT_WHEN_FOCUSED_PREVENT_KEYBOARD_SHORTCUTS.includes(document.activeElement.tagName);
59
}

addon/tailwind/components/docs-md.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
.docs-h3,
2121
.docs-md__h3 a,
2222
.docs-h3 a {
23-
@apply docs-pt-4 docs-mb-1 docs-text-grey-darkest docs-leading-tight docs-no-underline;
23+
@apply docs-pt-4 docs-mb-1 docs-text-grey-darkest docs-leading-normal docs-no-underline;
2424
}
2525

2626
.docs-md p {

0 commit comments

Comments
 (0)