react#isValidElement JavaScript Examples

The following examples show how to use react#isValidElement. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: children-utilities.js    From react-dsfr with MIT License 7 votes vote down vote up
deepFilter = (children, deepFilterFn) => Children.toArray(children)
  .filter(deepFilterFn)
  .map((child) => {
    if (isValidElement(child) && hasComplexChildren(child)) {
      // Clone the child that has children and filter them too
      return cloneElement(child, {
        ...child.props,
        children: deepFilter(child.props.children, deepFilterFn),
      });
    }
    return child;
  })
Example #2
Source File: children-utilities.js    From react-dsfr with MIT License 7 votes vote down vote up
deepForEach = (children, deepForEachFn) => {
  Children.forEach(children, (child, index) => {
    if (isValidElement(child) && hasComplexChildren(child)) {
      // Each inside the child that has children
      deepForEach(child.props.children, deepForEachFn);
    }
    deepForEachFn(child, index);
  });
}
Example #3
Source File: utils.js    From hzero-front with Apache License 2.0 7 votes vote down vote up
export function getQueryFields(dataSet) {
  const {
    props: { queryFields },
  } = dataSet;
  const queryDataSet = dataSet.queryDataSet || dataSet.props.queryDataSet;
  const result = [];
  if (queryDataSet) {
    const fields = queryDataSet.fields || queryDataSet.props.fields;
    return [...fields.entries()].reduce((list, [name, field]) => {
      if (!field.get('bind')) {
        const props = {
          key: name,
          name,
          dataSet: queryDataSet,
        };
        const element = queryFields[name];
        list.push(
          isValidElement(element)
            ? cloneElement(element, props)
            : cloneElement(getEditorByField(field), {
                ...props,
                ...(isObject(element) ? element : {}),
              })
        );
      }
      return list;
    }, result);
  }
  return result;
}
Example #4
Source File: CardGrid.js    From HackShack-Session-Landing-Page with MIT License 6 votes vote down vote up
CardGrid = ({ children, size, ...rest }) => {
  const childrenWithProps = Children.map(children, child => {
    if (isValidElement(child)) {
      return cloneElement(child, { size });
    }

    return child;
  });
  return (
    <StyledGrid gap="large" {...rest}>
      {childrenWithProps}
    </StyledGrid>
  );
}
Example #5
Source File: Dropdown.jsx    From kube-design with MIT License 6 votes vote down vote up
render() {
    const { className, children, onClick, theme, ...restProps } = this.props;
    const isTriggerValid = isValidElement(children);

    return (
      <Popper
        {...restProps}
        type="dropdown"
        className={classNames("dropdown", `dropdown-${theme}`, className)}
        onClick={onClick}
      >
        {isTriggerValid ? (
          cloneElement(children, {
            className: classNames("is-trigger", children.props.className),
          })
        ) : (
          <span className="is-trigger">{children}</span>
        )}
      </Popper>
    );
  }
Example #6
Source File: full-tree.js    From next-layout with MIT License 6 votes vote down vote up
validateLayoutTree = (node) => {
    /* istanbul ignore if */
    if (process.env.NODE_ENV === 'production') {
        return;
    }

    if (!isValidElement(node)) {
        throw new TypeError('Only unary trees composed by react elements are supported as layouts');
    }

    if (node.props.children) {
        validateLayoutTree(node.props.children);
    }
}
Example #7
Source File: ChildMapping.js    From mern_docker_demo with MIT License 6 votes vote down vote up
/**
 * Given `this.props.children`, return an object mapping key to child.
 *
 * @param {*} children `this.props.children`
 * @return {object} Mapping of key to child
 */

export function getChildMapping(children, mapFn) {
  var mapper = function mapper(child) {
    return mapFn && isValidElement(child) ? mapFn(child) : child;
  };

  var result = Object.create(null);
  if (children) Children.map(children, function (c) {
    return c;
  }).forEach(function (child) {
    // run the map function here instead so that the key is the computed one
    result[child.key] = mapper(child);
  });
  return result;
}
Example #8
Source File: ChildMapping.js    From mern_docker_demo with MIT License 6 votes vote down vote up
export function getNextChildMapping(nextProps, prevChildMapping, onExited) {
  var nextChildMapping = getChildMapping(nextProps.children);
  var children = mergeChildMappings(prevChildMapping, nextChildMapping);
  Object.keys(children).forEach(function (key) {
    var child = children[key];
    if (!isValidElement(child)) return;
    var hasPrev = (key in prevChildMapping);
    var hasNext = (key in nextChildMapping);
    var prevChild = prevChildMapping[key];
    var isLeaving = isValidElement(prevChild) && !prevChild.props.in; // item is new (entering)

    if (hasNext && (!hasPrev || isLeaving)) {
      // console.log('entering', key)
      children[key] = cloneElement(child, {
        onExited: onExited.bind(null, child),
        in: true,
        exit: getProp(child, 'exit', nextProps),
        enter: getProp(child, 'enter', nextProps)
      });
    } else if (!hasNext && hasPrev && !isLeaving) {
      // item is old (exiting)
      // console.log('leaving', key)
      children[key] = cloneElement(child, {
        in: false
      });
    } else if (hasNext && hasPrev && isValidElement(prevChild)) {
      // item hasn't changed transition states
      // copy over the last transition props;
      // console.log('unchanged', key)
      children[key] = cloneElement(child, {
        onExited: onExited.bind(null, child),
        in: prevChild.props.in,
        exit: getProp(child, 'exit', nextProps),
        enter: getProp(child, 'enter', nextProps)
      });
    }
  });
  return children;
}
Example #9
Source File: key-value-pair-table.js    From ThreatMapper with Apache License 2.0 6 votes vote down vote up
renderObjects(data) {
    let rendered;
    // check if data is a valid JSX or React Element
    if(isValidElement(data)) {
      rendered = this.renderJSX(data);
    // check id JSX is embedded inside an array
    } else if (Array.isArray(data) && data.length > 0 && isValidElement(data[0])) {
      rendered = this.renderJSX(data);
    } else {
      rendered = this.getNestedValueView(data);
    }
    return rendered;
  }
Example #10
Source File: children-utilities.js    From react-dsfr with MIT License 6 votes vote down vote up
hasComplexChildren = (element) => isValidElement(element)
    && hasChildren(element)
    && Children.toArray(element.props.children)
      .reduce((response, child) => response || isValidElement(child), false)
Example #11
Source File: children-utilities.js    From react-dsfr with MIT License 6 votes vote down vote up
hasChildren = (element) => isValidElement(element) && Boolean(element.props.children)
Example #12
Source File: validators.js    From beautiful-react-diagrams with MIT License 6 votes vote down vote up
validateNode = (node) => {
  if (!node.id) {
    throw ERR.INVALID_ID();
  }

  if (!node.coordinates || (!Array.isArray(node.coordinates) || node.coordinates.length !== 2)) {
    throw ERR.INVALID_COORDS(node.id);
  }

  // eslint-disable-next-line max-len
  if (!!node.content && (typeof node.content !== 'string' && typeof node.content !== 'function' && !isValidElement(node.content))) {
    throw ERR.INVALID_CONTENT(node.id);
  }

  if (node.inputs) {
    if (!Array.isArray(node.inputs)) {
      throw ERR.INVALID_INPUTS_ARRAY(node.id);
    }

    node.inputs.forEach(validatePort);
  }

  if (node.outputs) {
    if (!Array.isArray(node.outputs)) {
      throw ERR.INVALID_INPUTS_ARRAY(node.id);
    }

    node.outputs.forEach(validatePort);
  }

  return true;
}
Example #13
Source File: index.js    From hzero-front with Apache License 2.0 6 votes vote down vote up
/**
   * 递归遍历 react 节点
   * @param {array} children - react node
   * @param {function} fn - 回调函数
   */
  @Bind()
  mapReactChildren(children, fn) {
    return React.Children.map(children, child => {
      if (!isValidElement(child)) {
        return child;
      }
      if (child.props.children) {
        // eslint-disable-next-line
        child = React.cloneElement(child, {
          children: this.mapReactChildren(child.props.children, fn),
        });
      }
      return fn(child);
    });
  }
Example #14
Source File: index.js    From discovery-mobile-ui with MIT License 6 votes vote down vote up
FilterDrawer = ({
  children,
}) => {
  const drawerRef = useRef(null);
  const handleOpenDrawer = () => {
    drawerRef.current.openDrawer();
  };

  const childrenWithProps = Children.map(children, (child) => {
    if (isValidElement(child)) {
      return cloneElement(child, { handleOpenDrawer });
    }
    return child;
  });

  return (
    <DrawerLayout
      ref={drawerRef}
      drawerWidth={wp('60%')}
      keyboardDismissMode="on-drag"
      drawerPosition={DrawerLayout.positions.Left}
      drawerType="front"
      drawerBackgroundColor="white"
      renderNavigationView={() => <RecordTypeFilters />}
      edgeWidth={-wp('100%')}
    >
      <View style={styles.childrenContainer}>
        {childrenWithProps}
      </View>
    </DrawerLayout>
  );
}
Example #15
Source File: wrapConnectorHooks.js    From the-eye-knows-the-garbage with MIT License 6 votes vote down vote up
function wrapHookToRecognizeElement(hook) {
  return function () {
    var elementOrNode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;

    // When passed a node, call the hook straight away.
    if (!isValidElement(elementOrNode)) {
      var node = elementOrNode;
      hook(node, options); // return the node so it can be chained (e.g. when within callback refs
      // <div ref={node => connectDragSource(connectDropTarget(node))}/>

      return node;
    } // If passed a ReactElement, clone it and attach this function as a ref.
    // This helps us achieve a neat API where user doesn't even know that refs
    // are being used under the hood.


    var element = elementOrNode;
    throwIfCompositeComponentElement(element); // When no options are passed, use the hook directly

    var ref = options ? function (node) {
      return hook(node, options);
    } : hook;
    return cloneWithRef(element, ref);
  };
}
Example #16
Source File: wrapConnectorHooks.js    From the-eye-knows-the-garbage with MIT License 6 votes vote down vote up
function wrapHookToRecognizeElement(hook) {
    return (elementOrNode = null, options = null) => {
        // When passed a node, call the hook straight away.
        if (!isValidElement(elementOrNode)) {
            const node = elementOrNode;
            hook(node, options);
            // return the node so it can be chained (e.g. when within callback refs
            // <div ref={node => connectDragSource(connectDropTarget(node))}/>
            return node;
        }
        // If passed a ReactElement, clone it and attach this function as a ref.
        // This helps us achieve a neat API where user doesn't even know that refs
        // are being used under the hood.
        const element = elementOrNode;
        throwIfCompositeComponentElement(element);
        // When no options are passed, use the hook directly
        const ref = options ? (node) => hook(node, options) : hook;
        return cloneWithRef(element, ref);
    };
}
Example #17
Source File: wrapConnectorHooks.js    From the-eye-knows-the-garbage with MIT License 6 votes vote down vote up
function wrapHookToRecognizeElement(hook) {
  return function () {
    var elementOrNode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;

    // When passed a node, call the hook straight away.
    if (!isValidElement(elementOrNode)) {
      var node = elementOrNode;
      hook(node, options); // return the node so it can be chained (e.g. when within callback refs
      // <div ref={node => connectDragSource(connectDropTarget(node))}/>

      return node;
    } // If passed a ReactElement, clone it and attach this function as a ref.
    // This helps us achieve a neat API where user doesn't even know that refs
    // are being used under the hood.


    var element = elementOrNode;
    throwIfCompositeComponentElement(element); // When no options are passed, use the hook directly

    var ref = options ? function (node) {
      return hook(node, options);
    } : hook;
    return cloneWithRef(element, ref);
  };
}
Example #18
Source File: wrapConnectorHooks.js    From the-eye-knows-the-garbage with MIT License 6 votes vote down vote up
function wrapHookToRecognizeElement(hook) {
    return (elementOrNode = null, options = null) => {
        // When passed a node, call the hook straight away.
        if (!isValidElement(elementOrNode)) {
            const node = elementOrNode;
            hook(node, options);
            // return the node so it can be chained (e.g. when within callback refs
            // <div ref={node => connectDragSource(connectDropTarget(node))}/>
            return node;
        }
        // If passed a ReactElement, clone it and attach this function as a ref.
        // This helps us achieve a neat API where user doesn't even know that refs
        // are being used under the hood.
        const element = elementOrNode;
        throwIfCompositeComponentElement(element);
        // When no options are passed, use the hook directly
        const ref = options ? (node) => hook(node, options) : hook;
        return cloneWithRef(element, ref);
    };
}
Example #19
Source File: use-children.js    From awesome-react-starter with MIT License 6 votes vote down vote up
useChildren = (children) => {
  const childrenArray = isArray(children) ? children : [children];
  const elements = flatten(childrenArray).filter(isValidElement);

  return Children.map(elements, ({ props }) => {
    const { value, children, ...rest } = props;
    return {
      value: value || children,
      label: children,
      ...rest,
    };
  }).filter(({ hidden }) => !hidden);
}
Example #20
Source File: recursiveMethods.js    From ra-compact-ui with MIT License 6 votes vote down vote up
cloneRecursively = (child, conditionFnc, renderFnc) => (
    child
        && isValidElement(child)
        ? recursivelyFindRealChildren(
            {
                child,
                renderFnc,
                conditionFnc,
            },
        )
        : null
)
Example #21
Source File: DropDown.jsx    From vertx-web-site.github.io with Apache License 2.0 5 votes vote down vote up
DropDown = (({ title, children, align = "left" }) => {
  const [visible, setVisible] = useState(false)

  useEffect(() => {
    function onDocumentClick() {
      if (visible) {
        setVisible(false)
      }
    }

    document.addEventListener("click", onDocumentClick)

    return () => {
      document.removeEventListener("click", onDocumentClick)
    }
  }, [visible])

  function onClick() {
    // Let the click propagate to the parent element first before we make
    // the drop down menu visible. This makes sure other drop down menus on the
    // page are closed. If we'd call setVisible without setTimeout here, our
    // menu would never be displayed because the onDocumentClick handler above
    // would just hide it again.
    setTimeout(() => {
      setVisible(!visible)
    }, 0)
  }

  let hasActive = false
  Children.forEach(children, c => {
    let active = isValidElement(c) && c.props !== undefined && c.props.active
    if (active) {
      hasActive = true
    }
  })

  let menuItems = children
  if (hasActive) {
    menuItems = Children.map(children, c => cloneElement(c, { hasActiveSiblings: true }))
  }

  return (
    <div className="dropdown">
      <a className="dropdown-title" onClick={onClick}>{title}<ChevronDown /></a>
      <ul className={classNames("dropdown-menu", { visible, "align-right": align === "right" })}>
        {menuItems}
      </ul>
      <style jsx>{styles}</style>
    </div>
  )
})
Example #22
Source File: index.js    From HackShack-Session-Landing-Page with MIT License 5 votes vote down vote up
Layout = ({ children, background }) => {
  const [layer, setLayer] = useState(false);
  const size = useContext(ResponsiveContext);

  const childrenWithProps = Children.map(children, child => {
    if (isValidElement(child)) {
      return cloneElement(child, { size });
    }

    return child;
  });
  return (
    <ResponsiveLayout
      background={{
        image: `url(${background})`,
        size: '100%',
        position: 'top center',
      }}
      justify="between"
      layer={layer}
    >
      <Box>
        <Header setLayer={setLayer} size={size} />
        <Box direction="row">
          {size !== 'small' && (
            <Box margin={{ top: 'xlarge', left: 'large' }}>
              <SideNav size={size} />
            </Box>
          )}
          <Box
            align={size !== 'small' ? 'start' : 'center'}
            fill="horizontal"
            direction="column"
            pad="xlarge"
          >
            {childrenWithProps}
          </Box>
        </Box>
      </Box>
      <Footer size={size} />
      {layer && (
        <StyledLayer>
          <Box pad={{ top: 'xlarge', right: 'large' }}>
            <Box
              direction="row"
              align="center"
              justify="end"
              margin={{ bottom: 'xlarge' }}
            >
              <Text color="#FFFFFF">CLOSE</Text>
              <Button icon={<Close />} onClick={() => setLayer(false)} />
            </Box>
            <Box align="start" gap="large" pad="xlarge">
              <SideNav size={size} />
            </Box>
          </Box>
        </StyledLayer>
      )}
    </ResponsiveLayout>
  );
}
Example #23
Source File: validator.js    From reoverlay with MIT License 5 votes vote down vote up
validate = (type, value) => {
  switch (type) {
    case VALIDATE.CONFIG: {
      if (!isArray(value)) {
        throw new Error(
          'Reoverlay: Config data is probably not a valid array. Make sure you pass a valid array to the config method'
        )
      }

      // Check if value containts objects with "name" and "component" properties
      value.forEach((item) => {
        if (!item.name || !item.component) {
          throw new Error(
            `Reoverlay: Make sure your config array contains objects with a 'name' and 'component' property.`
          )
        }
      })

      // Check if all "name" properties are unique
      const names = value.map((item) => item.name)
      if (!isArrayUnique(names))
        throw new Error('Reoverlay: Make sure your config array data is unique.')

      return true
    }

    case VALIDATE.SHOW_MODAL: {
      const throwError = () => {
        throw new Error(
          "Reoverlay: Method 'showModal' has one required argument. Please pass on a React Component, or a pre-configuered identifier string."
        )
      }

      if (!value) throwError()
      if (isString(value)) return 'string'
      if (isFunction(value) || isValidElement(value)) return 'component'

      throwError()

      break
    }

    case VALIDATE.HIDE_MODAL: {
      if (isString(value)) return true
      throw new Error(
        `Reoverlay: Method 'hideModal' has one optional argument. Expected a 'string', got a ${typeof value}`
      )
    }
    default:
      return false
  }
}
Example #24
Source File: childMapping.js    From smart-contracts with MIT License 5 votes vote down vote up
getChildMapping = function getChildMapping(children) {
  return _keyBy(_filter(Children.toArray(children), isValidElement), 'key');
}
Example #25
Source File: childMapping.js    From smart-contracts with MIT License 5 votes vote down vote up
getChildMapping = (children) =>
  _.keyBy(_.filter(Children.toArray(children), isValidElement), 'key')
Example #26
Source File: Modal.js    From smart-contracts with MIT License 5 votes vote down vote up
render() {
    const { centered, closeOnDocumentClick, dimmer, eventPool, trigger } = this.props
    const { open, scrolling } = this.state
    const mountNode = this.getMountNode()

    // Short circuit when server side rendering
    if (!isBrowser()) {
      return isValidElement(trigger) ? trigger : null
    }

    const unhandled = getUnhandledProps(Modal, this.props)
    const portalPropNames = Portal.handledProps

    const rest = _.reduce(
      unhandled,
      (acc, val, key) => {
        if (!_.includes(portalPropNames, key)) acc[key] = val

        return acc
      },
      {},
    )
    const portalProps = _.pick(unhandled, portalPropNames)

    // Heads up!
    //
    // The SUI CSS selector to prevent the modal itself from blurring requires an immediate .dimmer child:
    // .blurring.dimmed.dimmable>:not(.dimmer) { ... }
    //
    // The .blurring.dimmed.dimmable is the body, so that all body content inside is blurred.
    // We need the immediate child to be the dimmer to :not() blur the modal itself!
    // Otherwise, the portal div is also blurred, blurring the modal.
    //
    // We cannot them wrap the modalJSX in an actual <Dimmer /> instead, we apply the dimmer classes to the <Portal />.

    return (
      <Portal
        closeOnDocumentClick={closeOnDocumentClick}
        {...portalProps}
        trigger={trigger}
        eventPool={eventPool}
        mountNode={mountNode}
        open={open}
        onClose={this.handleClose}
        onMount={this.handlePortalMount}
        onOpen={this.handleOpen}
        onUnmount={this.handlePortalUnmount}
      >
        <Ref innerRef={this.dimmerRef}>
          {ModalDimmer.create(_.isPlainObject(dimmer) ? dimmer : {}, {
            autoGenerateKey: false,
            defaultProps: {
              blurring: dimmer === 'blurring',
              inverted: dimmer === 'inverted',
            },
            overrideProps: {
              children: this.renderContent(rest),
              centered,
              mountNode,
              scrolling,
            },
          })}
        </Ref>
      </Portal>
    )
  }
Example #27
Source File: Modal.js    From spring-boot-ecommerce with Apache License 2.0 5 votes vote down vote up
render() {
    const { open } = this.state
    const { centered, closeOnDocumentClick, dimmer, eventPool, trigger } = this.props
    const mountNode = this.getMountNode()

    // Short circuit when server side rendering
    if (!isBrowser()) {
      return isValidElement(trigger) ? trigger : null
    }

    const unhandled = getUnhandledProps(Modal, this.props)
    const portalPropNames = Portal.handledProps

    const rest = _.reduce(
      unhandled,
      (acc, val, key) => {
        if (!_.includes(portalPropNames, key)) acc[key] = val

        return acc
      },
      {},
    )
    const portalProps = _.pick(unhandled, portalPropNames)

    // wrap dimmer modals
    const dimmerClasses = cx(
      'ui',
      dimmer === 'inverted' && 'inverted',
      !centered && 'top aligned',
      'page modals dimmer transition visible active',
    )

    // Heads up!
    //
    // The SUI CSS selector to prevent the modal itself from blurring requires an immediate .dimmer child:
    // .blurring.dimmed.dimmable>:not(.dimmer) { ... }
    //
    // The .blurring.dimmed.dimmable is the body, so that all body content inside is blurred.
    // We need the immediate child to be the dimmer to :not() blur the modal itself!
    // Otherwise, the portal div is also blurred, blurring the modal.
    //
    // We cannot them wrap the modalJSX in an actual <Dimmer /> instead, we apply the dimmer classes to the <Portal />.

    return (
      <Portal
        closeOnDocumentClick={closeOnDocumentClick}
        {...portalProps}
        trigger={trigger}
        eventPool={eventPool}
        mountNode={mountNode}
        open={open}
        onClose={this.handleClose}
        onMount={this.handlePortalMount}
        onOpen={this.handleOpen}
        onUnmount={this.handlePortalUnmount}
      >
        <div className={dimmerClasses} ref={this.dimmerRef}>
          {this.renderContent(rest)}
        </div>
      </Portal>
    )
  }
Example #28
Source File: childMapping.js    From smart-contracts with MIT License 5 votes vote down vote up
getChildMapping = function getChildMapping(children) {
  return _keyBy(_filter(Children.toArray(children), isValidElement), 'key');
}
Example #29
Source File: header.js    From react-multi-date-picker with MIT License 4 votes vote down vote up
export default function Header({
  state,
  setState,
  disableYearPicker,
  disableMonthPicker,
  buttons,
  renderButton,
  handleMonthChange,
  disabled,
  hideMonth,
  hideYear,
  isRTL,
  fullYear,
  monthAndYears: [months, years],
}) {
  let style = {},
    {
      date,
      onlyMonthPicker,
      onlyYearPicker,
      mustShowYearPicker,
      minDate,
      maxDate,
      year,
      today,
    } = state,
    isPreviousDisable =
      minDate &&
      date.year <= minDate.year &&
      minDate.monthIndex > date.monthIndex - 1,
    isNextDisable =
      maxDate &&
      date.year >= maxDate.year &&
      maxDate.monthIndex < date.monthIndex + 1;

  let maxYear = today.year + 7;

  maxYear = maxYear - 12 * Math.floor((maxYear - year) / 12);

  if ((hideMonth || fullYear) && hideYear && !buttons) return null;

  if (
    (hideMonth && hideYear) ||
    (onlyYearPicker && hideYear) ||
    (buttons && hideYear)
  ) {
    style.minHeight = "36px";
  }

  if (onlyMonthPicker || fullYear) {
    if (minDate && minDate.year >= date.year) isPreviousDisable = true;
    if (maxDate && maxDate.year <= date.year) isNextDisable = true;
  }

  if (mustShowYearPicker || onlyYearPicker) {
    let minYear = maxYear - 11;

    isPreviousDisable = minDate && minDate.year > minYear;
    isNextDisable = maxDate && maxDate.year < maxYear;
  }

  if (disabled) {
    isPreviousDisable = true;
    isNextDisable = true;
  }

  return (
    <div className="rmdp-header">
      <div style={{ position: "relative", display: "flex" }}>
        {buttons && getButton("left")}
        {fullYear ? (
          <div className="rmdp-header-values" style={style}>
            {!hideYear && date.format("YYYY")}
          </div>
        ) : (
          months.map((month, index) => (
            <div key={index} className="rmdp-header-values" style={style}>
              {!hideMonth && (
                <span
                  style={{
                    cursor:
                      disabled || disableMonthPicker || onlyMonthPicker
                        ? "default"
                        : "pointer",
                  }}
                  onClick={() =>
                    !disableMonthPicker && toggle("mustShowMonthPicker")
                  }
                >
                  {month}
                  {!hideYear && (isRTL ? "،" : ",")}
                </span>
              )}
              {!hideYear && (
                <span
                  style={{
                    cursor:
                      disabled || disableYearPicker || onlyYearPicker
                        ? "default"
                        : "pointer",
                  }}
                  onClick={() =>
                    !disableYearPicker && toggle("mustShowYearPicker")
                  }
                >
                  {years[index]}
                </span>
              )}
            </div>
          ))
        )}
        {buttons && getButton("right")}
      </div>
    </div>
  );

  function getButton(direction) {
    let handleClick = () => increaseValue(direction === "right" ? 1 : -1),
      disabled =
        (direction === "left" && isPreviousDisable) ||
        (direction === "right" && isNextDisable);

    return renderButton instanceof Function ? (
      renderButton(direction, handleClick, disabled)
    ) : isValidElement(renderButton) ? (
      cloneElement(renderButton, { direction, handleClick, disabled })
    ) : (
      <Arrow
        direction={`rmdp-${direction}`}
        onClick={handleClick}
        disabled={disabled}
      />
    );
  }

  function increaseValue(value) {
    if (
      disabled ||
      (value < 0 && isPreviousDisable) ||
      (value > 0 && isNextDisable)
    )
      return;

    if (fullYear) {
      date.year += value;
    } else if (!mustShowYearPicker && !onlyYearPicker) {
      date.toFirstOfMonth();

      if (onlyMonthPicker) {
        date.year += value;
      } else {
        date.month += value;

        handleMonthChange(date);
      }
    } else {
      year = year + value * 12;

      if (value < 0 && minDate && year < minDate.year) year = minDate.year;
      if (value > 0 && maxDate && year > maxDate.year) year = maxDate.year;
    }

    setState({
      ...state,
      date,
      year,
    });
  }

  function toggle(picker) {
    if (disabled) return;

    let object = {
      mustShowMonthPicker: false,
      mustShowYearPicker: false,
    };

    object[picker] = !state[picker];

    setState({
      ...state,
      ...object,
    });
  }
}