-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BD-46] refactor Pagination component #1911
[BD-46] refactor Pagination component #1911
Conversation
Thanks for the pull request, @viktorrusakov! When this pull request is ready, tag your edX technical lead. |
✅ Deploy Preview for paragon-openedx ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify site configuration. |
4aa622d
to
0fbded8
Compare
0fbded8
to
ea7b140
Compare
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## master #1911 +/- ##
==========================================
+ Coverage 92.82% 92.86% +0.03%
==========================================
Files 235 246 +11
Lines 4237 4245 +8
Branches 1029 1018 -11
==========================================
+ Hits 3933 3942 +9
+ Misses 300 299 -1
Partials 4 4
☔ View full report in Codecov by Sentry. |
ea7b140
to
d90f3ce
Compare
d90f3ce
to
0895385
Compare
0895385
to
43ba12f
Compare
@@ -1,6 +1,7 @@ | |||
import React, { useContext } from 'react'; | |||
import DataTableContext from './DataTableContext'; | |||
import Pagination from '../Pagination'; | |||
import { ArrowBackIos, ArrowForwardIos } from '../../icons'; | |||
|
|||
function TablePaginationMinimal() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add propTypes
for this component?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This component does not receive any props, so I don't think propTypes
are needed here
efc00db
to
1ec4fa7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, this looks great! Left a few comments and clarifying questions. Also, sanity check... will we likely want to release these changes as new major version release (i.e., breaking change)?
I'm seeing at least the following possible breaking changes for consumers:
- Removed SCSS variables for
Pagination
that theme authors may have been relying on. icons
prop now expects elements (e.g., icons imported from@edx/paragon/icons
rather than nodes).
src/Pagination/index.jsx
Outdated
leftIcon: PropTypes.oneOfType([PropTypes.element, PropTypes.func]), | ||
rightIcon: PropTypes.oneOfType([PropTypes.element, PropTypes.func]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[clarification] Is this intended to be a breaking change from what's supported today? In the current state, consumers can technically pass any node rather than just an element.
That said, it only looks like this impacts 1 usage of Pagination
though as a breaking change according to usage insights; I think it's probably fine to go this route. That 1 usage should be using the buttonLabels
instead of passing a node with <Icon>
and <span className="sr-only">...</span>
elements. Everything in the sr-only
span really should probably be in the buttonLabels
prop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! That was a while ago, took me some time to remember why I did this haha, I was definitely trying to avoid making breaking changes, but here it's almost unavoidable I think.
The reason is that in original implementation these icon props worked only for the default
variant of Pagination
, i.e. they were ignored for all other variants and you could not override icons for secondary
variant for example. I felt like this definitely should be fixed during this refactoring and I don't really see any other way, because we use IconButton
s for other variants and they expect our icon instances, not any node.
We could probably add some magic with our withDeprecatedProps
HOC to support both behaviours, but I think that would be pretty ugly... not sure if it's worth doing that, I feel like this breaking change is pretty minor and we can go with it to keep this component clean.
previous: 'Previous', | ||
next: 'Next', | ||
page: 'Page', | ||
currentPage: 'Current Page', | ||
pageOfCount: 'of', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[curious] Is this a place where we should add i18n support to Pagination
(could be a follow-up issue).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it crossed my mind, but I think in this case it's harder than it seems because we use these strings in a way that does not support translation I think, e.g. the screen reader text for the component is generated as follows:
const getScreenReaderText = () => `${buttonLabels.page} ${currentPage}, ${buttonLabels.currentPage}, ${buttonLabels.pageOfCount} ${pageCount}`;
(this would generate following text Page 3, Current Page, of 20
)
I'm pretty sure that for it to be translated correctly, the whole string has to be marked for translation, not just parts of it (in this case it would be page
, currentPage
and pageOfCount
strings)
So yeah, I'm not sure that just marking these props for i18n would be useful
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we might need to make another breaking change here to correctly support i18n, i.e. make consumers pass the whole text instead of parts of it, for example add screenReaderText
prop and allow adding placeholders there, e.g. default value would be Page {currentPage}, Current Page, of {totalPagesCount}
where we have predefined placeholders that will be replaced by the component with correct values. What do you think?
export const PAGINATION_BUTTON_LABEL_NEXT = 'Next'; | ||
export const PAGINATION_BUTTON_LABEL_PAGE = 'Page'; | ||
export const PAGINATION_BUTTON_LABEL_CURRENT_PAGE = 'Current Page'; | ||
export const PAGINATION_BUTTON_LABEL_PAGE_OF_COUNT = 'of'; | ||
export const PAGINATION_BUTTON_ICON_BUTTON_NEXT_ALT = 'Go to next page'; | ||
export const PAGINATION_BUTTON_ICON_BUTTON_PREV_ALT = 'Go to previous page'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also asked in another comment related to Pagination's default props, but wondering if these default English strings should be marked for i18n translation?
import { greaterThan } from '../utils/propTypes'; | ||
import { ChevronLeft, ChevronRight } from '../../icons'; | ||
|
||
function Pagination(props) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice cleanup of the root Pagination
component and abstracting out all its variants to subcomponents. Much cleaner and simpler to reason about!
@@ -0,0 +1,7 @@ | |||
export { default as Ellipsis } from './Ellipsis'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tiniest of nits: this could be a vanilla .js
file as it doesn't render JSX
src/index.js
Outdated
PAGINATION_BUTTON_LABEL_PREV, | ||
PAGINATION_BUTTON_ICON_BUTTON_NEXT_ALT, | ||
PAGINATION_BUTTON_ICON_BUTTON_PREV_ALT, | ||
PAGINATION_BUTTON_LABEL_PAGE_OF_COUNT, | ||
PAGINATION_BUTTON_LABEL_CURRENT_PAGE, | ||
PAGINATION_BUTTON_LABEL_NEXT, | ||
PAGINATION_BUTTON_LABEL_PAGE, | ||
} from './Pagination'; | ||
} from './Pagination/constants'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: i wonder if it's worth sticking to convention in this file of exporting constants from the top-level component file? Could consider adding the following to ./src/Pagination/index.jsx
:
export * from './constants';
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, makes sense, updated, thanks!
b0a4053
to
ba7deae
Compare
We plan to release all breaking changes at the same time, a new PR is open here. |
@viktorrusakov Even though your pull request wasn’t merged, please take a moment to answer a two question survey so we can improve your experience in the future. |
Description
Refactors
Pagination
component to fix its style and API issues (and to improve it overall to ease maintenance).Note: should be merged after #1190 and edx/brand-edx.org#49, as they would fix ongoing issues with styles.
Deploy Preview
https://deploy-preview-1911--paragon-openedx.netlify.app/components/pagination/
Merge Checklist
example
app?wittjeff
andadamstankiewicz
as reviewers on this PR.Post-merge Checklist