elbe-ui 2.0.10 → 2.0.12
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/dist/ui/app/app.d.ts +2 -1
- package/dist/ui/app/app.js +15 -7
- package/dist/ui/app/app_ctxt.d.ts +4 -2
- package/dist/ui/app/app_ctxt.js +15 -2
- package/dist/ui/components/base/box.js +1 -1
- package/dist/ui/components/base/card.js +2 -2
- package/dist/ui/components/base/state_builder.js +1 -1
- package/dist/ui/components/button/button.js +1 -1
- package/dist/ui/components/button/icon_button.js +1 -1
- package/dist/ui/components/button/toggle_button.js +1 -1
- package/dist/ui/components/dialog/dialog.d.ts +1 -1
- package/dist/ui/components/dialog/dialog.js +2 -2
- package/dist/ui/components/error_view.js +3 -4
- package/dist/ui/components/footer.js +10 -2
- package/dist/ui/components/input/_labeled_input.js +1 -1
- package/dist/ui/components/input/checkbox.js +1 -1
- package/dist/ui/components/input/range.js +1 -1
- package/dist/ui/components/input/switch.js +1 -1
- package/dist/ui/components/input/text/input_field.js +1 -1
- package/dist/ui/components/layout/header.d.ts +34 -7
- package/dist/ui/components/layout/header.js +76 -25
- package/dist/ui/components/layout/menu.js +5 -5
- package/dist/ui/components/layout/page.js +1 -1
- package/dist/ui/components/layout/toolbar.js +1 -1
- package/dist/ui/components/link.js +1 -1
- package/dist/ui/components/progress_bar.js +1 -1
- package/dist/ui/components/routing/route.d.ts +1 -1
- package/dist/ui/components/routing/route.js +8 -1
- package/dist/ui/components/section_card.js +2 -2
- package/dist/ui/components/spinner.js +1 -1
- package/dist/ui/components/table.js +1 -1
- package/dist/ui/components/text.js +1 -1
- package/dist/ui/components/tooltip.js +1 -1
- package/dist/ui/util/_util.d.ts +2 -0
- package/dist/ui/util/_util.js +12 -0
- package/dist/ui/util/toast/toast_ctx.js +1 -1
- package/dist/ui/util/types.d.ts +1 -0
- package/package.json +2 -2
package/dist/ui/app/app.d.ts
CHANGED
|
@@ -23,7 +23,8 @@ type AppProps = _AppProps & {
|
|
|
23
23
|
* - `themeSelector` (function | undefined): An optional function to further customize the theme based on the current theme configuration.
|
|
24
24
|
* - `routerConfig` (object | undefined): Configuration options for the router, such as basePath.
|
|
25
25
|
* - `noGlobalStyles` (boolean | undefined): If true, global styles will not be applied to the document. Useful if you have multiple Elbe apps on the same page.
|
|
26
|
-
* - `children` (ElbeRoute | ElbeRoute[] | undefined): The route components to be rendered within the application.
|
|
26
|
+
* - `children` (ElbeRoute | ElbeRoute[] | undefined): The route components to be rendered within the application. Pass
|
|
27
|
+
* `MenuRoute` components here to define the application's routes and menu items. You may also wrap the menu routes Fragments (<></>).
|
|
27
28
|
* - `globalActions` (ElbeChild[] | undefined): An array of global action components to be displayed in the application header.
|
|
28
29
|
* - `footer` (ElbeChild | undefined): A footer component to be displayed at the bottom of the application.
|
|
29
30
|
*
|
package/dist/ui/app/app.js
CHANGED
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useMemo, useState } from "react";
|
|
3
3
|
import { Box, DialogsProvider, isMenuRoute, omit, ToastProvider, Wouter, } from "../..";
|
|
4
4
|
import { Menu } from "../components/layout/menu";
|
|
5
|
+
import { unwrapFragments } from "../util/_util";
|
|
5
6
|
import { AppContext } from "./app_ctxt";
|
|
6
7
|
/** The main application component that sets up the application context, theme, and routing.
|
|
7
8
|
* Render this component at the root of your application to initialize Elbe UI features:
|
|
@@ -17,7 +18,8 @@ import { AppContext } from "./app_ctxt";
|
|
|
17
18
|
* - `themeSelector` (function | undefined): An optional function to further customize the theme based on the current theme configuration.
|
|
18
19
|
* - `routerConfig` (object | undefined): Configuration options for the router, such as basePath.
|
|
19
20
|
* - `noGlobalStyles` (boolean | undefined): If true, global styles will not be applied to the document. Useful if you have multiple Elbe apps on the same page.
|
|
20
|
-
* - `children` (ElbeRoute | ElbeRoute[] | undefined): The route components to be rendered within the application.
|
|
21
|
+
* - `children` (ElbeRoute | ElbeRoute[] | undefined): The route components to be rendered within the application. Pass
|
|
22
|
+
* `MenuRoute` components here to define the application's routes and menu items. You may also wrap the menu routes Fragments (<></>).
|
|
21
23
|
* - `globalActions` (ElbeChild[] | undefined): An array of global action components to be displayed in the application header.
|
|
22
24
|
* - `footer` (ElbeChild | undefined): A footer component to be displayed at the bottom of the application.
|
|
23
25
|
*
|
|
@@ -76,12 +78,19 @@ function _App(p) {
|
|
|
76
78
|
document.documentElement.style.backgroundColor = bg;
|
|
77
79
|
document.body.style.backgroundColor = bg;
|
|
78
80
|
}, [themeSelected, p.config.noGlobalStyles]);
|
|
79
|
-
const menuItems = useMemo(() => {
|
|
80
|
-
return _extractMenuItems(p.children);
|
|
81
|
-
}, [p.children]);
|
|
82
81
|
const [location, navigate] = Wouter.useLocation();
|
|
83
82
|
const [history, setHistory] = useState([_initialLocation()]);
|
|
84
83
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
84
|
+
const { children, menuItems } = useMemo(() => {
|
|
85
|
+
const childsOrFrags = Array.isArray(p.children)
|
|
86
|
+
? p.children
|
|
87
|
+
: p.children
|
|
88
|
+
? [p.children]
|
|
89
|
+
: [];
|
|
90
|
+
const children = unwrapFragments(childsOrFrags);
|
|
91
|
+
const menuItems = _extractMenuItems(children);
|
|
92
|
+
return { children, menuItems };
|
|
93
|
+
}, [p.children]);
|
|
85
94
|
return (_jsx(p.themeContext.WithTheme, { theme: themeSelected, children: _jsx(AppContext.Provider, { value: {
|
|
86
95
|
appConfig: p.config,
|
|
87
96
|
_appThemeContext: p.themeContext,
|
|
@@ -118,14 +127,13 @@ function _App(p) {
|
|
|
118
127
|
display: "flex",
|
|
119
128
|
width: "100%",
|
|
120
129
|
minHeight: "100vh",
|
|
121
|
-
}, children: [menuItems.length > 0 && _jsx(Menu, { items: menuItems }), _jsx("div", { style: { flex: 1, width: "0px" }, children: _jsx(Wouter.Switch, { children:
|
|
130
|
+
}, children: [menuItems.length > 0 && _jsx(Menu, { items: menuItems }), _jsx("div", { style: { flex: 1, width: "0px" }, children: _jsx(Wouter.Switch, { children: children }) })] }) }) }) }) }));
|
|
122
131
|
}
|
|
123
132
|
function _extractMenuItems(children) {
|
|
124
133
|
if (!children)
|
|
125
134
|
return [];
|
|
126
|
-
const childs = Array.isArray(children) ? children : [children];
|
|
127
135
|
const items = [];
|
|
128
|
-
for (const child of
|
|
136
|
+
for (const child of children) {
|
|
129
137
|
if (!isMenuRoute(child))
|
|
130
138
|
continue;
|
|
131
139
|
items.push(child.props);
|
|
@@ -3,7 +3,7 @@ import { ElbeThemeContext } from "../theme/theme_context";
|
|
|
3
3
|
import { ElbeChild, ElbeChildren, int } from "../util/types";
|
|
4
4
|
export type AppConfig = {
|
|
5
5
|
title?: string;
|
|
6
|
-
|
|
6
|
+
branding?: HeaderLogos;
|
|
7
7
|
globalActions?: ElbeChild[];
|
|
8
8
|
footer?: ElbeChildren | null;
|
|
9
9
|
routerConfig?: {
|
|
@@ -32,6 +32,8 @@ export interface AppState {
|
|
|
32
32
|
_appThemeContext: ElbeThemeContext;
|
|
33
33
|
}
|
|
34
34
|
export declare const AppContext: import("react").Context<AppState | null>;
|
|
35
|
-
export declare function useApp(
|
|
35
|
+
export declare function useApp({ useFallback }?: {
|
|
36
|
+
useFallback?: boolean | undefined;
|
|
37
|
+
}): AppState;
|
|
36
38
|
export declare function useMaybeApp(): AppState | null;
|
|
37
39
|
export {};
|
package/dist/ui/app/app_ctxt.js
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import { createContext, useContext } from "react";
|
|
2
|
+
import { makeThemeContext } from "../theme/theme_context";
|
|
2
3
|
import { throwError, tryOrNull } from "../util/util";
|
|
3
4
|
export const AppContext = createContext(null);
|
|
4
|
-
|
|
5
|
+
const _fallbackAppContext = {
|
|
6
|
+
appConfig: {},
|
|
7
|
+
router: {
|
|
8
|
+
go: () => { },
|
|
9
|
+
goBack: () => { },
|
|
10
|
+
history: [],
|
|
11
|
+
location: "/",
|
|
12
|
+
},
|
|
13
|
+
_appThemeContext: makeThemeContext({}),
|
|
14
|
+
};
|
|
15
|
+
export function useApp({ useFallback = false } = {}) {
|
|
5
16
|
var _a;
|
|
6
|
-
return ((_a = tryOrNull(() => useContext(AppContext))) !== null && _a !== void 0 ? _a :
|
|
17
|
+
return ((_a = tryOrNull(() => useContext(AppContext))) !== null && _a !== void 0 ? _a : (useFallback
|
|
18
|
+
? _fallbackAppContext
|
|
19
|
+
: throwError("useApp must be used within an ElbeApp context. try using useMaybeApp() or useApp({ useFallback: true }) instead.")));
|
|
7
20
|
}
|
|
8
21
|
export function useMaybeApp() {
|
|
9
22
|
return tryOrNull(() => useContext(AppContext));
|
|
@@ -61,7 +61,7 @@ Box.inverse = (p) => createElement(Box, Object.assign(Object.assign({}, p), { sc
|
|
|
61
61
|
* @returns
|
|
62
62
|
*/
|
|
63
63
|
export function _Box(p) {
|
|
64
|
-
const { _appThemeContext } = useApp();
|
|
64
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
65
65
|
const usedTheme = _appThemeContext.useTheme().useWith(({ color }) => {
|
|
66
66
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
67
67
|
return {
|
|
@@ -18,7 +18,7 @@ import { WithTooltip } from "../tooltip";
|
|
|
18
18
|
export function Card(_a) {
|
|
19
19
|
var _b, _c;
|
|
20
20
|
var { mode, scheme, kind, manner, state, padding = 1, margin = 0, onTap, onLongTap, frosted, bordered, elevated, sharp, overflow, children } = _a, elbe = __rest(_a, ["mode", "scheme", "kind", "manner", "state", "padding", "margin", "onTap", "onLongTap", "frosted", "bordered", "elevated", "sharp", "overflow", "children"]);
|
|
21
|
-
const { _appThemeContext } = useApp();
|
|
21
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
22
22
|
const { theme } = _appThemeContext.useTheme();
|
|
23
23
|
const isBordered = useMemo(() => {
|
|
24
24
|
return (bordered !== null && bordered !== void 0 ? bordered : false) || theme.color.isContrast;
|
|
@@ -31,7 +31,7 @@ export function Card(_a) {
|
|
|
31
31
|
? "var(--elbe-context-color-border, transparent)"
|
|
32
32
|
: undefined,
|
|
33
33
|
};
|
|
34
|
-
return (_jsx(WithTooltip, { tooltip: elbe.tooltip, children: _jsx(_Box, { mode: mode, scheme: scheme, kind: kind, manner: manner, padding: padding, margin: margin, state: state, className: elbe.className, flex: elbe.flex, elevated: elevated, frosted: frosted, style: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ overflow: overflow }, css.borderRadius(styles.radius)), css.borderStyle(styles.borderStyle)), css.borderWidth(styles.borderWidth)), css.borderColor(styles.borderColor)), { opacity: onTap === null ? 0.5 : 1 }), ((_b = elbe.style) !== null && _b !== void 0 ? _b : {})), native: Object.assign(Object.assign(Object.assign({}, (onTap !== undefined
|
|
34
|
+
return (_jsx(WithTooltip, { tooltip: elbe.tooltip, children: _jsx(_Box, { mode: mode, scheme: scheme, kind: kind, manner: manner, padding: padding, margin: margin, state: state, className: elbe.className, flex: elbe.flex, elevated: elevated, frosted: frosted, typeLabel: elbe.typeLabel, style: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ overflow: overflow }, css.borderRadius(styles.radius)), css.borderStyle(styles.borderStyle)), css.borderWidth(styles.borderWidth)), css.borderColor(styles.borderColor)), { opacity: onTap === null ? 0.5 : 1 }), ((_b = elbe.style) !== null && _b !== void 0 ? _b : {})), native: Object.assign(Object.assign(Object.assign({}, (onTap !== undefined
|
|
35
35
|
? {
|
|
36
36
|
onClick: (e) => {
|
|
37
37
|
e.preventDefault();
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
import { useApp } from "../../app/app_ctxt";
|
|
4
4
|
export function WithStateTheme(p) {
|
|
5
|
-
const { _appThemeContext } = useApp();
|
|
5
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
6
6
|
const [elState, setElState] = useState("neutral");
|
|
7
7
|
if (!p.theme) {
|
|
8
8
|
console.error("WithStateTheme: No theme provided");
|
|
@@ -32,7 +32,7 @@ function _Btn(_a) {
|
|
|
32
32
|
var _b, _c;
|
|
33
33
|
var { manner, kind, onTap, icon, label, children, contentAlign } = _a, elbe = __rest(_a, ["manner", "kind", "onTap", "icon", "label", "children", "contentAlign"]);
|
|
34
34
|
const toolbarCtx = useToolbar();
|
|
35
|
-
const { _appThemeContext } = useApp();
|
|
35
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
36
36
|
const baseTheme = _appThemeContext.useTheme().useWith(({ color }) => ({
|
|
37
37
|
color: Object.assign(Object.assign({}, color), { selection: Object.assign(Object.assign({}, color.selection), { kind: kind !== null && kind !== void 0 ? kind : color.selection.kind, manner: manner }) }),
|
|
38
38
|
}), [kind, manner]);
|
|
@@ -28,7 +28,7 @@ IconButton.plain = (p) => _jsx(_btn, Object.assign({}, p, { manner: "plain" }));
|
|
|
28
28
|
function _btn(_a) {
|
|
29
29
|
var _b;
|
|
30
30
|
var { icon, onTap, manner } = _a, elbe = __rest(_a, ["icon", "onTap", "manner"]);
|
|
31
|
-
const { _appThemeContext } = useApp();
|
|
31
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
32
32
|
const baseTheme = _appThemeContext.useTheme().useWith(({ color }) => {
|
|
33
33
|
var _a, _b;
|
|
34
34
|
return ({
|
|
@@ -20,7 +20,7 @@ import { Icon } from "./icon_button";
|
|
|
20
20
|
export function ToggleButton(_a) {
|
|
21
21
|
var _b;
|
|
22
22
|
var { value, onChange, label, icon, kind } = _a, elbe = __rest(_a, ["value", "onChange", "label", "icon", "kind"]);
|
|
23
|
-
const { _appThemeContext } = useApp();
|
|
23
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
24
24
|
const { theme } = _appThemeContext.useTheme();
|
|
25
25
|
return (_jsxs(Button, Object.assign({ manner: value ? "major" : "flat", kind: kind, tooltip: elbe.tooltip, onTap: onChange && (() => onChange(!value)), ariaLabel: (_b = elbe.ariaLabel) !== null && _b !== void 0 ? _b : label, contentAlign: "space-between" }, applyProps("toggle_button", elbe, [], {
|
|
26
26
|
overflow: "hidden",
|
|
@@ -18,7 +18,7 @@ export type ElbeDialogProps = {
|
|
|
18
18
|
* - `kind` (ColorSelection.KindsAlert | undefined): An optional kind to display an alert icon next to the title.
|
|
19
19
|
* - `dismissible` ("none" | "button" | "barrier" | undefined): Controls how the dialog can be dismissed.
|
|
20
20
|
* - "none": The dialog cannot be dismissed by user actions.
|
|
21
|
-
* - "button": A close button is provided in the title bar.
|
|
21
|
+
* - "button": A close button is provided in the title bar. (**DEFAULT**)
|
|
22
22
|
* - "barrier": Clicking outside the dialog will close it.
|
|
23
23
|
* Default is "button".
|
|
24
24
|
* - `maxWidth` (number | undefined): The maximum width of the dialog in rem units. Defaults to 90vw if not provided.
|
|
@@ -34,7 +34,7 @@ export function elevatedBackdropStyle(open, theme, openMergeStyle) {
|
|
|
34
34
|
* - `kind` (ColorSelection.KindsAlert | undefined): An optional kind to display an alert icon next to the title.
|
|
35
35
|
* - `dismissible` ("none" | "button" | "barrier" | undefined): Controls how the dialog can be dismissed.
|
|
36
36
|
* - "none": The dialog cannot be dismissed by user actions.
|
|
37
|
-
* - "button": A close button is provided in the title bar.
|
|
37
|
+
* - "button": A close button is provided in the title bar. (**DEFAULT**)
|
|
38
38
|
* - "barrier": Clicking outside the dialog will close it.
|
|
39
39
|
* Default is "button".
|
|
40
40
|
* - `maxWidth` (number | undefined): The maximum width of the dialog in rem units. Defaults to 90vw if not provided.
|
|
@@ -55,7 +55,7 @@ export function elevatedBackdropStyle(open, theme, openMergeStyle) {
|
|
|
55
55
|
*/
|
|
56
56
|
export function Dialog(_a) {
|
|
57
57
|
var { dismissible = "button" } = _a, p = __rest(_a, ["dismissible"]);
|
|
58
|
-
const { _appThemeContext } = useApp();
|
|
58
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
59
59
|
const theme = _appThemeContext.useTheme().useWith((c) => ({
|
|
60
60
|
color: Object.assign(Object.assign({}, c.color), { selection: Object.assign(Object.assign({}, c.color.selection), { scheme: "primary", kind: "accent", manner: "plain", state: "neutral" }) }),
|
|
61
61
|
}), []);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { icons } from "lucide-react";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
-
import { Card, Column, Dialog, Icon, Icons,
|
|
4
|
+
import { Button, Card, Column, Dialog, Icon, Icons, Text, toElbeError, } from "../..";
|
|
5
5
|
import { _maybeL10n } from "../util/l10n/_l10n_util";
|
|
6
6
|
/** * A component to display error messages in a user-friendly manner.
|
|
7
7
|
*
|
|
@@ -45,9 +45,8 @@ export function PrettyErrorView({ error, retry, labels = {
|
|
|
45
45
|
pt: "detalhes do erro",
|
|
46
46
|
},
|
|
47
47
|
}, }) {
|
|
48
|
-
var _a, _b, _c, _d, _e, _f;
|
|
48
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
49
49
|
const l10n = _maybeL10n();
|
|
50
50
|
const [open, setOpen] = useState(false);
|
|
51
|
-
|
|
52
|
-
return (_jsxs(Column, { cross: "center", style: { margin: "1rem 0", padding: "1rem" }, children: [_jsx(Icon, { icon: (_a = error.icon) !== null && _a !== void 0 ? _a : icons.OctagonAlert }), _jsx("h4", { style: { margin: 0 }, children: (_b = l10n === null || l10n === void 0 ? void 0 : l10n.inline(error.message)) !== null && _b !== void 0 ? _b : "error" }), _jsx("span", { className: "pointer", onClick: () => setOpen(true), children: (_c = l10n === null || l10n === void 0 ? void 0 : l10n.inline(error.description)) !== null && _c !== void 0 ? _c : "" }), retry && (_jsxs("button", { className: "action", onClick: () => retry(), children: [_jsx(Icons.RotateCcw, {}), " ", (_d = l10n === null || l10n === void 0 ? void 0 : l10n.inline(labels.retry)) !== null && _d !== void 0 ? _d : "retry"] })), error.code === 404 && (_jsxs("button", { className: "action", onClick: () => navigate("/", { replace: true }), children: [_jsx(Icons.House, {}), (_e = l10n === null || l10n === void 0 ? void 0 : l10n.inline(labels.home)) !== null && _e !== void 0 ? _e : "go home"] })), _jsx(Dialog, { title: (_f = l10n === null || l10n === void 0 ? void 0 : l10n.inline(labels.details)) !== null && _f !== void 0 ? _f : "error details", open: open, onClose: () => setOpen(false), children: _jsx("pre", { className: "card inverse", children: `code: ${error.code}\n\n` + JSON.stringify(error.details, null, 2) }) })] }));
|
|
51
|
+
return (_jsxs(Column, { cross: "center", style: { margin: "1rem 0", padding: "1rem" }, children: [_jsx(Icon, { icon: (_a = error.icon) !== null && _a !== void 0 ? _a : icons.OctagonAlert }), _jsx(Text.h4, { v: (_b = l10n === null || l10n === void 0 ? void 0 : l10n.inline(error.message)) !== null && _b !== void 0 ? _b : "error" }), _jsx(Text, { align: "center", v: (_c = l10n === null || l10n === void 0 ? void 0 : l10n.inline(error.description)) !== null && _c !== void 0 ? _c : "", style: { cursor: "pointer" }, native: { onClick: () => setOpen(true) } }), retry && (_jsx(Button.flat, { ariaLabel: (_d = l10n === null || l10n === void 0 ? void 0 : l10n.inline(labels.retry)) !== null && _d !== void 0 ? _d : "retry", label: (_e = l10n === null || l10n === void 0 ? void 0 : l10n.inline(labels.retry)) !== null && _e !== void 0 ? _e : "retry", icon: Icons.RotateCcw, onTap: () => retry() })), error.code === 404 && (_jsx(Button.flat, { ariaLabel: (_f = l10n === null || l10n === void 0 ? void 0 : l10n.inline(labels.home)) !== null && _f !== void 0 ? _f : "go home", label: (_g = l10n === null || l10n === void 0 ? void 0 : l10n.inline(labels.home)) !== null && _g !== void 0 ? _g : "go home", icon: Icons.House, onTap: () => (window.location.href = "/") })), _jsx(Dialog, { title: (_h = l10n === null || l10n === void 0 ? void 0 : l10n.inline(labels.details)) !== null && _h !== void 0 ? _h : "error details", open: open, onClose: () => setOpen(false), children: _jsx("pre", { children: `code: ${error.code}\n\n` + JSON.stringify(error.details, null, 2) }) })] }));
|
|
53
52
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { HeartIcon } from "lucide-react";
|
|
3
3
|
import { Card, Column, FlexSpace, Link, Row, Text, useLayoutMode, } from "../..";
|
|
4
|
+
import { useApp } from "../app/app_ctxt";
|
|
4
5
|
/**
|
|
5
6
|
* Footer component. Can contain links, copyright info, version and legal link.
|
|
6
7
|
*
|
|
@@ -13,14 +14,21 @@ import { Card, Column, FlexSpace, Link, Row, Text, useLayoutMode, } from "../.."
|
|
|
13
14
|
* - `marginTop` (number): Margin top in rem units to add space above the footer.
|
|
14
15
|
*/
|
|
15
16
|
export function Footer({ left, right, copyright, version, legal, marginTop, }) {
|
|
17
|
+
const app = useApp({ useFallback: true });
|
|
18
|
+
const { theme } = app._appThemeContext.useTheme();
|
|
16
19
|
const layoutMode = useLayoutMode();
|
|
17
20
|
return (_jsx(Card, { scheme: "secondary", sharp: true, role: "contentinfo", ariaLabel: "footer", style: {
|
|
18
21
|
borderLeftStyle: "none",
|
|
19
22
|
borderRightStyle: "none",
|
|
20
23
|
borderBottomStyle: "none",
|
|
21
|
-
borderTopLeftRadius: layoutMode.isWide
|
|
22
|
-
|
|
24
|
+
borderTopLeftRadius: layoutMode.isWide
|
|
25
|
+
? `${theme.geometry.radius}rem`
|
|
26
|
+
: undefined,
|
|
27
|
+
/*color: theme.color.currentColor.front
|
|
28
|
+
.inter(theme.color.currentColor.back, 0.6)
|
|
29
|
+
.asCss(),*/
|
|
23
30
|
marginTop: `${marginTop !== null && marginTop !== void 0 ? marginTop : 0}rem`,
|
|
31
|
+
marginLeft: layoutMode.isWide && !!app.menu ? "1rem" : undefined,
|
|
24
32
|
}, children: _jsxs(Column, { gap: 1, children: [(left || right) && (_jsxs(Row, { main: "space-between", cross: "start", children: [left && (_jsx(Column, { gap: 0.5, flex: 1, cross: "start", children: left.map((item, i) => item.label ? _jsx(_Link, Object.assign({}, item), i) : item) })), right && (_jsx(Column, { gap: 0.5, flex: 1, cross: "end", children: right.map((item, i) => item.label ? _jsx(_Link, Object.assign({}, item), i) : item) }))] })), (left || right) && (copyright || version || legal) && _jsx("hr", {}), (copyright || version || legal) && (_jsxs(Row, { children: [copyright &&
|
|
25
33
|
(typeof copyright === "string" ? (_jsx(Text, { bold: true, v: copyright })) : (copyright)), version && _jsx(_Version, { version: version }), _jsx(FlexSpace, {}), legal && _jsx(_Link, Object.assign({}, legal))] }))] }) }));
|
|
26
34
|
}
|
|
@@ -11,7 +11,7 @@ import { WithTooltip } from "../tooltip";
|
|
|
11
11
|
*/
|
|
12
12
|
export function LabeledInput(p) {
|
|
13
13
|
var _a, _b;
|
|
14
|
-
const { _appThemeContext } = useApp();
|
|
14
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
15
15
|
const baseTheme = _appThemeContext.useTheme();
|
|
16
16
|
return (_jsx(WithTooltip, { tooltip: p.tooltip, children: _jsx(WithStateTheme, { disabled: (_a = p.disabled) !== null && _a !== void 0 ? _a : false, theme: baseTheme, manner: p.manner, children: _jsxs("div", Object.assign({}, applyProps(p.typeLabel, p, [], Object.assign({ flex: p.flex ? (p.flex === true ? 1 : p.flex) : undefined, width: p.flex ? undefined : ((_b = p.width) !== null && _b !== void 0 ? _b : 12) + "rem", display: "flex", flexDirection: "column", alignItems: "stretch" }, p.style)), { children: [_jsx("label", { htmlFor: p.id, style: {
|
|
17
17
|
display: p.hideLabel ? "none" : "block",
|
|
@@ -17,7 +17,7 @@ import { WithTooltip } from "../tooltip";
|
|
|
17
17
|
* - `manner` ("flat" | "plain" | undefined): The visual style of the checkbox when it is unchecked.
|
|
18
18
|
*/
|
|
19
19
|
export function Checkbox(p) {
|
|
20
|
-
const { _appThemeContext } = useApp();
|
|
20
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
21
21
|
const baseTheme = _appThemeContext.useTheme().useWith(({ color }) => {
|
|
22
22
|
var _a;
|
|
23
23
|
return ({
|
|
@@ -31,7 +31,7 @@ export function Range(p) {
|
|
|
31
31
|
function _StyledRange(_a) {
|
|
32
32
|
var _b, _c;
|
|
33
33
|
var { min = 0, max = 100, step = 1, value, onChange } = _a, elbe = __rest(_a, ["min", "max", "step", "value", "onChange"]);
|
|
34
|
-
const { _appThemeContext } = useApp();
|
|
34
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
35
35
|
const { theme } = _appThemeContext.useTheme().useWith((c) => ({
|
|
36
36
|
color: Object.assign(Object.assign({}, c.color), { selection: Object.assign(Object.assign({}, c.color.selection), { manner: "major" }) }),
|
|
37
37
|
}), []);
|
|
@@ -17,7 +17,7 @@ import { WithTooltip } from "../tooltip";
|
|
|
17
17
|
* - `manner` ("flat" | "plain" | undefined): The visual style of the switch when it is off.
|
|
18
18
|
*/
|
|
19
19
|
export function Switch(p) {
|
|
20
|
-
const { _appThemeContext } = useApp();
|
|
20
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
21
21
|
const baseTheme = _appThemeContext.useTheme().useWith(({ color }) => {
|
|
22
22
|
var _a;
|
|
23
23
|
return ({
|
|
@@ -92,7 +92,7 @@ export var Field;
|
|
|
92
92
|
function _Field(p) {
|
|
93
93
|
var _a, _b, _c, _d;
|
|
94
94
|
{
|
|
95
|
-
const { _appThemeContext } = useApp();
|
|
95
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
96
96
|
const usedTheme = _appThemeContext.useTheme();
|
|
97
97
|
const id = (_a = p.id) !== null && _a !== void 0 ? _a : randomAlphaNum(8, "input_field_");
|
|
98
98
|
const manner = (_b = p.manner) !== null && _b !== void 0 ? _b : "plain";
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { ColorSelection, ElbeChild } from "../../..";
|
|
1
|
+
import { ColorSelection, ElbeChild, remSize } from "../../..";
|
|
2
|
+
/**
|
|
3
|
+
* props for the Header component. Provide logos to the application.
|
|
4
|
+
*
|
|
5
|
+
* You can provide either a custom ElbeChild component or use the AssetLogo component to display an image logo.
|
|
6
|
+
*/
|
|
2
7
|
export type HeaderLogos = {
|
|
3
|
-
logo?:
|
|
4
|
-
|
|
5
|
-
endLogo?: string | ElbeChild;
|
|
6
|
-
endLogoDark?: string | ElbeChild;
|
|
8
|
+
logo?: ElbeChild;
|
|
9
|
+
endLogo?: ElbeChild;
|
|
7
10
|
};
|
|
8
11
|
export type HeaderProps = HeaderLogos & {
|
|
9
12
|
leading?: ElbeChild | "back" | "close";
|
|
@@ -13,10 +16,34 @@ export type HeaderProps = HeaderLogos & {
|
|
|
13
16
|
scheme?: ColorSelection.Schemes;
|
|
14
17
|
};
|
|
15
18
|
export declare function Header(p: HeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
/**
|
|
20
|
+
* Component to display an image logo from asset files.
|
|
21
|
+
*
|
|
22
|
+
* Props:
|
|
23
|
+
* - src: string - The source path for the light theme logo image.
|
|
24
|
+
* - srcDark?: string - Optional source path for the dark theme logo image.
|
|
25
|
+
* - onTap?: () => void - Optional callback function to be called when the logo is clicked.
|
|
26
|
+
* - height?: remSize - Optional height of the logo in rem units (default is 1.25rem).
|
|
27
|
+
*
|
|
28
|
+
* Example usage:
|
|
29
|
+
* ```tsx
|
|
30
|
+
* <AssetLogo
|
|
31
|
+
* src="/assets/logo_light.png"
|
|
32
|
+
* srcDark="/assets/logo_dark.png"
|
|
33
|
+
* onTap={() => window.open("https://example.com", "_blank")}
|
|
34
|
+
* height={2}
|
|
35
|
+
* />
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function AssetLogo(p: {
|
|
39
|
+
src: string;
|
|
40
|
+
srcDark?: string;
|
|
41
|
+
onTap?: () => void;
|
|
42
|
+
height?: remSize;
|
|
43
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
16
44
|
export declare function _Logo(p: {
|
|
17
45
|
flex?: boolean;
|
|
18
|
-
logo:
|
|
19
|
-
logoDark?: string | ElbeChild | null;
|
|
46
|
+
logo: ElbeChild;
|
|
20
47
|
lMargin?: number;
|
|
21
48
|
rMargin?: number;
|
|
22
49
|
}): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { ChevronLeft, MenuIcon, XIcon } from "lucide-react";
|
|
3
|
-
import { useMemo
|
|
4
|
-
import { Card, IconButton, Text, useLayoutMode, useSiteScroll, } from "../../..";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import { Card, IconButton, metaTagContent, Text, useLayoutMode, useSiteScroll, } from "../../..";
|
|
5
5
|
import { useApp } from "../../app/app_ctxt";
|
|
6
6
|
import { _Toolbar } from "./toolbar";
|
|
7
7
|
export function Header(p) {
|
|
8
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j
|
|
9
|
-
const
|
|
10
|
-
const {
|
|
8
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
9
|
+
const gap = 1;
|
|
10
|
+
const { _appThemeContext, appConfig, menu } = useApp({ useFallback: true });
|
|
11
|
+
const { theme } = _appThemeContext.useTheme();
|
|
11
12
|
const layoutMode = useLayoutMode();
|
|
12
13
|
const scroll = useSiteScroll();
|
|
13
|
-
|
|
14
|
-
color: Object.assign(Object.assign({}, t.color), { selection: Object.assign(Object.assign({}, t.color.selection), { scheme: "secondary", manner: "plain" }) }),
|
|
15
|
-
}), [theme]);
|
|
16
|
-
return (_jsxs(Card, { padding: 0, scheme: (_a = p.scheme) !== null && _a !== void 0 ? _a : "primary", manner: "plain", frosted: !theme.color.isContrast,
|
|
14
|
+
return (_jsxs(Card, { typeLabel: "elbe_header", padding: 0, scheme: (_a = p.scheme) !== null && _a !== void 0 ? _a : "primary", manner: "plain", frosted: !theme.color.isContrast,
|
|
17
15
|
//elevated={!!scroll}
|
|
18
16
|
bordered: true, sharp: true, style: {
|
|
19
17
|
position: "sticky",
|
|
@@ -27,39 +25,85 @@ export function Header(p) {
|
|
|
27
25
|
borderTopStyle: "none",
|
|
28
26
|
borderLeftStyle: "none",
|
|
29
27
|
borderRightStyle: "none",
|
|
30
|
-
|
|
28
|
+
borderBottomColor: theme.color.isContrast || scroll
|
|
31
29
|
? theme.color.currentColor.border
|
|
32
30
|
.withAlpha(theme.color.isContrast ? 1 : 0.25)
|
|
33
31
|
.asCss()
|
|
34
32
|
: "transparent",
|
|
35
|
-
|
|
36
|
-
gap:
|
|
33
|
+
borderBottomWidth: theme.geometry.borderWidth + "rem",
|
|
34
|
+
gap: `${gap}rem`,
|
|
37
35
|
zIndex: 80,
|
|
38
|
-
}, children: [p.leading && p.
|
|
39
|
-
? p.leading
|
|
40
|
-
: !layoutMode.isWide &&
|
|
41
|
-
menu && (_jsx(IconButton.plain, { ariaLabel: "open/close menu", onTap: () => menu.setOpen(!menu.isOpen), icon: MenuIcon })), p.leading === "back" && _jsx(BackButton, {}), p.leading === "close" && _jsx(BackButton, { close: true }), !layoutMode.isMobile && (_jsx(_Logo, { logo: (_b = p.logo) !== null && _b !== void 0 ? _b : (_c = appConfig === null || appConfig === void 0 ? void 0 : appConfig.icons) === null || _c === void 0 ? void 0 : _c.logo, logoDark: (_d = p.logoDark) !== null && _d !== void 0 ? _d : (_e = appConfig === null || appConfig === void 0 ? void 0 : appConfig.icons) === null || _e === void 0 ? void 0 : _e.logoDark, lMargin: 0.5 })), (!appConfig || layoutMode.isWide) && (_jsx("div", { style: { margin: "-1rem", width: "1.5rem" } })), _jsx(_HeaderTitle, { title: p.title, center: (_f = p.centerTitle) !== null && _f !== void 0 ? _f : false }), _jsx(_Toolbar, { actions: [...((_g = p.actions) !== null && _g !== void 0 ? _g : []), ...((_h = appConfig === null || appConfig === void 0 ? void 0 : appConfig.globalActions) !== null && _h !== void 0 ? _h : [])] }), layoutMode.isWide && (_jsx(_Logo, { logo: (_j = p.endLogo) !== null && _j !== void 0 ? _j : (_k = appConfig === null || appConfig === void 0 ? void 0 : appConfig.icons) === null || _k === void 0 ? void 0 : _k.endLogo, logoDark: (_l = p.endLogoDark) !== null && _l !== void 0 ? _l : (_m = appConfig === null || appConfig === void 0 ? void 0 : appConfig.icons) === null || _m === void 0 ? void 0 : _m.endLogoDark, rMargin: 0.5 }))] }));
|
|
36
|
+
}, children: [_jsx(_LeadingIcon, { leading: (_b = p.leading) !== null && _b !== void 0 ? _b : null, isWide: layoutMode.isWide, gap: gap }), !layoutMode.isMobile && (_jsx(_Logo, { logo: (_c = p.logo) !== null && _c !== void 0 ? _c : (_d = appConfig === null || appConfig === void 0 ? void 0 : appConfig.branding) === null || _d === void 0 ? void 0 : _d.logo })), _jsx(_HeaderTitle, { title: p.title, center: (_e = p.centerTitle) !== null && _e !== void 0 ? _e : false }), _jsx(_Toolbar, { actions: [...((_f = p.actions) !== null && _f !== void 0 ? _f : []), ...((_g = appConfig === null || appConfig === void 0 ? void 0 : appConfig.globalActions) !== null && _g !== void 0 ? _g : [])] }), layoutMode.isWide && (_jsx(_Logo, { logo: (_h = p.endLogo) !== null && _h !== void 0 ? _h : (_j = appConfig === null || appConfig === void 0 ? void 0 : appConfig.branding) === null || _j === void 0 ? void 0 : _j.endLogo, rMargin: 0.5 }))] }));
|
|
42
37
|
}
|
|
43
|
-
|
|
38
|
+
function _LeadingIcon(p) {
|
|
44
39
|
var _a, _b;
|
|
45
|
-
const {
|
|
40
|
+
const { router, menu } = useApp({ useFallback: true });
|
|
41
|
+
const canGoBack = ((_b = (_a = router.history) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) < 2;
|
|
42
|
+
// if leading is custom component, just return it
|
|
43
|
+
if (p.leading && typeof p.leading !== "string")
|
|
44
|
+
return p.leading;
|
|
45
|
+
// if you can go back and leading is "back" or "close", show it
|
|
46
|
+
if ((p.leading === "back" || p.leading === "close") && canGoBack) {
|
|
47
|
+
return _jsx(BackButton, { close: p.leading === "close" });
|
|
48
|
+
}
|
|
49
|
+
// if the layout is not wide and there is a menu, show menu button
|
|
50
|
+
if (!p.isWide && menu) {
|
|
51
|
+
return (_jsx(IconButton.plain, { ariaLabel: "open/close menu", onTap: () => menu.setOpen(!(menu === null || menu === void 0 ? void 0 : menu.isOpen)), icon: MenuIcon }));
|
|
52
|
+
}
|
|
53
|
+
// return a spacer so content is not squeezed to the left if there is no icon
|
|
54
|
+
return (_jsx("div", { style: {
|
|
55
|
+
marginRight: `-${p.gap}rem`,
|
|
56
|
+
width: ".5rem",
|
|
57
|
+
} }));
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Component to display an image logo from asset files.
|
|
61
|
+
*
|
|
62
|
+
* Props:
|
|
63
|
+
* - src: string - The source path for the light theme logo image.
|
|
64
|
+
* - srcDark?: string - Optional source path for the dark theme logo image.
|
|
65
|
+
* - onTap?: () => void - Optional callback function to be called when the logo is clicked.
|
|
66
|
+
* - height?: remSize - Optional height of the logo in rem units (default is 1.25rem).
|
|
67
|
+
*
|
|
68
|
+
* Example usage:
|
|
69
|
+
* ```tsx
|
|
70
|
+
* <AssetLogo
|
|
71
|
+
* src="/assets/logo_light.png"
|
|
72
|
+
* srcDark="/assets/logo_dark.png"
|
|
73
|
+
* onTap={() => window.open("https://example.com", "_blank")}
|
|
74
|
+
* height={2}
|
|
75
|
+
* />
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export function AssetLogo(p) {
|
|
79
|
+
var _a;
|
|
80
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
46
81
|
const { theme } = _appThemeContext.useTheme();
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
82
|
+
const trueSrc = getTrueSrc(theme.color.isDark && p.srcDark ? p.srcDark : p.src);
|
|
83
|
+
return (_jsx("img", { src: trueSrc, onClick: (e) => {
|
|
84
|
+
var _a;
|
|
85
|
+
(_a = p.onTap) === null || _a === void 0 ? void 0 : _a.call(p);
|
|
86
|
+
e.preventDefault();
|
|
87
|
+
e.stopPropagation();
|
|
88
|
+
}, style: {
|
|
89
|
+
cursor: p.onTap ? "pointer" : "default",
|
|
90
|
+
height: `${(_a = p.height) !== null && _a !== void 0 ? _a : 1.25}rem`,
|
|
91
|
+
} }));
|
|
92
|
+
}
|
|
93
|
+
export function _Logo(p) {
|
|
94
|
+
var _a, _b;
|
|
95
|
+
return !p.logo ? null : (_jsx("div", { style: {
|
|
50
96
|
flex: p.flex ? 1 : undefined,
|
|
51
97
|
display: "flex",
|
|
52
98
|
alignItems: "center",
|
|
53
99
|
justifyContent: "center",
|
|
54
100
|
marginLeft: `${(_a = p.lMargin) !== null && _a !== void 0 ? _a : 0}rem`,
|
|
55
101
|
marginRight: `${(_b = p.rMargin) !== null && _b !== void 0 ? _b : 0}rem`,
|
|
56
|
-
}, children:
|
|
57
|
-
height: "1.25rem",
|
|
58
|
-
} })) : (logo) }));
|
|
102
|
+
}, children: p.logo }));
|
|
59
103
|
}
|
|
60
104
|
export function BackButton(p) {
|
|
61
105
|
var _a, _b;
|
|
62
|
-
const { router } = useApp();
|
|
106
|
+
const { router } = useApp({ useFallback: true });
|
|
63
107
|
const hidden = ((_b = (_a = router.history) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) < 2;
|
|
64
108
|
return hidden ? null : (_jsx(IconButton.plain, { ariaLabel: p.close ? "close" : "go back", onTap: () => router.goBack(), icon: p.close ? XIcon : ChevronLeft }, "hello-back"));
|
|
65
109
|
}
|
|
@@ -81,3 +125,10 @@ export function _HeaderTitle(p) {
|
|
|
81
125
|
left: globalCenter ? "50%" : "0",
|
|
82
126
|
}, children: typeof p.title === "string" ? (_jsx(Text.h3, { align: p.center ? "center" : "start", v: p.title })) : (p.title) }) }));
|
|
83
127
|
}
|
|
128
|
+
function getTrueSrc(src) {
|
|
129
|
+
var _a;
|
|
130
|
+
const _basePath = (_a = metaTagContent("basepath")) !== null && _a !== void 0 ? _a : "/";
|
|
131
|
+
return src.startsWith("./") && typeof window !== "undefined"
|
|
132
|
+
? window.location.origin + _basePath + src.slice(2)
|
|
133
|
+
: src;
|
|
134
|
+
}
|
|
@@ -7,7 +7,7 @@ import { Card } from "../base/card";
|
|
|
7
7
|
import { Button } from "../button/button";
|
|
8
8
|
import { Column } from "./flex";
|
|
9
9
|
export function Menu(p) {
|
|
10
|
-
const { _appThemeContext, menu } = useApp();
|
|
10
|
+
const { _appThemeContext, menu } = useApp({ useFallback: true });
|
|
11
11
|
const { theme } = _appThemeContext.useTheme();
|
|
12
12
|
const layoutMode = useLayoutMode();
|
|
13
13
|
const isWideOrOpen = useMemo(() => {
|
|
@@ -42,8 +42,8 @@ export function Menu(p) {
|
|
|
42
42
|
})) }), _jsx(_Menu, { topBot: topBot, wideOrOpen: isWideOrOpen, menuWidth: menuWidth })] }));
|
|
43
43
|
}
|
|
44
44
|
function _Menu(p) {
|
|
45
|
-
var _a
|
|
46
|
-
const { _appThemeContext, menu, appConfig } = useApp();
|
|
45
|
+
var _a;
|
|
46
|
+
const { _appThemeContext, menu, appConfig } = useApp({ useFallback: true });
|
|
47
47
|
const { theme } = _appThemeContext.useTheme();
|
|
48
48
|
const layoutMode = useLayoutMode();
|
|
49
49
|
if (!menu)
|
|
@@ -73,10 +73,10 @@ function _Menu(p) {
|
|
|
73
73
|
transition: theme.motion.reduced ? "none" : "width 200ms ease-in-out",
|
|
74
74
|
}, children: p.wideOrOpen && (_jsxs(_Fragment, { children: [_jsx(Button.plain, { sharp: layoutMode.isWide, contentAlign: "start", ariaLabel: "open/close menu", onTap: () => menu.setOpen(!menu.isOpen), icon: MenuIcon, style: {
|
|
75
75
|
marginBottom: ".5rem",
|
|
76
|
-
}, children: !layoutMode.isWide && (_jsx(_Logo, { logo: (_a = appConfig.
|
|
76
|
+
}, children: !layoutMode.isWide && (_jsx(_Logo, { logo: (_a = appConfig.branding) === null || _a === void 0 ? void 0 : _a.logo, lMargin: 0.5 })) }), _jsx(Column, { flex: 1, scroll: true, noScrollbar: true, children: p.topBot.top.map((i, index) => (_jsx(_MenuItemView, { item: i }, index))) }), p.topBot.bottom.map((i, index) => (_jsx(_MenuItemView, { item: i }, index)))] })) }));
|
|
77
77
|
}
|
|
78
78
|
function _MenuItemView({ item }) {
|
|
79
|
-
const { menu, router } = useApp();
|
|
79
|
+
const { menu, router } = useApp({ useFallback: true });
|
|
80
80
|
if (!menu)
|
|
81
81
|
return null;
|
|
82
82
|
return (_jsx(Button
|
|
@@ -32,7 +32,7 @@ export function _Toolbar(p) {
|
|
|
32
32
|
}
|
|
33
33
|
export function OverflowMenu(p) {
|
|
34
34
|
var _a;
|
|
35
|
-
const { _appThemeContext } = useApp();
|
|
35
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
36
36
|
const { theme } = _appThemeContext.useTheme();
|
|
37
37
|
const [open, setOpen] = useState(false);
|
|
38
38
|
return !((_a = p.items) === null || _a === void 0 ? void 0 : _a.length) ? null : (_jsxs("div", { style: {
|
|
@@ -19,7 +19,7 @@ import { WithTooltip } from "./tooltip";
|
|
|
19
19
|
*/
|
|
20
20
|
export function Link(p) {
|
|
21
21
|
var _a;
|
|
22
|
-
const { _appThemeContext } = useApp();
|
|
22
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
23
23
|
const baseTheme = _appThemeContext.useTheme().useWith(({ color }) => {
|
|
24
24
|
var _a;
|
|
25
25
|
return ({
|
|
@@ -21,7 +21,7 @@ import { useApp } from "../app/app_ctxt";
|
|
|
21
21
|
*/
|
|
22
22
|
export function ProgressBar(_a) {
|
|
23
23
|
var { value, max = 100, manner = "flat" } = _a, elbe = __rest(_a, ["value", "max", "manner"]);
|
|
24
|
-
const { _appThemeContext } = useApp();
|
|
24
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
25
25
|
const theme = _appThemeContext.useTheme().useWith(({ color }) => ({
|
|
26
26
|
color: Object.assign(Object.assign({}, color), { selection: Object.assign(Object.assign({}, color.selection), { manner: manner }) }),
|
|
27
27
|
}), [manner]);
|
|
@@ -26,5 +26,5 @@ export declare function MenuRoute(p: _MenuRouteProps): import("react/jsx-runtime
|
|
|
26
26
|
* a helper function to create a <Wouter.Route> with a path.
|
|
27
27
|
*/
|
|
28
28
|
export declare const Route: typeof Wouter.Route;
|
|
29
|
-
export declare function isMenuRoute(r:
|
|
29
|
+
export declare function isMenuRoute(r: React.ReactNode): r is React.ReactElement<_MenuRouteProps>;
|
|
30
30
|
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
2
3
|
import { Wouter } from "../../..";
|
|
3
4
|
/**
|
|
4
5
|
* a route that also renders a menu item in the <AppBase> component.
|
|
@@ -16,5 +17,11 @@ export function MenuRoute(p) {
|
|
|
16
17
|
*/
|
|
17
18
|
export const Route = Wouter.Route;
|
|
18
19
|
export function isMenuRoute(r) {
|
|
19
|
-
|
|
20
|
+
// check if r is a React element with props path, label and icon
|
|
21
|
+
if (!React.isValidElement(r))
|
|
22
|
+
return false;
|
|
23
|
+
const rEl = r;
|
|
24
|
+
if (!rEl.props || typeof rEl.props !== "object")
|
|
25
|
+
return false;
|
|
26
|
+
return "path" in rEl.props && "label" in rEl.props && "icon" in rEl.props;
|
|
20
27
|
}
|
|
@@ -28,13 +28,13 @@ import { useApp } from "../app/app_ctxt";
|
|
|
28
28
|
*/
|
|
29
29
|
export function SectionCard(p) {
|
|
30
30
|
var _a;
|
|
31
|
-
const _app = useApp();
|
|
31
|
+
const _app = useApp({ useFallback: true });
|
|
32
32
|
const _appTheme = _app._appThemeContext.useTheme();
|
|
33
33
|
const [collapsed, setCollapsed] = useState(p.collapsed);
|
|
34
34
|
const [hintOpen, setHintOpen] = useState(false);
|
|
35
35
|
return (_jsxs(Card, { bordered: p.bordered, style: {
|
|
36
36
|
padding: ` ${1 - (p.bordered ? _appTheme.theme.geometry.borderWidth : 0)}rem`,
|
|
37
|
-
}, children: [_jsx(Dialog, { title: p.title + " - Info", open: hintOpen, onClose: () => setHintOpen(false), children: typeof p.hint === "string" ? (_jsx("div", { className: "elbe-hint-markdown", children: _jsx(Markdown, { children: p.hint, allowElement: () => true }) })) : (p.hint) }), _jsxs(Column, { children: [_jsxs(Card, { onTap: collapsed === undefined
|
|
37
|
+
}, children: [_jsx(Dialog, { title: p.title + " - Info", open: hintOpen, maxWidth: 35, onClose: () => setHintOpen(false), children: typeof p.hint === "string" ? (_jsx("div", { className: "elbe-hint-markdown", children: _jsx(Markdown, { children: p.hint, allowElement: () => true }) })) : (p.hint) }), _jsxs(Column, { children: [_jsxs(Card, { onTap: collapsed === undefined
|
|
38
38
|
? undefined
|
|
39
39
|
: () => setCollapsed(!collapsed), margin: -1, padding: 1, className: collapsed === undefined ? undefined : "hoverable_card", style: {
|
|
40
40
|
border: "none",
|
|
@@ -19,7 +19,7 @@ function _toPath(c, yFac, yOffset = 0, clamp = [0, 1], xFac = 1) {
|
|
|
19
19
|
export function Spinner(p) {
|
|
20
20
|
var _a;
|
|
21
21
|
const [x, setX] = useState(0);
|
|
22
|
-
const { _appThemeContext } = useApp();
|
|
22
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
23
23
|
const theme = _appThemeContext.useTheme().useWith(({ color }) => {
|
|
24
24
|
var _a;
|
|
25
25
|
return ({
|
|
@@ -29,7 +29,7 @@ import { useApp } from "../app/app_ctxt";
|
|
|
29
29
|
*/
|
|
30
30
|
export function Table(p) {
|
|
31
31
|
var _a, _b;
|
|
32
|
-
const _app = useApp();
|
|
32
|
+
const _app = useApp({ useFallback: true });
|
|
33
33
|
const _appTheme = _app._appThemeContext.useTheme();
|
|
34
34
|
const themeSec = _appTheme.useWith(({ color }) => ({
|
|
35
35
|
color: Object.assign(Object.assign({}, color), { selection: Object.assign(Object.assign({}, color.selection), { scheme: "secondary" }) }),
|
|
@@ -45,7 +45,7 @@ Text.defaultProps = {
|
|
|
45
45
|
variant: "bodyM",
|
|
46
46
|
};
|
|
47
47
|
function _Text(p) {
|
|
48
|
-
const { _appThemeContext } = useApp();
|
|
48
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
49
49
|
const usedTheme = _appThemeContext.useTheme();
|
|
50
50
|
const tVariant = useMemo(() => {
|
|
51
51
|
var _a;
|
|
@@ -8,7 +8,7 @@ export function WithTooltip(p) {
|
|
|
8
8
|
const timeoutRef = useRef(null);
|
|
9
9
|
const [visible, setVisible] = useState(false);
|
|
10
10
|
const [coords, setCoords] = useState({ x: 0, y: 0, top: false, left: false });
|
|
11
|
-
const { _appThemeContext } = useApp();
|
|
11
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
12
12
|
const { theme } = _appThemeContext.useTheme().useWith((c) => ({
|
|
13
13
|
color: Object.assign(Object.assign({}, c.color), { selection: Object.assign(Object.assign({}, c.color.selection), { scheme: "inverse", kind: "accent", manner: "plain", state: "neutral" }) }),
|
|
14
14
|
}), []);
|
package/dist/ui/util/_util.d.ts
CHANGED
|
@@ -6,3 +6,5 @@ export declare namespace css {
|
|
|
6
6
|
function borderWidth(v: React.CSSProperties["borderLeftWidth"] | undefined): React.CSSProperties;
|
|
7
7
|
function borderColor(v: React.CSSProperties["borderLeftColor"] | undefined): React.CSSProperties;
|
|
8
8
|
}
|
|
9
|
+
export declare function isFragment(child: any): child is React.ReactElement;
|
|
10
|
+
export declare function unwrapFragments(children: React.ReactNode): React.ReactNode[];
|
package/dist/ui/util/_util.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import React from "react";
|
|
1
2
|
export function elevatedShadow(dark) {
|
|
2
3
|
return `0px 0px .625rem -.125rem ${dark ? "#ffffff60" : "#00000060"}`;
|
|
3
4
|
}
|
|
@@ -40,3 +41,14 @@ export var css;
|
|
|
40
41
|
}
|
|
41
42
|
css.borderColor = borderColor;
|
|
42
43
|
})(css || (css = {}));
|
|
44
|
+
export function isFragment(child) {
|
|
45
|
+
return React.isValidElement(child) && child.type === React.Fragment;
|
|
46
|
+
}
|
|
47
|
+
export function unwrapFragments(children) {
|
|
48
|
+
return React.Children.toArray(children).flatMap((child) => {
|
|
49
|
+
var _a, _b;
|
|
50
|
+
return isFragment(child)
|
|
51
|
+
? React.Children.toArray((_b = (_a = child.props) === null || _a === void 0 ? void 0 : _a["children"]) !== null && _b !== void 0 ? _b : [])
|
|
52
|
+
: child;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
@@ -17,7 +17,7 @@ export function useToast() {
|
|
|
17
17
|
* @returns a context provider for toast messages
|
|
18
18
|
*/
|
|
19
19
|
export function ToastProvider(p) {
|
|
20
|
-
const { _appThemeContext } = useApp();
|
|
20
|
+
const { _appThemeContext } = useApp({ useFallback: true });
|
|
21
21
|
const { theme } = _appThemeContext.useTheme();
|
|
22
22
|
const rootDOM = useMemo(() => getRootElement("elbe_toast"), []);
|
|
23
23
|
const [toasts, setToasts] = useState([]);
|
package/dist/ui/util/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "elbe-ui",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.12",
|
|
4
4
|
"author": "Robin Naumann",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"build:dts": "tsc --declaration",
|
|
24
24
|
"build:css": "sass -q style/elbe-util.scss dist/elbe.css",
|
|
25
25
|
"build": "rm -rf ./dist && bun run build:ts && bun run build:dts && bun run build:css ",
|
|
26
|
-
"
|
|
26
|
+
"serve": "bun run build && (cd example && bun run dev)",
|
|
27
27
|
"pub": "npm login && bun run build && npm publish && bun run pub:example",
|
|
28
28
|
"pub:example": "bun run build && (cd example && bun run build) && open example/dist"
|
|
29
29
|
},
|