elbe-ui 0.2.21 → 0.2.23
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/package.json +1 -1
- package/src/index.tsx +1 -0
- package/src/ui/components/flex.tsx +1 -1
- package/src/ui/components/scaffold.tsx +79 -0
- package/style/color_style.scss +9 -8
- package/style/components.scss +26 -0
package/package.json
CHANGED
package/src/index.tsx
CHANGED
|
@@ -17,6 +17,7 @@ export * from "./ui/components/input/input_field";
|
|
|
17
17
|
export * from "./ui/components/input/range";
|
|
18
18
|
export * from "./ui/components/input/select";
|
|
19
19
|
export * from "./ui/components/padded";
|
|
20
|
+
export * from "./ui/components/scaffold";
|
|
20
21
|
export * from "./ui/components/spinner";
|
|
21
22
|
export * from "./ui/components/text";
|
|
22
23
|
export * from "./ui/components/toggle_button";
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { useEffect, useState } from "preact/compat";
|
|
2
|
+
import { Column, IconButton, Icons, Row, Text } from "../..";
|
|
3
|
+
|
|
4
|
+
type HeaderParams = {
|
|
5
|
+
title?: string;
|
|
6
|
+
back: null | "close" | "back";
|
|
7
|
+
actions?: any;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Header is a layout component that provides a header for a page.
|
|
12
|
+
* It is used to create a consistent header for pages.
|
|
13
|
+
* @param back - The back button type. If null, no back button is shown. If "close", a close button is shown. If "back", a back button is shown.
|
|
14
|
+
* @param title - The title of the page.
|
|
15
|
+
* @param actions - The actions to show on the right side of the header.
|
|
16
|
+
*/
|
|
17
|
+
export function Header({ back, title, actions }: HeaderParams) {
|
|
18
|
+
if (history.length == 0) back = null;
|
|
19
|
+
const goBack = () => history.go(-1);
|
|
20
|
+
|
|
21
|
+
const [isScrolledTop, setIsScrolled] = useState(false);
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const _handle = () => setIsScrolled(window.scrollY > 0);
|
|
25
|
+
window.addEventListener("scroll", _handle);
|
|
26
|
+
return () => {
|
|
27
|
+
window.removeEventListener("scroll", _handle);
|
|
28
|
+
};
|
|
29
|
+
}, []);
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<div>
|
|
33
|
+
<div style="height: 4.5rem"></div>
|
|
34
|
+
<div
|
|
35
|
+
class="header"
|
|
36
|
+
style={isScrolledTop ? "" : "border-color: transparent"}
|
|
37
|
+
>
|
|
38
|
+
<div class="flex-1">
|
|
39
|
+
{back === "close" ? (
|
|
40
|
+
<IconButton.integrated icon={Icons.X} onTap={goBack} />
|
|
41
|
+
) : back === "back" ? (
|
|
42
|
+
<IconButton.integrated icon={Icons.ArrowLeft} onTap={goBack} />
|
|
43
|
+
) : null}
|
|
44
|
+
</div>
|
|
45
|
+
<Text.h4 v={title} />
|
|
46
|
+
<Row class="flex-1" gap={0.5} main="end">
|
|
47
|
+
{actions}
|
|
48
|
+
</Row>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Scaffold is a layout component that provides a header and a content area.
|
|
56
|
+
* It is used to create a consistent layout for pages.
|
|
57
|
+
*/
|
|
58
|
+
export function Scaffold({
|
|
59
|
+
children,
|
|
60
|
+
limited = false,
|
|
61
|
+
gap = 1,
|
|
62
|
+
...header
|
|
63
|
+
}: {
|
|
64
|
+
limited?: boolean;
|
|
65
|
+
children: any;
|
|
66
|
+
gap?: number;
|
|
67
|
+
} & HeaderParams) {
|
|
68
|
+
return (
|
|
69
|
+
<Column cross="stretch" gap={0}>
|
|
70
|
+
<Header {...header} />
|
|
71
|
+
|
|
72
|
+
<div class={`padded ${limited ? "base-limited" : ""}`}>
|
|
73
|
+
<Column cross="stretch" gap={gap ?? 1}>
|
|
74
|
+
{children}
|
|
75
|
+
</Column>
|
|
76
|
+
</div>
|
|
77
|
+
</Column>
|
|
78
|
+
);
|
|
79
|
+
}
|
package/style/color_style.scss
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
@use "sass:color";
|
|
2
|
+
@function cPart($c, $part) {@return color.channel($c, $part, $space: rgb)}
|
|
3
|
+
|
|
4
|
+
@function cHumanGray($c) {
|
|
5
|
+
@return calc(((cPart($c, "red") * 299) + (cPart($c,"green") * 587) + (cPart($c,"blue") * 114)) / 1000);
|
|
6
|
+
}
|
|
7
|
+
|
|
1
8
|
@function contrast($colorA, $colorB) {
|
|
2
|
-
$yiqA:
|
|
3
|
-
|
|
4
|
-
1000
|
|
5
|
-
);
|
|
6
|
-
$yiqB: calc(
|
|
7
|
-
((red($colorB) * 299) + (green($colorB) * 587) + (blue($colorB) * 114)) /
|
|
8
|
-
1000
|
|
9
|
-
);
|
|
9
|
+
$yiqA: cHumanGray($colorA);
|
|
10
|
+
$yiqB: cHumanGray($colorB);
|
|
10
11
|
@return abs($yiqA - $yiqB);
|
|
11
12
|
}
|
|
12
13
|
|
package/style/components.scss
CHANGED
|
@@ -305,6 +305,32 @@ dialog {
|
|
|
305
305
|
transition: max-height 0.25s ease-in;
|
|
306
306
|
}
|
|
307
307
|
|
|
308
|
+
.header {
|
|
309
|
+
@extend .box;
|
|
310
|
+
@extend .row;
|
|
311
|
+
width: 100%;
|
|
312
|
+
position: fixed;
|
|
313
|
+
left: 0;
|
|
314
|
+
top: 0;
|
|
315
|
+
display: flex;
|
|
316
|
+
font-size: larger;
|
|
317
|
+
font-weight: 900;
|
|
318
|
+
border-width: 20px;
|
|
319
|
+
border-style: solid;
|
|
320
|
+
border-width: 0 0 2px 0;
|
|
321
|
+
//border-width: 0 0 2px 0;
|
|
322
|
+
|
|
323
|
+
background-color: #ffffff70;
|
|
324
|
+
backdrop-filter: blur(10px);
|
|
325
|
+
-webkit-backdrop-filter: blur(10px);
|
|
326
|
+
z-index: 20;
|
|
327
|
+
// place border inside the element:
|
|
328
|
+
box-sizing: border-box;
|
|
329
|
+
height: 4.5rem;
|
|
330
|
+
justify-content: space-between;
|
|
331
|
+
align-items: center;
|
|
332
|
+
}
|
|
333
|
+
|
|
308
334
|
// =============== INPUTS ===============
|
|
309
335
|
|
|
310
336
|
input[type="text"],
|