elbe-ui 2.0.11 → 2.0.15
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/bit/_bit_provider.js +4 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/ui/app/app.d.ts +2 -1
- package/dist/ui/app/app.js +67 -43
- 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 +2 -2
- package/dist/ui/components/button/toggle_button.js +1 -1
- package/dist/ui/components/dialog/dialog.js +1 -1
- package/dist/ui/components/error_view.d.ts +2 -1
- package/dist/ui/components/error_view.js +2 -2
- 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/flex.js +2 -0
- 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 +6 -3
- 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.d.ts +4 -1
- package/dist/ui/components/tooltip.js +39 -16
- package/dist/ui/theme/subthemes/color/_seed.js +1 -1
- package/dist/ui/util/_util.d.ts +2 -0
- package/dist/ui/util/_util.js +12 -0
- package/dist/ui/util/l10n/l10n.d.ts +3 -0
- package/dist/ui/util/l10n/l10n.js +10 -3
- package/dist/ui/util/toast/toast_ctx.js +1 -1
- package/dist/ui/util/toast/toast_legacy.js +2 -2
- package/dist/ui/util/types.d.ts +1 -0
- package/package.json +2 -2
|
@@ -84,7 +84,7 @@ export function _makeBitProvider(context, bitP) {
|
|
|
84
84
|
if (streamCancel)
|
|
85
85
|
streamCancel();
|
|
86
86
|
const cancel = _bit.stream(p, _partCtrl);
|
|
87
|
-
setStreamCancel(() => cancel);
|
|
87
|
+
setStreamCancel(() => cancel());
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
90
|
catch (e) {
|
|
@@ -107,14 +107,14 @@ export function _makeBitProvider(context, bitP) {
|
|
|
107
107
|
if (state.v.type === "data") {
|
|
108
108
|
return _isFn(onData)
|
|
109
109
|
? onData(state.v.value)
|
|
110
|
-
: (_a = onData) !== null && _a !== void 0 ? _a : null;
|
|
110
|
+
: ((_a = onData) !== null && _a !== void 0 ? _a : null);
|
|
111
111
|
}
|
|
112
112
|
if (state.v.type === "error") {
|
|
113
113
|
return _isFn(onError)
|
|
114
114
|
? onError(state.v.value)
|
|
115
|
-
: (_b = onError) !== null && _b !== void 0 ? _b : null;
|
|
115
|
+
: ((_b = onError) !== null && _b !== void 0 ? _b : null);
|
|
116
116
|
}
|
|
117
|
-
return _isFn(onLoading) ? onLoading() : (_c = onLoading) !== null && _c !== void 0 ? _c : null;
|
|
117
|
+
return _isFn(onLoading) ? onLoading() : ((_c = onLoading) !== null && _c !== void 0 ? _c : null);
|
|
118
118
|
}
|
|
119
119
|
function mapUI(onData, onError, onLoading) {
|
|
120
120
|
return map((d) => onData(d), (e) => (onError !== null && onError !== void 0 ? onError : ((e) => _jsx(ErrorView, { error: e, retry: () => _reload(false) })))(e), () => (onLoading !== null && onLoading !== void 0 ? onLoading : (() => _jsx(_LoadView, {})))());
|
package/dist/index.d.ts
CHANGED
|
@@ -47,7 +47,9 @@ export * from "./ui/components/section_card";
|
|
|
47
47
|
export * from "./ui/components/spinner";
|
|
48
48
|
export * from "./ui/components/table";
|
|
49
49
|
export * from "./ui/components/text";
|
|
50
|
+
export * from "./ui/components/tooltip";
|
|
50
51
|
export * from "./ui/app/app";
|
|
52
|
+
export * from "./ui/app/app_ctxt";
|
|
51
53
|
export * from "./ui/components/dev/todo";
|
|
52
54
|
export * from "./ui/theme/subthemes/color/colors/colors";
|
|
53
55
|
export * from "./ui/theme/theme";
|
package/dist/index.js
CHANGED
|
@@ -49,7 +49,9 @@ export * from "./ui/components/section_card";
|
|
|
49
49
|
export * from "./ui/components/spinner";
|
|
50
50
|
export * from "./ui/components/table";
|
|
51
51
|
export * from "./ui/components/text";
|
|
52
|
+
export * from "./ui/components/tooltip";
|
|
52
53
|
export * from "./ui/app/app";
|
|
54
|
+
export * from "./ui/app/app_ctxt";
|
|
53
55
|
export * from "./ui/components/dev/todo";
|
|
54
56
|
export * from "./ui/theme/subthemes/color/colors/colors";
|
|
55
57
|
export * from "./ui/theme/theme";
|
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
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo, useState } from "react";
|
|
3
|
-
import { Box, DialogsProvider, isMenuRoute, omit, ToastProvider, Wouter, } from "../..";
|
|
3
|
+
import { Box, DialogsProvider, Icons, isMenuRoute, omit, PrettyErrorView, Route, ToastProvider, WithL10nOrDefault, 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,59 +78,81 @@ 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);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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]);
|
|
94
|
+
return (_jsx(p.themeContext.WithTheme, { theme: themeSelected, children: _jsx(WithL10nOrDefault, { children: _jsx(AppContext.Provider, { value: {
|
|
95
|
+
appConfig: p.config,
|
|
96
|
+
_appThemeContext: p.themeContext,
|
|
97
|
+
router: {
|
|
98
|
+
goBack: (steps = 1) => {
|
|
99
|
+
if (history.length === 0)
|
|
100
|
+
return;
|
|
101
|
+
const targetIndex = Math.max(0, history.length - 1 - steps);
|
|
102
|
+
const target = history[targetIndex];
|
|
103
|
+
setHistory((h) => h.slice(0, targetIndex + 1));
|
|
104
|
+
navigate(target, { replace: true });
|
|
105
|
+
},
|
|
106
|
+
go: (p, replace) => {
|
|
107
|
+
setHistory((h) => {
|
|
108
|
+
if (replace === "all")
|
|
109
|
+
return [p];
|
|
110
|
+
const repl = Math.max(0, replace !== null && replace !== void 0 ? replace : 0);
|
|
111
|
+
if (repl === 0)
|
|
112
|
+
return [...h, p];
|
|
113
|
+
return [...h.slice(0, -repl), p];
|
|
114
|
+
});
|
|
115
|
+
navigate(p, { replace: (replace !== null && replace !== void 0 ? replace : 0) !== 0 });
|
|
116
|
+
},
|
|
117
|
+
history: history,
|
|
118
|
+
location: location,
|
|
116
119
|
},
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
menu: menuItems.length === 0
|
|
121
|
+
? undefined
|
|
122
|
+
: {
|
|
123
|
+
isOpen: menuOpen,
|
|
124
|
+
setOpen: (s) => setMenuOpen(s),
|
|
125
|
+
},
|
|
126
|
+
}, children: _jsx(ToastProvider, { children: _jsx(DialogsProvider, { children: _jsxs(Box, { typeLabel: "app_base", scheme: "primary", style: {
|
|
127
|
+
display: "flex",
|
|
128
|
+
width: "100%",
|
|
129
|
+
minHeight: "100vh",
|
|
130
|
+
}, children: [menuItems.length > 0 && _jsx(Menu, { items: menuItems }), _jsx("div", { style: {
|
|
131
|
+
flex: 1,
|
|
132
|
+
width: "0px",
|
|
133
|
+
display: "flex",
|
|
134
|
+
flexDirection: "column",
|
|
135
|
+
}, children: _jsxs(Wouter.Switch, { children: [children, ",", _jsx(_404Route, {})] }) })] }) }) }) }) }) }));
|
|
122
136
|
}
|
|
123
137
|
function _extractMenuItems(children) {
|
|
124
138
|
if (!children)
|
|
125
139
|
return [];
|
|
126
|
-
const childs = Array.isArray(children) ? children : [children];
|
|
127
140
|
const items = [];
|
|
128
|
-
for (const child of
|
|
141
|
+
for (const child of children) {
|
|
129
142
|
if (!isMenuRoute(child))
|
|
130
143
|
continue;
|
|
131
144
|
items.push(child.props);
|
|
132
145
|
}
|
|
133
146
|
return items;
|
|
134
147
|
}
|
|
148
|
+
function _404Route() {
|
|
149
|
+
return (_jsx(Route, { path: "*", children: _jsx(PrettyErrorView, { flex: true, error: {
|
|
150
|
+
icon: Icons.Frown,
|
|
151
|
+
code: "404",
|
|
152
|
+
message: "404 - Not Found",
|
|
153
|
+
description: "The requested page could not be found.",
|
|
154
|
+
}, retry: () => {
|
|
155
|
+
//set browser location to / manuall:
|
|
156
|
+
window.location.href = "/";
|
|
157
|
+
} }) }));
|
|
158
|
+
}
|
|
@@ -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 ({
|
|
@@ -45,7 +45,7 @@ function _btn(_a) {
|
|
|
45
45
|
borderRadius: elbe.sharp ? 0 : "3rem",
|
|
46
46
|
height: "3rem",
|
|
47
47
|
width: "3rem",
|
|
48
|
-
}), { title: elbe.tooltip ? undefined : (_b = elbe.ariaLabel) !== null && _b !== void 0 ? _b : undefined, onClick: (e) => {
|
|
48
|
+
}), { title: elbe.tooltip ? undefined : ((_b = elbe.ariaLabel) !== null && _b !== void 0 ? _b : undefined), onClick: (e) => {
|
|
49
49
|
e.stopPropagation();
|
|
50
50
|
onTap && onTap(e);
|
|
51
51
|
}, children: _jsx(Icon, { icon: icon }) })) }) }));
|
|
@@ -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",
|
|
@@ -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
|
}), []);
|
|
@@ -11,7 +11,7 @@ export declare function ErrorView({ error, retry, debug, }: {
|
|
|
11
11
|
retry?: () => any;
|
|
12
12
|
debug?: boolean;
|
|
13
13
|
}): import("react/jsx-runtime").JSX.Element;
|
|
14
|
-
export declare function PrettyErrorView({ error, retry, labels, }: {
|
|
14
|
+
export declare function PrettyErrorView({ error, retry, labels, flex, }: {
|
|
15
15
|
error: ElbeError;
|
|
16
16
|
retry?: () => any;
|
|
17
17
|
labels?: {
|
|
@@ -19,4 +19,5 @@ export declare function PrettyErrorView({ error, retry, labels, }: {
|
|
|
19
19
|
home?: L10nInlinePlain;
|
|
20
20
|
details: L10nInlinePlain;
|
|
21
21
|
};
|
|
22
|
+
flex?: boolean;
|
|
22
23
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -44,9 +44,9 @@ export function PrettyErrorView({ error, retry, labels = {
|
|
|
44
44
|
it: "dettagli dell'errore",
|
|
45
45
|
pt: "detalhes do erro",
|
|
46
46
|
},
|
|
47
|
-
}, }) {
|
|
47
|
+
}, flex = false, }) {
|
|
48
48
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
49
49
|
const l10n = _maybeL10n();
|
|
50
50
|
const [open, setOpen] = useState(false);
|
|
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) }) })] }));
|
|
51
|
+
return (_jsxs(Column, { cross: "center", main: "center", flex: flex, 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) }) })] }));
|
|
52
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 && !theme.color.isContrast
|
|
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";
|
|
@@ -38,5 +38,7 @@ function _FlexLayout(row, p, elbe, wraps) {
|
|
|
38
38
|
overflowX: !row ? undefined : p.scroll ? "auto" : undefined,
|
|
39
39
|
overflowY: row ? undefined : p.scroll ? "auto" : undefined,
|
|
40
40
|
flex: ((_c = elbe.flex) !== null && _c !== void 0 ? _c : p.scroll) ? 1 : undefined,
|
|
41
|
+
minWidth: 0,
|
|
42
|
+
minHeight: 0,
|
|
41
43
|
}), { children: p.children })));
|
|
42
44
|
}
|
|
@@ -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,16 +28,19 @@ 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
|
+
borderLeftStyle: "none",
|
|
41
|
+
borderTopStyle: "none",
|
|
42
|
+
borderRightStyle: "none",
|
|
43
|
+
borderBottomStyle: "none",
|
|
41
44
|
display: "flex",
|
|
42
45
|
alignItems: "center",
|
|
43
46
|
backgroundColor: "transparent",
|
|
@@ -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;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { ElbeChildren } from "../util/types";
|
|
2
2
|
export declare function WithTooltip(p: {
|
|
3
|
-
tooltip?: string;
|
|
3
|
+
tooltip?: string | ElbeChildren;
|
|
4
|
+
delay?: number;
|
|
5
|
+
alignHorizontal?: "left" | "center" | "right" | "auto";
|
|
6
|
+
alignVertical?: "top" | "center" | "bottom" | "auto";
|
|
4
7
|
children?: ElbeChildren;
|
|
5
8
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -8,14 +8,41 @@ 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
|
}), []);
|
|
15
|
+
const align = useMemo(() => {
|
|
16
|
+
var _a, _b;
|
|
17
|
+
let xVals = { xOffset: -12, xTransform: "-100%" };
|
|
18
|
+
let yVals = { yOffset: -12, yTransform: "-100%" };
|
|
19
|
+
let xAlign = (_a = p.alignHorizontal) !== null && _a !== void 0 ? _a : "auto";
|
|
20
|
+
let yAlign = (_b = p.alignVertical) !== null && _b !== void 0 ? _b : "auto";
|
|
21
|
+
// if center-center, align above cursor to avoid covering it
|
|
22
|
+
if (xAlign === "center" && yAlign === "center") {
|
|
23
|
+
console.warn("Center-Center alignment may cause the tooltip" +
|
|
24
|
+
" to cover the cursor. Aligning to top-center instead.");
|
|
25
|
+
yAlign = "top";
|
|
26
|
+
}
|
|
27
|
+
if (xAlign === "auto")
|
|
28
|
+
xAlign = coords.left ? "right" : "left";
|
|
29
|
+
if (yAlign === "auto")
|
|
30
|
+
yAlign = coords.top ? "bottom" : "top";
|
|
31
|
+
if (xAlign === "center")
|
|
32
|
+
xVals = { xOffset: 0, xTransform: "-50%" };
|
|
33
|
+
if (xAlign === "right")
|
|
34
|
+
xVals = { xOffset: 12, xTransform: "0%" };
|
|
35
|
+
if (yAlign === "center")
|
|
36
|
+
yVals = { yOffset: 0, yTransform: "-50%" };
|
|
37
|
+
if (yAlign === "bottom")
|
|
38
|
+
yVals = { yOffset: 12, yTransform: "0%" };
|
|
39
|
+
return Object.assign(Object.assign({}, xVals), yVals);
|
|
40
|
+
}, [p.alignHorizontal, coords.left]);
|
|
15
41
|
if (!p.tooltip)
|
|
16
42
|
return _jsx(_Fragment, { children: p.children });
|
|
17
43
|
return (_jsxs("span", { onMouseEnter: () => {
|
|
18
|
-
|
|
44
|
+
var _a;
|
|
45
|
+
timeoutRef.current = window.setTimeout(() => setVisible(true), (_a = p.delay) !== null && _a !== void 0 ? _a : 1000);
|
|
19
46
|
}, onMouseLeave: () => {
|
|
20
47
|
console.log("leave");
|
|
21
48
|
if (timeoutRef.current) {
|
|
@@ -31,18 +58,14 @@ export function WithTooltip(p) {
|
|
|
31
58
|
left: e.clientX > window.innerWidth / 2,
|
|
32
59
|
});
|
|
33
60
|
}, style: { display: "contents" }, children: [p.children, visible &&
|
|
34
|
-
createPortal(_jsx("div", { role: "tooltip", className: "elbe_tooltip", style: {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
padding: ".125rem .3rem",
|
|
45
|
-
borderRadius: ".25rem",
|
|
46
|
-
transform: `translate(${coords.left ? "-100%" : "0"}, ${coords.top ? "-100%" : "0"})`,
|
|
47
|
-
}, children: p.tooltip }), rootDOM)] }));
|
|
61
|
+
createPortal(_jsx("div", { role: "tooltip", className: "elbe_tooltip", style: Object.assign({ position: "fixed", pointerEvents: "none", zIndex: 1001, top: coords.y + align.yOffset, left: coords.x + align.xOffset, transform: `translate(${align.xTransform}, ${align.yTransform})` }, (typeof p.tooltip === "string"
|
|
62
|
+
? {
|
|
63
|
+
background: theme.color.currentColor.back
|
|
64
|
+
.inter(theme.color.currentColor.front, 0.2)
|
|
65
|
+
.asCss(),
|
|
66
|
+
color: theme.color.currentColor.front.asCss(),
|
|
67
|
+
padding: ".125rem .3rem",
|
|
68
|
+
borderRadius: ".25rem",
|
|
69
|
+
}
|
|
70
|
+
: {})), children: p.tooltip }), rootDOM)] }));
|
|
48
71
|
}
|
|
@@ -19,7 +19,7 @@ const _makeSecondary = ({ base, seed }) => LayerColor.new({
|
|
|
19
19
|
border: base.border,
|
|
20
20
|
});
|
|
21
21
|
const _makeInverse = ({ base }) => base.mirrorBrightnessLayer();
|
|
22
|
-
const _makeMajor = ({ style
|
|
22
|
+
const _makeMajor = ({ style }) => {
|
|
23
23
|
return LayerColor.fromBack(style.back, { border: style.back });
|
|
24
24
|
};
|
|
25
25
|
const _makeMinor = ({ base, style }) => {
|
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
|
+
}
|
|
@@ -23,4 +23,7 @@ export declare function makeL10n<T extends _L10nData>(fallback: {
|
|
|
23
23
|
L10n: React.FunctionComponent<_L10nProps>;
|
|
24
24
|
useL10n: () => _L10nState<T>;
|
|
25
25
|
};
|
|
26
|
+
export declare function WithL10nOrDefault(p: {
|
|
27
|
+
children: ElbeChildren;
|
|
28
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
26
29
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useState } from "react";
|
|
3
|
-
import { _bestMatch, _L10nContext, _useL10n, } from "./_l10n_util";
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useState } from "react";
|
|
3
|
+
import { _bestMatch, _L10nContext, _maybeL10n, _useL10n, } from "./_l10n_util";
|
|
4
4
|
/**
|
|
5
5
|
* L10nBase is a function that creates a localization context provider and a hook to use the localization context.
|
|
6
6
|
* @param fallback this is the fallback locale, which is used if no other locale is found. It is the basis for the locale type and must thus be complete.
|
|
@@ -44,3 +44,10 @@ function _l10nInlineResolver(locale) {
|
|
|
44
44
|
return (_d = (_c = value[bestMatch !== null && bestMatch !== void 0 ? bestMatch : anyEnglish]) !== null && _c !== void 0 ? _c : value[locales[0]]) !== null && _d !== void 0 ? _d : "";
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
|
+
export function WithL10nOrDefault(p) {
|
|
48
|
+
const l10n = useMemo(() => makeL10n({ en: {} }, {}), []);
|
|
49
|
+
const existing = _maybeL10n();
|
|
50
|
+
if (!!existing)
|
|
51
|
+
return _jsx(_Fragment, { children: p.children });
|
|
52
|
+
return _jsx(l10n.L10n, { children: p.children });
|
|
53
|
+
}
|
|
@@ -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([]);
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export function showToast(message) {
|
|
6
6
|
// find the 'elbe' element
|
|
7
|
-
const elbe = document.getElementById("
|
|
7
|
+
const elbe = document.getElementById("elbe_app");
|
|
8
8
|
if (!elbe) {
|
|
9
|
-
console.warn("could not show legacy toast, no base element with '#
|
|
9
|
+
console.warn("could not show legacy toast, no base element with '#elbe_app' found");
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
12
|
const toast = document.createElement("div");
|
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.15",
|
|
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
|
},
|