-
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
ResponsiveWrapper: Convert to TypeScript #46480
Changes from 6 commits
ee1db92
11d3384
52aa7ba
2e6ba93
b4e56a3
0c0f654
b879fdd
d47f17c
a70bf32
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 |
---|---|---|
|
@@ -9,20 +9,41 @@ import classnames from 'classnames'; | |
import { cloneElement, Children } from '@wordpress/element'; | ||
import { useResizeObserver } from '@wordpress/compose'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import type { ResponsiveWrapperProps } from './types'; | ||
|
||
/** | ||
* A wrapper component that maintains its aspect ratio when resized. | ||
* | ||
* ```jsx | ||
* import { ResponsiveWrapper } from '@wordpress/components'; | ||
* | ||
* const MyResponsiveWrapper = () => ( | ||
* <ResponsiveWrapper naturalWidth={ 2000 } naturalHeight={ 680 }> | ||
* <img | ||
* src="https://s.w.org/style/images/about/WordPress-logotype-standard.png" | ||
* alt="WordPress" | ||
* /> | ||
* </ResponsiveWrapper> | ||
* ); | ||
* ``` | ||
*/ | ||
function ResponsiveWrapper( { | ||
naturalWidth, | ||
naturalHeight, | ||
children, | ||
isInline = false, | ||
} ) { | ||
}: ResponsiveWrapperProps ) { | ||
const [ containerResizeListener, { width: containerWidth } ] = | ||
useResizeObserver(); | ||
if ( Children.count( children ) !== 1 ) { | ||
return null; | ||
} | ||
const imageStyle = { | ||
paddingBottom: | ||
naturalWidth < containerWidth | ||
naturalWidth < ( containerWidth ?? 0 ) | ||
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. TS was not happy because My code change here just makes explicit what was happening implicitly — a 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. Excellent explanation, saved a bunch of time on my end and will make it clear for anyone looking into the reasons behind this code change. Thank you! |
||
? naturalHeight | ||
: ( naturalHeight / naturalWidth ) * 100 + '%', | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import type { ComponentMeta, ComponentStory } from '@storybook/react'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import ResponsiveWrapper from '..'; | ||
|
||
const meta: ComponentMeta< typeof ResponsiveWrapper > = { | ||
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. Should we hide |
||
component: ResponsiveWrapper, | ||
title: 'Components/ResponsiveWrapper', | ||
parameters: { | ||
controls: { expanded: true }, | ||
docs: { source: { state: 'open' } }, | ||
}, | ||
}; | ||
export default meta; | ||
|
||
const Template: ComponentStory< typeof ResponsiveWrapper > = ( args ) => ( | ||
<ResponsiveWrapper { ...args } /> | ||
); | ||
|
||
export const Default = Template.bind( {} ); | ||
Default.args = { | ||
naturalWidth: 2000, | ||
naturalHeight: 680, | ||
children: ( | ||
<img | ||
src="https://s.w.org/style/images/about/WordPress-logotype-standard.png" | ||
alt="WordPress" | ||
/> | ||
), | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
export type ResponsiveWrapperProps = { | ||
/** | ||
* The intrinsic width of the element to wrap. Will be used to determine the aspect ratio. | ||
*/ | ||
naturalWidth: number; | ||
/** | ||
* The intrinsic height of the element to wrap. Will be used to determine the aspect ratio. | ||
*/ | ||
naturalHeight: number; | ||
/** | ||
* The element to wrap. | ||
*/ | ||
children: React.ReactElement; | ||
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. The choice of |
||
/** | ||
* If true, the wrapper will be `span` instead of `div`. | ||
* | ||
* @default false | ||
*/ | ||
isInline?: boolean; | ||
}; |
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.
May need repositioning after the last package release