Browse Source

Remove Absolute Positioning Of Carousel Buttons

Francesco Baccetti 4 years ago
parent
commit
ea2173d2b8

+ 1 - 0
packages/app/src/components/SeriesGallery.tsx

@@ -62,6 +62,7 @@ export default function SeriesGallery({ title }: SeriesGalleryProps) {
 		<Gallery title={title}>
 			{series.map((series) => (
 				<SeriesPreview
+					key={series.series}
 					channel={series.channel}
 					poster={series.poster}
 					series={series.series}

+ 35 - 35
packages/components/src/components/Button/Button.style.ts

@@ -1,15 +1,15 @@
-import { typography, colors } from "../../theme"
-import { makeStyles, StyleFn } from "../../utils"
-import { disabled, dimensionsFromProps, log } from "../../theme/fragments"
+import { typography, colors } from "../../theme";
+import { makeStyles, StyleFn } from "../../utils";
+import { disabled, dimensionsFromProps } from "../../theme/fragments";
 
 export type ButtonStyleProps = {
-	text?: string
-	type?: "primary" | "secondary"
-	full?: boolean
-	size?: "regular" | "small" | "smaller"
-	children?: React.ReactNode
-	disabled?: boolean
-}
+	text?: string;
+	type?: "primary" | "secondary";
+	full?: boolean;
+	size?: "regular" | "small" | "smaller";
+	children?: React.ReactNode;
+	disabled?: boolean;
+};
 
 const baseStyles: StyleFn = () => ({
 	borderWidth: "1px",
@@ -21,9 +21,9 @@ const baseStyles: StyleFn = () => ({
 	alignItems: "center",
 	color: colors.white,
 	"&::selected": {
-		background: "transparent"
-	}
-})
+		background: "transparent",
+	},
+});
 const colorFromType: StyleFn = (styles = {}, { type }: ButtonStyleProps) => {
 	switch (type) {
 		case "primary":
@@ -35,14 +35,14 @@ const colorFromType: StyleFn = (styles = {}, { type }: ButtonStyleProps) => {
 				"&:hover": {
 					backgroundColor: colors.blue[700],
 					borderColor: colors.blue[700],
-					color: colors.white
+					color: colors.white,
 				},
 				"&:active": {
 					backgroundColor: colors.blue[900],
 					borderColor: colors.blue[900],
-					color: colors.white
-				}
-			}
+					color: colors.white,
+				},
+			};
 
 		case "secondary":
 			return {
@@ -53,28 +53,28 @@ const colorFromType: StyleFn = (styles = {}, { type }: ButtonStyleProps) => {
 
 				"&:hover": {
 					borderColor: colors.blue[700],
-					color: colors.blue[300]
+					color: colors.blue[300],
 				},
 
 				"&:active": {
 					borderColor: colors.blue[700],
-					color: colors.blue[700]
-				}
-			}
+					color: colors.blue[700],
+				},
+			};
 
 		default:
-			return { ...styles }
+			return { ...styles };
 	}
-}
+};
 const paddingFromType: StyleFn = (
 	styles,
 	{
 		size = "regular",
 		children,
-		full = false
+		full = false,
 	}: { size: "regular" | "small" | "smaller"; children?: React.ReactNode; full: boolean }
 ) => {
-	const buttonHeight = size === "regular" ? "20px" : size === "small" ? "15px" : "10px"
+	const buttonHeight = size === "regular" ? "20px" : size === "small" ? "15px" : "10px";
 	return {
 		...styles,
 		margin: `0 ${full ? "0" : "15px"} 0 0`,
@@ -93,9 +93,9 @@ const paddingFromType: StyleFn = (
 				? typography.sizes.button.large
 				: size === "small"
 				? typography.sizes.button.medium
-				: typography.sizes.button.small
-	}
-}
+				: typography.sizes.button.small,
+	};
+};
 
 const iconStyles: StyleFn = (styles, { children, size }) => {
 	return {
@@ -110,15 +110,15 @@ const iconStyles: StyleFn = (styles, { children, size }) => {
 
 		flexShrink: 0,
 		"& > *": {
-			stroke: "currentColor"
-		}
-	}
-}
+			stroke: "currentColor",
+		},
+	};
+};
 
 export const useCSS = (props: ButtonStyleProps) => ({
-	container: makeStyles([baseStyles, colorFromType, dimensionsFromProps, log, paddingFromType, disabled])(props),
-	icon: makeStyles([iconStyles])(props)
-})
+	container: makeStyles([baseStyles, colorFromType, dimensionsFromProps, paddingFromType, disabled])(props),
+	icon: makeStyles([iconStyles])(props),
+});
 
 // 	text,
 // 	type = "primary",

+ 17 - 26
packages/components/src/components/Carousel/Carousel.style.ts

@@ -1,38 +1,29 @@
-import { css } from "@emotion/core"
-import { StyleFn, makeStyles } from "../../utils"
+import { StyleFn, makeStyles } from "../../utils";
 
 export type CarouselStyleProps = {
-	navTopPosition?: string
-}
+	navTopPosition?: string;
+};
 
-const wrapper: StyleFn = () => ({
-	position: "relative"
-})
 const container: StyleFn = () => ({
+	position: "relative",
+	display: "flex",
+	alignItems: "center",
+});
+const innerContainer: StyleFn = () => ({
 	display: "flex",
 	overflow: "hidden",
-	padding: "1rem"
-})
+	padding: "1rem",
+});
 
-const item: StyleFn = () => ({
-	display: "inline-block"
-})
-const navLeft: StyleFn = (_, { navTopPosition = 69 }) => ({
-	position: "absolute",
-	left: 0,
-	top: `${navTopPosition}px`
-})
+const navLeft: StyleFn = () => ({
+	order: -1,
+});
 
-const navRight: StyleFn = (_, { navTopPosition = 69 }) => ({
-	position: "absolute",
-	right: 0,
-	top: `${navTopPosition}px`
-})
+const navRight: StyleFn = () => ({});
 
 export const useCSS = (props: CarouselStyleProps) => ({
-	wrapper: makeStyles([wrapper])(props),
 	container: makeStyles([container])(props),
-	item: makeStyles([item])(props),
+	innerContainer: makeStyles([innerContainer])(props),
 	navLeft: makeStyles([navLeft])(props),
-	navRight: makeStyles([navRight])(props)
-})
+	navRight: makeStyles([navRight])(props),
+});

+ 58 - 29
packages/components/src/components/Carousel/Carousel.tsx

@@ -1,4 +1,5 @@
 import React, { useState, useRef, useEffect, useCallback } from "react";
+import { css } from "@emotion/core";
 import { animated, useSpring } from "react-spring";
 import { useCSS, CarouselStyleProps } from "./Carousel.style";
 import NavButton from "../NavButton";
@@ -6,10 +7,10 @@ import NavButton from "../NavButton";
 type CarouselProps = {
 	children: React.ReactNode[];
 	scrollAmount?: number;
-	maxInView?: number;
+	log?: boolean;
 } & CarouselStyleProps;
 
-export default function Carousel({ children, scrollAmount = 200, ...styleProps }: CarouselProps) {
+export default function Carousel({ children, scrollAmount = 200, log, ...styleProps }: CarouselProps) {
 	let styles = useCSS(styleProps);
 	const containerRef = useRef<HTMLDivElement>(null);
 	const elementsRefs = useRef<(HTMLDivElement | null)[]>([]);
@@ -36,35 +37,49 @@ export default function Carousel({ children, scrollAmount = 200, ...styleProps }
 		}
 	}, [children.length]);
 
-	const handleScroll = useCallback(
-		function (direction: "right" | "left") {
-			let newDist = NaN;
-			const MIN_DISTANCE = 0;
-			const MAX_DISTANCE = maxDistance;
-			switch (direction) {
-				case "left": {
-					newDist = distance + scrollAmount <= MIN_DISTANCE ? distance + scrollAmount : distance;
-					break;
-				}
-				case "right": {
-					newDist = distance - scrollAmount >= -MAX_DISTANCE ? distance - scrollAmount : distance;
-					break;
-				}
-			}
+	if (log) {
+		console.log({
+			totalChildrensLength: elementsRefs.current.reduce(
+				(accWidth, el) => (el != null ? accWidth + el.clientWidth : accWidth),
+				0
+			),
+			longestChildrenWidth: elementsRefs.current.reduce(
+				(longest, el) => (el != null && el.clientWidth > longest ? el.clientWidth : longest),
+				0
+			),
+			maxDistance,
+			childrens: children.length,
+			distance,
+		});
+	}
+	const MIN_DISTANCE = 0;
+	const MAX_DISTANCE = maxDistance;
 
-			setDistance(newDist);
-			set({
-				transform: `translateX(${newDist}px)`,
-			});
+	function handleScroll(direction: "right" | "left") {
+		let newDist = NaN;
 
-			return newDist;
-		},
-		[maxDistance]
-	);
+		switch (direction) {
+			case "left": {
+				newDist = distance + scrollAmount <= MIN_DISTANCE ? distance + scrollAmount : distance;
+				break;
+			}
+			case "right": {
+				newDist = distance - scrollAmount > -MAX_DISTANCE ? distance - scrollAmount : distance;
+				break;
+			}
+		}
+		console.log("newDist", newDist);
+		setDistance(newDist);
+		set({
+			transform: `translateX(${newDist}px)`,
+		});
+
+		return newDist;
+	}
 
 	return (
-		<div css={styles.wrapper}>
-			<div css={styles.container} ref={containerRef}>
+		<div css={styles.container}>
+			<div css={styles.innerContainer} ref={containerRef}>
 				{children.map((item, idx) => (
 					<animated.div
 						style={props}
@@ -78,10 +93,24 @@ export default function Carousel({ children, scrollAmount = 200, ...styleProps }
 					</animated.div>
 				))}
 			</div>
-			<div css={styles.navLeft}>
+			<div
+				css={[
+					styles.navLeft,
+					css`
+						opacity: ${distance === MIN_DISTANCE ? 0 : 1};
+					`,
+				]}
+			>
 				<NavButton type="primary" direction="left" onClick={() => handleScroll("left")} />
 			</div>
-			<div css={styles.navRight}>
+			<div
+				css={[
+					styles.navRight,
+					css`
+						opacity: ${distance - scrollAmount < -MAX_DISTANCE ? 0 : 1};
+					`,
+				]}
+			>
 				<NavButton type="primary" direction="right" onClick={() => handleScroll("right")} />
 			</div>
 		</div>