-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
[WIP] Add footnotes support to Gutenberg #6549
Changes from 1 commit
791305a
533aa51
95237fc
213150e
2e6de5e
40dc686
b5cee89
3941d18
55889c2
202dfd9
e8597a0
ec802ab
d2309af
e7dc2bc
23a3037
f519cac
e7715cd
a9ddeee
db6e61d
991a67a
bed9b39
33d0045
d06aff6
75fc957
089dd9d
c33beac
8c2a1a2
b3c303d
14b9b2d
0646693
ac2e5af
72277b5
11794cc
c958cca
578d71a
400140f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { get, isEqual } from 'lodash'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { Component } from '@wordpress/element'; | ||
import { __ } from '@wordpress/i18n'; | ||
import { withSelect } from '@wordpress/data'; | ||
import { RichText } from '@wordpress/blocks'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import './editor.scss'; | ||
|
||
class FootnotesEditor extends Component { | ||
constructor( props ) { | ||
super( ...arguments ); | ||
|
||
this.setFootnotesInOrder( props.footnotesOrder ); | ||
this.state = { | ||
editable: null, | ||
}; | ||
} | ||
|
||
setFootnotesInOrder( footnotesOrder ) { | ||
const { attributes, setAttributes } = this.props; | ||
|
||
const footnotes = footnotesOrder.map( ( { id } ) => { | ||
return this.getFootnoteById( attributes.footnotes, id ); | ||
} ); | ||
|
||
setAttributes( { footnotes } ); | ||
} | ||
|
||
getFootnoteById( footnotes, footnoteUid ) { | ||
const filteredFootnotes = footnotes.filter( | ||
( footnote ) => footnote.id === footnoteUid ); | ||
|
||
return get( filteredFootnotes, [ 0 ], { id: footnoteUid, text: '' } ); | ||
} | ||
|
||
onChange( footnoteUid ) { | ||
return ( nextValue ) => { | ||
const { attributes, footnotesOrder, setAttributes } = this.props; | ||
|
||
const nextFootnotes = footnotesOrder.map( ( { id } ) => { | ||
if ( id === footnoteUid ) { | ||
return { | ||
id, | ||
text: nextValue, | ||
}; | ||
} | ||
|
||
return this.getFootnoteById( attributes.footnotes, id ); | ||
} ); | ||
|
||
setAttributes( { | ||
footnotes: nextFootnotes, | ||
} ); | ||
}; | ||
} | ||
|
||
onSetActiveEditable( id ) { | ||
return () => { | ||
this.setState( { editable: id } ); | ||
}; | ||
} | ||
|
||
componentWillReceiveProps( nextProps ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This lifecycle method will be deprecated soon. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right! Will replace it. |
||
const { footnotesOrder } = this.props; | ||
const nextFootnotesOrder = nextProps.footnotesOrder; | ||
|
||
if ( ! isEqual( footnotesOrder, nextFootnotesOrder ) ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think we can avoid the deep comparison here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't think of any way to avoid this comparison for now. What we could easily do is to store these two arrays as an array of strings instead of an array of objects (from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I refactored the footnotes block so this comparison is no longer necessary (11794cc). |
||
this.setFootnotesInOrder( nextFootnotesOrder ); | ||
} | ||
} | ||
|
||
render() { | ||
const { attributes, editable, isSelected } = this.props; | ||
const { footnotes } = attributes; | ||
|
||
return ( | ||
<ol className="blocks-footnotes__footnotes-list"> | ||
{ footnotes.map( ( footnote ) => ( | ||
<li key={ footnote.id }> | ||
<RichText | ||
tagName="span" | ||
value={ footnote.text } | ||
onChange={ this.onChange( footnote.id ) } | ||
isSelected={ isSelected && editable === footnote.id } | ||
placeholder={ __( 'Write footnote…' ) } | ||
onFocus={ this.onSetActiveEditable( footnote.id ) } | ||
/> | ||
</li> | ||
) ) } | ||
</ol> | ||
); | ||
} | ||
} | ||
|
||
export default withSelect( ( select ) => ( { | ||
footnotesOrder: select( 'core/editor' ).getFootnotes(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can improve this name a bit – it doesn't only include the order, but also the footnotes. How about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I ended up renaming it to |
||
} ) )( FootnotesEditor ); |
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.
Should this file be
edit.js
like the other blocks?