wix-style-react
Version:
230 lines (199 loc) • 5.76 kB
JavaScript
import React from 'react';
import PropTypes from 'prop-types';
import Input from '../Input';
import { classes } from './ListItemEditable.st.css';
import { dataHooks } from './constants';
import IconButton from '../IconButton';
import Tooltip from '../Tooltip';
import Box from '../Box';
import { Check, X } from 'wix-ui-icons-common';
import { TooltipCommonProps } from '../common/PropTypes/TooltipCommon';
/** ListItemEditable */
class ListItemEditable extends React.PureComponent {
state = {
value: '',
};
/**
* Callback triggered when input value is changed
* @param event (Event)
* @private
*/
_onInputChange = event => {
this.setState({ value: event.target.value });
};
/**
* Callback triggered when approved button is clicked
* @private
*/
_onApproveClicked = () => {
const { value } = this.state;
const { onApprove } = this.props;
onApprove(value);
};
_renderInput = () => {
const { value } = this.state;
const { placeholder, status, size, statusMessage } = this.props;
return (
<Box marginRight={3} flex={1} minWidth={0}>
<Input
dataHook={dataHooks.input}
className={classes.input}
size={size}
status={status}
value={value}
statusMessage={statusMessage}
onChange={this._onInputChange}
placeholder={placeholder}
/>
</Box>
);
};
_renderCancelButton = () => {
const {
onCancel,
cancelButtonTooltipContent,
cancelButtonTooltipProps,
size,
} = this.props;
return (
<Box marginRight={2}>
<Tooltip
{...cancelButtonTooltipProps}
dataHook={dataHooks.cancelButtonTooltip}
disabled={!cancelButtonTooltipContent}
content={cancelButtonTooltipContent}
>
<IconButton
dataHook={dataHooks.cancelButton}
size={size}
priority="secondary"
onClick={onCancel}
children={<X />}
/>
</Tooltip>
</Box>
);
};
_renderApproveButton = () => {
const { value } = this.state;
const {
approveButtonTooltipContent,
approveButtonTooltipProps,
size,
} = this.props;
return (
<Tooltip
{...approveButtonTooltipProps}
dataHook={dataHooks.approveButtonTooltip}
disabled={!approveButtonTooltipContent || !this.state.value}
content={approveButtonTooltipContent}
>
<IconButton
size={size}
disabled={!value}
onClick={this._onApproveClicked}
dataHook={dataHooks.approveButton}
>
<Check />
</IconButton>
</Tooltip>
);
};
render() {
const { dataHook, className, margins } = this.props;
return (
<Box
dataHook={dataHook}
className={className}
margin={margins === 'list-item' && '3px 24px'}
>
{/* Input */}
{this._renderInput()}
{/* Buttons */}
{this._renderCancelButton()}
{this._renderApproveButton()}
</Box>
);
}
}
export const listItemEditableBuilder = ({
id,
dataHook,
className,
size,
placeholder,
onApprove,
onCancel,
cancelButtonTooltipContent,
cancelButtonTooltipProps,
approveButtonTooltipContent,
approveButtonTooltipProps,
status,
statusMessage,
margins,
}) => ({
id,
disabled: true,
overrideOptionStyle: true,
value: props => (
<ListItemEditable
{...props}
dataHook={dataHook}
className={className}
size={size}
placeholder={placeholder}
onApprove={onApprove}
onCancel={onCancel}
cancelButtonTooltipContent={cancelButtonTooltipContent}
cancelButtonTooltipProps={cancelButtonTooltipProps}
approveButtonTooltipContent={approveButtonTooltipContent}
approveButtonTooltipProps={approveButtonTooltipProps}
status={status}
statusMessage={statusMessage}
margins={margins}
/>
),
});
ListItemEditable.displayName = 'ListItemEditable';
ListItemEditable.propTypes = {
/** Applied as data-hook HTML attribute that can be used in the tests */
dataHook: PropTypes.string,
/** A css class to be applied to the component's root element */
className: PropTypes.string,
/** Placeholder to display */
placeholder: PropTypes.string,
/**
* A callback function triggered by clicking the approve button.
* ##### Signature:
* function(value: string) => void
* * `value`: the text contained in the input.
*/
onApprove: PropTypes.func.isRequired,
/**
* A callback function triggered by clicking the cancel button.
* ##### Signature:
* function() => void
*/
onCancel: PropTypes.func.isRequired,
/** Cancel button tooltip content */
cancelButtonTooltipContent: PropTypes.node,
/** Cancel button tooltip common props */
cancelButtonTooltipProps: PropTypes.shape(TooltipCommonProps),
/** Input status - use to display an status indication for the user */
status: PropTypes.oneOf(['error', 'warning', 'loading']),
/** Specifies the size of the input */
size: PropTypes.oneOf(['small', 'medium']),
/** Approve button tooltip content */
approveButtonTooltipContent: PropTypes.node,
/** Approve button tooltip common props */
approveButtonTooltipProps: PropTypes.shape(TooltipCommonProps),
/** The status (error/loading) message to display when hovering the status icon, if not given or empty there will be no tooltip */
statusMessage: PropTypes.node,
/** The type of margin */
margins: PropTypes.oneOf(['list-item', 'none']),
};
ListItemEditable.defaultProps = {
size: 'small',
margins: 'list-item',
};
export default ListItemEditable;