Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
coopwire-hypothesis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙灵跃 Leon Sun
coopwire-hypothesis
Commits
14c13589
Commit
14c13589
authored
Feb 10, 2021
by
Lyza Danger Gardner
Committed by
Lyza Gardner
Feb 16, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add PaginationNavigation component
- Add a component to render pagination controls - Component is unused
parent
e7790d76
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
291 additions
and
0 deletions
+291
-0
PaginationNavigation.js
src/sidebar/components/PaginationNavigation.js
+89
-0
PaginationNavigation-test.js
src/sidebar/components/test/PaginationNavigation-test.js
+151
-0
PaginationNavigation.scss
src/styles/sidebar/components/PaginationNavigation.scss
+50
-0
sidebar.scss
src/styles/sidebar/sidebar.scss
+1
-0
No files found.
src/sidebar/components/PaginationNavigation.js
0 → 100644
View file @
14c13589
import
propTypes
from
'prop-types'
;
import
{
pageNumberOptions
}
from
'../util/pagination'
;
import
Button
from
'./Button'
;
/**
* @typedef PaginationNavigationProps
* @prop {number} currentPage - The currently-visible page of results. Pages
* start at 1 (not 0).
* @prop {(page: number) => void} onChangePage - Callback for changing page
* @prop {number} totalPages
*/
/**
* Render pagination navigation controls, with buttons to go next, previous
* and nearby pages.
*
* @param {PaginationNavigationProps} props
*/
function
PaginationNavigation
({
currentPage
,
onChangePage
,
totalPages
})
{
// Pages are 1-indexed
const
hasNextPage
=
currentPage
<
totalPages
;
const
hasPreviousPage
=
currentPage
>
1
;
const
pageNumbers
=
pageNumberOptions
(
currentPage
,
totalPages
);
const
changePageTo
=
(
pageNumber
,
eventTarget
)
=>
{
onChangePage
(
pageNumber
);
// Because changing pagination page doesn't reload the page (as it would
// in a "traditional" HTML context), the clicked-upon navigation button
// will awkwardly retain focus unless it is actively removed.
// TODO: Evaluate this for a11y issues
/** @type HTMLElement */
(
eventTarget
)?.
blur
();
};
return
(
<
div
className
=
"PaginationNavigation"
>
<
div
className
=
"PaginationNavigation__relative PaginationNavigation__prev"
>
{
hasPreviousPage
&&
(
<
Button
className
=
"PaginationNavigation__button"
icon
=
"arrow-left"
buttonText
=
"prev"
title
=
"Go to previous page"
onClick
=
{
e
=>
changePageTo
(
currentPage
-
1
,
e
.
target
)}
/
>
)}
<
/div
>
<
ul
className
=
"PaginationNavigation__pages"
>
{
pageNumbers
.
map
((
page
,
idx
)
=>
(
<
li
key
=
{
idx
}
>
{
page
===
null
?
(
<
div
className
=
"PaginationNavigation__gap"
>
...
<
/div
>
)
:
(
<
Button
key
=
{
`page-
${
idx
}
`
}
buttonText
=
{
page
.
toString
()}
title
=
{
`Go to page
${
page
}
`
}
className
=
"PaginationNavigation__page-button"
isPressed
=
{
page
===
currentPage
}
onClick
=
{
e
=>
changePageTo
(
page
,
e
.
target
)}
/
>
)}
<
/li
>
))}
<
/ul
>
<
div
className
=
"PaginationNavigation__relative PaginationNavigation__next"
>
{
hasNextPage
&&
(
<
Button
className
=
"PaginationNavigation__button PaginationNavigation__button-right"
icon
=
"arrow-right"
buttonText
=
"next"
iconPosition
=
"right"
title
=
"Go to next page"
onClick
=
{
e
=>
changePageTo
(
currentPage
+
1
,
e
.
target
)}
/
>
)}
<
/div
>
<
/div
>
);
}
PaginationNavigation
.
propTypes
=
{
currentPage
:
propTypes
.
number
,
onChangePage
:
propTypes
.
func
,
totalPages
:
propTypes
.
number
,
};
export
default
PaginationNavigation
;
src/sidebar/components/test/PaginationNavigation-test.js
0 → 100644
View file @
14c13589
import
{
mount
}
from
'enzyme'
;
import
{
act
}
from
'preact/test-utils'
;
import
PaginationNavigation
,
{
$imports
}
from
'../PaginationNavigation'
;
describe
(
'PaginationNavigation'
,
()
=>
{
let
fakeOnChangePage
;
let
fakePageNumberOptions
;
const
findButton
=
(
wrapper
,
title
)
=>
wrapper
.
find
(
'button'
).
filterWhere
(
n
=>
n
.
props
().
title
===
title
);
const
createComponent
=
(
props
=
{})
=>
{
return
mount
(
<
PaginationNavigation
currentPage
=
{
1
}
onChangePage
=
{
fakeOnChangePage
}
totalPages
=
{
10
}
{...
props
}
/
>
);
};
beforeEach
(()
=>
{
fakeOnChangePage
=
sinon
.
stub
();
fakePageNumberOptions
=
sinon
.
stub
().
returns
([
1
,
2
,
3
,
4
,
null
,
10
]);
$imports
.
$mock
({
'../util/pagination'
:
{
pageNumberOptions
:
fakePageNumberOptions
},
});
});
afterEach
(()
=>
{
$imports
.
$restore
();
});
describe
(
'prev button'
,
()
=>
{
it
(
'should render a prev button when there are previous pages to show'
,
()
=>
{
const
wrapper
=
createComponent
({
currentPage
:
2
});
const
button
=
findButton
(
wrapper
,
'Go to previous page'
);
assert
.
isTrue
(
button
.
exists
());
});
it
(
'should not render a prev button if there are no previous pages to show'
,
()
=>
{
const
wrapper
=
createComponent
({
currentPage
:
1
});
const
button
=
findButton
(
wrapper
,
'Go to previous page'
);
assert
.
isFalse
(
button
.
exists
());
});
it
(
'should invoke the onChangePage callback when clicked'
,
()
=>
{
const
wrapper
=
createComponent
({
currentPage
:
2
});
const
button
=
findButton
(
wrapper
,
'Go to previous page'
);
button
.
simulate
(
'click'
);
assert
.
calledWith
(
fakeOnChangePage
,
1
);
});
it
(
'should remove focus from button after clicked'
,
()
=>
{
const
wrapper
=
createComponent
({
currentPage
:
2
});
const
button
=
findButton
(
wrapper
,
'Go to previous page'
);
const
buttonEl
=
button
.
getDOMNode
();
const
blurSpy
=
sinon
.
spy
(
buttonEl
,
'blur'
);
act
(()
=>
{
button
.
simulate
(
'click'
);
});
assert
.
equal
(
blurSpy
.
callCount
,
1
);
});
});
describe
(
'next button'
,
()
=>
{
it
(
'should render a next button when there are further pages to show'
,
()
=>
{
const
wrapper
=
createComponent
({
currentPage
:
1
});
const
button
=
findButton
(
wrapper
,
'Go to next page'
);
assert
.
isTrue
(
button
.
exists
());
});
it
(
'should not render a next button if there are no further pages to show'
,
()
=>
{
const
wrapper
=
createComponent
({
currentPage
:
10
});
const
button
=
findButton
(
wrapper
,
'Go to next page'
);
assert
.
isFalse
(
button
.
exists
());
});
it
(
'should invoke the `onChangePage` callback when clicked'
,
()
=>
{
const
wrapper
=
createComponent
({
currentPage
:
1
});
const
button
=
findButton
(
wrapper
,
'Go to next page'
);
button
.
simulate
(
'click'
);
assert
.
calledWith
(
fakeOnChangePage
,
2
);
});
it
(
'should remove focus from button after clicked'
,
()
=>
{
const
wrapper
=
createComponent
({
currentPage
:
1
});
const
button
=
findButton
(
wrapper
,
'Go to next page'
);
const
buttonEl
=
button
.
getDOMNode
();
const
blurSpy
=
sinon
.
spy
(
buttonEl
,
'blur'
);
act
(()
=>
{
button
.
simulate
(
'click'
);
});
assert
.
equal
(
blurSpy
.
callCount
,
1
);
});
});
describe
(
'page number buttons'
,
()
=>
{
it
(
'should render buttons for each page number available'
,
()
=>
{
fakePageNumberOptions
.
returns
([
1
,
2
,
3
,
4
,
null
,
10
]);
const
wrapper
=
createComponent
();
[
1
,
2
,
3
,
4
,
10
].
forEach
(
pageNumber
=>
{
const
button
=
findButton
(
wrapper
,
`Go to page
${
pageNumber
}
`
);
assert
.
isTrue
(
button
.
exists
());
});
// There is one "gap":
assert
.
equal
(
wrapper
.
find
(
'.PaginationNavigation__gap'
).
length
,
1
);
});
it
(
'should invoke the onChangePage callback when page number button clicked'
,
()
=>
{
fakePageNumberOptions
.
returns
([
1
,
2
,
3
,
4
,
null
,
10
]);
const
wrapper
=
createComponent
();
[
1
,
2
,
3
,
4
,
10
].
forEach
(
pageNumber
=>
{
const
button
=
findButton
(
wrapper
,
`Go to page
${
pageNumber
}
`
);
button
.
simulate
(
'click'
);
assert
.
calledWith
(
fakeOnChangePage
,
pageNumber
);
});
});
});
});
src/styles/sidebar/components/PaginationNavigation.scss
0 → 100644
View file @
14c13589
@use
'../../mixins/buttons'
;
@use
"../../mixins/layout"
;
@use
"../../mixins/utils"
;
@use
"../../variables"
as
var
;
.PaginationNavigation
{
@include
utils
.
font--large
;
@include
layout
.
row
;
&
__relative
{
// Set a minimum width for the previous and next button containers so that
// there is no jumping around as they appear and disappear.
min-width
:
5em
;
}
&
__next
{
// Make sure "next" button is flush right
@include
layout
.
row
(
$justify
:
flex-end
);
}
&
__pages
{
@include
layout
.
row
(
$justify
:
center
,
$align
:
center
);
flex-grow
:
1
;
}
&
__button
,
&
__page-button
{
@include
buttons
.
button--labeled
(
$background-color
:
transparent
,
$active-background-color
:
var
.
$grey-3
);
}
&
__page-button
{
margin
:
var
.
$layout-space--xxsmall
;
padding
:
var
.
$layout-space--small
var
.
$layout-space
;
}
&
__button-right
{
// TODO TEMPORARY adjustment until we can adjust the actual icon
svg
{
margin-left
:
var
.
$layout-space--xxsmall
;
}
padding-right
:
var
.
$layout-space--xxsmall
;
}
&
__page-button
[
aria-pressed
=
'true'
]
{
background-color
:
var
.
$grey-3
;
}
}
src/styles/sidebar/sidebar.scss
View file @
14c13589
...
...
@@ -41,6 +41,7 @@
@use
'./components/ModerationBanner'
;
@use
'./components/NotebookView'
;
@use
'./components/NotebookResultCount'
;
@use
'./components/PaginationNavigation'
;
@use
'./components/SelectionTabs'
;
@use
'./components/ShareAnnotationsPanel'
;
@use
'./components/SearchInput'
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment