This repository has been archived by the owner on Dec 21, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 96
/
ui.tsx
117 lines (104 loc) · 3.13 KB
/
ui.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { createElement, CSSProperties, HTMLAttributes, ReactElement, ReactEventHandler } from "react";
import classNames from "classnames";
import { HeightUnitEnum, WidthUnitEnum } from "../../../typings/ImageViewerProps";
import { LightboxProps } from "../Lightbox";
import "../../ui/Image.scss";
function getStyle(value: string | number, type: WidthUnitEnum | HeightUnitEnum): number | string {
// when type is auto default browser styles applies
if (type === "pixels") {
return value;
} else if (type === "percentage") {
return value + "%";
}
return "";
}
export interface ImageViewerWrapperProps {
className?: string;
responsive: boolean;
hasImage: boolean;
children:
| ReactElement<ImageViewerGlyphicon | ImageViewerImage>
| [ReactElement<ImageViewerGlyphicon | ImageViewerImage>, ReactElement<LightboxProps> | false];
}
export interface ImageViewerContentProps {
style?: CSSProperties;
onClick?: ReactEventHandler<HTMLElement>;
altText?: string;
}
function Wrapper(props: ImageViewerWrapperProps): ReactElement {
return (
<div
className={classNames(
"mx-image-viewer",
{ "mx-image-viewer-responsive": props.responsive },
props.className,
{ hidden: !props.hasImage }
)}
>
{props.children}
</div>
);
}
export interface ImageViewerGlyphicon extends ImageViewerContentProps {
icon: string | undefined;
size: number;
}
function Glyphicon(props: ImageViewerGlyphicon): ReactElement {
const accessibilityProps = props.altText
? {
"aria-label": props.altText,
role: "img"
}
: {};
const onClickProps = getImageContentOnClickProps(props.onClick);
return (
<span
className={classNames("glyphicon", props.icon)}
style={{ ...props.style, fontSize: `${props.size}px` }}
{...accessibilityProps}
{...onClickProps}
/>
);
}
export interface ImageViewerImage extends ImageViewerContentProps {
image: string | undefined;
height: number;
heightUnit: HeightUnitEnum;
width: number;
widthUnit: WidthUnitEnum;
}
function Image(props: ImageViewerImage): ReactElement {
const onClickProps = getImageContentOnClickProps(props.onClick);
return (
<img
src={props.image}
style={{
...props.style,
height: getStyle(props.height, props.heightUnit),
width: getStyle(props.width, props.widthUnit)
}}
alt={props.altText}
{...onClickProps}
/>
);
}
function getImageContentOnClickProps(onClick: ImageViewerContentProps["onClick"]): HTMLAttributes<HTMLElement> {
if (!onClick) {
return {};
}
return {
onClick,
role: "button",
tabIndex: 0,
onKeyDown: event => {
if (event.key === "Enter" || event.key === " ") {
onClick(event);
}
}
};
}
export const ImageViewerUi = {
Wrapper,
Glyphicon,
Image
};