Skip to content

Commit

Permalink
fix: add custom renderers for loading, error and fullscreen icons
Browse files Browse the repository at this point in the history
  • Loading branch information
igordanchenko committed May 20, 2022
1 parent d322867 commit 70a0c65
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 20 deletions.
25 changes: 19 additions & 6 deletions src/core/components/ImageSlide.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import * as React from "react";

import { SlideImage } from "../../types.js";
import { Render, SlideImage } from "../../types.js";
import { clsx, cssClass } from "../utils.js";
import { useLatest } from "../hooks/index.js";
import { ErrorIcon, LoadingIcon } from "./Icons.js";
import { useController } from "../modules/Controller.js";

export const ImageSlide = ({ slide: image }: { slide: SlideImage }) => {
export type ImageSlideProps = {
slide: SlideImage;
render: Render;
};

export const ImageSlide = ({ slide: image, render }: ImageSlideProps) => {
const [state, setState] = React.useState<"loading" | "error" | "complete">("loading");
const latestState = useLatest(state);

Expand Down Expand Up @@ -96,10 +101,18 @@ export const ImageSlide = ({ slide: image }: { slide: SlideImage }) => {

{state !== "complete" && (
<div className={cssClass("slide_placeholder")}>
{state === "loading" && (
<LoadingIcon className={clsx(cssClass("icon"), cssClass("slide_loading"))} />
)}
{state === "error" && <ErrorIcon className={clsx(cssClass("icon"), cssClass("slide_error"))} />}
{state === "loading" &&
(render.iconLoading ? (
render.iconLoading()
) : (
<LoadingIcon className={clsx(cssClass("icon"), cssClass("slide_loading"))} />
))}
{state === "error" &&
(render.iconError ? (
render.iconError()
) : (
<ErrorIcon className={clsx(cssClass("icon"), cssClass("slide_error"))} />
))}
</div>
)}
</>
Expand Down
16 changes: 7 additions & 9 deletions src/core/modules/Carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@ import { useController } from "./Controller.js";
type CarouselSlideProps = {
slide: Slide;
offset: number;
renderSlide: Render["slide"];
render: Render;
};

const CarouselSlide = ({ slide, offset, renderSlide }: CarouselSlideProps) => (
const CarouselSlide = ({ slide, offset, render }: CarouselSlideProps) => (
<div className={clsx(cssClass("slide"), cssClass("flex_center"))} style={{ [cssVar("slide_offset")]: offset }}>
{renderSlide?.(slide) || ("src" in slide && <ImageSlide slide={slide} />)}
{render.slide?.(slide) || ("src" in slide && <ImageSlide slide={slide} render={render} />)}
</div>
);

export const Carousel: Component = (props) => {
const {
slides,
carousel: { finite, preload, padding, spacing },
render: { slide: renderSlide },
render,
} = props;

const { currentIndex, globalIndex } = useController();
Expand All @@ -37,15 +37,13 @@ export const Carousel: Component = (props) => {
key={globalIndex + i - currentIndex}
slide={slides[(i + preload * slides.length) % slides.length]}
offset={i - currentIndex}
renderSlide={renderSlide}
render={render}
/>
);
}
}

items.push(
<CarouselSlide key={globalIndex} slide={slides[currentIndex]} offset={0} renderSlide={renderSlide} />
);
items.push(<CarouselSlide key={globalIndex} slide={slides[currentIndex]} offset={0} render={render} />);

for (let i = currentIndex + 1; i <= currentIndex + preload; i += 1) {
if (!finite || i <= slides.length - 1) {
Expand All @@ -54,7 +52,7 @@ export const Carousel: Component = (props) => {
key={globalIndex + i - currentIndex}
slide={slides[i % slides.length]}
offset={i - currentIndex}
renderSlide={renderSlide}
render={render}
/>
);
}
Expand Down
33 changes: 28 additions & 5 deletions src/plugins/Fullscreen.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
import * as React from "react";

import { LightboxProps, Plugin } from "../types.js";
import { LightboxProps, Plugin, Render } from "../types.js";
import { createIcon, IconButton, label, useController, useLatest } from "../core/index.js";

declare module "../types.js" {
interface LightboxProps {
fullscreen?: boolean;
}

interface Render {
buttonFullscreen?: ({
fullscreen,
toggleFullscreen,
}: {
fullscreen: boolean;
toggleFullscreen: () => void;
}) => React.ReactNode;
iconEnterFullscreen?: () => React.ReactNode;
iconExitFullscreen?: () => React.ReactNode;
}
}

declare global {
Expand Down Expand Up @@ -43,9 +55,12 @@ const ExitFullscreenIcon = createIcon(
<path d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z" />
);

export type FullscreenButtonProps = Pick<LightboxProps, "labels"> & { auto: boolean };
export type FullscreenButtonProps = Pick<LightboxProps, "labels"> & {
auto: boolean;
render: Render;
};

export const FullscreenButton = ({ auto, labels }: FullscreenButtonProps) => {
export const FullscreenButton = ({ auto, labels, render }: FullscreenButtonProps) => {
const [fullscreen, setFullscreen] = React.useState(false);
const latestAuto = useLatest(auto);

Expand Down Expand Up @@ -144,10 +159,13 @@ export const FullscreenButton = ({ auto, labels }: FullscreenButtonProps) => {

if (!isFullscreenEnabled()) return null;

return (
return render.buttonFullscreen ? (
<>{render.buttonFullscreen({ fullscreen, toggleFullscreen })}</>
) : (
<IconButton
label={fullscreen ? label(labels, "Exit Fullscreen") : label(labels, "Enter Fullscreen")}
icon={fullscreen ? ExitFullscreenIcon : EnterFullscreenIcon}
renderIcon={fullscreen ? render.iconExitFullscreen : render.iconEnterFullscreen}
onClick={toggleFullscreen}
/>
);
Expand All @@ -157,7 +175,12 @@ export const Fullscreen: Plugin = ({ augment }) => {
augment(({ toolbar: { buttons, ...restToolbar }, ...restProps }) => ({
toolbar: {
buttons: [
<FullscreenButton key="fullscreen" auto={Boolean(restProps.fullscreen)} labels={restProps.labels} />,
<FullscreenButton
key="fullscreen"
auto={Boolean(restProps.fullscreen)}
labels={restProps.labels}
render={restProps.render}
/>,
...buttons,
],
...restToolbar,
Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export interface Render {
iconPrev?: () => React.ReactNode;
iconNext?: () => React.ReactNode;
iconClose?: () => React.ReactNode;
iconLoading?: () => React.ReactNode;
iconError?: () => React.ReactNode;
buttonPrev?: () => React.ReactNode;
buttonNext?: () => React.ReactNode;
buttonClose?: () => React.ReactNode;
Expand Down

0 comments on commit 70a0c65

Please sign in to comment.