import React from 'react'; /** * @fileOverview Redux Layer Actions * @namespace Actions/Layer */ /* !- React Elements */ import Modal from './modal'; import Preload from './preload'; import Menu from './menu'; /* !- Constants */ const extendPositions = ({ left, top, width, height }) => { const positions = { width, height, center: {}, screen: {} }; positions.left = left + window.pageXOffset; positions.top = top + window.pageYOffset; positions.center.x = positions.left + (positions.width / 2); positions.center.y = positions.top + (positions.height / 2); positions.screen.x = (positions.left - window.pageXOffset) / window.innerWidth; positions.screen.y = (positions.top - window.pageYOffset) / window.innerHeight; return positions; } const getPositionsElement = (target) => { if (!target) { return {}; } const rect = target.getBoundingClientRect(); return extendPositions(rect) }; const getDynamicPopoverStyle = (position) => { const style = {}; const { screen, left, top, center, width, height } = position; if (screen.x < 0.3) { style.left = left; style.transform = ''; } else if (screen.x > 0.7) { style.left = left + width; style.transform = 'translateX(-100%)'; } else { style.left = `${center.x}px`; style.transform = 'translateX(-50%)'; } if (screen.y > 0.6) { style.top = `${top - 6}px`; style.transform += ' translateY(-100%)'; } else { style.top = `${top + height + 6}px`; } return style; }; /** * Create and show dialog layer. * * @since 1.0.0 * @memberof Actions/Layer * @param {ReactElement} element Layer (dialog) content * @example * dialog(
This is a dialog content
); * @example * //=> options * { * } */ export const dialog = (element: React.Element, options = {}) => ({ type: 'SET_LAYER', active: true, method: 'dialog', element, options, containerStyle: options.containerStyle, }); /** * Create and show fullscreen layer. * * @since 1.0.0 * @memberof Actions/Layer * @param {ReactElement} element Layer (fullscreen) content * @example * fullscreen(
This is a fullscreen content
); */ export const fullscreen = (element: React.Element, options = {}) => ({ type: 'SET_LAYER', active: true, method: 'fullscreen', element, options, containerStyle: options.containerStyle, }); /** * Create and show sidebar layer. * * @since 1.0.0 * @memberof Actions/Layer * @param {ReactElement} element Layer (sidebar) content * @example * sidebar(
This is a sidebar content
); */ export const sidebar = (element: React.Element, options = {}) => ({ type: 'SET_LAYER', active: true, method: 'sidebar', element, containerStyle: options.containerStyle, options: { ...options, className: options.position || 'right', }, }); /** * Create and show popover layer. * * @since 1.0.0 * @memberof Actions/Layer * @param {ReactElement} element Layer (popover) content * @param {object} event * @param {object} options { className, containerStyle, useMousePosition } * @example * popover( * Hello, * event, * { * className: 'no-close', * containerStyle: { width: '400px' }, * useMousePosition: true, * }, * ); */ export const popover = (element: React.Element | string, event: {} = {}, options = {}) => { let containerStyle = options.containerStyle || {}; const target = event.currentTarget; if (target) { const position = options.useMousePosition ? extendPositions({ left: event.clientX + window.pageXOffset, top: event.clientY + window.pageYOffset, width: 0, height: 0, }) : getPositionsElement(target); containerStyle = { ...getDynamicPopoverStyle(position), ...containerStyle }; } // console.log(target); // // if (!options.style) // { // options.style = {}; // } // // options.style.pointerEvents = 'none'; // containerStyle.pointerEvents = 'auto'; return ({ type: 'SET_LAYER', active: true, method: 'popover', closeable: true, containerStyle, // if the element is a string then put in a wrapper element: React.isValidElement(element) ? element :
{element}
, options, }); }; /** * Create and show tooltip layer. * * @since 1.15.0 * @memberof Actions/Layer * @param {ReactElement} element Layer (tooltip) content * @param {object} event */ export const tooltip = (element: React.Element | string, event: {} = {}, options = {}) => { return ({ ...popover(element, event, options), closeable: false, options: { ...options, className: 'tooltip', } }); }; /** * Set the layer visible. * * @since 1.0.0 * @memberof Actions/Layer * @example * show(); * open(); */ export const show = () => ({ type: 'SET_LAYER_VISIBLE', active: true, }); /** * Set the layer invisible. * * @since 1.0.0 * @memberof Actions/Layer * @example * hide(); */ export const hide = () => ({ type: 'SET_LAYER_VISIBLE', active: false, }); /** * Toggle visibility of layer. * * @since 1.0.0 * @memberof Actions/Layer * @example * toggle(); */ export const toggle = () => ({ type: 'TOGGLE_LAYER', }); /** * Truncate layer state. * * @since 1.0.0 * @memberof Actions/Layer * @example * flush(); */ export const flush = () => ({ type: 'FLUSH_LAYER', }); /* !- Predefined actions */ /** * Modal is a predefined dialog layer. Do not use element, just Modal element props. * * @since 1.0.0 * @memberof Actions/Layer * @param {Object} [props={}] icon, title, content, button, buttonSecondary, className, * @example * modal(); */ export const modal = (props = {}, options = {}) => ({ type: 'SET_LAYER', active: true, method: 'dialog', element: , options, containerStyle: options.containerStyle, }); /** * Preloader layer * @since 1.0.0 * @memberof Actions/Layer * * @param {ReactElement} [element] change default element * @example * preload(
Loading...
) */ export const preload = (element: React.Element, event: React.MouseEvent) => { const target = event || React.isValidElement(element) ? null : element; let containerStyle = {}; if (target) { const { center } = getPositionsElement(target.target); containerStyle = { top: `${center.y}px`, left: `${center.x}px`, }; } return ({ type: 'SET_LAYER', active: true, method: 'preload', closeable: false, element: , // options: { className: 'preload' }, containerStyle, }); }; /** * Menu is a special popover * @param {Object} [props={}] { id, title, handler, icon } * @param {Event} event */ export const menu = (props = {}, event: React.MouseEvent | {} = {}, options = {}) => popover(, event, { ...options, className: 'no-padding no-close' }); export const contextMenu = (props = {}, event: React.MouseEvent | {} = {}, options = {}) => { event.preventDefault(); return menu(props, event, options); } /* !- Alias actions */ export const open = show; export const close = flush;