Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import React, { Component } from 'react';
import React from 'react';

import { RenderWithEuiStylesMemoizer } from '../../../services';
import { DistributiveOmit } from '../../common';
Expand Down Expand Up @@ -53,130 +53,135 @@ export interface EuiFormControlLayoutIconsProps {
isDisabled?: boolean;
}

export class EuiFormControlLayoutIcons extends Component<EuiFormControlLayoutIconsProps> {
render() {
const {
side = 'left',
iconsPosition = 'absolute',
compressed,
isDisabled,
} = this.props;

const customIcon = this.renderCustomIcon();
const loadingSpinner = this.renderLoadingSpinner();
const clearButton = this.renderClearButton();
const invalidIcon = this.renderInvalidIcon();
const dropdownIcon = this.renderDropdownIcon();

return (
<RenderWithEuiStylesMemoizer>
{(stylesMemoizer) => {
const styles = stylesMemoizer(euiFormControlLayoutIconsStyles);
const cssStyles = [
styles.euiFormControlLayoutIcons,
compressed ? styles.compressed : styles.uncompressed,
...(iconsPosition === 'absolute'
? [
styles.position.absolute.absolute,
compressed
? styles.position.absolute.compressed[side]
: styles.position.absolute.uncompressed[side],
]
: [
styles.position.static.static,
compressed
? styles.position.static.compressed
: styles.position.static.uncompressed,
]),
isDisabled && styles.disabled,
];
return (
<div css={cssStyles} className="euiFormControlLayoutIcons">
{clearButton}
{loadingSpinner}
{invalidIcon}
{customIcon}
{dropdownIcon}
</div>
);
}}
</RenderWithEuiStylesMemoizer>
);
}
export const EuiFormControlLayoutIcons = ({
side = 'left',
iconsPosition = 'absolute',
compressed,
isDisabled,
icon,
clear,
isLoading,
isInvalid,
isDropdown,
}: EuiFormControlLayoutIconsProps) => {
const customIcon = renderCustomIcon(icon, isDisabled);
const loadingSpinner = renderLoadingSpinner(isLoading);
const clearButton = renderClearButton(clear, isDisabled);
const invalidIcon = renderInvalidIcon(isInvalid);
const dropdownIcon = renderDropdownIcon(isDropdown, isDisabled);

return (
<RenderWithEuiStylesMemoizer>
{(stylesMemoizer) => {
const styles = stylesMemoizer(euiFormControlLayoutIconsStyles);
const cssStyles = [
styles.euiFormControlLayoutIcons,
compressed ? styles.compressed : styles.uncompressed,
...(iconsPosition === 'absolute'
? [
styles.position.absolute.absolute,
compressed
? styles.position.absolute.compressed[side]
: styles.position.absolute.uncompressed[side],
]
: [
styles.position.static.static,
compressed
? styles.position.static.compressed
: styles.position.static.uncompressed,
]),
isDisabled && styles.disabled,
];
return (
<div css={cssStyles} className="euiFormControlLayoutIcons">
{clearButton}
{loadingSpinner}
{invalidIcon}
{customIcon}
{dropdownIcon}
</div>
);
}}
</RenderWithEuiStylesMemoizer>
);
};

renderCustomIcon() {
const { icon, isDisabled } = this.props;

if (!icon) {
return null;
}

// Normalize the icon to an object if it's a string.
const iconProps: IconShape = isIconShape(icon)
? icon
: {
type: icon,
};
const { ref: iconRef, side, ...iconRest } = iconProps;

return (
<EuiFormControlLayoutCustomIcon
size="m"
disabled={isDisabled}
iconRef={iconRef}
{...iconRest}
/>
);
const renderCustomIcon = (
icon: EuiFormControlLayoutIconsProps['icon'],
isDisabled: EuiFormControlLayoutIconsProps['isDisabled']
) => {
if (!icon) {
return null;
}

renderDropdownIcon() {
const { isDropdown, isDisabled } = this.props;

if (!isDropdown) {
return null;
}
// Normalize the icon to an object if it's a string.
const iconProps: IconShape = isIconShape(icon)
? icon
: {
type: icon,
};
const { ref: iconRef, side, ...iconRest } = iconProps;

return (
<EuiFormControlLayoutCustomIcon
size="m"
disabled={isDisabled}
iconRef={iconRef}
{...iconRest}
/>
);
};
Comment on lines +109 to +133
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@toffku It's absolutely okay for the purposes of the class to function migration to simply raise these render functions to module level and call it a day. But a more idiomatic approach here would be to make them into components.

E.g.

Suggested change
const renderCustomIcon = (
icon: EuiFormControlLayoutIconsProps['icon'],
isDisabled: EuiFormControlLayoutIconsProps['isDisabled']
) => {
if (!icon) {
return null;
}
renderDropdownIcon() {
const { isDropdown, isDisabled } = this.props;
if (!isDropdown) {
return null;
}
// Normalize the icon to an object if it's a string.
const iconProps: IconShape = isIconShape(icon)
? icon
: {
type: icon,
};
const { ref: iconRef, side, ...iconRest } = iconProps;
return (
<EuiFormControlLayoutCustomIcon
size="m"
disabled={isDisabled}
iconRef={iconRef}
{...iconRest}
/>
);
};
const CustomIcon = ({ icon, isDisabled }: {
icon: EuiFormControlLayoutIconsProps['icon'],
isDisabled: EuiFormControlLayoutIconsProps['isDisabled']
}) => {
if (!icon) return null;
// Normalize the icon to an object if it's a string.
const iconProps: IconShape = isIconShape(icon)
? icon
: { type: icon };
const { ref: iconRef, side, ...iconRest } = iconProps;
return (
<EuiFormControlLayoutCustomIcon
size="m"
disabled={isDisabled}
iconRef={iconRef}
{...iconRest}
/>
);
};

and then in EuiFormControlLayoutIcons render: <CustomIcon icon={icon} isDisabled={isDisabled} />


return (
<EuiFormControlLayoutCustomIcon
size="m"
disabled={isDisabled}
type="chevronSingleDown"
/>
);
const renderDropdownIcon = (
isDropdown: EuiFormControlLayoutIconsProps['isDropdown'],
isDisabled: EuiFormControlLayoutIconsProps['isDisabled']
) => {
if (!isDropdown) {
return null;
}

renderLoadingSpinner() {
const { isLoading } = this.props;

if (!isLoading) {
return null;
}
return (
<EuiFormControlLayoutCustomIcon
size="m"
disabled={isDisabled}
type="chevronSingleDown"
/>
);
};

return <EuiLoadingSpinner size="m" />;
const renderLoadingSpinner = (
isLoading: EuiFormControlLayoutIconsProps['isLoading']
) => {
if (!isLoading) {
return null;
}

renderClearButton() {
const { clear, isDisabled } = this.props;
if (!clear) {
return null;
}

return (
<EuiFormControlLayoutClearButton
size="m"
disabled={isDisabled}
{...clear}
/>
);
}
return <EuiLoadingSpinner size="m" />;
};

renderInvalidIcon() {
const { isInvalid } = this.props;
const renderClearButton = (
clear: EuiFormControlLayoutIconsProps['clear'],
isDisabled: EuiFormControlLayoutIconsProps['isDisabled']
) => {
if (!clear) {
return null;
}

if (!isInvalid) {
return null;
}
return (
<EuiFormControlLayoutClearButton
size="m"
disabled={isDisabled}
{...clear}
/>
);
};

return <EuiIcon size="m" color="danger" type="warning" />;
const renderInvalidIcon = (
isInvalid: EuiFormControlLayoutIconsProps['isInvalid']
) => {
if (!isInvalid) {
return null;
}
}

return <EuiIcon size="m" color="danger" type="warning" />;
};