This repository has been archived by the owner on Jul 17, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #155 from turistikrota/feature/calendar-v2
Feature/calendar v2
- Loading branch information
Showing
7 changed files
with
270 additions
and
75 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import React from 'react' | ||
import { useAgentMobile } from '../hooks/dom' | ||
import { CarouselButtonProps } from './carousel.types' | ||
|
||
const CarouselButton: React.FC<CarouselButtonProps> = ({ position, onClick }) => { | ||
const isMobile = useAgentMobile() | ||
const icon = position === 'left' ? 'bx-chevron-left' : 'bx-chevron-right' | ||
const left = position === 'left' ? 'left-2' : 'right-2' | ||
return ( | ||
<button | ||
className={`${ | ||
!isMobile ? 'flex' : 'hidden' | ||
} invisible absolute top-1/2 opacity-0 transition-all duration-200 group-hover:visible group-hover:opacity-90 group-hover:hover:opacity-100 ${left} shadow-xs bg-second h-8 w-8 -translate-y-1/2 transform items-center justify-center rounded-full border bg-opacity-95 text-gray-600 dark:bg-opacity-10 dark:text-white`} | ||
onClick={onClick} | ||
> | ||
<i className={`bx bx-sm ${icon}`} /> | ||
</button> | ||
) | ||
} | ||
|
||
export default CarouselButton |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { PreviewComponent } from './carousel.types' | ||
import CarouselSidePreview from './side-preview' | ||
import CarouselSubPreview from './sub-preview' | ||
|
||
export enum CarouselVariant { | ||
Map = 'map', | ||
List = 'list', | ||
Detail = 'detail', | ||
DetailHorizontal = 'detail-horizontal', | ||
DetailVertical = 'detail-vertical', | ||
} | ||
|
||
export type PreviewStyles = { | ||
provider: string | ||
item: string | ||
} | ||
|
||
export type CarouselStyles = { | ||
container: string | ||
provider: string | ||
item: string | ||
itemLoading: string | ||
preview: PreviewStyles | ||
Preview?: PreviewComponent | ||
} | ||
|
||
export const CarouselVariants: Record<CarouselVariant, CarouselStyles> = { | ||
[CarouselVariant.Map]: { | ||
container: '', | ||
provider: 'h-75 w-75', | ||
item: 'rounded-b-none', | ||
itemLoading: '', | ||
preview: { | ||
provider: '', | ||
item: '', | ||
}, | ||
}, | ||
[CarouselVariant.List]: { | ||
container: '', | ||
provider: 'h-72', | ||
item: 'rounded-b-none', | ||
itemLoading: 'rounded-t-md', | ||
preview: { | ||
provider: '', | ||
item: '', | ||
}, | ||
}, | ||
[CarouselVariant.DetailHorizontal]: { | ||
container: 'grid grid-cols-12 gap-2', | ||
provider: 'h-104 col-span-12 lg:col-span-9', | ||
item: '', | ||
itemLoading: '', | ||
preview: { | ||
provider: 'col-span-12 lg:col-span-3 grid-rows-1 lg:grid-rows-3', | ||
item: 'col-span-3 lg:col-span-6 row-span-1 lg:row-span-1', | ||
}, | ||
Preview: CarouselSidePreview, | ||
}, | ||
[CarouselVariant.DetailVertical]: { | ||
container: '', | ||
provider: 'h-104', | ||
item: '', | ||
itemLoading: '', | ||
preview: { | ||
provider: '', | ||
item: '', | ||
}, | ||
Preview: CarouselSubPreview, | ||
}, | ||
[CarouselVariant.Detail]: { | ||
container: '', | ||
provider: 'h-104', | ||
item: '', | ||
itemLoading: '', | ||
preview: { | ||
provider: '', | ||
item: '', | ||
}, | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { CarouselVariant, PreviewStyles } from './carousel.design' | ||
|
||
export type CarouselProps = { | ||
images: string[] | ||
variant?: CarouselVariant | ||
imageAltPrefix: string | ||
imageTitlePrefix?: string | ||
activeIndex?: number | ||
onClick?: (image: string, idx: number) => void | ||
autoPlay?: boolean | ||
autoPlayInterval?: number | ||
showDots?: boolean | ||
showPreview?: boolean | ||
} | ||
|
||
export type CarouselButtonProps = { | ||
position: 'left' | 'right' | ||
onClick: () => void | ||
} | ||
|
||
export type PreviewProps = { | ||
styles?: PreviewStyles | ||
images: string[] | ||
imageTitlePrefix?: string | ||
currentIndex: number | ||
setCurrentIndex: (idx: number) => void | ||
onClick?: (image: string, idx: number) => void | ||
} | ||
|
||
export type PreviewComponent = React.FC<PreviewProps> | ||
|
||
export type CarouselComponent = React.FC<CarouselProps> & { | ||
Variants: typeof CarouselVariant | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import React, { FC, useMemo } from 'react' | ||
import { useIsDesktop } from '../hooks/dom' | ||
import PerfectImage from '../image/perfect' | ||
import { PreviewProps } from './carousel.types' | ||
|
||
const CarouselSidePreview: FC<PreviewProps> = ({ | ||
styles, | ||
images, | ||
imageTitlePrefix, | ||
currentIndex, | ||
setCurrentIndex, | ||
onClick, | ||
}) => { | ||
const isDesktop = useIsDesktop() | ||
const max = useMemo<number>(() => (isDesktop ? 6 : 4), [isDesktop]) | ||
const [firstImages, totalCount] = useMemo(() => { | ||
if (images.length > max) return [images.slice(0, max - 1), images.length] | ||
return [images, images.length] | ||
}, [images, max]) | ||
|
||
return ( | ||
<div className={`grid grid-cols-12 gap-2 ${styles ? styles.provider : ''}`}> | ||
{firstImages.map((img, idx) => ( | ||
<div key={idx} className={`${styles ? styles.item : ''}`}> | ||
<PerfectImage | ||
src={img} | ||
full={false} | ||
alt={``} | ||
title={imageTitlePrefix ? `${imageTitlePrefix}-${idx}` : undefined} | ||
imgClassName='rounded-md w-full h-full' | ||
loadingClassName='rounded-md w-full h-full' | ||
className={`rounded-md object-cover transition-opacity duration-200 ${ | ||
idx === currentIndex ? 'opacity-100' : 'cursor-pointer opacity-50' | ||
}`} | ||
onClick={(e) => { | ||
setCurrentIndex(idx) | ||
e.stopPropagation() | ||
}} | ||
/> | ||
</div> | ||
))} | ||
{totalCount > max && ( | ||
<div className={`relative ${styles ? styles.item : ''}`}> | ||
<div className='absolute inset-0 flex items-center justify-center bg-white bg-opacity-100 dark:bg-black'> | ||
<span className='text-2xl font-bold text-black dark:text-white lg:text-4xl'>{totalCount - max}+</span> | ||
</div> | ||
<PerfectImage | ||
src={images[max - 1]} | ||
full={false} | ||
alt={``} | ||
title={imageTitlePrefix ? `${imageTitlePrefix}-${5}` : undefined} | ||
imgClassName='rounded-md w-full h-full' | ||
loadingClassName='rounded-md w-full h-full' | ||
className={`cursor-pointer rounded-md object-cover opacity-20 transition-opacity duration-200`} | ||
onClick={(e) => { | ||
if (onClick) onClick(images[max - 1], max - 1) | ||
else setCurrentIndex(5) | ||
e.stopPropagation() | ||
}} | ||
/> | ||
</div> | ||
)} | ||
</div> | ||
) | ||
} | ||
|
||
export default CarouselSidePreview |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import React, { FC } from 'react' | ||
import PerfectImage from '../image/perfect' | ||
import { PreviewProps } from './carousel.types' | ||
|
||
const CarouselSubPreview: FC<PreviewProps> = ({ styles, images, imageTitlePrefix, currentIndex, setCurrentIndex }) => { | ||
return ( | ||
<div className={`mt-2 flex justify-start gap-1 overflow-x-auto pb-2 ${styles ? styles.provider : ''}`}> | ||
{images.map((img, idx) => ( | ||
<div | ||
key={idx} | ||
className={`max-w-12 relative h-12 max-h-12 min-h-[3rem] w-12 min-w-[3rem] ${styles ? styles.item : ''}`} | ||
> | ||
<PerfectImage | ||
src={img} | ||
full={false} | ||
alt={``} | ||
title={imageTitlePrefix ? `${imageTitlePrefix}-${idx}` : undefined} | ||
imgClassName='rounded-md w-full h-full' | ||
loadingClassName='rounded-md w-full h-full' | ||
className={`max-w-12 h-12 max-h-12 min-h-[3rem] w-12 min-w-[3rem] rounded-md object-cover transition-opacity duration-200 ${ | ||
idx === currentIndex ? 'opacity-100' : 'cursor-pointer opacity-50' | ||
}`} | ||
onClick={(e) => { | ||
setCurrentIndex(idx) | ||
e.stopPropagation() | ||
}} | ||
/> | ||
</div> | ||
))} | ||
</div> | ||
) | ||
} | ||
|
||
export default CarouselSubPreview |