-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
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
[TextareaAutosize] Convert code to TypeScript #35862
Changes from 13 commits
6d41eb0
2fce294
360804a
f646861
a1d4ccf
7f4df48
9f58cf1
9dd9d7a
664e49c
fba5039
2282019
32a77ec
beb368e
2b32d3b
dfd1cea
c994e23
14fd717
cb83064
52531d2
b734b86
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 |
---|---|---|
|
@@ -7,12 +7,29 @@ import { | |
unstable_useEnhancedEffect as useEnhancedEffect, | ||
unstable_ownerWindow as ownerWindow, | ||
} from '@mui/utils'; | ||
import { KebabKeys } from '@mui/types'; | ||
import { TextareaAutosizeProps } from './TextareaAutosize.types'; | ||
|
||
function getStyleValue(computedStyle, property) { | ||
return parseInt(computedStyle[property], 10) || 0; | ||
type State = | ||
| { | ||
outerHeightStyle?: undefined; | ||
overflow?: undefined; | ||
} | ||
| { | ||
outerHeightStyle: number; | ||
overflow: boolean | undefined; | ||
}; | ||
|
||
function getStyleValue( | ||
computedStyle: KebabKeys<CSSStyleDeclaration>, | ||
property: keyof KebabKeys<CSSStyleDeclaration>, | ||
) { | ||
return parseInt(`${computedStyle[property]}`, 10) || 0; | ||
} | ||
|
||
const styles = { | ||
const styles: { | ||
shadow: React.CSSProperties; | ||
} = { | ||
shadow: { | ||
// Visibility needed to hide the extra text area on iPads | ||
visibility: 'hidden', | ||
|
@@ -28,31 +45,53 @@ const styles = { | |
}, | ||
}; | ||
|
||
function isEmpty(obj) { | ||
function isEmpty(obj: State) { | ||
return obj === undefined || obj === null || Object.keys(obj).length === 0; | ||
} | ||
|
||
const TextareaAutosize = React.forwardRef(function TextareaAutosize(props, ref) { | ||
/** | ||
* | ||
* Demos: | ||
* | ||
* - [Textarea Autosize](https://mui.com/base/react-textarea-autosize/) | ||
* - [Textarea Autosize](https://mui.com/material-ui/react-textarea-autosize/) | ||
* | ||
* API: | ||
* | ||
* - [TextareaAutosize API](https://mui.com/base/api/textarea-autosize/) | ||
*/ | ||
const TextareaAutosize = React.forwardRef(function TextareaAutosize( | ||
props: TextareaAutosizeProps, | ||
ref: React.ForwardedRef<Element>, | ||
) { | ||
const { onChange, maxRows, minRows = 1, style, value, ...other } = props; | ||
|
||
const { current: isControlled } = React.useRef(value != null); | ||
const inputRef = React.useRef(null); | ||
const inputRef = React.useRef<HTMLInputElement>(null); | ||
const handleRef = useForkRef(ref, inputRef); | ||
const shadowRef = React.useRef(null); | ||
const shadowRef = React.useRef<HTMLTextAreaElement>(null); | ||
const renders = React.useRef(0); | ||
const [state, setState] = React.useState({}); | ||
const [state, setState] = React.useState<State>({}); | ||
|
||
const getUpdatedState = React.useCallback(() => { | ||
const input = inputRef.current; | ||
if (!input) { | ||
return {}; | ||
} | ||
oliviertassinari marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const containerWindow = ownerWindow(input); | ||
const computedStyle = containerWindow.getComputedStyle(input); | ||
const computedStyle = containerWindow.getComputedStyle( | ||
input, | ||
) as unknown as KebabKeys<CSSStyleDeclaration>; | ||
|
||
// If input's width is shrunk and it's not visible, don't sync height. | ||
if (computedStyle.width === '0px') { | ||
return {}; | ||
} | ||
|
||
const inputShallow = shadowRef.current; | ||
if (!inputShallow) { | ||
return {}; | ||
} | ||
oliviertassinari marked this conversation as resolved.
Show resolved
Hide resolved
|
||
inputShallow.style.width = computedStyle.width; | ||
inputShallow.value = input.value || props.placeholder || 'x'; | ||
if (inputShallow.value.slice(-1) === '\n') { | ||
|
@@ -94,8 +133,8 @@ const TextareaAutosize = React.forwardRef(function TextareaAutosize(props, ref) | |
return { outerHeightStyle, overflow }; | ||
}, [maxRows, minRows, props.placeholder]); | ||
|
||
const updateState = (prevState, newState) => { | ||
const { outerHeightStyle, overflow } = newState; | ||
const updateState = (prevState: State, newState: State) => { | ||
const { outerHeightStyle = 0, overflow } = newState; | ||
oliviertassinari marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Need a large enough difference to update the height. | ||
// This prevents infinite rendering loop. | ||
if ( | ||
|
@@ -164,18 +203,23 @@ const TextareaAutosize = React.forwardRef(function TextareaAutosize(props, ref) | |
syncHeightWithFlushSycn(); | ||
} | ||
}); | ||
const containerWindow = ownerWindow(inputRef.current); | ||
containerWindow.addEventListener('resize', handleResize); | ||
let resizeObserver; | ||
|
||
if (typeof ResizeObserver !== 'undefined') { | ||
resizeObserver = new ResizeObserver(handleResize); | ||
resizeObserver.observe(inputRef.current); | ||
let resizeObserver: ResizeObserver; | ||
let containerWindow: Window; | ||
if (inputRef.current) { | ||
containerWindow = ownerWindow(inputRef.current); | ||
containerWindow.addEventListener('resize', handleResize); | ||
|
||
if (typeof ResizeObserver !== 'undefined') { | ||
resizeObserver = new ResizeObserver(handleResize); | ||
resizeObserver.observe(inputRef.current); | ||
} | ||
} | ||
|
||
return () => { | ||
handleResize.clear(); | ||
containerWindow.removeEventListener('resize', handleResize); | ||
if (containerWindow) { | ||
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 would be in favor of removing all the defensive checks. e.g. this one and 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. 👍 We haven't seen any bug reports related to not having these checks in the JS version, so it's safe to skip them here as well. @sai6855 would you mind correcting this? The rest of the PR looks fine to me. 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. done, removed defensive checks , commit: cb83064 . cc @michaldudak |
||
containerWindow.removeEventListener('resize', handleResize); | ||
} | ||
if (resizeObserver) { | ||
resizeObserver.disconnect(); | ||
} | ||
|
@@ -190,7 +234,7 @@ const TextareaAutosize = React.forwardRef(function TextareaAutosize(props, ref) | |
renders.current = 0; | ||
}, [value]); | ||
|
||
const handleChange = (event) => { | ||
const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => { | ||
renders.current = 0; | ||
|
||
if (!isControlled) { | ||
|
@@ -209,12 +253,12 @@ const TextareaAutosize = React.forwardRef(function TextareaAutosize(props, ref) | |
onChange={handleChange} | ||
ref={handleRef} | ||
// Apply the rows prop to get a "correct" first SSR paint | ||
rows={minRows} | ||
rows={Number(minRows)} | ||
oliviertassinari marked this conversation as resolved.
Show resolved
Hide resolved
|
||
style={{ | ||
height: state.outerHeightStyle, | ||
// Need a large enough difference to allow scrolling. | ||
// This prevents infinite rendering loop. | ||
overflow: state.overflow ? 'hidden' : null, | ||
overflow: state.overflow ? 'hidden' : undefined, | ||
...style, | ||
}} | ||
{...other} | ||
|
@@ -238,7 +282,7 @@ const TextareaAutosize = React.forwardRef(function TextareaAutosize(props, ref) | |
TextareaAutosize.propTypes /* remove-proptypes */ = { | ||
// ----------------------------- Warning -------------------------------- | ||
// | These PropTypes are generated from the TypeScript type definitions | | ||
// | To update them edit the d.ts file and run "yarn proptypes" | | ||
// | To update them edit TypeScript types and run "yarn proptypes" | | ||
// ---------------------------------------------------------------------- | ||
/** | ||
* @ignore | ||
|
@@ -273,6 +317,6 @@ TextareaAutosize.propTypes /* remove-proptypes */ = { | |
PropTypes.number, | ||
PropTypes.string, | ||
]), | ||
}; | ||
} as any; | ||
|
||
export default TextareaAutosize; |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export { default } from './TextareaAutosize'; | ||
export * from './TextareaAutosize.types'; |
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.
'rootClass' is not present in
fullSuite
, hence removed to make typescript happy.material-ui/test/utils/describeConformanceUnstyled.tsx
Lines 321 to 332 in f13e534