react-miui 0.9.4 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/assets/checkmark.svg +1 -4
- package/assets/config.svg +1 -0
- package/assets/heart.svg +1 -0
- package/assets/sources/checkmark.fla +0 -0
- package/assets/sources/config.fla +0 -0
- package/assets/sources/heart.fla +0 -0
- package/assets/sources/trash.fla +0 -0
- package/assets/trash.svg +1 -0
- package/dist/components/form/Checkbox.d.ts +3 -3
- package/dist/components/form/Checkbox.d.ts.map +1 -1
- package/dist/components/icons/Back.js +1 -1
- package/dist/components/icons/Back.js.map +1 -1
- package/dist/components/icons/Battery.d.ts.map +1 -1
- package/dist/components/icons/Battery.js +1 -1
- package/dist/components/icons/Battery.js.map +1 -1
- package/dist/components/icons/Checkmark.d.ts.map +1 -1
- package/dist/components/icons/Checkmark.js +2 -2
- package/dist/components/icons/Checkmark.js.map +1 -1
- package/dist/components/icons/Config.d.ts +7 -0
- package/dist/components/icons/Config.d.ts.map +1 -0
- package/dist/components/icons/Config.js +13 -0
- package/dist/components/icons/Config.js.map +1 -0
- package/dist/components/icons/Forward.js +1 -1
- package/dist/components/icons/Forward.js.map +1 -1
- package/dist/components/icons/Heart.d.ts +7 -0
- package/dist/components/icons/Heart.d.ts.map +1 -0
- package/dist/components/icons/Heart.js +13 -0
- package/dist/components/icons/Heart.js.map +1 -0
- package/dist/components/icons/Icon.d.ts +4 -1
- package/dist/components/icons/Icon.d.ts.map +1 -1
- package/dist/components/icons/Icon.js +9 -0
- package/dist/components/icons/Icon.js.map +1 -1
- package/dist/components/icons/Search.js +1 -1
- package/dist/components/icons/Search.js.map +1 -1
- package/dist/components/icons/Trash.d.ts +7 -0
- package/dist/components/icons/Trash.d.ts.map +1 -0
- package/dist/components/icons/Trash.js +13 -0
- package/dist/components/icons/Trash.js.map +1 -0
- package/dist/components/ui/message/Message.d.ts +8 -0
- package/dist/components/ui/message/Message.d.ts.map +1 -0
- package/dist/components/ui/message/Message.js +20 -0
- package/dist/components/ui/message/Message.js.map +1 -0
- package/dist/components/ui/message/Message.module.scss +31 -0
- package/dist/components/ui/pop/HandleEsc.d.ts +7 -0
- package/dist/components/ui/pop/HandleEsc.d.ts.map +1 -0
- package/dist/components/ui/pop/HandleEsc.js +16 -0
- package/dist/components/ui/pop/HandleEsc.js.map +1 -0
- package/dist/components/ui/pop/OnButtonClick.d.ts +7 -0
- package/dist/components/ui/pop/OnButtonClick.d.ts.map +1 -0
- package/dist/components/ui/pop/OnButtonClick.js +44 -0
- package/dist/components/ui/pop/OnButtonClick.js.map +1 -0
- package/dist/components/ui/pop/Pop.d.ts +26 -0
- package/dist/components/ui/pop/Pop.d.ts.map +1 -0
- package/dist/components/ui/pop/Pop.js +130 -0
- package/dist/components/ui/pop/Pop.js.map +1 -0
- package/dist/components/ui/pop/Pop.module.scss +58 -0
- package/dist/components/ui/pop/PopOption.d.ts +10 -0
- package/dist/components/ui/pop/PopOption.d.ts.map +1 -0
- package/dist/components/ui/pop/PopOption.js +21 -0
- package/dist/components/ui/pop/PopOption.js.map +1 -0
- package/dist/global.scss +10 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/useKeyPress.d.ts +3 -0
- package/dist/utils/useKeyPress.d.ts.map +1 -0
- package/dist/utils/useKeyPress.js +28 -0
- package/dist/utils/useKeyPress.js.map +1 -0
- package/docs/assets/js/search.js +1 -1
- package/docs/assets/js/search.json +1 -1
- package/docs/classes/Pop.html +1134 -0
- package/docs/classes/ToasterProvider.html +18 -8
- package/docs/enums/ICON.html +60 -8
- package/docs/index.html +14 -4
- package/docs/modules/Item.html +7 -3
- package/docs/modules/List.html +7 -3
- package/docs/modules/Modal.html +7 -3
- package/docs/modules/ModalButtons.html +7 -3
- package/docs/modules/Section.html +7 -3
- package/docs/modules/StickyHeader.html +8 -4
- package/docs/modules.html +49 -27
- package/docs/pages/Tutorials/Test.html +7 -3
- package/esm/components/form/Checkbox.d.ts +3 -3
- package/esm/components/form/Checkbox.d.ts.map +1 -1
- package/esm/components/icons/Back.js +1 -1
- package/esm/components/icons/Back.js.map +1 -1
- package/esm/components/icons/Battery.d.ts.map +1 -1
- package/esm/components/icons/Battery.js +1 -1
- package/esm/components/icons/Battery.js.map +1 -1
- package/esm/components/icons/Checkmark.d.ts.map +1 -1
- package/esm/components/icons/Checkmark.js +2 -2
- package/esm/components/icons/Checkmark.js.map +1 -1
- package/esm/components/icons/Config.d.ts +7 -0
- package/esm/components/icons/Config.d.ts.map +1 -0
- package/esm/components/icons/Config.js +7 -0
- package/esm/components/icons/Config.js.map +1 -0
- package/esm/components/icons/Forward.js +1 -1
- package/esm/components/icons/Forward.js.map +1 -1
- package/esm/components/icons/Heart.d.ts +7 -0
- package/esm/components/icons/Heart.d.ts.map +1 -0
- package/esm/components/icons/Heart.js +7 -0
- package/esm/components/icons/Heart.js.map +1 -0
- package/esm/components/icons/Icon.d.ts +4 -1
- package/esm/components/icons/Icon.d.ts.map +1 -1
- package/esm/components/icons/Icon.js +9 -0
- package/esm/components/icons/Icon.js.map +1 -1
- package/esm/components/icons/Search.js +1 -1
- package/esm/components/icons/Search.js.map +1 -1
- package/esm/components/icons/Trash.d.ts +7 -0
- package/esm/components/icons/Trash.d.ts.map +1 -0
- package/esm/components/icons/Trash.js +7 -0
- package/esm/components/icons/Trash.js.map +1 -0
- package/esm/components/ui/message/Message.d.ts +8 -0
- package/esm/components/ui/message/Message.d.ts.map +1 -0
- package/esm/components/ui/message/Message.js +14 -0
- package/esm/components/ui/message/Message.js.map +1 -0
- package/esm/components/ui/message/Message.module.scss +31 -0
- package/esm/components/ui/pop/HandleEsc.d.ts +7 -0
- package/esm/components/ui/pop/HandleEsc.d.ts.map +1 -0
- package/esm/components/ui/pop/HandleEsc.js +13 -0
- package/esm/components/ui/pop/HandleEsc.js.map +1 -0
- package/esm/components/ui/pop/OnButtonClick.d.ts +7 -0
- package/esm/components/ui/pop/OnButtonClick.d.ts.map +1 -0
- package/esm/components/ui/pop/OnButtonClick.js +22 -0
- package/esm/components/ui/pop/OnButtonClick.js.map +1 -0
- package/esm/components/ui/pop/Pop.d.ts +26 -0
- package/esm/components/ui/pop/Pop.d.ts.map +1 -0
- package/esm/components/ui/pop/Pop.js +105 -0
- package/esm/components/ui/pop/Pop.js.map +1 -0
- package/esm/components/ui/pop/Pop.module.scss +58 -0
- package/esm/components/ui/pop/PopOption.d.ts +10 -0
- package/esm/components/ui/pop/PopOption.d.ts.map +1 -0
- package/esm/components/ui/pop/PopOption.js +15 -0
- package/esm/components/ui/pop/PopOption.js.map +1 -0
- package/esm/global.scss +10 -0
- package/esm/index.d.ts +2 -0
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +2 -0
- package/esm/index.js.map +1 -1
- package/esm/utils/useKeyPress.d.ts +3 -0
- package/esm/utils/useKeyPress.d.ts.map +1 -0
- package/esm/utils/useKeyPress.js +25 -0
- package/esm/utils/useKeyPress.js.map +1 -0
- package/next-env.d.ts +0 -1
- package/package.json +2 -2
- package/src/components/form/Checkbox.tsx +3 -3
- package/src/components/icons/Back.tsx +1 -1
- package/src/components/icons/Battery.tsx +3 -2
- package/src/components/icons/Checkmark.tsx +3 -6
- package/src/components/icons/Config.tsx +21 -0
- package/src/components/icons/Forward.tsx +1 -1
- package/src/components/icons/Heart.tsx +21 -0
- package/src/components/icons/Icon.tsx +9 -0
- package/src/components/icons/Search.tsx +1 -1
- package/src/components/icons/Trash.tsx +21 -0
- package/src/components/ui/message/Message.module.scss +31 -0
- package/src/components/ui/message/Message.tsx +21 -0
- package/src/components/ui/pop/HandleEsc.tsx +21 -0
- package/src/components/ui/pop/OnButtonClick.tsx +31 -0
- package/src/components/ui/pop/Pop.module.scss +58 -0
- package/src/components/ui/pop/Pop.tsx +153 -0
- package/src/components/ui/pop/PopOption.tsx +24 -0
- package/src/demo/components/ui/message/Message.tsx +27 -0
- package/src/demo/components/ui/pop/Pop.tsx +80 -0
- package/src/demo/componentsMap.ts +10 -0
- package/src/global.scss +10 -0
- package/src/index.ts +2 -0
- package/src/utils/useKeyPress.ts +32 -0
- package/ATTRIBUTION.md +0 -10
|
@@ -6,6 +6,9 @@ import { Back } from "./Back.js";
|
|
|
6
6
|
import { Forward } from "./Forward.js";
|
|
7
7
|
import { Search } from "./Search.js";
|
|
8
8
|
import { Battery } from "./Battery.js";
|
|
9
|
+
import { Heart } from "./Heart.js";
|
|
10
|
+
import { Trash } from "./Trash.js";
|
|
11
|
+
import { Config } from "./Config.js";
|
|
9
12
|
|
|
10
13
|
enum ICON {
|
|
11
14
|
checkmark = "checkmark",
|
|
@@ -13,6 +16,9 @@ enum ICON {
|
|
|
13
16
|
forward = "forward",
|
|
14
17
|
search = "search",
|
|
15
18
|
battery = "battery",
|
|
19
|
+
heart = "heart",
|
|
20
|
+
trash = "trash",
|
|
21
|
+
config = "config",
|
|
16
22
|
}
|
|
17
23
|
|
|
18
24
|
interface Props {
|
|
@@ -26,6 +32,9 @@ const iconsMap = new Map<ICON, AnyComponent>([
|
|
|
26
32
|
[ICON.forward, Forward],
|
|
27
33
|
[ICON.search, Search],
|
|
28
34
|
[ICON.battery, Battery],
|
|
35
|
+
[ICON.heart, Heart],
|
|
36
|
+
[ICON.trash, Trash],
|
|
37
|
+
[ICON.config, Config],
|
|
29
38
|
]);
|
|
30
39
|
|
|
31
40
|
const Icon: React.FC<Props> = ({ name: iconName, ...props }) => {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
interface Props {
|
|
4
|
+
className?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const Trash: React.FC<Props> = (props) => {
|
|
8
|
+
return (
|
|
9
|
+
<svg
|
|
10
|
+
width={"16"}
|
|
11
|
+
height={"16"}
|
|
12
|
+
viewBox={"0 0 41 37"}
|
|
13
|
+
xmlns={"http://www.w3.org/2000/svg"}
|
|
14
|
+
className={props.className}
|
|
15
|
+
>
|
|
16
|
+
<path d={"M35.7 9.25h3.95q1.4-.4 1.35-1.6-.1-1.2-1.35-1.45H25.6V1.25Q25.6 0 24.4 0h-8.7q-1.1-.05-1.2 1.25V6.2H1.35Q-.1 6.6 0 7.75.1 9 1.35 9.25H5.4v26.5q.15 1.2 1.25 1.25H34.5q1.1-.1 1.2-1.25V9.25M22.6 6.2h-5.05V3.1h5.05v3.1M8.45 33.9V9.25H32.7V33.9H8.45"} />
|
|
17
|
+
</svg>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export { Trash };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
border-top: 1px solid var(--border);
|
|
3
|
+
border-bottom: 1px solid var(--border);
|
|
4
|
+
padding: calc(47px / var(--ratio-dimensions)) calc(83px / var(--ratio-dimensions));
|
|
5
|
+
font-weight: 500;
|
|
6
|
+
line-height: 1.25;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.box {
|
|
10
|
+
border-left: 1px solid var(--border);
|
|
11
|
+
border-right: 1px solid var(--border);
|
|
12
|
+
margin: 12px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.warning {
|
|
16
|
+
background-color: var(--yellow3);
|
|
17
|
+
border-color: var(--yellow1);
|
|
18
|
+
color: var(--yellow2);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.error {
|
|
22
|
+
background-color: var(--pinky3);
|
|
23
|
+
border-color: var(--pinky1);
|
|
24
|
+
color: var(--pinky2);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.info {
|
|
28
|
+
background-color: var(--blue3);
|
|
29
|
+
border-color: var(--blue2);
|
|
30
|
+
color: var(--blue1);
|
|
31
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
|
|
4
|
+
import styles from "./Message.module.scss";
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
type: "warning" | "error" | "info" | "tip";
|
|
8
|
+
variant?: "box";
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const Message: React.FC<Props> = (props) => {
|
|
12
|
+
const cls = classnames(styles.container, {
|
|
13
|
+
[styles.box]: props.variant === "box",
|
|
14
|
+
[styles.warning]: props.type === "warning",
|
|
15
|
+
[styles.error]: props.type === "error",
|
|
16
|
+
[styles.info]: props.type === "info",
|
|
17
|
+
});
|
|
18
|
+
return <div className={cls}>{props.children}</div>;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export { Message };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import { useKeyPress } from "react-use";
|
|
3
|
+
import { useEffect } from "react";
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
onPress: () => void;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const HandleEsc: React.FC<Props> = (props) => {
|
|
10
|
+
const [pressed] = useKeyPress("Escape");
|
|
11
|
+
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (pressed) {
|
|
14
|
+
props.onPress();
|
|
15
|
+
}
|
|
16
|
+
}, [pressed]);
|
|
17
|
+
|
|
18
|
+
return null;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export { HandleEsc };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React, { useEffect, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
interface Props {
|
|
4
|
+
onClick: () => void;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const OnButtonClick: React.FC<Props> = (props) => {
|
|
8
|
+
const theRef = useRef<HTMLDivElement>(null);
|
|
9
|
+
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const div = theRef.current;
|
|
12
|
+
if (!div) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const cb = (e: MouseEvent) => {
|
|
17
|
+
if ((e.target as HTMLDivElement).nodeName.toLowerCase() === "button") {
|
|
18
|
+
setTimeout(() => {
|
|
19
|
+
props.onClick();
|
|
20
|
+
}, 0);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
div.addEventListener("click", cb);
|
|
25
|
+
return () => { div.removeEventListener("click", cb); };
|
|
26
|
+
}, [theRef]);
|
|
27
|
+
|
|
28
|
+
return <div ref={theRef}>{props.children}</div>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export { OnButtonClick };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
.overlay {
|
|
2
|
+
position: fixed;
|
|
3
|
+
background: #0000004c;
|
|
4
|
+
top: 0;
|
|
5
|
+
left: 0;
|
|
6
|
+
right: 0;
|
|
7
|
+
bottom: 0;
|
|
8
|
+
z-index: 4;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.pop {
|
|
12
|
+
z-index: 5;
|
|
13
|
+
position: absolute;
|
|
14
|
+
background: white;
|
|
15
|
+
margin: 0;
|
|
16
|
+
padding: 0;
|
|
17
|
+
|
|
18
|
+
ul, li {
|
|
19
|
+
margin: 0;
|
|
20
|
+
padding: 0;
|
|
21
|
+
list-style-type: none;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
li + li {
|
|
25
|
+
border-top: 1px solid var(--border);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
button {
|
|
29
|
+
border: none;
|
|
30
|
+
background: white;
|
|
31
|
+
height: calc(116px / var(--ratio-dimensions));
|
|
32
|
+
padding: 0 calc(42px / var(--ratio-dimensions));
|
|
33
|
+
box-sizing: border-box;
|
|
34
|
+
width: 100%;
|
|
35
|
+
min-width: calc(460px / var(--ratio-dimensions));
|
|
36
|
+
text-align: left;
|
|
37
|
+
color: var(--pop-text);
|
|
38
|
+
font-size: calc(26px / var(--ratio-font));
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
|
|
42
|
+
svg {
|
|
43
|
+
fill: currentColor;
|
|
44
|
+
margin-right: calc(42px / var(--ratio-dimensions));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
&:hover {
|
|
48
|
+
background: var(--active-bg);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.fakeIcon {
|
|
54
|
+
display: inline-block;
|
|
55
|
+
width: 16px;
|
|
56
|
+
height: 16px;
|
|
57
|
+
margin-right: calc(42px / var(--ratio-dimensions));
|
|
58
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import React, { Component, createRef } from "react";
|
|
2
|
+
|
|
3
|
+
import { HandleEsc } from "./HandleEsc";
|
|
4
|
+
import { OnButtonClick } from "./OnButtonClick";
|
|
5
|
+
import { PopOption } from "./PopOption";
|
|
6
|
+
import styles from "./Pop.module.scss";
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
open: boolean;
|
|
10
|
+
onClose: () => void;
|
|
11
|
+
anchor?: HTMLElement | "prev" | "next";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface State {
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
vertical: "top" | "bottom";
|
|
18
|
+
horizontal: "left" | "right";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const html = typeof document === "object" ? document.getElementsByTagName("html")[0] : null;
|
|
22
|
+
|
|
23
|
+
const getElementDimensions = (elem: HTMLElement) => {
|
|
24
|
+
return {
|
|
25
|
+
width: elem.clientWidth,
|
|
26
|
+
height: elem.clientHeight,
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const getElementLocation = (element: HTMLElement, outerElement = html): [State["vertical"], State["horizontal"]] => {
|
|
31
|
+
const outer = getElementDimensions(outerElement!);
|
|
32
|
+
const rect = element.getBoundingClientRect();
|
|
33
|
+
|
|
34
|
+
const distanceToBottom = outer.height - rect.bottom;
|
|
35
|
+
const distanceToTop = rect.top;
|
|
36
|
+
|
|
37
|
+
const verticalLocation = distanceToTop > distanceToBottom ? "bottom" : "top";
|
|
38
|
+
|
|
39
|
+
const distanceToLeft = rect.left;
|
|
40
|
+
const distanceToRight = outer.width - rect.right;
|
|
41
|
+
|
|
42
|
+
const horizontalLocation = distanceToLeft > distanceToRight ? "right" : "left";
|
|
43
|
+
|
|
44
|
+
return [verticalLocation, horizontalLocation];
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
class Pop extends Component<Props, State> {
|
|
48
|
+
public constructor(props: Props) {
|
|
49
|
+
super(props);
|
|
50
|
+
|
|
51
|
+
this.state = {
|
|
52
|
+
x: 0,
|
|
53
|
+
y: 0,
|
|
54
|
+
vertical: "top",
|
|
55
|
+
horizontal: "left",
|
|
56
|
+
};
|
|
57
|
+
this.rootRef = createRef();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public componentDidUpdate(prevProps: Props) {
|
|
61
|
+
if (!prevProps.open && this.props.open) {
|
|
62
|
+
this.onOpen();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public static Option: typeof PopOption = PopOption;
|
|
67
|
+
|
|
68
|
+
private readonly rootRef: React.RefObject<HTMLDivElement>;
|
|
69
|
+
|
|
70
|
+
private getAnchorElement() {
|
|
71
|
+
if (this.props.anchor instanceof HTMLElement) {
|
|
72
|
+
return this.props.anchor;
|
|
73
|
+
}
|
|
74
|
+
if (!this.rootRef.current) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (this.props.anchor === "prev") {
|
|
79
|
+
return this.rootRef.current.previousElementSibling;
|
|
80
|
+
}
|
|
81
|
+
if (this.props.anchor === "next") {
|
|
82
|
+
return this.rootRef.current.nextElementSibling;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private readonly onOpen = () => {
|
|
87
|
+
const anchorElement = this.getAnchorElement();
|
|
88
|
+
if (!anchorElement) {
|
|
89
|
+
console.warn("PopOptions can not find anchor element");
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// @todo use get derived state
|
|
93
|
+
|
|
94
|
+
const [vertical, horizontal] = getElementLocation(anchorElement as HTMLElement);
|
|
95
|
+
const dimensions = getElementDimensions(html!);
|
|
96
|
+
const rect = anchorElement.getBoundingClientRect();
|
|
97
|
+
|
|
98
|
+
const x = horizontal === "left" ? rect.left : dimensions.width - rect.right;
|
|
99
|
+
const y = vertical === "top" ? rect.bottom : dimensions.height - rect.top;
|
|
100
|
+
|
|
101
|
+
this.setState({
|
|
102
|
+
vertical,
|
|
103
|
+
horizontal,
|
|
104
|
+
x,
|
|
105
|
+
y,
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
private readonly handleOverlayClick = (e: React.MouseEvent) => {
|
|
110
|
+
if (e.target === e.currentTarget) {
|
|
111
|
+
this.props.onClose();
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
private readonly handleEsc = () => {
|
|
116
|
+
this.props.onClose();
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
public render() {
|
|
120
|
+
const style: React.CSSProperties = {};
|
|
121
|
+
|
|
122
|
+
if (this.state.vertical === "top") {
|
|
123
|
+
style.top = this.state.y;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
style.bottom = this.state.y;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (this.state.horizontal === "left") {
|
|
130
|
+
style.left = this.state.x;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
style.right = this.state.x;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!this.props.open) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<div className={styles.overlay} ref={this.rootRef} onClick={this.handleOverlayClick}>
|
|
142
|
+
<HandleEsc onPress={this.handleEsc} />
|
|
143
|
+
<OnButtonClick onClick={this.handleEsc}>
|
|
144
|
+
<ul className={styles.pop} style={style}>
|
|
145
|
+
{this.props.children}
|
|
146
|
+
</ul>
|
|
147
|
+
</OnButtonClick>
|
|
148
|
+
</div>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export { Pop };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import type { ICON } from "../../icons/Icon";
|
|
4
|
+
import { Icon } from "../../icons/Icon";
|
|
5
|
+
|
|
6
|
+
import styles from "./Pop.module.scss";
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
icon?: ICON;
|
|
10
|
+
forceEmptyIcon?: boolean;
|
|
11
|
+
onClick: () => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const PopOption: React.FC<Props> = (props) => {
|
|
15
|
+
const ic = props.icon
|
|
16
|
+
? <Icon name={props.icon} />
|
|
17
|
+
: ((props.forceEmptyIcon ?? true) ? <span className={styles.fakeIcon} /> : null);
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<li><button onClick={props.onClick}>{ic}{props.children}</button></li>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export { PopOption };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { Message } from "../../../../components/ui/message/Message";
|
|
4
|
+
|
|
5
|
+
interface Props {}
|
|
6
|
+
|
|
7
|
+
const MessageDemo: React.FC<Props> = () => {
|
|
8
|
+
return (
|
|
9
|
+
<>
|
|
10
|
+
<Message type={"warning"}>Files will be removed after 30 days.</Message>
|
|
11
|
+
<br /><br />
|
|
12
|
+
<Message type={"error"}>Files will be removed after 30 days.</Message>
|
|
13
|
+
<br /><br />
|
|
14
|
+
<Message type={"info"}>
|
|
15
|
+
Files will be removed after 30 days. Files will be removed after 30 days.
|
|
16
|
+
</Message>
|
|
17
|
+
<br /><br />
|
|
18
|
+
<Message type={"warning"} variant={"box"}>Files will be removed after 30 days.</Message>
|
|
19
|
+
<Message type={"error"} variant={"box"}>Files will be removed after 30 days.</Message>
|
|
20
|
+
<Message type={"info"} variant={"box"}>
|
|
21
|
+
Files will be removed after 30 days. Files will be removed after 30 days.
|
|
22
|
+
</Message>
|
|
23
|
+
</>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { MessageDemo };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import React, { useCallback, useState } from "react";
|
|
2
|
+
import { Pop } from "../../../../components/ui/pop/Pop";
|
|
3
|
+
import { Header } from "../../../../components/layout/header/Header";
|
|
4
|
+
import { StickyHeader } from "../../../../components/layout/header/StickyHeader";
|
|
5
|
+
import { HeaderIconAction } from "../../../../components/layout/header/HeaderIconAction";
|
|
6
|
+
import { ICON } from "../../../../components/icons/Icon";
|
|
7
|
+
import { PopOption } from "../../../../components/ui/pop/PopOption";
|
|
8
|
+
import { Section } from "../../../../components/layout/section/Section";
|
|
9
|
+
|
|
10
|
+
interface Props {}
|
|
11
|
+
|
|
12
|
+
const handleClick = () => {
|
|
13
|
+
console.info("Clicked an option");
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// eslint-disable-next-line max-lines-per-function
|
|
17
|
+
const PopDemo: React.FC<Props> = () => {
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
19
|
+
const [open, setOpen] = useState(false);
|
|
20
|
+
const [leftOpen, setLeftOpen] = useState(false);
|
|
21
|
+
|
|
22
|
+
const handleToggle = useCallback(() => {
|
|
23
|
+
setOpen(p => !p);
|
|
24
|
+
}, []);
|
|
25
|
+
|
|
26
|
+
const handleLeftToggle = useCallback(() => {
|
|
27
|
+
setLeftOpen(p => !p);
|
|
28
|
+
}, []);
|
|
29
|
+
|
|
30
|
+
const handleClose = useCallback(() => {
|
|
31
|
+
setOpen(false);
|
|
32
|
+
}, []);
|
|
33
|
+
|
|
34
|
+
const handleLeftClose = useCallback(() => {
|
|
35
|
+
setLeftOpen(false);
|
|
36
|
+
}, []);
|
|
37
|
+
|
|
38
|
+
const after = (
|
|
39
|
+
<>
|
|
40
|
+
<HeaderIconAction icon={ICON.config} onClick={handleToggle} />
|
|
41
|
+
<Pop anchor={"prev"} open={open} onClose={handleClose}>
|
|
42
|
+
<PopOption icon={ICON.heart} onClick={handleClick}>Add new list</PopOption>
|
|
43
|
+
<PopOption icon={ICON.trash} onClick={handleClick}>Remove empty lists</PopOption>
|
|
44
|
+
<PopOption onClick={handleClick}>Configure</PopOption>
|
|
45
|
+
</Pop>
|
|
46
|
+
</>
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const left = (
|
|
50
|
+
<>
|
|
51
|
+
<HeaderIconAction icon={ICON.checkmark} onClick={handleLeftToggle} />
|
|
52
|
+
<Pop anchor={"prev"} open={leftOpen} onClose={handleLeftClose}>
|
|
53
|
+
<PopOption icon={ICON.heart} onClick={handleClick}>Add new list</PopOption>
|
|
54
|
+
<PopOption icon={ICON.trash} onClick={handleClick}>Remove empty lists</PopOption>
|
|
55
|
+
<PopOption onClick={handleClick}>Configure</PopOption>
|
|
56
|
+
<PopOption icon={ICON.heart} onClick={handleClick}>Add new list</PopOption>
|
|
57
|
+
<PopOption icon={ICON.trash} onClick={handleClick}>Remove empty lists</PopOption>
|
|
58
|
+
<PopOption onClick={handleClick}>Configure</PopOption>
|
|
59
|
+
<PopOption icon={ICON.heart} onClick={handleClick}>Add new list</PopOption>
|
|
60
|
+
<PopOption icon={ICON.trash} onClick={handleClick}>Remove empty lists</PopOption>
|
|
61
|
+
<PopOption onClick={handleClick}>Configure</PopOption>
|
|
62
|
+
</Pop>
|
|
63
|
+
</>
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<StickyHeader>
|
|
68
|
+
<Header before={left} after={after}>
|
|
69
|
+
Some place
|
|
70
|
+
</Header>
|
|
71
|
+
<StickyHeader.Content>
|
|
72
|
+
<Section variant={["vertical", "horizontal"]}>
|
|
73
|
+
Click on the left or right icon to open the menu
|
|
74
|
+
</Section>
|
|
75
|
+
</StickyHeader.Content>
|
|
76
|
+
</StickyHeader>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export { PopDemo };
|
|
@@ -40,6 +40,8 @@ import { ListInsetDemo } from "./components/layout/list/Inset";
|
|
|
40
40
|
import { ListSelectionDemo } from "./components/layout/list/Selection";
|
|
41
41
|
import { TabsDemo } from "./components/ui/tabs/Tabs";
|
|
42
42
|
import { ChoiceDemo } from "./components/form/Choice";
|
|
43
|
+
import { MessageDemo } from "./components/ui/message/Message";
|
|
44
|
+
import { PopDemo } from "./components/ui/pop/Pop";
|
|
43
45
|
|
|
44
46
|
interface TheMap {
|
|
45
47
|
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
@@ -213,6 +215,10 @@ const componentsMap: TheMap = {
|
|
|
213
215
|
name: "Toaster",
|
|
214
216
|
Component: ToasterDemo,
|
|
215
217
|
},
|
|
218
|
+
Message: {
|
|
219
|
+
name: "Message",
|
|
220
|
+
Component: MessageDemo,
|
|
221
|
+
},
|
|
216
222
|
Modal: {
|
|
217
223
|
name: "Modal",
|
|
218
224
|
Component: ModalDemo,
|
|
@@ -227,6 +233,10 @@ const componentsMap: TheMap = {
|
|
|
227
233
|
},
|
|
228
234
|
},
|
|
229
235
|
},
|
|
236
|
+
Pop: {
|
|
237
|
+
name: "Pop up menu",
|
|
238
|
+
Component: PopDemo,
|
|
239
|
+
},
|
|
230
240
|
};
|
|
231
241
|
|
|
232
242
|
export {
|
package/src/global.scss
CHANGED
|
@@ -27,6 +27,8 @@
|
|
|
27
27
|
--text: #323232;
|
|
28
28
|
--sub: #959595;
|
|
29
29
|
|
|
30
|
+
--pop-text: #666;
|
|
31
|
+
|
|
30
32
|
--toolbar-border: #ababab;
|
|
31
33
|
--toolbar-bg: #f8f8f8;
|
|
32
34
|
--modal-bg: #f7f7f7;
|
|
@@ -47,6 +49,8 @@
|
|
|
47
49
|
|
|
48
50
|
// Shades: https://maketintsandshades.com/#038bf4,ff7200,7357e8,3ec234,3ec234,ff388f,ea2700
|
|
49
51
|
--blue1: #038bf4;
|
|
52
|
+
--blue2: #b7d6f5;
|
|
53
|
+
--blue3: #dbe6ff;
|
|
50
54
|
--orange1: #ff7200;
|
|
51
55
|
--orange1-darker: #cc5b00;
|
|
52
56
|
--purple1: #7357e8;
|
|
@@ -54,6 +58,12 @@
|
|
|
54
58
|
--green1-darker: #38af2f;
|
|
55
59
|
--pink1: #ff388f;
|
|
56
60
|
--red1: #ea2700;
|
|
61
|
+
--yellow1: #ffde9d;
|
|
62
|
+
--yellow2: #e4a429;
|
|
63
|
+
--yellow3: #fff5db;
|
|
64
|
+
--pinky1: #f5c0b7;
|
|
65
|
+
--pinky2: #e07b67;
|
|
66
|
+
--pinky3: #ffe1db;
|
|
57
67
|
|
|
58
68
|
--grey1: #737373;
|
|
59
69
|
|
package/src/index.ts
CHANGED
|
@@ -20,7 +20,9 @@ export * from "./components/ui/action/Action.js";
|
|
|
20
20
|
export * from "./components/ui/action/EqualActions.js";
|
|
21
21
|
export * from "./components/ui/button/Button.js";
|
|
22
22
|
export * from "./components/ui/directionPad/Pad.js";
|
|
23
|
+
export * from "./components/ui/message/Message.js";
|
|
23
24
|
export * from "./components/ui/modal/Modal.js";
|
|
24
25
|
export * from "./components/ui/modal/ModalButtons.js";
|
|
26
|
+
export * from "./components/ui/pop/Pop.js";
|
|
25
27
|
export * from "./components/ui/tabs/Selector.js";
|
|
26
28
|
export * from "./components/ui/toaster/Toaster.js";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
|
|
3
|
+
const useKeyPress = (targetKey: string) => {
|
|
4
|
+
const [keyPressed, setKeyPressed] = useState(false);
|
|
5
|
+
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const handleKeyDown = ({ key }: KeyboardEvent): void => {
|
|
8
|
+
if (key === targetKey) {
|
|
9
|
+
setKeyPressed(true);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const handleKeyUp = ({ key }: KeyboardEvent): void => {
|
|
14
|
+
if (key === targetKey) {
|
|
15
|
+
setKeyPressed(false);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
20
|
+
window.addEventListener("keyup", handleKeyUp);
|
|
21
|
+
return () => {
|
|
22
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
23
|
+
window.removeEventListener("keyup", handleKeyUp);
|
|
24
|
+
};
|
|
25
|
+
}, [targetKey]);
|
|
26
|
+
|
|
27
|
+
return keyPressed;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
useKeyPress,
|
|
32
|
+
};
|