-
Notifications
You must be signed in to change notification settings - Fork 812
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
Add page navigation for the new feedback dashboard #28826
Merged
Merged
Changes from 13 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
109aeb8
Implement the basic layout for the new Jetpack Forms dashboard
ice9js f5be308
changelog
ice9js e40faf6
[not verified] Add the table component
ice9js fe79a9a
Move lodash to dependencies from devDependencies
ice9js fd894e4
Add the responses table to the inbox view
ice9js eb9dcaa
Fix linter issues
ice9js 644f612
Add gridicons
ice9js f9a1372
Add PageNavigation component
ice9js 6673e78
Add pagination to the feedback list view
ice9js 2eb1b62
Merge branch 'trunk' into add/jetpack-forms-dashboard-page-navigation
ice9js a94ad4e
changelog
ice9js b825346
Merge branch 'trunk' into add/jetpack-forms-dashboard-page-navigation
ice9js 6a2d7f9
Update versions
ice9js fc716de
Add arrow incons to the <Gridicon /> component
ice9js 73f1aa5
Update <PageNavigation /> to use <Gridicon /> from jetpack-components
ice9js c3f7a85
Fix arrow style
ice9js a29b48c
Remove custom Gridicon implementation from jetpack-forms
ice9js 9a2fbd9
changelog
ice9js a77f5f2
Merge branch 'trunk' into add/jetpack-forms-dashboard-page-navigation
ice9js baf9a0b
[not verified] Update versions
ice9js ca60f34
Merge remote-tracking branch 'origin/trunk' into add/jetpack-forms-da…
jeherve File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
4 changes: 4 additions & 0 deletions
4
projects/packages/forms/changelog/add-jetpack-forms-dashboard-page-navigation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Significance: patch | ||
Type: added | ||
|
||
Added a page navigation component for the new feedback dashboard |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
107 changes: 107 additions & 0 deletions
107
projects/packages/forms/src/dashboard/components/gridicon/index.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* !!! | ||
This is a fork of the Jetpack Gridicon code: | ||
https://github.com/Automattic/jetpack/blob/f8078c2cd12ac508334da2fb08e37a92cf283c14/_inc/client/components/gridicon/index.jsx | ||
It has been modified to work with Preact, and only includes the icons that we need. | ||
!!! */ | ||
|
||
import { Component } from '@wordpress/element'; | ||
import { __ } from '@wordpress/i18n'; | ||
|
||
import './style.scss'; | ||
|
||
class Gridicon extends Component { | ||
static defaultProps = { | ||
'aria-hidden': 'false', | ||
focusable: 'true', | ||
}; | ||
|
||
needsOffset( icon, size ) { | ||
const iconNeedsOffset = [ 'gridicons-arrow-left', 'gridicons-arrow-right', 'gridicons-star' ]; | ||
|
||
if ( iconNeedsOffset.indexOf( icon ) >= 0 ) { | ||
return size % 18 === 0; | ||
} | ||
return false; | ||
} | ||
|
||
getSVGTitle( icon ) { | ||
// Enable overriding title with falsy/truthy values. | ||
if ( 'title' in this.props ) { | ||
return this.props.title ? <title>{ this.props.title }</title> : null; | ||
} | ||
|
||
switch ( icon ) { | ||
default: | ||
return null; | ||
case 'gridicons-arrow-left': | ||
return <title>{ __( 'Arrow left', 'jetpack-forms' ) }</title>; | ||
case 'gridicons-arrow-right': | ||
return <title>{ __( 'Arrow right', 'jetpack-forms' ) }</title>; | ||
case 'gridicons-search': | ||
return <title>{ __( 'Magnifying Glass', 'jetpack-forms' ) }</title>; | ||
} | ||
} | ||
|
||
renderIcon( icon ) { | ||
switch ( icon ) { | ||
default: | ||
return null; | ||
case 'gridicons-arrow-left': | ||
return ( | ||
<g> | ||
<path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" /> | ||
</g> | ||
); | ||
case 'gridicons-arrow-right': | ||
return ( | ||
<g> | ||
<path d="M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8-8-8z" /> | ||
</g> | ||
); | ||
case 'gridicons-search': | ||
return ( | ||
<g> | ||
<path d="M21 19l-5.154-5.154C16.574 12.742 17 11.42 17 10c0-3.866-3.134-7-7-7s-7 3.134-7 7 3.134 7 7 7c1.42 0 2.742-.426 3.846-1.154L19 21l2-2zM5 10c0-2.757 2.243-5 5-5s5 2.243 5 5-2.243 5-5 5-5-2.243-5-5z" /> | ||
</g> | ||
); | ||
} | ||
} | ||
|
||
render() { | ||
const { size = 24, className = '' } = this.props; | ||
|
||
const height = this.props.height || size; | ||
const width = this.props.width || size; | ||
const style = this.props.style || { height, width }; | ||
|
||
const icon = 'gridicons-' + this.props.icon, | ||
needsOffset = this.needsOffset( icon, size ); | ||
|
||
let iconClass = [ 'gridicon', icon, className ]; | ||
|
||
if ( needsOffset ) { | ||
iconClass.push( 'needs-offset' ); | ||
} | ||
iconClass = iconClass.join( ' ' ); | ||
|
||
return ( | ||
<svg | ||
aria-label={ this.props.description } | ||
className={ iconClass } | ||
focusable={ this.props.focusable } | ||
height={ height } | ||
onClick={ this.props.onClick } | ||
style={ style } | ||
viewBox="0 0 24 24" | ||
width={ width } | ||
xmlns="http://www.w3.org/2000/svg" | ||
aria-hidden={ this.props[ 'aria-hidden' ] } | ||
> | ||
{ this.getSVGTitle( icon ) } | ||
{ this.renderIcon( icon ) } | ||
</svg> | ||
); | ||
} | ||
} | ||
|
||
export default Gridicon; |
16 changes: 16 additions & 0 deletions
16
projects/packages/forms/src/dashboard/components/gridicon/style.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
.gridicon { | ||
fill: currentColor; | ||
display: inline-block; | ||
|
||
&.needs-offset g { | ||
transform: translate( 1px, 1px ); /* translates to .5px because it's in a child element */ | ||
} | ||
|
||
&.needs-offset-x g { | ||
transform: translate( 1px, 0 ); /* only nudges horizontally */ | ||
} | ||
|
||
&.needs-offset-y g { | ||
transform: translate( 0, 1px ); /* only nudges vertically */ | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
projects/packages/forms/src/dashboard/components/page-navigation/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import { useCallback } from '@wordpress/element'; | ||
import { __ } from '@wordpress/i18n'; | ||
import { filter, flatten, map, range } from 'lodash'; | ||
import Gridicon from '../Gridicon'; | ||
import PageNumber from './page-number'; | ||
|
||
import './style.scss'; | ||
|
||
const PageNavigation = ( { currentPage, expandedRange = 3, onSelectPage, pages } ) => { | ||
const goToPrevious = useCallback( () => onSelectPage( currentPage - 1 ), [ | ||
currentPage, | ||
onSelectPage, | ||
] ); | ||
const goToNext = useCallback( () => onSelectPage( currentPage + 1 ), [ | ||
currentPage, | ||
onSelectPage, | ||
] ); | ||
|
||
const currentRange = range( | ||
Math.max( 0, currentPage - expandedRange + 1 ), | ||
Math.min( pages, currentPage + expandedRange - 1 ) + 1 | ||
); | ||
const totalRange = filter( | ||
flatten( [ | ||
expandedRange < currentPage && 1, | ||
expandedRange + 1 < currentPage && ( currentPage === expandedRange + 2 ? 2 : Infinity ), | ||
currentRange, | ||
currentPage < pages - expandedRange && | ||
( currentPage === pages - expandedRange ? pages - 1 : Infinity ), | ||
currentPage < pages - expandedRange + 1 && pages, | ||
] ) | ||
); | ||
|
||
return ( | ||
<div className="jp-forms__page-navigation"> | ||
<button | ||
disabled={ currentPage === 1 } | ||
className="jp-forms__page-navigation-button" | ||
onClick={ goToPrevious } | ||
> | ||
<Gridicon icon="arrow-left" size={ 18 } /> | ||
{ __( 'Previous', 'jetpack-forms' ) } | ||
</button> | ||
|
||
{ map( totalRange, ( n, index ) => | ||
! isFinite( n ) ? ( | ||
<button | ||
key={ `placeholder-${ index }` } | ||
className="jp-forms__page-navigation-placeholder" | ||
disabled | ||
> | ||
… | ||
</button> | ||
) : ( | ||
<PageNumber | ||
key={ n } | ||
className="jp-forms__page-navigation-button" | ||
active={ n === currentPage } | ||
page={ n } | ||
onSelect={ onSelectPage } | ||
/> | ||
) | ||
) } | ||
|
||
<button | ||
disabled={ currentPage === pages } | ||
className="jp-forms__page-navigation-button" | ||
onClick={ goToNext } | ||
> | ||
{ __( 'Next', 'jetpack-forms' ) } | ||
<Gridicon icon="arrow-right" size={ 18 } /> | ||
</button> | ||
</div> | ||
); | ||
}; | ||
|
||
export default PageNavigation; |
18 changes: 18 additions & 0 deletions
18
projects/packages/forms/src/dashboard/components/page-navigation/page-number.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { useCallback } from '@wordpress/element'; | ||
import classNames from 'classnames'; | ||
|
||
const PageNumber = ( { active, className, page, onSelect } ) => { | ||
const buttonClass = classNames( 'jp-forms__page-navigation-page-number', className, { | ||
'is-active': active, | ||
} ); | ||
|
||
const selectPage = useCallback( () => onSelect( page ), [ page, onSelect ] ); | ||
|
||
return ( | ||
<button className={ buttonClass } onClick={ selectPage }> | ||
{ page } | ||
</button> | ||
); | ||
}; | ||
|
||
export default PageNumber; |
55 changes: 55 additions & 0 deletions
55
projects/packages/forms/src/dashboard/components/page-navigation/style.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
.jp-forms__page-navigation { | ||
background-color: #fff; | ||
border: 1px solid #dcdcde; | ||
border-radius: 3px; | ||
box-sizing: border-box; | ||
display: flex; | ||
flex-direction: row; | ||
height: 36px; | ||
justify-content: center; | ||
padding: 0; | ||
width: fit-content; | ||
} | ||
|
||
.jp-forms__page-navigation-button, | ||
.jp-forms__page-navigation-button:hover, | ||
.jp-forms__page-navigation-placeholder:hover, | ||
.jp-forms__page-navigation-placeholder { | ||
background: transparent; | ||
border: 0; | ||
box-sizing: border-box; | ||
color: #101517; | ||
cursor: pointer; | ||
display: inline-flex; | ||
font-weight: bold; | ||
font-size: 13px; | ||
height: 34px; | ||
line-height: 18px; | ||
text-align: center; | ||
padding: 8px 12px; | ||
|
||
&.is-active { | ||
background-color: #101517; | ||
color: #fff; | ||
} | ||
|
||
&:disabled { | ||
cursor: default; | ||
|
||
&:first-child, &:last-child { | ||
color: #dcdcde; | ||
} | ||
} | ||
|
||
.gridicon { | ||
display: inline-flex; | ||
|
||
&:first-child { | ||
margin-right: 3px; | ||
} | ||
|
||
&:last-child { | ||
margin-left: 3px; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 4 additions & 0 deletions
4
projects/plugins/jetpack/changelog/add-jetpack-forms-dashboard-page-navigation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Significance: patch | ||
Type: other | ||
|
||
This change doesn't affect the plugin. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 pull from the Jetpack component (
@automattic/jetpack-components
) instead of adding this copy here?jetpack/projects/js-packages/components/components/gridicon/index.tsx
Line 14 in 3a3c4ad
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 can, I'll make the change. Main reason I did it was I noticed a bunch of packages duplicating this component, which also makes me wonder if there's any edge cases related to that? Regardless of the use case here.