Skip to content

Commit 99584d6

Browse files
authoredMar 8, 2024
Add generic pager component (swiftlang#782)
* Add `Pager`. Introduces a new "pager" component, which can be used to group pages of content with only one page being visible at any given time. Users can toggle the page of content currently being shown. As an experiment, this pager component is being used on the grid-style `@Links` so that only a set number of links are shown at one time. * Add basic unit tests and docs for pager components. * Rewrite `Pager` using composition API. * Move license comment to top of file. * Fix license header comments. * Exploring animation. * Fix animation to slide in and out correctly. * Remove unused code. * Remove more unused code. * Remove unecessary property. * Only render indicators for multiple pages. * Adjust page size depending on breakpoint. * Update indicator styling. * Add gutter controls to advance/retreat pager. * Visually center page controls within links card grid. * Adjust page size for links grid based on its style. * Rewrite `Pager` using options API for now. * Rewrite specs for `TopicsLinkCardGrid`. * Re-implement pager using overflow and native scrolling. * Update active page indicator when scrolling naturally. * Hide native scrollbar UI. * Wait for scroll to finish before re-observing page visibility. * Use auto scroll behavior to match CSS. * Improve strategy for awaiting scroll. * Fix `Pager` specs. * Prevent selection of inactive pages. * Add basic transition for gutter controls. * Make pager an opt-in experience for links grid. * Optimize `Pager` with only a single page. * Only show compact next/prev controls at small breakpoint. * Fix vertical centering of gutter pager control. * Adjust styling of pager controls. * Fix `PagerControl` spec. * Use compact controls at medium breakpoint instead of small. * Add ARIA attributes where relevant. * Add ARIA labels to pager controls. * Add class for grid style. * Add optional `pageSize` prop that can override default behavior.
1 parent a06d8d4 commit 99584d6

File tree

12 files changed

+830
-43
lines changed

12 files changed

+830
-43
lines changed
 

‎src/components/ContentNode/LinksBlock.vue

+5-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
</template>
2626

2727
<script>
28-
import TopicsLinkCardGrid from 'docc-render/components/DocumentationTopic/TopicsLinkCardGrid.vue';
28+
import TopicsLinkCardGrid from 'theme/components/DocumentationTopic/TopicsLinkCardGrid.vue';
2929
import { TopicSectionsStyle } from 'docc-render/constants/TopicSectionsStyle';
3030
import referencesProvider from 'docc-render/mixins/referencesProvider';
3131

@@ -63,6 +63,10 @@ export default {
6363
margin-top: var(--spacing-stacked-margin-xlarge);
6464
}
6565

66+
* + .links-block {
67+
margin-top: var(--spacing-stacked-margin-xlarge);
68+
}
69+
6670
.topic-link-block {
6771
margin-top: 15px; // make sure its the same as in the TopicsTable
6872
}

‎src/components/DocumentationTopic/TopicsLinkCardGrid.vue

+72-15
Original file line numberDiff line numberDiff line change
@@ -9,43 +9,100 @@
99
-->
1010

1111
<template>
12-
<div class="TopicsLinkCardGrid">
13-
<Row :columns="{
14-
large: compactCards ? 3 : 2,
15-
medium: 2,
16-
}">
17-
<Column
18-
v-for="item in items"
19-
:key="item.title"
20-
>
21-
<TopicsLinkCardGridItem :item="item" :compact="compactCards" />
22-
</Column>
23-
</Row>
24-
</div>
12+
<Pager
13+
:aria-label="$t('links-grid.label')"
14+
:class="['TopicsLinkCardGrid', topicStyle]"
15+
:pages="pages"
16+
>
17+
<template #page="{ page }">
18+
<Row :columns="{
19+
large: compactCards ? 3 : 2,
20+
medium: 2,
21+
}">
22+
<Column
23+
v-for="item in page"
24+
:key="item.title"
25+
>
26+
<TopicsLinkCardGridItem :item="item" :compact="compactCards" />
27+
</Column>
28+
</Row>
29+
</template>
30+
<BreakpointEmitter @change="handleBreakpointChange" />
31+
</Pager>
2532
</template>
2633

2734
<script>
28-
import Row from 'docc-render/components/ContentNode/Row.vue';
35+
import BreakpointEmitter from 'docc-render/components/BreakpointEmitter.vue';
2936
import Column from 'docc-render/components/ContentNode/Column.vue';
37+
import Pager from 'docc-render/components/Pager.vue';
38+
import Row from 'docc-render/components/ContentNode/Row.vue';
3039
import { TopicSectionsStyle } from 'docc-render/constants/TopicSectionsStyle';
40+
import { BreakpointName } from 'docc-render/utils/breakpoints';
41+
import { page } from 'docc-render/utils/arrays';
3142
import TopicsLinkCardGridItem from './TopicsLinkCardGridItem.vue';
3243

3344
export default {
3445
name: 'TopicsLinkCardGrid',
35-
components: { TopicsLinkCardGridItem, Column, Row },
46+
components: {
47+
BreakpointEmitter,
48+
Column,
49+
Pager,
50+
Row,
51+
TopicsLinkCardGridItem,
52+
},
53+
data: () => ({
54+
breakpoint: BreakpointName.large,
55+
}),
3656
props: {
3757
items: {
3858
type: Array,
3959
required: true,
4060
},
61+
pageSize: {
62+
type: Number,
63+
required: false,
64+
},
4165
topicStyle: {
4266
type: String,
4367
default: TopicSectionsStyle.compactGrid,
4468
validator: v => v === TopicSectionsStyle.compactGrid || v === TopicSectionsStyle.detailedGrid,
4569
},
70+
usePager: {
71+
type: Boolean,
72+
default: false,
73+
},
4674
},
4775
computed: {
4876
compactCards: ({ topicStyle }) => topicStyle === TopicSectionsStyle.compactGrid,
77+
defaultPageSize: ({
78+
breakpoint,
79+
items,
80+
topicStyle,
81+
usePager,
82+
}) => (usePager ? {
83+
[TopicSectionsStyle.compactGrid]: {
84+
[BreakpointName.large]: 6,
85+
[BreakpointName.medium]: 4,
86+
[BreakpointName.small]: 1,
87+
},
88+
[TopicSectionsStyle.detailedGrid]: {
89+
[BreakpointName.large]: 4,
90+
[BreakpointName.medium]: 2,
91+
[BreakpointName.small]: 1,
92+
},
93+
}[topicStyle][breakpoint] : (
94+
items.length
95+
)),
96+
pages: ({
97+
items,
98+
defaultPageSize,
99+
pageSize,
100+
}) => page(items, (pageSize || defaultPageSize)),
101+
},
102+
methods: {
103+
handleBreakpointChange(breakpoint) {
104+
this.breakpoint = breakpoint;
105+
},
49106
},
50107
};
51108
</script>

0 commit comments

Comments
 (0)