import { IMedia, getClassNames, withSchema } from '@websolutespa/bom-core';
import { RefObject, forwardRef } from 'react';
import styled, { css } from 'styled-components';
import { UIComponentWithRef, UIStyledComponentProps } from '../../components/types';
import { getAspectResponsive, getCssResponsive } from '../../components/utils';
import { useMediaGalleryContext } from '../media-gallery/media-gallery-context';
import { MediaSize } from './media-image';
import { MediaItems } from './media-items';
export type MediaInfoProps = UIStyledComponentProps;
const StyledMediaInfo = styled.div`
position: absolute;
display: flex;
flex-direction: column;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
color: var(--color-neutral-100);
${props => getCssResponsive(props)}
`;
const MediaInfo = ({ children, className, ...props }: MediaInfoProps) => {
const classNames = getClassNames(className, 'media-info');
return ({children});
};
type Props = {
size?: MediaSize;
circle?: boolean;
rounded?: boolean;
overlay?: boolean | number;
eager?: boolean;
alt?: string;
title?: string;
informative?: boolean;
item?: IMedia | IMedia[];
onLoaded?: (ref: RefObject) => void;
canLoad?: boolean;
};
export type MediaProps = UIStyledComponentProps;
export type MediaComponent = UIComponentWithRef;
const StyledMedia = styled.div`
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
${props => getCssResponsive(props)}
&>:not(.media-info) {
width: 100%;
height: 100%;
}
&>.image:not(.image-svg),
&>video,
&>.video {
object-fit: cover;
background: transparent;
}
&>svg {
height: 100%;
}
&.media--gallery {
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
cursor: pointer;
&>:not(.media-info) {
transition: ease-in-out 200ms;
transition-property: transform, opacity;
}
&:hover {
&>:not(.media-info) {
transform: scale(1.05);
}
}
}
${props => props.circle ? css`
aspect-ratio: 1;
overflow: hidden;
border-radius: 50%;
&>* {
top: 0;
left: 0;
height: 100%;
}
` : ''}
${props => props.rounded ? css`
overflow: hidden;
border-radius: var(--border-radius);
` : ''}
${props => getAspectResponsive(props, props.circle ? { aspectRatio: 1 } : undefined)}
${props => props.overlay ? css`
position: relative;
&:after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
${getOverlayCss(props.overlay)}
}
` : ''}
`;
function getOverlayCss(overlay: boolean | number): string {
return (
typeof overlay === 'number' ?
`background: rgba(0,0,0,${overlay});` :
'background: rgba(0,0,0,0.4);'
);
// 'background-image: linear-gradient(180deg, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.1) 15.9%, rgba(0, 0, 0, 0) 41.67%, rgba(0, 0, 0, 0.1) 61.79%, rgba(0, 0, 0, 0.6) 100%);'
}
const MediaBase: MediaComponent = forwardRef(({
children,
item,
className,
width,
height,
size,
eager,
alt,
title,
informative,
onClick,
onLoaded,
canLoad,
as = 'div',
...props
}, ref) => {
const { id, open } = useMediaGalleryContext();
const classNames = getClassNames(className, 'media', { 'media--gallery': id });
const style: { width?: string, height?: string } = {};
if (typeof width === 'string') {
style.width = width;
}
if (typeof height === 'string') {
style.height = height;
}
return (
{children ? (
children
) : (
item &&
)}
);
});
MediaBase.displayName = 'Media';
export const Media = withSchema(
MediaBase,
{
Info: MediaInfo,
});