Skip to content

Commit a09bf18

Browse files
author
Dobromir Hristov
committed
refactor: Hierarchy.vue component to show more items at once
1 parent 3613a7c commit a09bf18

File tree

6 files changed

+88
-33
lines changed

6 files changed

+88
-33
lines changed

src/components/DocumentationTopic/DocumentationNav.vue

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
<template>
1212
<NavBase
13-
:breakpoint="BreakpointName.medium"
1413
:hasOverlay="false"
1514
hasSolidBackground
1615
:hasNoBorder="hasNoBorder"
@@ -149,9 +148,7 @@ export default {
149148
/deep/ .nav-menu {
150149
@include font-styles(documentation-nav);
151150
// vertically align the items
152-
@include breakpoint-only-largenav() {
153-
padding-top: 0;
154-
}
151+
padding-top: 0;
155152
}
156153
157154
.documentation-nav {

src/components/DocumentationTopic/DocumentationNav/Hierarchy.vue

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,24 @@
1414
:class="{ 'has-badge': hasBadge }"
1515
class="hierarchy"
1616
>
17+
<HierarchyItem
18+
v-if="root"
19+
:key="root.title"
20+
class="root-hierarchy"
21+
:url="addQueryParamsToUrl(root.url)"
22+
>
23+
{{ root.title }}
24+
</HierarchyItem>
1725
<HierarchyItem
1826
v-for="topic in collapsibleItems"
1927
:key="topic.title"
20-
:isCollapsed="shouldCollapseItems"
28+
isCollapsed
2129
:url="addQueryParamsToUrl(topic.url)"
2230
>
2331
{{ topic.title }}
2432
</HierarchyItem>
2533
<HierarchyCollapsedItems
26-
v-if="shouldCollapseItems"
34+
v-if="collapsibleItems.length"
2735
:topics="collapsibleItems"
2836
/>
2937
<HierarchyItem
@@ -54,6 +62,7 @@
5462
import { buildUrl } from 'docc-render/utils/url-helper';
5563
import NavMenuItems from 'docc-render/components/NavMenuItems.vue';
5664
import Badge from 'docc-render/components/Badge.vue';
65+
import throttle from 'docc-render/utils/throttle';
5766
import HierarchyCollapsedItems from './HierarchyCollapsedItems.vue';
5867
import HierarchyItem from './HierarchyItem.vue';
5968
@@ -87,18 +96,49 @@ export default {
8796
default: () => [],
8897
},
8998
},
99+
data() {
100+
return {
101+
windowWidth: window.innerWidth,
102+
};
103+
},
104+
mounted() {
105+
// start tracking the window size
106+
const cb = throttle(() => { this.windowWidth = window.innerWidth; }, 150);
107+
window.addEventListener('resize', cb);
108+
this.$once('hook:beforeDestroy', () => {
109+
window.removeEventListener('resize', cb);
110+
});
111+
},
90112
computed: {
91113
parentTopics() {
92114
return this.parentTopicIdentifiers.map((id) => {
93115
const { title, url } = this.references[id];
94116
return { title, url };
95117
});
96118
},
97-
shouldCollapseItems() {
98-
return (this.parentTopics.length + 1) > MaxVisibleItems;
119+
/**
120+
* Extract the root item from the parentTopics
121+
*/
122+
root: ({ parentTopics }) => parentTopics[0],
123+
/**
124+
* Figure out how many items we can show, after the collapsed items,
125+
* based on the window.innerWidth
126+
*/
127+
linksAfterCollapse: ({ windowWidth }) => {
128+
// never show more than the `MaxVisibleItems`
129+
if (windowWidth > 1200) return MaxVisibleItems;
130+
if (windowWidth > 1000) return MaxVisibleItems - 1;
131+
if (windowWidth >= 800) return MaxVisibleItems - 2;
132+
return 0;
99133
},
100-
collapsibleItems: ({ parentTopics }) => parentTopics.slice(0, -1),
101-
nonCollapsibleItems: ({ parentTopics }) => parentTopics.slice(-1),
134+
collapsibleItems: ({ parentTopics, linksAfterCollapse }) => (
135+
// if there are links, slice all except those, otherwise get all but the root
136+
linksAfterCollapse ? parentTopics.slice(1, -linksAfterCollapse) : parentTopics.slice(1)
137+
),
138+
nonCollapsibleItems: ({ parentTopics, linksAfterCollapse }) => (
139+
// if there are links to show, slice them out, otherwise return none
140+
linksAfterCollapse ? parentTopics.slice(1).slice(-linksAfterCollapse) : []
141+
),
102142
hasBadge: ({ isSymbolDeprecated, isSymbolBeta, currentTopicTags }) => (
103143
isSymbolDeprecated || isSymbolBeta || currentTopicTags.length
104144
),
@@ -110,9 +150,19 @@ export default {
110150
},
111151
};
112152
</script>
113-
<style scoped>
153+
<style scoped lang="scss">
154+
@import 'docc-render/styles/_core.scss';
155+
114156
.hierarchy {
115157
justify-content: flex-start;
116158
min-width: 0;
159+
margin-right: 80px;
160+
@include nav-in-breakpoint() {
161+
margin-right: 0;
162+
}
163+
164+
.root-hierarchy {
165+
flex: 1 0 auto;
166+
}
117167
}
118168
</style>

src/components/DocumentationTopic/DocumentationNav/HierarchyCollapsedItems.vue

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
<template>
1212
<li class="hierarchy-collapsed-items">
13-
<InlineChevronRightIcon class="hierarchy-item-icon icon-inline" />
13+
<span class="hierarchy-item-icon icon-inline">/</span>
1414
<button
1515
class="toggle"
1616
ref="btn"
@@ -29,12 +29,11 @@
2929

3030
<script>
3131
import { buildUrl } from 'docc-render/utils/url-helper';
32-
import InlineChevronRightIcon from 'theme/components/Icons/InlineChevronRightIcon.vue';
3332
import EllipsisIcon from 'theme/components/Icons/EllipsisIcon.vue';
3433
3534
export default {
3635
name: 'HierarchyCollapsedItems',
37-
components: { EllipsisIcon, InlineChevronRightIcon },
36+
components: { EllipsisIcon },
3837
data: () => ({ collapsed: true }),
3938
props: {
4039
topics: {
@@ -116,7 +115,7 @@ $hierarchy-dropdown-box-shadow: 0 1px 4px -1px var(--color-figure-gray-secondary
116115
117116
$tail-width: 1rem;
118117
$tail-offset: rem($nav-menu-item-left-margin)
119-
+ rem($nav-space-between-elements)
118+
+ rem($nav-space-hierarchy-elements)
120119
- ($toggle-width / 2)
121120
+ ($tail-width / 2) + rem(4px);
122121
@@ -126,12 +125,16 @@ $dropdown-vertical-offset: rem(7px);
126125
position: relative;
127126
display: inline-flex;
128127
align-items: center;
129-
margin-left: $nav-space-between-elements;
128+
margin-left: $nav-space-hierarchy-elements;
130129
131130
.hierarchy-item-icon {
132131
width: 9px;
133132
height: 15px;
134-
margin-right: $nav-space-between-elements;
133+
margin-right: $nav-space-hierarchy-elements;
134+
display: flex;
135+
justify-content: center;
136+
font-size: 1em;
137+
align-self: baseline;
135138
}
136139
137140
@include nav-in-breakpoint() {

src/components/DocumentationTopic/DocumentationNav/HierarchyItem.vue

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,18 @@
1111
<template functional>
1212
<component
1313
:is="$options.components.NavMenuItemBase"
14-
:class="{ collapsed: props.isCollapsed }"
14+
:class="[{ collapsed: props.isCollapsed }, data.staticClass]"
1515
class="hierarchy-item"
1616
>
17-
<component
18-
:is="$options.components.InlineChevronRightIcon"
19-
class="hierarchy-item-icon icon-inline"
20-
/>
17+
<span class="hierarchy-item-icon icon-inline">/</span>
2118
<router-link v-if="props.url" class="parent item nav-menu-link" :to="props.url">
2219
<slot />
2320
</router-link>
2421
<template v-else>
2522
<span class="current item">
2623
<slot />
2724
</span>
28-
<slot name="tags"/>
25+
<slot name="tags" />
2926
</template>
3027
</component>
3128
</template>
@@ -55,19 +52,20 @@ export default {
5552
/deep/ .hierarchy-item-icon {
5653
width: 9px;
5754
height: 15px;
58-
margin-right: $nav-space-between-elements;
59-
55+
margin-right: $nav-space-hierarchy-elements;
56+
display: flex;
57+
justify-content: center;
58+
font-size: 1em;
59+
align-self: baseline;
6060
// hide on when collapsed
6161
@include nav-in-breakpoint() {
6262
display: none;
6363
}
6464
}
6565
66-
@include breakpoint-only-largenav() {
67-
display: flex;
68-
align-items: center;
69-
margin-left: $nav-space-between-elements;
70-
}
66+
display: flex;
67+
align-items: center;
68+
margin-left: $nav-space-hierarchy-elements;
7169
7270
@include nav-in-breakpoint() {
7371
border-top: 1px solid var(--color-nav-hierarchy-item-borders);
@@ -103,11 +101,11 @@ export default {
103101
}
104102
}
105103
106-
$-max-uncollapsed-breadcrumbs: 3;
104+
$-max-uncollapsed-breadcrumbs: 5;
107105
$-max-breadcrumb-width: 9rem;
108106
$-max-breadcrumb-width-with-badge: 7.2rem;
109107
110-
@include breakpoint-only-largenav() {
108+
@include breakpoints-from(medium, nav) {
111109
@for $i from 1 through $-max-uncollapsed-breadcrumbs {
112110
$-multiplier: $-max-uncollapsed-breadcrumbs + 1 - $i;
113111
@@ -148,6 +146,12 @@ $-max-breadcrumb-width-with-badge: 7.2rem;
148146
.item {
149147
@include truncate($-max-breadcrumb-width * $-multiplier-truncated);
150148
}
149+
150+
&:last-child {
151+
.item {
152+
max-width: none;
153+
}
154+
}
151155
}
152156
153157
// With more than 3 breadcrumbs and a badge, the max-width is set to

src/styles/core/_nav.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ $nav-menu-item-displacement: none !default;
2323
$nav-menu-item-stagger-delay: 0s !default;
2424
$nav-bg-color-transition: 0.5s $nav-timingfunction !default;
2525
$nav-space-between-elements: rem(10px);
26+
$nav-space-hierarchy-elements: rem(3px);
2627

2728
@mixin nav-in-breakpoint($nested: false) {
2829
@include unify-selector('.nav--in-breakpoint-range', $nested) {

src/styles/core/typography/_font-styles.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ $font-styles: (
139139
large: 17_25_semibold,
140140
),
141141
documentation-nav: (
142-
large: (15_19, nav),
142+
large: (14_21, nav),
143143
medium: (14_21, nav),
144144
small: (14_21, nav),
145145
),

0 commit comments

Comments
 (0)