elbe-ui 0.2.52 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +12 -0
  2. package/dist/elbe.css +57 -56
  3. package/dist/elbe.css.map +1 -1
  4. package/dist/index.d.ts +6 -3
  5. package/dist/index.js +6 -3
  6. package/dist/ui/components/banner.d.ts +3 -2
  7. package/dist/ui/components/banner.js +13 -7
  8. package/dist/ui/components/base/box.d.ts +7 -5
  9. package/dist/ui/components/base/card.d.ts +5 -1
  10. package/dist/ui/components/base/card.js +5 -1
  11. package/dist/ui/components/base/roles.d.ts +1 -0
  12. package/dist/ui/components/base/roles.js +1 -0
  13. package/dist/ui/components/button/button.d.ts +1 -0
  14. package/dist/ui/components/button/button.js +12 -4
  15. package/dist/ui/components/button/choose_button.js +3 -2
  16. package/dist/ui/components/button/icon_button.d.ts +3 -0
  17. package/dist/ui/components/button/icon_button.js +9 -2
  18. package/dist/ui/components/button/toggle_button.js +7 -1
  19. package/dist/ui/components/footer.d.ts +18 -0
  20. package/dist/ui/components/footer.js +35 -0
  21. package/dist/ui/components/input/checkbox.d.ts +2 -5
  22. package/dist/ui/components/input/checkbox.js +10 -19
  23. package/dist/ui/components/input/range.js +4 -1
  24. package/dist/ui/components/input/select.js +1 -1
  25. package/dist/ui/components/input/switch.d.ts +6 -2
  26. package/dist/ui/components/input/switch.js +25 -22
  27. package/dist/ui/components/input/text/input_field.d.ts +28 -0
  28. package/dist/ui/components/input/text/input_field.js +70 -0
  29. package/dist/ui/components/input/text/multi_line.d.ts +10 -0
  30. package/dist/ui/components/input/text/multi_line.js +19 -0
  31. package/dist/ui/components/input/text/single_line.d.ts +18 -0
  32. package/dist/ui/components/input/text/single_line.js +28 -0
  33. package/dist/ui/components/layout/app_base.d.ts +14 -0
  34. package/dist/ui/components/layout/app_base.js +30 -0
  35. package/dist/ui/components/layout/ctx_app_base.d.ts +16 -0
  36. package/dist/ui/components/layout/ctx_app_base.js +13 -0
  37. package/dist/ui/components/layout/flex.d.ts +4 -2
  38. package/dist/ui/components/layout/flex.js +13 -5
  39. package/dist/ui/components/layout/header.d.ts +18 -18
  40. package/dist/ui/components/layout/header.js +54 -48
  41. package/dist/ui/components/layout/menu.d.ts +12 -0
  42. package/dist/ui/components/layout/menu.js +56 -0
  43. package/dist/ui/components/layout/spaced.d.ts +4 -2
  44. package/dist/ui/components/layout/spaced.js +6 -2
  45. package/dist/ui/components/layout/toolbar.d.ts +7 -0
  46. package/dist/ui/components/layout/toolbar.js +71 -0
  47. package/dist/ui/components/link.d.ts +10 -0
  48. package/dist/ui/components/link.js +15 -0
  49. package/dist/ui/components/progress_bar.js +7 -5
  50. package/dist/ui/components/spinner.js +4 -0
  51. package/dist/ui/components/text.js +4 -4
  52. package/dist/ui/theme/color_theme.d.ts +1 -1
  53. package/dist/ui/theme/color_theme.js +63 -52
  54. package/dist/ui/theme/colors.d.ts +33 -13
  55. package/dist/ui/theme/colors.js +42 -15
  56. package/dist/ui/theme/geometry_theme.js +2 -4
  57. package/dist/ui/theme/seed.d.ts +18 -8
  58. package/dist/ui/theme/seed.js +4 -1
  59. package/dist/ui/theme/theme.d.ts +3 -5
  60. package/dist/ui/theme/theme.js +9 -12
  61. package/dist/ui/theme/theme_context.d.ts +18 -0
  62. package/dist/ui/theme/theme_context.js +26 -0
  63. package/dist/ui/theme/type_theme.js +5 -2
  64. package/dist/ui/util/ctx_toolbar.d.ts +8 -0
  65. package/dist/ui/util/ctx_toolbar.js +9 -0
  66. package/dist/ui/util/util.d.ts +6 -0
  67. package/dist/ui/util/util.js +35 -0
  68. package/package.json +1 -1
  69. package/dist/ui/components/input/input_field.d.ts +0 -22
  70. package/dist/ui/components/input/input_field.js +0 -36
  71. package/dist/ui/components/input/text_area.d.ts +0 -10
  72. package/dist/ui/components/input/text_area.js +0 -22
  73. package/dist/ui/components/layout/scaffold.d.ts +0 -15
  74. package/dist/ui/components/layout/scaffold.js +0 -31
@@ -1,6 +1,8 @@
1
1
  import { hslToRgb, rgbToHsl } from "colors-convert";
2
2
  import { clamp } from "../util/util";
3
3
  import { colorThemePreset } from "./color_theme";
4
+ import { lColor, } from "./seed";
5
+ export const cContrasts = ["normal", "highvis"];
4
6
  export const cModes = ["light", "dark"];
5
7
  export const cSchemes = ["primary", "secondary", "inverse"];
6
8
  export const cKinds = [
@@ -159,7 +161,7 @@ export class StateColor extends LayerColor {
159
161
  `${activeS} { ${this.active.asCss()} }\n` +
160
162
  `${disS} { ${this.disabled.asCss()} }`);
161
163
  }
162
- static generate(_, context, style, fromFront) {
164
+ static generate(p, _, context, style, fromFront) {
163
165
  function _make(factor) {
164
166
  const front = style.front;
165
167
  return new LayerColor((fromFront
@@ -192,8 +194,12 @@ export class MannerColor extends StateColor {
192
194
  return ((maj ? ` .major { ${maj.asCss()} } \n` : "") +
193
195
  (min ? ` .minor { ${min.asCss()} } \n` : ""));
194
196
  }
195
- static generate(s, c, style) {
196
- return new MannerColor(style ? StateColor.generate(s, c, s.variant.major(s, c, style)) : null, style ? StateColor.generate(s, c, s.variant.minor(s, c, style)) : null, StateColor.generate(s, c, s.variant.flat(s, c, style), true));
197
+ static generate(path, seed, base, style) {
198
+ return new MannerColor(style
199
+ ? StateColor.generate([...path, "major"], seed, base, seed.variant.major({ path, seed, base, style }))
200
+ : null, style
201
+ ? StateColor.generate([...path, "minor"], seed, base, seed.variant.minor({ path, seed, base, style }))
202
+ : null, StateColor.generate([...path, "flat"], seed, base, seed.variant.flat({ path, seed, base, style }), true));
197
203
  /*
198
204
  if (!style) {
199
205
  return new MannerColor(null, null, StateColor.generate(s, c, c, true));
@@ -226,8 +232,8 @@ export class KindColor extends MannerColor {
226
232
  `.warning { ${this.warning.asCss()} }\n` +
227
233
  `.error { ${this.error.asCss()} }`);
228
234
  }
229
- static generate(s, c) {
230
- return new KindColor(MannerColor.generate(s, c), MannerColor.generate(s, c, s.style.accent(s, c, s.accent)), MannerColor.generate(s, c, s.style.info(s, c, s.info)), MannerColor.generate(s, c, s.style.success(s, c, s.success)), MannerColor.generate(s, c, s.style.warning(s, c, s.warning)), MannerColor.generate(s, c, s.style.error(s, c, s.error)));
235
+ static generate(path, seed, base) {
236
+ return new KindColor(MannerColor.generate([...path, "plain"], seed, base), MannerColor.generate([...path, "accent"], seed, base, seed.style.accent({ path, seed, base, style: lColor(seed.accent) })), MannerColor.generate([...path, "info"], seed, base, seed.style.info({ path, seed, base, style: lColor(seed.info) })), MannerColor.generate([...path, "success"], seed, base, seed.style.success({ path, seed, base, style: lColor(seed.success) })), MannerColor.generate([...path, "warning"], seed, base, seed.style.warning({ path, seed, base, style: lColor(seed.warning) })), MannerColor.generate([...path, "error"], seed, base, seed.style.error({ path, seed, base, style: lColor(seed.error) })));
231
237
  }
232
238
  }
233
239
  export class SchemeColor extends KindColor {
@@ -243,9 +249,9 @@ export class SchemeColor extends KindColor {
243
249
  `.secondary { ${this.secondary.asCss()} }\n` +
244
250
  `.inverse { ${this.inverse.asCss()} }`);
245
251
  }
246
- static generate(seed, c) {
252
+ static generate(path, seed, base) {
247
253
  const m = seed.scheme;
248
- return new SchemeColor(KindColor.generate(seed, m.primary(seed, c)), KindColor.generate(seed, m.secondary(seed, c)), KindColor.generate(seed, m.inverse(seed, c)));
254
+ return new SchemeColor(KindColor.generate([...path, "primary"], seed, m.primary({ path, seed, base })), KindColor.generate([...path, "secondary"], seed, m.secondary({ path, seed, base })), KindColor.generate([...path, "inverse"], seed, m.inverse({ path, seed, base })));
249
255
  }
250
256
  }
251
257
  export class ModeColor extends SchemeColor {
@@ -255,10 +261,24 @@ export class ModeColor extends SchemeColor {
255
261
  this.dark = dark;
256
262
  }
257
263
  asCss() {
258
- return (`.elbe { ${this.light.asCss()}}` + `.elbe.dark { ${this.dark.asCss()}}`);
264
+ return `&{ ${this.light.asCss()}}` + `&.dark { ${this.dark.asCss()}}`;
259
265
  }
260
- static generate(seed) {
261
- return new ModeColor(SchemeColor.generate(seed, seed.base), SchemeColor.generate(seed, seed.mode.dark(seed, seed.base)));
266
+ static generate(path, seed) {
267
+ return new ModeColor(SchemeColor.generate(path, seed, lColor(seed.base)), SchemeColor.generate([...path, "dark"], seed, seed.mode.dark({ path, seed, base: lColor(seed.base) })));
268
+ }
269
+ }
270
+ export class ContrastColor extends ModeColor {
271
+ constructor(normal, highvis) {
272
+ super(normal.light, normal.dark);
273
+ this.normal = normal;
274
+ this.highvis = highvis;
275
+ }
276
+ asCss() {
277
+ return (`& { ${this.normal.asCss()}}` + `&.highvis { ${this.highvis.asCss()}}`);
278
+ }
279
+ static generate(path, seed) {
280
+ const p = { path, base: lColor(seed.base), seed };
281
+ return new ContrastColor(ModeColor.generate(path, seed.contrast.normal(p)), ModeColor.generate([...path, "highvis"], seed.contrast.highvis(p)));
262
282
  }
263
283
  }
264
284
  export class ColorTheme {
@@ -267,17 +287,24 @@ export class ColorTheme {
267
287
  this.color = color;
268
288
  }
269
289
  asCss() {
270
- return (`:root {
290
+ return `
271
291
  --c-accent: ${this.colors.accent.back.asCss()};
272
292
  --c-info: ${this.colors.info.back.asCss()};
273
293
  --c-success: ${this.colors.success.back.asCss()};
274
294
  --c-warning: ${this.colors.warning.back.asCss()};
275
295
  --c-error: ${this.colors.error.back.asCss()};
276
- }` + this.color.asCss());
296
+ ${this.color.asCss()}`;
277
297
  }
278
- static generate(seed, highVis) {
279
- const s = colorThemePreset(seed, highVis !== null && highVis !== void 0 ? highVis : false);
280
- return new ColorTheme(s, ModeColor.generate(s));
298
+ static generate(seed) {
299
+ const s = colorThemePreset(seed);
300
+ return new ColorTheme({
301
+ base: lColor(s.base),
302
+ accent: lColor(s.accent),
303
+ info: lColor(s.info),
304
+ success: lColor(s.success),
305
+ warning: lColor(s.warning),
306
+ error: lColor(s.error),
307
+ }, ContrastColor.generate([], s));
281
308
  }
282
309
  }
283
310
  //Bun.write("./example.css", ColorTheme.generate().asCss());
@@ -6,12 +6,10 @@ export class GeometryTheme {
6
6
  this.borderWidth = borderWidth;
7
7
  }
8
8
  asCss() {
9
- return (`:root{` +
10
- `--g-size: ${this.size}px;` +
9
+ return (`--g-size: ${this.size}px;` +
11
10
  `--g-radius: ${this.radius}rem;` +
12
11
  `--g-padding: ${this.padding}rem;` +
13
- `--g-border-width: ${this.borderWidth}rem;` +
14
- "}");
12
+ `--g-border-width: ${this.borderWidth}rem;`);
15
13
  }
16
14
  static generate(seed) {
17
15
  const s = geometryThemePreset(seed);
@@ -1,11 +1,18 @@
1
- import { LayerColor, SeedFlatSelector, SeedSelector, SeedStyleSelector } from "../..";
2
- export type ColorSeedColors = {
3
- base: LayerColor;
4
- accent: LayerColor;
5
- info: LayerColor;
6
- success: LayerColor;
7
- warning: LayerColor;
8
- error: LayerColor;
1
+ import { LayerColor, SeedFlatSelector, SeedModifier, SeedSelector, SeedStyleSelector } from "../..";
2
+ export type HexColor = `#${string}`;
3
+ export type ColorSeedColors = _Colors<LayerColor | HexColor>;
4
+ export type ThemeColors = _Colors<LayerColor>;
5
+ type _Colors<T> = {
6
+ base: T;
7
+ accent: T;
8
+ info: T;
9
+ success: T;
10
+ warning: T;
11
+ error: T;
12
+ };
13
+ type _ContrastSeed = {
14
+ highvis: SeedModifier;
15
+ normal: SeedModifier;
9
16
  };
10
17
  type _ModeSeed = {
11
18
  light: SeedSelector;
@@ -29,15 +36,18 @@ type _VariantSeed = {
29
36
  flat: SeedFlatSelector;
30
37
  };
31
38
  export type ColorThemeSeed = ColorSeedColors & {
39
+ contrast: _ContrastSeed;
32
40
  mode: _ModeSeed;
33
41
  scheme: _SchemeSeed;
34
42
  style: _StyleSeed;
35
43
  variant: _VariantSeed;
36
44
  };
37
45
  export type PartialColorThemeSeed = Partial<ColorSeedColors> & {
46
+ contrast?: Partial<_ContrastSeed>;
38
47
  mode?: Partial<_ModeSeed>;
39
48
  scheme?: Partial<_SchemeSeed>;
40
49
  style?: Partial<_StyleSeed>;
41
50
  variant?: Partial<_VariantSeed>;
42
51
  };
52
+ export declare function lColor(color: LayerColor | HexColor): LayerColor;
43
53
  export {};
@@ -1 +1,4 @@
1
- export {};
1
+ import { LayerColor, } from "../..";
2
+ export function lColor(color) {
3
+ return typeof color === "string" ? LayerColor.fromHex(color) : color;
4
+ }
@@ -2,6 +2,7 @@ import "../../elbe.css";
2
2
  import { ColorTheme } from "./colors";
3
3
  import { GeometryTheme, type GeometryThemeSeed } from "./geometry_theme";
4
4
  import { PartialColorThemeSeed } from "./seed";
5
+ import { ElbeThemeConfig } from "./theme_context";
5
6
  import { TypeTheme, type TypeThemeSeed } from "./type_theme";
6
7
  export * from "./color_theme";
7
8
  export * from "./colors";
@@ -18,15 +19,12 @@ export declare class ElbeThemeData {
18
19
  readonly geometry: GeometryTheme;
19
20
  constructor(color: ColorTheme, type: TypeTheme, geometry: GeometryTheme);
20
21
  asCss(): string;
21
- _pageBackground(dark?: boolean): string;
22
- static fromSeed(seed: ElbeThemeSeed, highVis: boolean): ElbeThemeData;
22
+ static fromSeed(seed: ElbeThemeSeed): ElbeThemeData;
23
23
  }
24
24
  export declare function ElbeTheme(p: {
25
25
  children: any;
26
- dark?: boolean;
27
26
  todoOverlay?: boolean;
28
- highVis?: boolean;
29
- } & ({
27
+ } & Partial<ElbeThemeConfig> & ({
30
28
  theme: ElbeThemeData;
31
29
  } | {
32
30
  seed?: ElbeThemeSeed;
@@ -3,6 +3,7 @@ import "../../elbe.css";
3
3
  import { ToDo } from "../components/dev/todo";
4
4
  import { ColorTheme } from "./colors";
5
5
  import { GeometryTheme } from "./geometry_theme";
6
+ import { _configCss, makeThemeConfig, ThemeConfigContext, ThemeContext, } from "./theme_context";
6
7
  import { TypeTheme } from "./type_theme";
7
8
  export * from "./color_theme";
8
9
  export * from "./colors";
@@ -15,22 +16,18 @@ export class ElbeThemeData {
15
16
  this.geometry = geometry;
16
17
  }
17
18
  asCss() {
18
- return [this.color, this.type, this.geometry]
19
+ const inner = [this.color, this.type, this.geometry]
19
20
  .map((s) => s.asCss())
20
21
  .join("\n");
22
+ return `.elbe {${inner}}`;
21
23
  }
22
- _pageBackground(dark) {
23
- const c = this.color.color;
24
- return `html,:root {${(!!dark ? c.dark : c.light).asCss()};`;
25
- }
26
- static fromSeed(seed, highVis) {
27
- return new ElbeThemeData(ColorTheme.generate(seed.color, highVis), TypeTheme.generate(seed.type), GeometryTheme.generate(seed.geometry));
24
+ static fromSeed(seed) {
25
+ return new ElbeThemeData(ColorTheme.generate(seed.color), TypeTheme.generate(seed.type), GeometryTheme.generate(seed.geometry));
28
26
  }
29
27
  }
30
28
  export function ElbeTheme(p) {
31
- var _a, _b;
32
- const theme = "theme" in p
33
- ? p.theme
34
- : ElbeThemeData.fromSeed((_a = p.seed) !== null && _a !== void 0 ? _a : {}, (_b = p.highVis) !== null && _b !== void 0 ? _b : false);
35
- return (_jsxs("div", { class: `elbe ${p.dark ? "dark" : ""} ${p.highVis ? "high_vis" : ""}`, children: [p.todoOverlay && _jsx(ToDo.Overlay, {}), _jsx("style", { children: theme.asCss() }), _jsx("style", { children: theme._pageBackground(p.dark) }), p.children] }));
29
+ var _a;
30
+ const theme = "theme" in p ? p.theme : ElbeThemeData.fromSeed((_a = p.seed) !== null && _a !== void 0 ? _a : {});
31
+ const config = makeThemeConfig(p);
32
+ return (_jsxs("div", { class: `elbe ${config.dark ? "dark" : ""} ${config.highVis ? "highvis" : ""} ${config.reducedMotion ? "reduced_motion" : ""}`, children: [p.todoOverlay && _jsx(ToDo.Overlay, {}), _jsx("style", { children: theme.asCss() }), _jsx("style", { children: _configCss(theme, config) }), _jsx(ThemeConfigContext.Provider, { value: config, children: _jsx(ThemeContext.Provider, { value: theme, children: p.children }) })] }));
36
33
  }
@@ -0,0 +1,18 @@
1
+ import { ElbeThemeData } from "./theme";
2
+ export interface ElbeThemeConfig {
3
+ highVis: boolean;
4
+ dark: boolean;
5
+ reducedMotion: boolean;
6
+ scale: number;
7
+ }
8
+ export declare function makeThemeConfig(p: Partial<ElbeThemeConfig>): {
9
+ highVis: boolean;
10
+ dark: boolean;
11
+ reducedMotion: boolean;
12
+ scale: number;
13
+ };
14
+ export declare const ThemeConfigContext: import("preact").Context<ElbeThemeConfig>;
15
+ export declare function _configCss(t: ElbeThemeData, c: ElbeThemeConfig): string;
16
+ export declare const ThemeContext: import("preact").Context<ElbeThemeData>;
17
+ export declare function useThemeConfig(): ElbeThemeConfig;
18
+ export declare function useTheme(): ElbeThemeData;
@@ -0,0 +1,26 @@
1
+ import { createContext } from "preact";
2
+ import { useContext } from "preact/hooks";
3
+ import { ElbeThemeData } from "./theme";
4
+ export function makeThemeConfig(p) {
5
+ var _a, _b, _c, _d;
6
+ return {
7
+ highVis: (_a = p.highVis) !== null && _a !== void 0 ? _a : false,
8
+ dark: (_b = p.dark) !== null && _b !== void 0 ? _b : false,
9
+ reducedMotion: (_c = p.reducedMotion) !== null && _c !== void 0 ? _c : false,
10
+ scale: (_d = p.scale) !== null && _d !== void 0 ? _d : 1,
11
+ };
12
+ }
13
+ export const ThemeConfigContext = createContext(makeThemeConfig({}));
14
+ export function _configCss(t, c) {
15
+ const cBack = c.dark ? t.color.color.dark : t.color.color.light;
16
+ return `html,:root {
17
+ font-size: ${c.scale * 16}px;
18
+ ${cBack.asCss()};}`;
19
+ }
20
+ export const ThemeContext = createContext(ElbeThemeData.fromSeed({}));
21
+ export function useThemeConfig() {
22
+ return useContext(ThemeConfigContext);
23
+ }
24
+ export function useTheme() {
25
+ return useContext(ThemeContext);
26
+ }
@@ -51,7 +51,7 @@ export function typeThemePreset(merge) {
51
51
  return Object.assign({ heading: {
52
52
  bold: true,
53
53
  family: ["Calistoga", "Arial", "sans-serif"],
54
- size: 2.2,
54
+ size: 2,
55
55
  }, body: {
56
56
  bold: false,
57
57
  family: ["Helvetica", "Arial", "sans-serif"],
@@ -61,7 +61,10 @@ export function typeThemePreset(merge) {
61
61
  family: ["Courier", "monospace"],
62
62
  size: 1,
63
63
  }, headingVariants: (style, variant) => {
64
- const size = style.size * (1 - (variant - 1) * 0.1);
64
+ const reg = 1;
65
+ const diff = style.size - reg;
66
+ const varFac = (4 - (variant - 2)) / 6;
67
+ const size = reg + diff * Math.pow(varFac, 1.5);
65
68
  return Object.assign(Object.assign({}, style), { size });
66
69
  }, bodyVariants: (style, variant) => {
67
70
  const size = style.size * (variant === "s" ? 0.8 : 1.2);
@@ -0,0 +1,8 @@
1
+ import React from "preact/compat";
2
+ type _ToolbarState = "toolbar" | "overflow" | null;
3
+ export declare const ToolbarContext: React.Context<_ToolbarState>;
4
+ export declare function useToolbar(): {
5
+ isInToolbar: boolean;
6
+ isInOverflow: boolean;
7
+ };
8
+ export {};
@@ -0,0 +1,9 @@
1
+ import React, { useContext } from "preact/compat";
2
+ export const ToolbarContext = React.createContext(null);
3
+ export function useToolbar() {
4
+ const ctx = useContext(ToolbarContext);
5
+ return {
6
+ isInToolbar: ctx === "toolbar",
7
+ isInOverflow: ctx === "overflow",
8
+ };
9
+ }
@@ -1,4 +1,6 @@
1
1
  import type React from "preact/compat";
2
+ export type int = number;
3
+ export type float = number;
2
4
  export type ElbeChild = React.ReactNode;
3
5
  export type ElbeChildren = ElbeChild[] | ElbeChild;
4
6
  export declare function clamp(value: number, min: number, max: number): number;
@@ -20,3 +22,7 @@ export declare function share(data: {
20
22
  */
21
23
  export declare function copyToClipboard(text: string, toastMsg?: string): void;
22
24
  export declare function scrollToId(id: string): void;
25
+ export declare function randomAlphaNum(length: int, prefix?: string): string;
26
+ export type LayoutModes = "mobile" | "narrow" | "wide";
27
+ export declare function useLayoutMode(): LayoutModes;
28
+ export declare function useSiteScroll(): number;
@@ -1,3 +1,4 @@
1
+ import { useEffect, useState } from "preact/compat";
1
2
  import { showToast } from "./toast";
2
3
  export function clamp(value, min, max) {
3
4
  return Math.min(Math.max(value, min), max);
@@ -36,3 +37,37 @@ export function scrollToId(id) {
36
37
  if (el)
37
38
  el.scrollIntoView({ behavior: "smooth" });
38
39
  }
40
+ export function randomAlphaNum(length, prefix = "") {
41
+ const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
42
+ let result = prefix;
43
+ for (let i = 0; i < length; i++) {
44
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
45
+ }
46
+ return result;
47
+ }
48
+ function _layoutMode() {
49
+ const w = window.innerWidth;
50
+ if (w < 700)
51
+ return "mobile";
52
+ if (w < 1100)
53
+ return "narrow";
54
+ return "wide";
55
+ }
56
+ export function useLayoutMode() {
57
+ const [mode, setMode] = useState(_layoutMode());
58
+ useEffect(() => {
59
+ const onResize = () => setMode(_layoutMode());
60
+ window.addEventListener("resize", onResize);
61
+ return () => window.removeEventListener("resize", onResize);
62
+ });
63
+ return mode;
64
+ }
65
+ export function useSiteScroll() {
66
+ const [scroll, setScroll] = useState(0);
67
+ useEffect(() => {
68
+ const onScroll = () => setScroll(window.scrollY);
69
+ window.addEventListener("scroll", onScroll);
70
+ return () => window.removeEventListener("scroll", onScroll);
71
+ }, []);
72
+ return scroll;
73
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "elbe-ui",
3
- "version": "0.2.52",
3
+ "version": "0.4.0",
4
4
  "author": "Robin Naumann",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,22 +0,0 @@
1
- import React from "preact/compat";
2
- import { ActionElbeProps } from "../base/box";
3
- import { _TextArea } from "./text_area";
4
- export type InputFieldProps = {
5
- label?: string;
6
- hint: string;
7
- readonly?: boolean;
8
- value: string | number;
9
- onInput?: (value: string) => void;
10
- } & ActionElbeProps;
11
- export declare class Field extends React.Component<InputFieldProps & {
12
- type?: "text" | "number" | "password" | "date" | "time" | "email";
13
- }> {
14
- static text: (p: InputFieldProps) => React.JSX.Element;
15
- static number: (p: InputFieldProps) => React.JSX.Element;
16
- static password: (p: InputFieldProps) => React.JSX.Element;
17
- static date: (p: InputFieldProps) => React.JSX.Element;
18
- static time: (p: InputFieldProps) => React.JSX.Element;
19
- static email: (p: InputFieldProps) => React.JSX.Element;
20
- static multiLine: typeof _TextArea;
21
- render(): React.JSX.Element;
22
- }
@@ -1,36 +0,0 @@
1
- var __rest = (this && this.__rest) || function (s, e) {
2
- var t = {};
3
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
- t[p] = s[p];
5
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
- t[p[i]] = s[p[i]];
9
- }
10
- return t;
11
- };
12
- import { jsx as _jsx } from "preact/jsx-runtime";
13
- import React from "preact/compat";
14
- import { applyProps } from "../base/box";
15
- import { _TextArea } from "./text_area";
16
- export class Field extends React.Component {
17
- render() {
18
- var _a;
19
- const _b = this.props, { label, hint, readonly, type, value, onInput } = _b, elbe = __rest(_b, ["label", "hint", "readonly", "type", "value", "onInput"]);
20
- return (_jsx("div", { style: {
21
- width: "12rem !important",
22
- display: "flex",
23
- flexDirection: "column",
24
- alignItems: "stretch",
25
- }, "data-tooltip": (_a = this.props) === null || _a === void 0 ? void 0 : _a.tooltip, children: _jsx("input", Object.assign({ type: this.props.type }, applyProps("text_field", this.props, null, {
26
- width: "100%",
27
- }), { size: 5, label: this.props.label, placeholder: this.props.hint, value: this.props.value, onInput: (e) => this.props.onInput && this.props.onInput(e.currentTarget.value), readonly: this.props.readonly })) }));
28
- }
29
- }
30
- Field.text = (p) => _jsx(Field, Object.assign({}, p, { type: "text" }));
31
- Field.number = (p) => _jsx(Field, Object.assign({}, p, { type: "number" }));
32
- Field.password = (p) => _jsx(Field, Object.assign({}, p, { type: "password" }));
33
- Field.date = (p) => _jsx(Field, Object.assign({}, p, { type: "date" }));
34
- Field.time = (p) => _jsx(Field, Object.assign({}, p, { type: "time" }));
35
- Field.email = (p) => _jsx(Field, Object.assign({}, p, { type: "email" }));
36
- Field.multiLine = _TextArea;
@@ -1,10 +0,0 @@
1
- import { ActionElbeProps } from "../base/box";
2
- export declare function _TextArea({ label, hint, readonly, rows, maxLength, value, onInput, ...elbe }: {
3
- label?: string;
4
- hint: string;
5
- rows?: number;
6
- maxLength?: number;
7
- readonly?: boolean;
8
- value: string | number;
9
- onInput?: (value: string) => void;
10
- } & ActionElbeProps): import("preact").JSX.Element;
@@ -1,22 +0,0 @@
1
- var __rest = (this && this.__rest) || function (s, e) {
2
- var t = {};
3
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
- t[p] = s[p];
5
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
- t[p[i]] = s[p[i]];
9
- }
10
- return t;
11
- };
12
- import { jsx as _jsx } from "preact/jsx-runtime";
13
- import { applyProps } from "../base/box";
14
- export function _TextArea(_a) {
15
- var { label, hint, readonly, rows = 4, maxLength, value, onInput } = _a, elbe = __rest(_a, ["label", "hint", "readonly", "rows", "maxLength", "value", "onInput"]);
16
- return (_jsx("div", { style: {
17
- width: "12rem !important",
18
- display: "flex",
19
- flexDirection: "column",
20
- alignItems: "stretch",
21
- }, "data-tooltip": elbe.tooltip, children: _jsx("textarea", Object.assign({}, applyProps("text_area", elbe, null, { width: "100%" }), { label: label, size: 5, cols: 5, placeholder: hint, rows: rows, maxLength: maxLength, value: value, onInput: (e) => onInput && onInput(e.currentTarget.value), readonly: readonly })) }));
22
- }
@@ -1,15 +0,0 @@
1
- import { type ElbeColorSchemes } from "../../..";
2
- import { HeaderParams } from "./header";
3
- /**
4
- * Scaffold is a layout component that provides a header and a content area.
5
- * It is used to create a consistent layout for pages.
6
- */
7
- export declare function Scaffold({ children, baseLimited, gap, padded, scheme, scroll, height, ...header }: {
8
- baseLimited?: boolean;
9
- children: any;
10
- gap?: number;
11
- padded?: boolean;
12
- scheme?: ElbeColorSchemes;
13
- scroll?: boolean;
14
- height?: number;
15
- } & HeaderParams): import("preact").JSX.Element;
@@ -1,31 +0,0 @@
1
- var __rest = (this && this.__rest) || function (s, e) {
2
- var t = {};
3
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
- t[p] = s[p];
5
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
- t[p[i]] = s[p[i]];
9
- }
10
- return t;
11
- };
12
- import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
13
- import { classString } from "../../..";
14
- import { Column } from "./flex";
15
- import { Header } from "./header";
16
- /**
17
- * Scaffold is a layout component that provides a header and a content area.
18
- * It is used to create a consistent layout for pages.
19
- */
20
- export function Scaffold(_a) {
21
- var { children, baseLimited = false, gap = 1, padded = true, scheme, scroll = false, height } = _a, header = __rest(_a, ["children", "baseLimited", "gap", "padded", "scheme", "scroll", "height"]);
22
- return (_jsxs(Column, { cross: "stretch", gap: 0, typeLabel: "Scaffold", class: `${scheme !== null && scheme !== void 0 ? scheme : "primary"}`, style: {
23
- overflowY: height ? "scroll" : null,
24
- height: height ? `${height}rem` : scroll ? null : "100vh",
25
- //height: header.limitToParent ? "100px" : null,
26
- }, children: [_jsx(Header, Object.assign({}, header, { _absolute: height ? true : false })), _jsx("div", { class: classString([
27
- !scroll && "flex-1",
28
- padded && "padded",
29
- baseLimited && "base-limited",
30
- ]), children: _jsx(Column, { cross: "stretch", style: { height: scroll ? null : "100%" }, gap: gap !== null && gap !== void 0 ? gap : 1, children: children }) })] }));
31
- }