Skip to content

Commit

Permalink
React: Use isomorphic effect + Slots
Browse files Browse the repository at this point in the history
  • Loading branch information
nolimits4web committed Jun 3, 2020
1 parent eb7a015 commit beaf50b
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import React from 'react';

function getSlidesFromChildren(children) {
function getChildren(children) {
const slides = [];

const slots = {
'container-start': [],
'container-end': [],
'wrapper-start': [],
'wrapper-end': [],
};
function processChildren(c) {
React.Children.toArray(c).forEach((child) => {
if (child.type === React.Fragment && child.props.children) {
Expand All @@ -10,11 +17,15 @@ function getSlidesFromChildren(children) {
}
if (child.type && child.type.displayName === 'SwiperSlide') {
slides.push(child);
} else if (child.props && child.props.slot && slots[child.props.slot]) {
slots[child.props.slot].push(child);
} else {
slots['container-end'].push(child);
}
});
}
processChildren(children);
return slides;
return { slides, slots };
}

export { getSlidesFromChildren };
export { getChildren };
21 changes: 14 additions & 7 deletions src/react/swiper.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React, { useRef, useState, useEffect, useLayoutEffect } from 'react';
import React, { useRef, useState, useEffect } from 'react';
import { getParams } from './get-params';
import { initSwiper } from './init-swiper';
import { needsScrollbar, needsNavigation, needsPagination, uniqueClasses } from './utils';
import { renderLoop, calcLoopedSlides } from './loop';
import { getChangedParams } from './get-changed-params';
import { getSlidesFromChildren } from './get-slides-from-children';
import { getChildren } from './get-children';
import { updateSwiper } from './update-swiper';
import { renderVirtual, updateOnVirtualData } from './virtual';
import { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect';

const Swiper = ({
className,
Expand All @@ -31,7 +32,7 @@ const Swiper = ({

const { params: swiperParams, passedParams, rest: restProps } = getParams(rest);

const slides = getSlidesFromChildren(children);
const { slides, slots } = getChildren(children);

const changedParams = getChangedParams(
passedParams,
Expand Down Expand Up @@ -70,19 +71,19 @@ const Swiper = ({
});

// watch for params change
useLayoutEffect(() => {
useIsomorphicLayoutEffect(() => {
if (changedParams.length && swiperRef.current && !swiperRef.current.destroyed) {
updateSwiper(swiperRef.current, slides, passedParams, changedParams);
}
});

// update on virtual update
useLayoutEffect(() => {
useIsomorphicLayoutEffect(() => {
updateOnVirtualData(swiperRef.current);
}, [virtualData]);

// init swiper
useLayoutEffect(() => {
useIsomorphicLayoutEffect(() => {
if (!swiperElRef.current) return;
initSwiper(
{
Expand Down Expand Up @@ -123,6 +124,7 @@ const Swiper = ({
className={uniqueClasses(`${containerClasses}${className ? ` ${className}` : ''}`)}
{...restProps}
>
{slots['container-start']}
{needsNavigation(swiperParams) && (
<>
<div ref={prevElRef} className="swiper-button-prev" />
Expand All @@ -131,7 +133,12 @@ const Swiper = ({
)}
{needsScrollbar(swiperParams) && <div ref={scrollbarElRef} className="swiper-scrollbar" />}
{needsPagination(swiperParams) && <div ref={paginationElRef} className="swiper-pagination" />}
<WrapperTag className="swiper-wrapper">{renderSlides()}</WrapperTag>
<WrapperTag className="swiper-wrapper">
{slots['wrapper-start']}
{renderSlides()}
{slots['wrapper-end']}
</WrapperTag>
{slots['container-end']}
</Tag>
);
};
Expand Down
9 changes: 9 additions & 0 deletions src/react/use-isomorphic-layout-effect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useEffect, useLayoutEffect } from 'react';

function useIsomorphicLayoutEffect(callback, deps) {
// eslint-disable-next-line
if (typeof window === 'undefined') return useEffect(callback, deps);
return useLayoutEffect(callback, deps);
}

export { useIsomorphicLayoutEffect };

0 comments on commit beaf50b

Please sign in to comment.