@monkey-mini-app/panel 0.1.0 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # @monkey-mini-app/panel
2
+
3
+ Pure React panel UI (the `PanelHost` seam). It renders the shell you see around a mini-app
4
+ —— the app list, settings, theme pop, tab bar. It talks to a host **over HTTP/frame**, so
5
+ it bundles no server and must not depend on `host` or `dsh`.
6
+
7
+ ## Mount
8
+
9
+ ```tsx
10
+ import { createMiniAppPanel, createRestPanelHost } from "@monkey-mini-app/panel";
11
+
12
+ const panel = createMiniAppPanel(createRestPanelHost({ baseUrl, ... }), { ... });
13
+ // panel.mount(el) / panel.unmount()
14
+ ```
15
+
16
+ `createMiniAppPanel(host: PanelHost, options?)` returns a `PanelInstance`. `PanelProvider`
17
+ supplies `usePanelActions` / `usePanelI18n` for the state + i18n context. For a REST
18
+ backend, build the host with `createRestPanelHost` (`RestOptions`) which drives the host's
19
+ `HttpGateway`.
20
+
21
+ ## Seams
22
+
23
+ | Export | Role |
24
+ |--------|------|
25
+ | `PanelHost` / `capabilitiesOf` | The panel adapter seam (fetchApps / persistTheme / frame …) |
26
+ | `createRestPanelHost` / `RestOptions` | REST client that drives `HttpGateway` |
27
+ | `createFrameController` / `FrameController` | iframe ↔ host frame bridge |
28
+ | `createHostShell` / `HostShellInstance` | host wiring for the panel |
29
+ | `createMiniAppPanel` / `MiniAppPanel` | The top-level panel component / mount |
30
+
31
+ ## State & theme
32
+
33
+ - `usePanelState` / `getPanelState` / `setPanelState` / `subscribePanel` — shared store.
34
+ - `themes.ts` — `cssVars`, `PALETTES`, `tokensOf`, `applyThemeTo`, `runnerThemeCss`,
35
+ `parseThemeCss`, `*Theme*` helpers.
36
+ - `styles.ts` — `injectPanelCss` / `PANEL_CSS_TAG` (inject the panel CSS without a file).
37
+
38
+ ## Errors
39
+
40
+ `HostUnreachableError` — thrown by the REST host when the host socket is unreachable; the
41
+ panel renders a browser-actionable message instead of a blank screen.
42
+
43
+ ## Constraints
44
+
45
+ - Pure React: no `/api`, no `host`/`dsh` dependency (import direction enforced by eslint).
46
+ - Theme/CSS helpers are self-contained so the panel can be dropped into any host.
@@ -3,6 +3,16 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
 
5
5
  // src/themes.ts
6
+ var LOCAL_PALETTE_ID = "__local__";
7
+ var GLOBAL_PALETTE_ID = "__global__";
8
+ function effectivePalette(stored, hasLocalTheme, hostPalette) {
9
+ if (stored && stored !== GLOBAL_PALETTE_ID) return stored;
10
+ if (!stored && hasLocalTheme) return LOCAL_PALETTE_ID;
11
+ return hostPalette;
12
+ }
13
+ function selectedPalette(stored, hasLocalTheme) {
14
+ return stored ?? (hasLocalTheme ? LOCAL_PALETTE_ID : GLOBAL_PALETTE_ID);
15
+ }
6
16
  var PALETTES = [
7
17
  { id: "default", label: "\u9ED8\u8BA4", swatch: "#2563eb" },
8
18
  { id: "tokyo", label: "\u4E1C\u4EAC\u591C", swatch: "#7aa2f7" },
@@ -432,6 +442,18 @@ function clampPalette(value) {
432
442
  function clampMode(value) {
433
443
  return value === "dark" ? "dark" : "light";
434
444
  }
445
+ function resolveMode(value) {
446
+ if (value === "system") {
447
+ try {
448
+ if (typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches) {
449
+ return "dark";
450
+ }
451
+ } catch {
452
+ }
453
+ return "light";
454
+ }
455
+ return clampMode(value);
456
+ }
435
457
  function tokensOf(palette, mode) {
436
458
  return TOKENS[clampPalette(palette)][clampMode(mode)];
437
459
  }
@@ -482,14 +504,12 @@ function runnerThemeCss() {
482
504
  blocks.push(`html[data-theme="light"] input[type="date"],html[data-theme="light"] input[type="time"],html[data-theme="light"] input[type="datetime-local"],html[data-theme="light"] input[type="month"],html[data-theme="light"] input[type="week"]{color-scheme:light}`);
483
505
  return blocks.join("\n ");
484
506
  }
485
- function applyThemeTo(el, theme, palette, custom) {
507
+ function themeCssVars(theme, palette, custom) {
486
508
  const mode = clampMode(theme);
487
509
  const c = custom && palette ? custom[String(palette)] : void 0;
488
510
  const pal = c ? String(palette) : clampPalette(palette);
489
511
  const t = c && c.tokens && c.tokens[mode] || tokensOf(pal, mode);
490
- el.setAttribute("data-theme", mode);
491
- el.setAttribute("data-palette", pal);
492
- const map = {
512
+ return {
493
513
  "--dsw-alias-bg": t.bg,
494
514
  "--dsw-alias-fg": t.fg,
495
515
  "--dsw-alias-surface": t.surface,
@@ -519,10 +539,21 @@ function applyThemeTo(el, theme, palette, custom) {
519
539
  "--radius": t.radius,
520
540
  "--shadow": t.shadow
521
541
  };
542
+ }
543
+ function applyThemeTo(el, theme, palette, custom) {
544
+ const mode = resolveMode(theme);
545
+ const c = custom && palette ? custom[String(palette)] : void 0;
546
+ const pal = c ? String(palette) : clampPalette(palette);
547
+ const t = c && c.tokens && c.tokens[mode] || tokensOf(pal, mode);
548
+ el.setAttribute("data-theme", mode);
549
+ if (theme === "system") el.setAttribute("data-theme-pref", "system");
550
+ else el.removeAttribute("data-theme-pref");
551
+ el.setAttribute("data-palette", pal);
552
+ const map = themeCssVars(mode, palette, custom);
522
553
  for (const k of Object.keys(map)) el.style.setProperty(k, map[k]);
523
554
  el.style.background = t.bg;
524
555
  el.style.color = t.fg;
525
556
  return { theme: mode, palette: pal };
526
557
  }
527
558
 
528
- export { PALETTES, __publicField, applyThemeTo, clampMode, clampPalette, cssVars, parseThemeCss, runnerThemeCss, themeLabelFromCss, tokensOf };
559
+ export { GLOBAL_PALETTE_ID, LOCAL_PALETTE_ID, PALETTES, __publicField, applyThemeTo, clampMode, clampPalette, cssVars, effectivePalette, parseThemeCss, resolveMode, runnerThemeCss, selectedPalette, themeCssVars, themeLabelFromCss, tokensOf };