-
Notifications
You must be signed in to change notification settings - Fork 44
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 inline media controls for the Image component #269
Merged
fabiankaegy
merged 14 commits into
feature/include-figure-in-image-component
from
feature/include-figure-in-image-component-inline-controls
Jan 29, 2024
Merged
Changes from 6 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
905324e
Added inline image controls options
ncoetzer e92b5ce
Refactored the inline controls as a separate component
ncoetzer a7225b1
Changes Image.Image component to Media and split into separate compon…
ncoetzer 4491c43
Refactored the index to pull in external components
ncoetzer 4cb8b51
Split the figure component out into its own file
ncoetzer 9126341
Refactored child components into their own sub directory for easier i…
ncoetzer e670cea
Updated readme
ncoetzer 4dba3d1
Fixes media styles block error
ncoetzer 25394d6
Reworked the style prop for rendering conditional
ncoetzer 5a64b45
Updated figure styles
ncoetzer f006e22
Updated figire component style prop
ncoetzer 4db07f2
Updated media component props
ncoetzer 786c680
Created `Figure` compound component for the main Image component
ncoetzer df92c33
Added styling fix for the figure lement for block API 3
ncoetzer 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
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,25 @@ | ||
import PropTypes from 'prop-types'; | ||
import { StyledComponentContext } from '../../styled-components-context'; | ||
import { InlineControlsStyleWrapper } from '../styles'; | ||
|
||
export const Figure = (props) => { | ||
const { style, children, ...rest } = props; | ||
|
||
return ( | ||
<StyledComponentContext cacheKey="tenup-component-image"> | ||
<InlineControlsStyleWrapper {...style} {...rest}> | ||
{children} | ||
</InlineControlsStyleWrapper> | ||
</StyledComponentContext> | ||
); | ||
}; | ||
|
||
Figure.defaultProps = { | ||
style: {}, | ||
children: [], | ||
}; | ||
|
||
Figure.propTypes = { | ||
style: PropTypes.object, | ||
children: PropTypes.array, | ||
}; |
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,5 @@ | ||
import { Media, ImageContext } from './media'; | ||
import { Figure } from './figure'; | ||
import { InlineControls } from './inline-controls'; | ||
|
||
export { Media, ImageContext, Figure, InlineControls }; |
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,39 @@ | ||
import { __ } from '@wordpress/i18n'; | ||
import { MediaReplaceFlow } from '@wordpress/block-editor'; | ||
import { ToolbarButton } from '@wordpress/components'; | ||
import PropTypes from 'prop-types'; | ||
|
||
/** | ||
* Internal Dependencies | ||
*/ | ||
|
||
export const InlineControls = (props) => { | ||
const { imageUrl, onSelect, isOptional, onRemove } = props; | ||
|
||
return ( | ||
<div className="inline-controls-sticky-wrapper"> | ||
<div className="inline-controls"> | ||
<MediaReplaceFlow mediaUrl={imageUrl} onSelect={onSelect} name={__('Replace')} /> | ||
{!!isOptional && ( | ||
<ToolbarButton onClick={onRemove} className="remove-button"> | ||
{__('Remove')} | ||
</ToolbarButton> | ||
)} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
InlineControls.defaultProps = { | ||
imageUrl: '', | ||
onSelect: undefined, | ||
isOptional: false, | ||
onRemove: undefined, | ||
}; | ||
|
||
InlineControls.propTypes = { | ||
imageUrl: PropTypes.string, | ||
onSelect: PropTypes.func, | ||
isOptional: PropTypes.bool, | ||
onRemove: PropTypes.func, | ||
}; |
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,78 @@ | ||
import PropTypes from 'prop-types'; | ||
import { MediaPlaceholder, InspectorControls } from '@wordpress/block-editor'; | ||
import { useContext, createContext } from '@wordpress/element'; | ||
import { Spinner, FocalPointPicker, PanelBody, Placeholder } from '@wordpress/components'; | ||
import { __ } from '@wordpress/i18n'; | ||
|
||
export const ImageContext = createContext(); | ||
|
||
export const Media = (props) => { | ||
const { style } = props; | ||
const { | ||
imageUrl, | ||
altText, | ||
labels, | ||
onSelect, | ||
isResolvingMedia, | ||
shouldDisplayFocalPointPicker, | ||
focalPoint, | ||
onChangeFocalPoint, | ||
canEditImage, | ||
hasImage, | ||
} = useContext(ImageContext); | ||
|
||
if (shouldDisplayFocalPointPicker) { | ||
const focalPointStyle = { | ||
objectFit: 'cover', | ||
objectPosition: `${focalPoint.x * 100}% ${focalPoint.y * 100}%`, | ||
}; | ||
|
||
props.styles = { | ||
...style, | ||
...focalPointStyle, | ||
}; | ||
} | ||
|
||
if (isResolvingMedia) { | ||
return <Spinner />; | ||
} | ||
|
||
if (!hasImage && !canEditImage) { | ||
return <Placeholder className="block-editor-media-placeholder" withIllustration />; | ||
} | ||
|
||
return ( | ||
<> | ||
{shouldDisplayFocalPointPicker && ( | ||
<InspectorControls> | ||
<PanelBody title={__('Image Settings')}> | ||
<FocalPointPicker | ||
label={__('Focal Point Picker')} | ||
url={imageUrl} | ||
value={focalPoint} | ||
onChange={onChangeFocalPoint} | ||
/> | ||
</PanelBody> | ||
</InspectorControls> | ||
)} | ||
{hasImage && <img src={imageUrl} alt={altText} {...props} />} | ||
{canEditImage && ( | ||
<MediaPlaceholder | ||
labels={labels} | ||
onSelect={onSelect} | ||
accept="image" | ||
multiple={false} | ||
disableMediaButtons={imageUrl} | ||
/> | ||
)} | ||
</> | ||
); | ||
}; | ||
|
||
Media.defaultProps = { | ||
style: {}, | ||
}; | ||
|
||
Media.propTypes = { | ||
style: PropTypes.object, | ||
}; |
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
Oops, something went wrong.
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.
Would this also work as a singling if the image tag?
I'd love to not add an additional div around the image :)
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.
@fabiankaegy Think this is where I got confused and am not sure I'm following 😆. Apologies! So, the
Figure
component already had thefigure
wrapper before the change:I basically just swapped it for a styled component that also renders a figure.
Should there not be other conditional log in the main component? Or am I missing something completely.
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.
@ncoetzer Okay I may have misunderstood the code then.
What I was trying to get at is that the end markup should look like this:
and not:
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.
@fabiankaegy Aah okay cool. In that case, yes, that is how it currently works and outputs the code.

However, for any existing instances of this component, it would also wrap their
<img>
tags inside a<figure>
, which is a breaking change if I understood things correctly. So, I'm thinking of changing the logic in the main component to conditionally check if inline controls are needed, and if so, wrap the<img>
in a<figure>
. Otherwise, it will just output the<img>
directly as it currently does. We could do this with any other feature placed behind a flag as well.Of course, this new API also accommodates creating custom
children
, so the user would be able to override anything we have with anything they need.Thoughts?