import React, { Component, HTMLAttributes } from 'react';
import PopoutWrapper from '../PopoutWrapper/PopoutWrapper';
import { transitionEvent } from '../../lib/supportEvents';
import { withPlatform } from '../../hoc/withPlatform';
import { withAdaptivity, AdaptivityProps, ViewWidth, ViewHeight } from '../../hoc/withAdaptivity';
import { HasPlatform } from '../../types';
import { ANDROID, IOS, VKCOM } from '../../lib/platform';
import ActionSheetDropdownDesktop from './ActionSheetDropdownDesktop';
import ActionSheetDropdown from './ActionSheetDropdown';
import { hasReactNode } from '../../lib/utils';
import { ActionSheetContext, ItemClickHandler } from './ActionSheetContext';
import Caption from '../Typography/Caption/Caption';
export interface ActionSheetProps extends HTMLAttributes, HasPlatform, AdaptivityProps {
header?: React.ReactNode;
text?: React.ReactNode;
onClose?: VoidFunction;
/**
* Desktop only
*/
toggleRef: Element;
/**
* Desktop only
*/
popupDirection?: 'top' | 'bottom';
/**
* iOS only
*/
iosCloseItem: React.ReactNode;
}
export interface ActionSheetState {
closing: boolean;
}
export type CloseCallback = () => void;
export type AnimationEndCallback = (e?: AnimationEvent) => void;
class ActionSheet extends Component {
constructor(props: ActionSheetProps) {
super(props);
this.elRef = React.createRef();
}
state: ActionSheetState = {
closing: false,
};
elRef: React.RefObject;
private transitionFinishTimeout: ReturnType;
static defaultProps: Partial = {
popupDirection: 'bottom',
};
onClose: CloseCallback = () => {
this.setState({ closing: true });
this.waitTransitionFinish(this.props.onClose);
};
onItemClick: ItemClickHandler = (action, autoclose) => (event) => {
event.persist();
if (autoclose) {
this.setState({ closing: true });
this.waitTransitionFinish(() => {
this.props.onClose();
action && action(event);
});
} else {
action && action(event);
}
};
get isDesktop() {
const { viewWidth, viewHeight, hasMouse } = this.props;
return viewWidth >= ViewWidth.SMALL_TABLET && (hasMouse || viewHeight >= ViewHeight.MEDIUM);
}
waitTransitionFinish(eventHandler: AnimationEndCallback) {
if (this.isDesktop) {
eventHandler();
}
if (transitionEvent.supported) {
this.elRef.current.removeEventListener(transitionEvent.name, eventHandler);
this.elRef.current.addEventListener(transitionEvent.name, eventHandler);
} else {
clearTimeout(this.transitionFinishTimeout);
this.transitionFinishTimeout = setTimeout(eventHandler, this.props.platform === ANDROID || this.props.platform === VKCOM ? 200 : 300);
}
}
render() {
const {
children,
className,
header,
text,
style,
platform,
viewWidth,
viewHeight,
hasMouse,
iosCloseItem,
...restProps
} = this.props;
const isDesktop = this.isDesktop;
const DropdownComponent = isDesktop
? ActionSheetDropdownDesktop
: ActionSheetDropdown;
return (
{(hasReactNode(header) || hasReactNode(text)) &&
{hasReactNode(header) &&
{header}
}
{hasReactNode(text) && {text}}
}
{children}
{platform === IOS && !isDesktop && iosCloseItem}
);
}
}
export default withAdaptivity(withPlatform(ActionSheet), {
viewWidth: true,
viewHeight: true,
hasMouse: true,
});