@jirawatpyk/aura-react 5.33.0 → 5.35.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/README.md +16 -2
- package/dist/aura.bundle.js +831 -412
- package/dist/cjs/index.cjs +830 -411
- package/dist/esm/ActionBar.js +1 -0
- package/dist/esm/AppShell.js +16 -2
- package/dist/esm/BottomNav.js +26 -2
- package/dist/esm/StatusTile.js +53 -0
- package/dist/esm/autoTip.js +5 -0
- package/dist/esm/breakpoints.js +18 -1
- package/dist/esm/index.js +5 -0
- package/dist/esm/responsive.js +1 -15
- package/dist/esm/scrollHide.js +96 -0
- package/dist/esm/strings.js +5 -0
- package/dist/esm/strings.sv.js +5 -0
- package/dist/esm/strings.th.js +5 -0
- package/dist/esm/tiles.js +220 -0
- package/dist/index.d.cts +126 -36
- package/dist/index.d.ts +126 -36
- package/dist/locales/sv.cjs +5 -0
- package/dist/locales/sv.d.cts +7 -0
- package/dist/locales/sv.d.ts +7 -0
- package/dist/locales/th.cjs +5 -0
- package/dist/locales/th.d.cts +7 -0
- package/dist/locales/th.d.ts +7 -0
- package/dist/server/index.cjs +274 -27
- package/dist/server/index.d.cts +78 -0
- package/dist/server/index.d.ts +78 -0
- package/dist/server/index.js +274 -27
- package/dist/styles.css +86 -5
- package/dist/styles.layer.css +86 -5
- package/package.json +1 -1
package/dist/esm/ActionBar.js
CHANGED
|
@@ -35,6 +35,7 @@ const ActionBar = React.forwardRef(function ActionBar2(props, ref) {
|
|
|
35
35
|
},
|
|
36
36
|
role: "region",
|
|
37
37
|
"aria-label": props.label || t.actions,
|
|
38
|
+
"data-aura-hide-bottomnav": props.hidesBottomNav && !idle ? "" : void 0,
|
|
38
39
|
className: cx(
|
|
39
40
|
"aura-actionbar",
|
|
40
41
|
"aura-actionbar--" + (props.position || "viewport"),
|
package/dist/esm/AppShell.js
CHANGED
|
@@ -5,6 +5,7 @@ import { IconButton } from "./IconButton.js";
|
|
|
5
5
|
import { cx, useIsoLayoutEffect, useMergedRef } from "./internal.js";
|
|
6
6
|
import { useStrings } from "./locale.js";
|
|
7
7
|
import { useBreakpoint } from "./responsive.js";
|
|
8
|
+
import { useHideOnScroll } from "./scrollHide.js";
|
|
8
9
|
import { IconMenu } from "./icons.js";
|
|
9
10
|
const AppShell = React.forwardRef(function AppShell2(props, ref) {
|
|
10
11
|
const t = useStrings();
|
|
@@ -29,13 +30,24 @@ const AppShell = React.forwardRef(function AppShell2(props, ref) {
|
|
|
29
30
|
const mergedRef = useMergedRef(ref, rootRef);
|
|
30
31
|
const hasBar = !!(props.header || props.nav);
|
|
31
32
|
const barH = React.useState(null);
|
|
33
|
+
const away = useHideOnScroll(!!props.headerHideOnScroll && hasBar, barRef, "(max-width: 1023.98px)", barH[0] || 56);
|
|
34
|
+
const awayRef = React.useRef(away);
|
|
35
|
+
awayRef.current = away;
|
|
36
|
+
useIsoLayoutEffect(
|
|
37
|
+
function() {
|
|
38
|
+
const root = rootRef.current, bar = barRef.current;
|
|
39
|
+
if (!root || !bar) return;
|
|
40
|
+
root.style.setProperty("--aura-shell-bar-height", away ? "0px" : bar.getBoundingClientRect().height + "px");
|
|
41
|
+
},
|
|
42
|
+
[away]
|
|
43
|
+
);
|
|
32
44
|
useIsoLayoutEffect(
|
|
33
45
|
function() {
|
|
34
46
|
const root = rootRef.current, bar = barRef.current;
|
|
35
47
|
if (!root || !bar) return;
|
|
36
48
|
function sync() {
|
|
37
49
|
const h = bar.getBoundingClientRect().height;
|
|
38
|
-
root.style.setProperty("--aura-shell-bar-height", h + "px");
|
|
50
|
+
root.style.setProperty("--aura-shell-bar-height", awayRef.current ? "0px" : h + "px");
|
|
39
51
|
if (h > 0) barH[1](Math.round(h));
|
|
40
52
|
}
|
|
41
53
|
sync();
|
|
@@ -103,7 +115,9 @@ const AppShell = React.forwardRef(function AppShell2(props, ref) {
|
|
|
103
115
|
ref: barRef,
|
|
104
116
|
className: cx(
|
|
105
117
|
"aura-shell__bar",
|
|
106
|
-
(!props.header || props.headerHideFrom === "lg") && "aura-shell__bar--menu-only"
|
|
118
|
+
(!props.header || props.headerHideFrom === "lg") && "aura-shell__bar--menu-only",
|
|
119
|
+
props.headerHideOnScroll && "aura-shell__bar--hides",
|
|
120
|
+
away && "is-away"
|
|
107
121
|
)
|
|
108
122
|
},
|
|
109
123
|
props.nav ? /* @__PURE__ */ React.createElement(
|
package/dist/esm/BottomNav.js
CHANGED
|
@@ -3,6 +3,8 @@ import * as React from "react";
|
|
|
3
3
|
import { Icon } from "./Icon.js";
|
|
4
4
|
import { cx, devWarnOnce, plainClick, useMaybeControlled } from "./internal.js";
|
|
5
5
|
import { useLinkComponent, useStrings } from "./locale.js";
|
|
6
|
+
import { useHideOnScroll } from "./scrollHide.js";
|
|
7
|
+
import { breakpoints } from "./breakpoints.js";
|
|
6
8
|
const BottomNav = React.forwardRef(function BottomNav2(props, ref) {
|
|
7
9
|
const t = useStrings();
|
|
8
10
|
const Link = useLinkComponent(props.linkComponent);
|
|
@@ -13,11 +15,33 @@ const BottomNav = React.forwardRef(function BottomNav2(props, ref) {
|
|
|
13
15
|
);
|
|
14
16
|
const active = st[0];
|
|
15
17
|
const hide = props.hideFrom === false ? "always" : "below-" + (props.hideFrom || "lg");
|
|
18
|
+
const own = React.useRef(null);
|
|
19
|
+
const hf = props.hideFrom === false ? null : props.hideFrom || "lg";
|
|
20
|
+
const away = useHideOnScroll(
|
|
21
|
+
!!props.hideOnScroll,
|
|
22
|
+
own,
|
|
23
|
+
hf ? "(max-width: " + (breakpoints[hf] - 0.02) + "px)" : "all",
|
|
24
|
+
64
|
|
25
|
+
);
|
|
26
|
+
const setRef = React.useCallback(
|
|
27
|
+
function(el) {
|
|
28
|
+
own.current = el;
|
|
29
|
+
if (typeof ref === "function") ref(el);
|
|
30
|
+
else if (ref) ref.current = el;
|
|
31
|
+
},
|
|
32
|
+
[ref]
|
|
33
|
+
);
|
|
16
34
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: cx("aura-bottomnav-spacer", "aura-bottomnav--" + hide), "aria-hidden": "true" }), /* @__PURE__ */ React.createElement(
|
|
17
35
|
"nav",
|
|
18
36
|
{
|
|
19
|
-
ref,
|
|
20
|
-
className: cx(
|
|
37
|
+
ref: setRef,
|
|
38
|
+
className: cx(
|
|
39
|
+
"aura-bottomnav",
|
|
40
|
+
"aura-bottomnav--" + hide,
|
|
41
|
+
props.hideOnScroll && "aura-bottomnav--hides",
|
|
42
|
+
away && "is-away",
|
|
43
|
+
props.className
|
|
44
|
+
),
|
|
21
45
|
"aria-label": props.label || t.mainNav
|
|
22
46
|
},
|
|
23
47
|
/* @__PURE__ */ React.createElement("ul", { className: "aura-bottomnav__list" }, props.items.map(function(it) {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { useLinkComponent, useStrings } from "./locale.js";
|
|
4
|
+
import { useAutoTip } from "./autoTip.js";
|
|
5
|
+
import { devWarnOnce } from "./classes.js";
|
|
6
|
+
import { statusTileElement } from "./tiles.js";
|
|
7
|
+
const useIsoLayoutEffect = typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect;
|
|
8
|
+
const StatusTile = React.forwardRef(function StatusTile2(props, ref) {
|
|
9
|
+
const Link = useLinkComponent(props.linkComponent);
|
|
10
|
+
const t = useStrings();
|
|
11
|
+
useAutoTip();
|
|
12
|
+
if (!props.href && (props["aria-label"] || props["aria-labelledby"]))
|
|
13
|
+
devWarnOnce(
|
|
14
|
+
"status-tile-label",
|
|
15
|
+
"StatusTile `aria-label` needs `href`: without a link the tile is a plain box, where a name is not allowed."
|
|
16
|
+
);
|
|
17
|
+
const titleRef = React.useRef(null);
|
|
18
|
+
const check = React.useCallback(function() {
|
|
19
|
+
const el = titleRef.current;
|
|
20
|
+
if (!el) return;
|
|
21
|
+
const cut = el.scrollHeight > el.clientHeight + 1;
|
|
22
|
+
const text = (el.textContent || "").replace(/,$/, "").trim();
|
|
23
|
+
if (cut && text) el.setAttribute("data-aura-tip", text);
|
|
24
|
+
else el.removeAttribute("data-aura-tip");
|
|
25
|
+
}, []);
|
|
26
|
+
useIsoLayoutEffect(check, [props.title, check]);
|
|
27
|
+
const linked = !!props.href;
|
|
28
|
+
React.useEffect(
|
|
29
|
+
function() {
|
|
30
|
+
const el = titleRef.current;
|
|
31
|
+
if (!el) return;
|
|
32
|
+
let live = true;
|
|
33
|
+
const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(check) : null;
|
|
34
|
+
const mo = typeof MutationObserver !== "undefined" ? new MutationObserver(check) : null;
|
|
35
|
+
if (ro) ro.observe(el);
|
|
36
|
+
if (mo) mo.observe(el, { characterData: true, childList: true, subtree: true });
|
|
37
|
+
if (document.fonts && document.fonts.ready)
|
|
38
|
+
document.fonts.ready.then(function() {
|
|
39
|
+
if (live) check();
|
|
40
|
+
});
|
|
41
|
+
return function() {
|
|
42
|
+
live = false;
|
|
43
|
+
if (ro) ro.disconnect();
|
|
44
|
+
if (mo) mo.disconnect();
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
[check, linked]
|
|
48
|
+
);
|
|
49
|
+
return statusTileElement(props, ref, Link, t, titleRef);
|
|
50
|
+
});
|
|
51
|
+
export {
|
|
52
|
+
StatusTile
|
|
53
|
+
};
|
package/dist/esm/autoTip.js
CHANGED
|
@@ -22,6 +22,11 @@ function source(t) {
|
|
|
22
22
|
const tag = el.closest(".aura-tag");
|
|
23
23
|
if (tag) s = tag.querySelector(".aura-tag__text[" + ATTR + "]");
|
|
24
24
|
}
|
|
25
|
+
if (!s) {
|
|
26
|
+
const tile = el.closest(".aura-status-tile");
|
|
27
|
+
const control = el.closest("a, button, input, select, textarea, [tabindex]");
|
|
28
|
+
if (tile && (!control || control === tile)) s = tile.querySelector(".aura-status-tile__title[" + ATTR + "]");
|
|
29
|
+
}
|
|
25
30
|
if (!s || !s.getAttribute(ATTR) || !s.isConnected) return null;
|
|
26
31
|
if (s.getAttribute("aria-expanded") === "true") return null;
|
|
27
32
|
return s;
|
package/dist/esm/breakpoints.js
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
const breakpoints = { sm: 640, md: 768, lg: 1024, xl: 1280 };
|
|
3
|
+
const ORDER = ["base", "sm", "md", "lg", "xl"];
|
|
4
|
+
function respVars(prefix, value, map) {
|
|
5
|
+
const style = {};
|
|
6
|
+
if (value == null) return style;
|
|
7
|
+
if (typeof value !== "object") value = { base: value };
|
|
8
|
+
let byBp = value, cur;
|
|
9
|
+
ORDER.forEach(function(k) {
|
|
10
|
+
if (byBp[k] !== void 0) cur = map ? map(byBp[k]) : byBp[k];
|
|
11
|
+
if (cur !== void 0) style["--" + prefix + "-" + k] = cur;
|
|
12
|
+
});
|
|
13
|
+
return style;
|
|
14
|
+
}
|
|
15
|
+
const space = function(v) {
|
|
16
|
+
return typeof v === "number" ? "var(--aura-space-" + v + ")" : v;
|
|
17
|
+
};
|
|
3
18
|
export {
|
|
4
|
-
breakpoints
|
|
19
|
+
breakpoints,
|
|
20
|
+
respVars,
|
|
21
|
+
space
|
|
5
22
|
};
|
package/dist/esm/index.js
CHANGED
|
@@ -36,6 +36,8 @@ import { Stack } from "./Stack.js";
|
|
|
36
36
|
import { Grid } from "./Grid.js";
|
|
37
37
|
import { Container } from "./Container.js";
|
|
38
38
|
import { PageHeader } from "./PageHeader.js";
|
|
39
|
+
import { StatusTile } from "./StatusTile.js";
|
|
40
|
+
import { TileGrid, Sparkline } from "./tiles.js";
|
|
39
41
|
import { AppShell } from "./AppShell.js";
|
|
40
42
|
import { ActionBar } from "./ActionBar.js";
|
|
41
43
|
import { Separator } from "./Separator.js";
|
|
@@ -111,9 +113,11 @@ export {
|
|
|
111
113
|
Separator,
|
|
112
114
|
SideNav,
|
|
113
115
|
Skeleton,
|
|
116
|
+
Sparkline,
|
|
114
117
|
Stack,
|
|
115
118
|
Stat,
|
|
116
119
|
StatusPill,
|
|
120
|
+
StatusTile,
|
|
117
121
|
Stepper,
|
|
118
122
|
Surface,
|
|
119
123
|
Switch,
|
|
@@ -128,6 +132,7 @@ export {
|
|
|
128
132
|
Textarea,
|
|
129
133
|
Th,
|
|
130
134
|
ThemeStyle,
|
|
135
|
+
TileGrid,
|
|
131
136
|
TimePicker,
|
|
132
137
|
Toaster,
|
|
133
138
|
Tooltip,
|
package/dist/esm/responsive.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
import { breakpoints } from "./breakpoints.js";
|
|
3
|
+
import { breakpoints, respVars, space } from "./breakpoints.js";
|
|
4
4
|
const ORDER = ["base", "sm", "md", "lg", "xl"];
|
|
5
5
|
function useBreakpoint() {
|
|
6
6
|
return React.useSyncExternalStore(subscribe, current, function() {
|
|
@@ -27,20 +27,6 @@ function useResponsive(value) {
|
|
|
27
27
|
for (let i = ORDER.indexOf(bp); i >= 0; i--) if (map[ORDER[i]] !== void 0) return map[ORDER[i]];
|
|
28
28
|
return void 0;
|
|
29
29
|
}
|
|
30
|
-
function respVars(prefix, value, map) {
|
|
31
|
-
const style = {};
|
|
32
|
-
if (value == null) return style;
|
|
33
|
-
if (typeof value !== "object") value = { base: value };
|
|
34
|
-
let byBp = value, cur;
|
|
35
|
-
ORDER.forEach(function(k) {
|
|
36
|
-
if (byBp[k] !== void 0) cur = map ? map(byBp[k]) : byBp[k];
|
|
37
|
-
if (cur !== void 0) style["--" + prefix + "-" + k] = cur;
|
|
38
|
-
});
|
|
39
|
-
return style;
|
|
40
|
-
}
|
|
41
|
-
const space = function(v) {
|
|
42
|
-
return typeof v === "number" ? "var(--aura-space-" + v + ")" : v;
|
|
43
|
-
};
|
|
44
30
|
export {
|
|
45
31
|
breakpoints,
|
|
46
32
|
respVars,
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
const STEP = 8;
|
|
4
|
+
function useHideOnScroll(enabled, el, media, from) {
|
|
5
|
+
const st = React.useState(false), hidden = st[0], setHidden = st[1];
|
|
6
|
+
React.useEffect(
|
|
7
|
+
function() {
|
|
8
|
+
if (!enabled || typeof window === "undefined") {
|
|
9
|
+
setHidden(false);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const mq = window.matchMedia ? window.matchMedia(media) : null;
|
|
13
|
+
let last = window.scrollY, lastH = window.innerHeight, resizedAt = -1e9, run = 0;
|
|
14
|
+
let restore = null;
|
|
15
|
+
function update() {
|
|
16
|
+
if (restore) {
|
|
17
|
+
const r = restore;
|
|
18
|
+
if (performance.now() > r.until || window.scrollY >= r.y - 1) restore = null;
|
|
19
|
+
else {
|
|
20
|
+
restore = null;
|
|
21
|
+
last = r.y;
|
|
22
|
+
window.scrollTo(window.scrollX, r.y);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const y = window.scrollY, dy = y - last;
|
|
27
|
+
last = y;
|
|
28
|
+
const node2 = el.current;
|
|
29
|
+
if (mq && !mq.matches || y <= from || node2 && document.activeElement && node2.contains(document.activeElement)) {
|
|
30
|
+
run = 0;
|
|
31
|
+
setHidden(false);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (window.innerHeight !== lastH || performance.now() - resizedAt < 150) {
|
|
35
|
+
lastH = window.innerHeight;
|
|
36
|
+
resizedAt = performance.now();
|
|
37
|
+
run = 0;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (y + window.innerHeight > document.documentElement.scrollHeight + 1) return;
|
|
41
|
+
run = dy > 0 === run > 0 ? run + dy : dy;
|
|
42
|
+
if (run > STEP) setHidden(true);
|
|
43
|
+
else if (run < -STEP) setHidden(false);
|
|
44
|
+
}
|
|
45
|
+
let tabbing = false;
|
|
46
|
+
function disarm() {
|
|
47
|
+
restore = null;
|
|
48
|
+
}
|
|
49
|
+
function onKey(e) {
|
|
50
|
+
if (e.key !== "Tab" && e.code !== "Tab") {
|
|
51
|
+
if (e.key !== "Shift") restore = null;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
tabbing = true;
|
|
55
|
+
requestAnimationFrame(function() {
|
|
56
|
+
tabbing = false;
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function reveal() {
|
|
60
|
+
const n = el.current;
|
|
61
|
+
if (n && n.classList.contains("is-away")) {
|
|
62
|
+
n.classList.remove("is-away");
|
|
63
|
+
if (tabbing) {
|
|
64
|
+
if (window.scrollY < last) window.scrollTo(window.scrollX, last);
|
|
65
|
+
else restore = { y: last, until: performance.now() + 400 };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
setHidden(false);
|
|
69
|
+
}
|
|
70
|
+
window.addEventListener("scroll", update, { passive: true });
|
|
71
|
+
window.addEventListener("resize", update);
|
|
72
|
+
document.addEventListener("keydown", onKey, true);
|
|
73
|
+
window.addEventListener("wheel", disarm, { passive: true, capture: true });
|
|
74
|
+
window.addEventListener("touchstart", disarm, { passive: true, capture: true });
|
|
75
|
+
window.addEventListener("pointerdown", disarm, true);
|
|
76
|
+
const node = el.current;
|
|
77
|
+
if (node) node.addEventListener("focusin", reveal);
|
|
78
|
+
if (mq && mq.addEventListener) mq.addEventListener("change", update);
|
|
79
|
+
return function() {
|
|
80
|
+
window.removeEventListener("scroll", update);
|
|
81
|
+
window.removeEventListener("resize", update);
|
|
82
|
+
document.removeEventListener("keydown", onKey, true);
|
|
83
|
+
window.removeEventListener("wheel", disarm, true);
|
|
84
|
+
window.removeEventListener("touchstart", disarm, true);
|
|
85
|
+
window.removeEventListener("pointerdown", disarm, true);
|
|
86
|
+
if (node) node.removeEventListener("focusin", reveal);
|
|
87
|
+
if (mq && mq.removeEventListener) mq.removeEventListener("change", update);
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
[enabled, el, media, from]
|
|
91
|
+
);
|
|
92
|
+
return enabled && hidden;
|
|
93
|
+
}
|
|
94
|
+
export {
|
|
95
|
+
useHideOnScroll
|
|
96
|
+
};
|
package/dist/esm/strings.js
CHANGED
|
@@ -127,6 +127,11 @@ const STRINGS = {
|
|
|
127
127
|
},
|
|
128
128
|
breadcrumbMore: "Show the full path",
|
|
129
129
|
stepError: "has errors",
|
|
130
|
+
statusDown: "Down",
|
|
131
|
+
statusProblem: "Problem",
|
|
132
|
+
statusMaintenance: "Maintenance",
|
|
133
|
+
statusOk: "OK",
|
|
134
|
+
statusUnknown: "No data",
|
|
130
135
|
accepts: function(list, max) {
|
|
131
136
|
return [list, max && "up to " + max + " each"].filter(Boolean).join(", ");
|
|
132
137
|
}
|
package/dist/esm/strings.sv.js
CHANGED
|
@@ -123,6 +123,11 @@ const sv = {
|
|
|
123
123
|
},
|
|
124
124
|
breadcrumbMore: "Visa hela s\xF6kv\xE4gen",
|
|
125
125
|
stepError: "har fel",
|
|
126
|
+
statusDown: "Nere",
|
|
127
|
+
statusProblem: "Problem",
|
|
128
|
+
statusMaintenance: "Underh\xE5ll",
|
|
129
|
+
statusOk: "OK",
|
|
130
|
+
statusUnknown: "Ingen data",
|
|
126
131
|
accepts: function(list, max) {
|
|
127
132
|
return [list, max && "h\xF6gst " + max + " per fil"].filter(Boolean).join(", ");
|
|
128
133
|
}
|
package/dist/esm/strings.th.js
CHANGED
|
@@ -123,6 +123,11 @@ const th = {
|
|
|
123
123
|
},
|
|
124
124
|
breadcrumbMore: "\u0E41\u0E2A\u0E14\u0E07\u0E40\u0E2A\u0E49\u0E19\u0E17\u0E32\u0E07\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14",
|
|
125
125
|
stepError: "\u0E21\u0E35\u0E02\u0E49\u0E2D\u0E1C\u0E34\u0E14\u0E1E\u0E25\u0E32\u0E14",
|
|
126
|
+
statusDown: "\u0E25\u0E48\u0E21",
|
|
127
|
+
statusProblem: "\u0E21\u0E35\u0E1B\u0E31\u0E0D\u0E2B\u0E32",
|
|
128
|
+
statusMaintenance: "\u0E1B\u0E34\u0E14\u0E1B\u0E23\u0E31\u0E1A\u0E1B\u0E23\u0E38\u0E07",
|
|
129
|
+
statusOk: "\u0E1B\u0E01\u0E15\u0E34",
|
|
130
|
+
statusUnknown: "\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E21\u0E35\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25",
|
|
126
131
|
accepts: function(list, max) {
|
|
127
132
|
return [list, max && "\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 " + max + " \u0E15\u0E48\u0E2D\u0E44\u0E1F\u0E25\u0E4C"].filter(Boolean).join(" \xB7 ");
|
|
128
133
|
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { Icon } from "./Icon.js";
|
|
4
|
+
import { cx, devWarnOnce } from "./classes.js";
|
|
5
|
+
import { respVars } from "./breakpoints.js";
|
|
6
|
+
import { STRINGS } from "./strings.js";
|
|
7
|
+
import { IconCircleAlert, IconCircleCheck, IconCircleDotDashed, IconTriangleAlert, IconWrench } from "./icons.js";
|
|
8
|
+
const h = React.createElement;
|
|
9
|
+
const STATUS_ICON = {
|
|
10
|
+
down: IconCircleAlert,
|
|
11
|
+
problem: IconTriangleAlert,
|
|
12
|
+
maintenance: IconWrench,
|
|
13
|
+
ok: IconCircleCheck,
|
|
14
|
+
unknown: IconCircleDotDashed
|
|
15
|
+
};
|
|
16
|
+
const STATUS_TONE = {
|
|
17
|
+
down: "danger",
|
|
18
|
+
problem: "warning",
|
|
19
|
+
maintenance: "accent",
|
|
20
|
+
ok: "default",
|
|
21
|
+
unknown: "default"
|
|
22
|
+
};
|
|
23
|
+
const STATUS_WORD = {
|
|
24
|
+
down: "statusDown",
|
|
25
|
+
problem: "statusProblem",
|
|
26
|
+
maintenance: "statusMaintenance",
|
|
27
|
+
ok: "statusOk",
|
|
28
|
+
unknown: "statusUnknown"
|
|
29
|
+
};
|
|
30
|
+
function statusWord(status, t) {
|
|
31
|
+
return String(t[STATUS_WORD[status]] || STATUS_WORD[status]);
|
|
32
|
+
}
|
|
33
|
+
function attrs(props) {
|
|
34
|
+
const out = {};
|
|
35
|
+
Object.keys(props).forEach(function(k) {
|
|
36
|
+
if (k === "id" || k === "style" || k === "lang" || k === "dir" || /^(aria|data)-/.test(k))
|
|
37
|
+
out[k] = props[k];
|
|
38
|
+
});
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
const comma = h("span", { className: "aura-status-tile__sep" }, ",");
|
|
42
|
+
function statusTileElement(props, ref, Link, t, titleRef) {
|
|
43
|
+
const status = STATUS_ICON[props.status] ? props.status : "unknown";
|
|
44
|
+
if (status !== props.status)
|
|
45
|
+
devWarnOnce(
|
|
46
|
+
"status-tile-status-" + String(props.status),
|
|
47
|
+
'StatusTile status="' + String(props.status) + '" is not down, problem, maintenance, ok or unknown: it shows as unknown ("No data"). Map your value first.'
|
|
48
|
+
);
|
|
49
|
+
const valueTone = props.valueTone || STATUS_TONE[status];
|
|
50
|
+
const word = props.statusLabel || statusWord(status, t);
|
|
51
|
+
const markers = (props.markers || []).filter(Boolean);
|
|
52
|
+
const has = function(v) {
|
|
53
|
+
return v != null && v !== false && v !== "";
|
|
54
|
+
};
|
|
55
|
+
const hasValue = has(props.value), hasMeta = has(props.meta);
|
|
56
|
+
const Tag = props.href ? Link : "div";
|
|
57
|
+
return h(
|
|
58
|
+
Tag,
|
|
59
|
+
Object.assign(attrs(props), {
|
|
60
|
+
ref,
|
|
61
|
+
href: props.href,
|
|
62
|
+
className: cx("aura-status-tile", "aura-status-tile--" + status, props.href && "is-interactive", props.className)
|
|
63
|
+
}),
|
|
64
|
+
h(
|
|
65
|
+
"span",
|
|
66
|
+
{ className: "aura-status-tile__head" },
|
|
67
|
+
h(Icon, { name: h(STATUS_ICON[status]), size: 16, className: "aura-status-tile__icon" }),
|
|
68
|
+
h("span", { className: "aura-status-tile__title", ref: titleRef }, props.title, comma),
|
|
69
|
+
h("span", { className: "aura-sr-only" }, word + (hasValue || hasMeta || markers.length ? "," : "")),
|
|
70
|
+
hasValue ? h(
|
|
71
|
+
"span",
|
|
72
|
+
{ className: cx("aura-status-tile__value", "is-" + valueTone) },
|
|
73
|
+
props.value,
|
|
74
|
+
hasMeta || markers.length ? comma : null
|
|
75
|
+
) : null
|
|
76
|
+
),
|
|
77
|
+
hasMeta || markers.length ? h(
|
|
78
|
+
"span",
|
|
79
|
+
{ className: "aura-status-tile__foot" },
|
|
80
|
+
hasMeta ? h("span", { className: "aura-status-tile__meta" }, props.meta, markers.length ? comma : null) : null,
|
|
81
|
+
markers.length ? h(
|
|
82
|
+
"span",
|
|
83
|
+
{ className: "aura-status-tile__markers" },
|
|
84
|
+
markers.map(function(m, i) {
|
|
85
|
+
return h(
|
|
86
|
+
"span",
|
|
87
|
+
{
|
|
88
|
+
key: i,
|
|
89
|
+
className: cx("aura-status-tile__marker", "is-" + (m.tone || "neutral")),
|
|
90
|
+
"data-aura-tip": m.label
|
|
91
|
+
},
|
|
92
|
+
h(Icon, { name: m.icon, size: 14 }),
|
|
93
|
+
h("span", { className: "aura-sr-only" }, m.label + (i < markers.length - 1 ? "," : ""))
|
|
94
|
+
);
|
|
95
|
+
})
|
|
96
|
+
) : null
|
|
97
|
+
) : null
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
function ServerStatusTile(props) {
|
|
101
|
+
return statusTileElement(props, void 0, props.linkComponent || "a", STRINGS.en);
|
|
102
|
+
}
|
|
103
|
+
const TileGrid = React.forwardRef(function TileGrid2(props, ref) {
|
|
104
|
+
const style = Object.assign(
|
|
105
|
+
{},
|
|
106
|
+
respVars("aura-grid-cols", props.columns == null ? { base: 2, md: 3 } : props.columns),
|
|
107
|
+
props.style
|
|
108
|
+
);
|
|
109
|
+
return h(
|
|
110
|
+
"ul",
|
|
111
|
+
Object.assign(attrs(props), {
|
|
112
|
+
ref,
|
|
113
|
+
role: "list",
|
|
114
|
+
className: cx("aura-grid-layout", "aura-tile-grid", props.className),
|
|
115
|
+
style
|
|
116
|
+
}),
|
|
117
|
+
/* toArray drops null and booleans and keys each element; a Fragment's children are items too. */
|
|
118
|
+
flat(props.children).map(function(c, i) {
|
|
119
|
+
return h("li", { key: React.isValidElement(c) && c.key != null ? c.key : i }, c);
|
|
120
|
+
})
|
|
121
|
+
);
|
|
122
|
+
});
|
|
123
|
+
function flat(children) {
|
|
124
|
+
const out = [];
|
|
125
|
+
React.Children.toArray(children).forEach(function(c) {
|
|
126
|
+
if (React.isValidElement(c) && c.type === React.Fragment)
|
|
127
|
+
flat(c.props.children).forEach(function(x) {
|
|
128
|
+
out.push(React.isValidElement(x) ? React.cloneElement(x, { key: String(c.key) + "/" + String(x.key) }) : x);
|
|
129
|
+
});
|
|
130
|
+
else if (c !== "") out.push(c);
|
|
131
|
+
});
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
const SIZES = { sm: [80, 24], md: [120, 32] };
|
|
135
|
+
const PAD = 2;
|
|
136
|
+
function r(n) {
|
|
137
|
+
return Math.round(n * 100) / 100;
|
|
138
|
+
}
|
|
139
|
+
function num(v) {
|
|
140
|
+
return typeof v === "number" && isFinite(v) ? v : null;
|
|
141
|
+
}
|
|
142
|
+
const Sparkline = React.forwardRef(function Sparkline2(props, ref) {
|
|
143
|
+
const wh = SIZES[props.size || "sm"] || SIZES.sm;
|
|
144
|
+
const W = wh[0], H = wh[1];
|
|
145
|
+
const data = (props.data || []).map(num);
|
|
146
|
+
const n = data.length;
|
|
147
|
+
const vals = data.filter(function(v) {
|
|
148
|
+
return v != null;
|
|
149
|
+
});
|
|
150
|
+
let lo = num(props.min), hi = num(props.max);
|
|
151
|
+
if (lo == null) lo = vals.length ? Math.min.apply(null, vals) : 0;
|
|
152
|
+
if (hi == null) hi = vals.length ? Math.max.apply(null, vals) : 0;
|
|
153
|
+
if (lo > hi) {
|
|
154
|
+
const s = lo;
|
|
155
|
+
lo = hi;
|
|
156
|
+
hi = s;
|
|
157
|
+
}
|
|
158
|
+
const step = n > 1 ? (W - 2 * PAD) / (n - 1) : 0;
|
|
159
|
+
const x = function(i) {
|
|
160
|
+
return n > 1 ? PAD + i * step : W / 2;
|
|
161
|
+
};
|
|
162
|
+
const y = function(v) {
|
|
163
|
+
if (hi === lo) return H / 2;
|
|
164
|
+
const k = Math.max(0, Math.min(1, (v - lo) / (hi - lo)));
|
|
165
|
+
return H - PAD - k * (H - 2 * PAD);
|
|
166
|
+
};
|
|
167
|
+
let d = "";
|
|
168
|
+
const dots = [];
|
|
169
|
+
data.forEach(function(v, i) {
|
|
170
|
+
if (v == null) return;
|
|
171
|
+
const prev = i > 0 && data[i - 1] != null, next = i < n - 1 && data[i + 1] != null;
|
|
172
|
+
if (!prev && !next) dots.push(h("circle", { key: "d" + i, cx: r(x(i)), cy: r(y(v)), r: 1.5 }));
|
|
173
|
+
else d += (prev ? "L" : "M") + r(x(i)) + " " + r(y(v));
|
|
174
|
+
});
|
|
175
|
+
const mode = props.failures || "none";
|
|
176
|
+
const fails = [];
|
|
177
|
+
if (mode !== "none" && props.failed)
|
|
178
|
+
data.forEach(function(_v, i) {
|
|
179
|
+
if (!props.failed[i]) return;
|
|
180
|
+
if (mode === "band") {
|
|
181
|
+
const w = Math.max(2, step || W), left = Math.max(0, x(i) - w / 2), right = Math.min(W, x(i) + w / 2);
|
|
182
|
+
fails.push(h("rect", { key: "f" + i, x: r(left), y: 0, width: r(right - left), height: H }));
|
|
183
|
+
} else
|
|
184
|
+
fails.push(
|
|
185
|
+
h("rect", {
|
|
186
|
+
key: "f" + i,
|
|
187
|
+
x: r(Math.max(0, Math.min(W - 1.5, x(i) - 0.75))),
|
|
188
|
+
y: H - 6,
|
|
189
|
+
width: 1.5,
|
|
190
|
+
height: 6
|
|
191
|
+
})
|
|
192
|
+
);
|
|
193
|
+
});
|
|
194
|
+
const named = !!props.label;
|
|
195
|
+
return h(
|
|
196
|
+
"svg",
|
|
197
|
+
Object.assign(attrs(props), {
|
|
198
|
+
ref,
|
|
199
|
+
className: cx("aura-sparkline", "is-" + (props.tone || "neutral"), props.className),
|
|
200
|
+
width: W,
|
|
201
|
+
height: H,
|
|
202
|
+
viewBox: "0 0 " + W + " " + H,
|
|
203
|
+
role: named ? "img" : void 0,
|
|
204
|
+
"aria-label": named ? props.label : void 0,
|
|
205
|
+
"aria-hidden": named ? void 0 : true,
|
|
206
|
+
focusable: "false"
|
|
207
|
+
}),
|
|
208
|
+
fails.length && mode === "band" ? h("g", { className: "aura-sparkline__band" }, fails) : null,
|
|
209
|
+
d ? h("path", { className: "aura-sparkline__line", d }) : null,
|
|
210
|
+
dots.length ? h("g", { className: "aura-sparkline__dots" }, dots) : null,
|
|
211
|
+
fails.length && mode === "ticks" ? h("g", { className: "aura-sparkline__ticks" }, fails) : null
|
|
212
|
+
);
|
|
213
|
+
});
|
|
214
|
+
export {
|
|
215
|
+
ServerStatusTile,
|
|
216
|
+
Sparkline,
|
|
217
|
+
TileGrid,
|
|
218
|
+
statusTileElement,
|
|
219
|
+
statusWord
|
|
220
|
+
};
|