Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions packages/react-core/src/components/TextInput/TextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import * as React from 'react';
import styles from '@patternfly/react-styles/css/components/FormControl/form-control';
import { css } from '@patternfly/react-styles';
import { ValidatedOptions } from '../../helpers/constants';
import { debounce, trimLeft, canUseDOM } from '../../helpers/util';
import { trimLeft } from '../../helpers/util';
import { getDefaultOUIAId, getOUIAProps, OUIAProps } from '../../helpers';
import { getResizeObserver } from '../../helpers/resizeObserver';

export enum TextInputTypes {
text = 'text',
Expand Down Expand Up @@ -89,6 +90,7 @@ export class TextInputBase extends React.Component<TextInputProps, TextInputStat
ouiaSafe: true
};
inputRef = React.createRef<HTMLInputElement>();
observer: any = () => {};

constructor(props: TextInputProps) {
super(props);
Expand All @@ -109,18 +111,15 @@ export class TextInputBase extends React.Component<TextInputProps, TextInputStat

componentDidMount() {
if (this.props.isLeftTruncated) {
const inputRef = this.props.innerRef || this.inputRef;
this.observer = getResizeObserver(inputRef.current, this.handleResize);
this.handleResize();
if (canUseDOM) {
window.addEventListener('resize', debounce(this.handleResize, 250));
}
}
}

componentWillUnmount() {
if (this.props.isLeftTruncated) {
if (canUseDOM) {
window.removeEventListener('resize', debounce(this.handleResize, 250));
}
this.observer();
}
}

Expand Down
91 changes: 91 additions & 0 deletions packages/react-core/src/helpers/resizeObserver.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import * as React from 'react';
import { canUseDOM } from './util';

/**
* This function creates a ResizeObserver used to handle resize events for the given containerRef. If ResizeObserver
* or the given containerRef are not available, a window resize event listener is used by default.
*
* Example 1:
*
* private containerRef = React.createRef<HTMLDivElement>();
* private observer: any = () => {};
*
* public componentDidMount() {
* this.observer = getResizeObserver(this.containerRef.current, this.handleResize);
* }
*
* public componentWillUnmount() {
* this.observer();
* }
*
* private handleResize = () => {
* if (this.containerRef.current && this.containerRef.current.clientWidth) {
* this.setState({ width: this.containerRef.current.clientWidth });
* }
* };
*
* public render() {
* return (
* <div ref={this.containerRef} >
* <Chart width={this.state.width} ... />
* </div>
* );
* }
*
* Example 2:
*
* private inputRef = React.createRef<HTMLInputElement>();
* private observer: any = () => {};
*
* public componentDidMount() {
* this.observer = getResizeObserver(this.inputRef.current, this.handleResize);
* }
*
* public componentWillUnmount() {
* this.observer();
* }
*
* private handleResize = () => {
* if (this.inputRef.current) {
* trimLeft(inputRef.current, String(this.props.value));
* }
* };
*
* public render() {
* return (
* <input ref={this.inputRef} ... />
* );
* }
*
* @param {React.RefObject} containerRef The container reference to observe
* @param {Function} handleResize The function to call for resize events
* @return {Function} The function used to unobserve resize events
*/
export const getResizeObserver = (containerRef: React.RefObject<any>, handleResize: () => void) => {
let unobserve: any;

if (canUseDOM) {
const { ResizeObserver } = window as any;

if (containerRef && ResizeObserver) {
const resizeObserver = new ResizeObserver((entries: any) => {
// Wrap resize function in requestAnimationFrame to avoid "ResizeObserver loop limit exceeded" errors
window.requestAnimationFrame(() => {
if (Array.isArray(entries) && entries.length > 0) {
handleResize();
}
});
});
resizeObserver.observe(containerRef);
unobserve = () => resizeObserver.unobserve(containerRef);
} else {
window.addEventListener('resize', handleResize);
unobserve = () => window.removeEventListener('resize', handleResize);
}
}
return () => {
if (unobserve) {
unobserve();
}
};
};