@monkey-mini-app/panel 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-X3QW77RD.js +528 -0
- package/dist/index.cjs +2525 -0
- package/dist/index.d.cts +401 -0
- package/dist/index.d.ts +401 -0
- package/dist/index.js +1923 -0
- package/dist/themes.cjs +534 -0
- package/dist/themes.d.cts +63 -0
- package/dist/themes.d.ts +63 -0
- package/dist/themes.js +1 -0
- package/package.json +48 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
import { TokenSet } from './themes.js';
|
|
2
|
+
export { CustomPaletteMap, ModeId, PALETTES, PaletteId, applyThemeTo, clampMode, clampPalette, cssVars, parseThemeCss, runnerThemeCss, themeLabelFromCss, tokensOf } from './themes.js';
|
|
3
|
+
import * as react from 'react';
|
|
4
|
+
|
|
5
|
+
declare const LOCALE_IDS: readonly ["zh-CN", "en"];
|
|
6
|
+
type LocaleId = (typeof LOCALE_IDS)[number];
|
|
7
|
+
type AppItem = {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
acronym?: string;
|
|
12
|
+
commits?: number;
|
|
13
|
+
version?: string;
|
|
14
|
+
theme?: {
|
|
15
|
+
theme: string;
|
|
16
|
+
palette: string;
|
|
17
|
+
} | null;
|
|
18
|
+
};
|
|
19
|
+
type TabKind = "all" | "app";
|
|
20
|
+
type TabItem = {
|
|
21
|
+
id: string;
|
|
22
|
+
title: string;
|
|
23
|
+
kind: TabKind;
|
|
24
|
+
app?: AppItem;
|
|
25
|
+
};
|
|
26
|
+
type BrowseKind = "history" | "storage";
|
|
27
|
+
type ThemeScope = "global" | "app";
|
|
28
|
+
type DockId = "fill" | "side";
|
|
29
|
+
type CardStyle = "stamp" | "etch" | "hero" | "list";
|
|
30
|
+
type CommitFile = {
|
|
31
|
+
path: string;
|
|
32
|
+
add?: number;
|
|
33
|
+
del?: number;
|
|
34
|
+
preview?: string;
|
|
35
|
+
};
|
|
36
|
+
type Commit = {
|
|
37
|
+
id: string;
|
|
38
|
+
message: string;
|
|
39
|
+
time: string;
|
|
40
|
+
files?: CommitFile[];
|
|
41
|
+
};
|
|
42
|
+
type StorageTable = {
|
|
43
|
+
name: string;
|
|
44
|
+
size?: number;
|
|
45
|
+
updatedAt?: string;
|
|
46
|
+
};
|
|
47
|
+
type PanelCapabilities = {
|
|
48
|
+
history: boolean;
|
|
49
|
+
storage: boolean;
|
|
50
|
+
config: boolean;
|
|
51
|
+
appTheme: boolean;
|
|
52
|
+
customPalettes: boolean;
|
|
53
|
+
deleteApp: boolean;
|
|
54
|
+
};
|
|
55
|
+
type PanelActions = {
|
|
56
|
+
openAppTab: (app: AppItem) => void;
|
|
57
|
+
closeTab: (id: string) => void;
|
|
58
|
+
switchTab: (id: string) => void;
|
|
59
|
+
setDock: (next: DockId) => void;
|
|
60
|
+
setQuery: (q: string) => void;
|
|
61
|
+
toggleThemePop: () => void;
|
|
62
|
+
setAppearance: (next: {
|
|
63
|
+
theme?: string;
|
|
64
|
+
palette?: string;
|
|
65
|
+
}, scope: string) => void;
|
|
66
|
+
setThemeScope: (scope: ThemeScope) => void;
|
|
67
|
+
clearAppTheme: () => void;
|
|
68
|
+
getActiveApp: () => AppItem | null;
|
|
69
|
+
toggleSettings: (open: boolean) => void;
|
|
70
|
+
getCfg: () => Record<string, string>;
|
|
71
|
+
saveHostConfig: (form: Record<string, string>) => void;
|
|
72
|
+
toggleBrowse: (kind: string) => void;
|
|
73
|
+
loadCommitDetail: (id: string) => void;
|
|
74
|
+
loadTable: (name: string) => void;
|
|
75
|
+
browseBack: () => void;
|
|
76
|
+
browseFile: (path: string) => void;
|
|
77
|
+
reloadActive: () => void;
|
|
78
|
+
askDelete: () => void;
|
|
79
|
+
hideModal: () => void;
|
|
80
|
+
confirmDelete: () => void | Promise<void>;
|
|
81
|
+
closeDashboard: () => void;
|
|
82
|
+
fetchApps: () => void;
|
|
83
|
+
setCardStyle: (v: CardStyle) => void;
|
|
84
|
+
};
|
|
85
|
+
type PanelState = {
|
|
86
|
+
tabs: TabItem[];
|
|
87
|
+
active: string;
|
|
88
|
+
apps: AppItem[];
|
|
89
|
+
error: string | null;
|
|
90
|
+
loading: boolean;
|
|
91
|
+
query: string;
|
|
92
|
+
dock: DockId;
|
|
93
|
+
theme: string;
|
|
94
|
+
palette: string;
|
|
95
|
+
themeScope: ThemeScope;
|
|
96
|
+
customPalettes: Record<string, {
|
|
97
|
+
label?: string;
|
|
98
|
+
swatch?: string;
|
|
99
|
+
tokens?: unknown;
|
|
100
|
+
}>;
|
|
101
|
+
cardStyle: CardStyle;
|
|
102
|
+
visible: boolean;
|
|
103
|
+
pendingDelete: string | null;
|
|
104
|
+
themePopOpen: boolean;
|
|
105
|
+
settingsOpen: boolean;
|
|
106
|
+
cfgMsg: string;
|
|
107
|
+
cfgVersion: number;
|
|
108
|
+
cfg: Record<string, string>;
|
|
109
|
+
emptyText: string | undefined;
|
|
110
|
+
capabilities: PanelCapabilities;
|
|
111
|
+
locale: LocaleId;
|
|
112
|
+
browseOpen: boolean;
|
|
113
|
+
browseKind: BrowseKind;
|
|
114
|
+
browseAppId: string | null;
|
|
115
|
+
browseAppName: string;
|
|
116
|
+
browseLoading: boolean;
|
|
117
|
+
browseError: string | null;
|
|
118
|
+
browseList: unknown[];
|
|
119
|
+
browseDetail: unknown;
|
|
120
|
+
browseTable: string | null;
|
|
121
|
+
browseTableValue: unknown;
|
|
122
|
+
browseOpenFile: string | null;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
type I18nParams = Record<string, string | number>;
|
|
126
|
+
type PanelI18n = {
|
|
127
|
+
readonly locale: LocaleId;
|
|
128
|
+
t(key: string, params?: I18nParams): string;
|
|
129
|
+
};
|
|
130
|
+
/** i18next helper bound to `locale`. Missing keys throw outside production. */
|
|
131
|
+
declare function createPanelI18n(locale: LocaleId): PanelI18n;
|
|
132
|
+
declare function resolvePanelLocale(value: string | undefined): LocaleId;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* PanelHost — the only seam between the panel UI and a host (dsh client, demo, …).
|
|
136
|
+
* Optional fields hide the matching chrome (history / storage / settings / delete).
|
|
137
|
+
*/
|
|
138
|
+
|
|
139
|
+
type Palette = {
|
|
140
|
+
id: string;
|
|
141
|
+
label: string;
|
|
142
|
+
swatch: string;
|
|
143
|
+
tokens?: {
|
|
144
|
+
light: TokenSet;
|
|
145
|
+
dark: TokenSet;
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
interface PanelHost {
|
|
149
|
+
/** Locale for panel chrome. Falls back to createMiniAppPanel options, then zh-CN. */
|
|
150
|
+
locale?: LocaleId;
|
|
151
|
+
fetchApps(): Promise<AppItem[]>;
|
|
152
|
+
frame: {
|
|
153
|
+
url(appId: string): string;
|
|
154
|
+
mount(appId: string): void;
|
|
155
|
+
unmount(appId: string): void;
|
|
156
|
+
reload(appId: string): void;
|
|
157
|
+
/** Push current theme/palette/dock into open app iframes. */
|
|
158
|
+
syncEnv?(): void;
|
|
159
|
+
};
|
|
160
|
+
openPanel(): void;
|
|
161
|
+
closePanel(): void;
|
|
162
|
+
palettes?(): Promise<Palette[]>;
|
|
163
|
+
persistTheme?(theme: string, palette: string): void;
|
|
164
|
+
appTheme?: {
|
|
165
|
+
save(appId: string, t: {
|
|
166
|
+
theme: string;
|
|
167
|
+
palette: string;
|
|
168
|
+
}): Promise<void>;
|
|
169
|
+
clear(appId: string): Promise<void>;
|
|
170
|
+
};
|
|
171
|
+
config?: {
|
|
172
|
+
load(): Promise<Record<string, string>>;
|
|
173
|
+
save(cfg: Record<string, string>): Promise<void>;
|
|
174
|
+
};
|
|
175
|
+
history?: {
|
|
176
|
+
list(appId: string): Promise<Commit[]>;
|
|
177
|
+
detail(appId: string, id: string): Promise<Commit>;
|
|
178
|
+
};
|
|
179
|
+
storage?: {
|
|
180
|
+
listTables(appId: string): Promise<StorageTable[]>;
|
|
181
|
+
readTable(appId: string, name: string): Promise<unknown>;
|
|
182
|
+
};
|
|
183
|
+
onOpenRequest?(cb: (appId?: string) => void): () => void;
|
|
184
|
+
emptyText?: string;
|
|
185
|
+
deleteApp?(appId: string): Promise<void>;
|
|
186
|
+
}
|
|
187
|
+
declare function capabilitiesOf(host: PanelHost): PanelCapabilities;
|
|
188
|
+
|
|
189
|
+
declare function activeAppFrom(state: PanelState): AppItem | null;
|
|
190
|
+
declare function createPanelActions(host: PanelHost, getRootEl: () => HTMLElement | null, i18n: PanelI18n): PanelActions;
|
|
191
|
+
declare function defaultHideThemePop(): boolean;
|
|
192
|
+
declare function clampPaletteId(v: unknown): string;
|
|
193
|
+
|
|
194
|
+
declare function AppList(): react.JSX.Element;
|
|
195
|
+
declare function ListRegion(): react.JSX.Element;
|
|
196
|
+
|
|
197
|
+
declare function Browse(): react.JSX.Element | null;
|
|
198
|
+
|
|
199
|
+
declare function Loading(): react.JSX.Element;
|
|
200
|
+
|
|
201
|
+
declare function MiniAppPanel(): react.JSX.Element;
|
|
202
|
+
|
|
203
|
+
declare function Modal(): react.JSX.Element | null;
|
|
204
|
+
|
|
205
|
+
declare function Settings(): react.JSX.Element | null;
|
|
206
|
+
|
|
207
|
+
declare function Tabs(): react.JSX.Element;
|
|
208
|
+
|
|
209
|
+
declare function ThemePop(): react.JSX.Element;
|
|
210
|
+
|
|
211
|
+
declare function Toolbar(): react.JSX.Element;
|
|
212
|
+
|
|
213
|
+
declare function PanelProvider({ actions, i18n, children, }: {
|
|
214
|
+
actions: PanelActions;
|
|
215
|
+
i18n: PanelI18n;
|
|
216
|
+
children: react.ReactNode;
|
|
217
|
+
}): react.JSX.Element;
|
|
218
|
+
declare function usePanelActions(): PanelActions;
|
|
219
|
+
declare function usePanelI18n(): PanelI18n;
|
|
220
|
+
|
|
221
|
+
declare class PanelError extends Error {
|
|
222
|
+
readonly code: string;
|
|
223
|
+
constructor(code: string, message: string, options?: {
|
|
224
|
+
cause?: unknown;
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* FrameController — browser iframe hosting for mini-apps.
|
|
230
|
+
*
|
|
231
|
+
* Reusable chrome: mounts an app iframe into a given container, posts the
|
|
232
|
+
* current theme/palette/dock env into it (the appRunnerHtml listens for
|
|
233
|
+
* `mma-set-env`), and shows a loading overlay. Host-agnostic: the container and
|
|
234
|
+
* an `envOf(appId)` accessor are injected, so dsh and apps/react-host both use it.
|
|
235
|
+
*/
|
|
236
|
+
type FrameEnv = {
|
|
237
|
+
theme: string;
|
|
238
|
+
palette: string;
|
|
239
|
+
dock: string;
|
|
240
|
+
};
|
|
241
|
+
type FrameRecord = {
|
|
242
|
+
wrap: HTMLElement;
|
|
243
|
+
iframe: HTMLIFrameElement;
|
|
244
|
+
};
|
|
245
|
+
type FrameController = {
|
|
246
|
+
url(appId: string): string;
|
|
247
|
+
mount(appId: string, title?: string): void;
|
|
248
|
+
unmount(appId: string): void;
|
|
249
|
+
unmountAll(): void;
|
|
250
|
+
reload(appId: string): void;
|
|
251
|
+
postEnv(appId: string): void;
|
|
252
|
+
postEnvAll(): void;
|
|
253
|
+
/** Set/rebind the container the app iframes mount into (e.g. the panel's #mma-frames). */
|
|
254
|
+
setContainer(el: HTMLElement): void;
|
|
255
|
+
readonly map: Map<string, FrameRecord>;
|
|
256
|
+
};
|
|
257
|
+
type FrameControllerOptions = {
|
|
258
|
+
/** The element app iframes mount into; may be bound later via setContainer. */
|
|
259
|
+
container?: HTMLElement | null;
|
|
260
|
+
/** Build the iframe src for an app. Usually appFrameUrl(origin, appId, env). */
|
|
261
|
+
urlOf(appId: string): string;
|
|
262
|
+
/** Current env for an app (theme/palette/dock), posted via mma-set-env. */
|
|
263
|
+
envOf(appId: string): FrameEnv;
|
|
264
|
+
};
|
|
265
|
+
declare function createFrameController(opts: FrameControllerOptions): FrameController;
|
|
266
|
+
|
|
267
|
+
type CreateMiniAppPanelOptions = {
|
|
268
|
+
locale?: LocaleId;
|
|
269
|
+
};
|
|
270
|
+
interface PanelInstance {
|
|
271
|
+
actions: PanelActions;
|
|
272
|
+
mount(el: HTMLElement): void;
|
|
273
|
+
unmount(): void;
|
|
274
|
+
open(): void;
|
|
275
|
+
close(): void;
|
|
276
|
+
}
|
|
277
|
+
declare function createMiniAppPanel(host: PanelHost, options?: CreateMiniAppPanelOptions): PanelInstance;
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* createHostShell — reusable outer host chrome for mini-apps.
|
|
281
|
+
*
|
|
282
|
+
* Assembles the panel↔host seam in one call: a `PanelHost` (REST to a
|
|
283
|
+
* `packages/host` server), a frame controller for the app iframes, and a mount
|
|
284
|
+
* that renders `MiniAppPanel` into a container with theme apply/persist. Host
|
|
285
|
+
* layout details (dock tab sizing, sidebar sync) are supplied by the caller via
|
|
286
|
+
* injected callbacks; this shell owns the theme + panel + frames.
|
|
287
|
+
*
|
|
288
|
+
* Both the dsh plugin and a standalone apps/react-host SPA use this.
|
|
289
|
+
*/
|
|
290
|
+
|
|
291
|
+
type HostShellOptions = {
|
|
292
|
+
/** Origin to a `packages/host` Hono server (e.g. http://127.0.0.1:17880). */
|
|
293
|
+
hostUrl: string;
|
|
294
|
+
/** Persistence backend. Defaults to window.localStorage. */
|
|
295
|
+
storage?: Pick<Storage, "getItem" | "setItem" | "removeItem"> | null;
|
|
296
|
+
cardStyle?: CardStyle;
|
|
297
|
+
locale?: string;
|
|
298
|
+
emptyText?: string;
|
|
299
|
+
/** Optional: resolve the host URL (defaults to the passed hostUrl). */
|
|
300
|
+
resolveHostUrl?: (current: string, storage: HostShellOptions["storage"]) => string;
|
|
301
|
+
/** Fired when the host reports a new port. */
|
|
302
|
+
onHostChange?: (nextHostUrl: string) => void;
|
|
303
|
+
/** Dock layout hooks — real layout is host-specific; shell just tracks dock state. */
|
|
304
|
+
layout?: {
|
|
305
|
+
setDock?(dock: DockId): void;
|
|
306
|
+
getDock?(): DockId;
|
|
307
|
+
};
|
|
308
|
+
onOpen?: () => void;
|
|
309
|
+
onClose?: () => void;
|
|
310
|
+
};
|
|
311
|
+
interface HostShellInstance {
|
|
312
|
+
panel: PanelInstance;
|
|
313
|
+
host: PanelHost;
|
|
314
|
+
frames: FrameController;
|
|
315
|
+
mount(el: HTMLElement): void;
|
|
316
|
+
unmount(): void;
|
|
317
|
+
openPanel(): void;
|
|
318
|
+
closePanel(): void;
|
|
319
|
+
toggle(): void;
|
|
320
|
+
/** Persist theme to storage + re-apply to the panel host DOM + push to frames. */
|
|
321
|
+
persistTheme(theme: string, palette: string): void;
|
|
322
|
+
setCardStyle(v: CardStyle): void;
|
|
323
|
+
setDock(v: DockId): void;
|
|
324
|
+
}
|
|
325
|
+
declare function createHostShell(opts: HostShellOptions): HostShellInstance;
|
|
326
|
+
|
|
327
|
+
/** Pure panel helpers. */
|
|
328
|
+
|
|
329
|
+
declare function hue(id: string): number;
|
|
330
|
+
declare function appBlurb(a: AppItem): string;
|
|
331
|
+
declare function monoOf(a: AppItem): string;
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* RestPanelHost — a host-agnostic `PanelHost` backed by a mini-app host over HTTP.
|
|
335
|
+
*
|
|
336
|
+
* This is the reusable core of the panel↔host seam: it knows how to talk to a
|
|
337
|
+
* `packages/host` Hono server (/api/*) and persist theme prefs, but knows nothing
|
|
338
|
+
* about dsh. Both the dsh plugin and a standalone `apps/react-host` SPA implement
|
|
339
|
+
* the same `PanelHost` by wrapping this. All data/HTTP logic lives here; the panel
|
|
340
|
+
* never contains /api strings.
|
|
341
|
+
*/
|
|
342
|
+
|
|
343
|
+
type RestOptions = {
|
|
344
|
+
/** Origin to reach a `packages/host` Hono server (e.g. http://127.0.0.1:17880). */
|
|
345
|
+
hostUrl: string;
|
|
346
|
+
/** Optional: resolve the host URL dynamically (host-port migration). Defaults to hostUrl. */
|
|
347
|
+
getHostUrl?: () => string;
|
|
348
|
+
/** Persistence backend for theme prefs. Defaults to window.localStorage. */
|
|
349
|
+
storage?: Pick<Storage, "getItem" | "setItem"> | null;
|
|
350
|
+
/** The current host's card style (for host-config form defaults). */
|
|
351
|
+
cardStyle?: CardStyle;
|
|
352
|
+
/** Optional: resolve the current card style dynamically (defaults to cardStyle). */
|
|
353
|
+
getCardStyle?: () => CardStyle;
|
|
354
|
+
locale?: LocaleId;
|
|
355
|
+
emptyText?: string;
|
|
356
|
+
/** Optional overrides for opening/closing the panel (SPA wiring). */
|
|
357
|
+
onOpen?: () => void;
|
|
358
|
+
onClose?: () => void;
|
|
359
|
+
/** Fired when the host reports a new port (e.g. after saving a different hostPort). */
|
|
360
|
+
onHostChange?: (nextHostUrl: string) => void;
|
|
361
|
+
/** Fired after a successful host-config save (theme/cardStyle/origin side effects). */
|
|
362
|
+
onConfigSaved?: (form: Record<string, string>) => void;
|
|
363
|
+
/** Iframe control — provide a function that mounts/unmounts the app iframe. */
|
|
364
|
+
frameController?: PanelHost["frame"];
|
|
365
|
+
deleteApp?: (appId: string) => Promise<void>;
|
|
366
|
+
};
|
|
367
|
+
declare function readJson(url: string, init?: RequestInit): Promise<unknown>;
|
|
368
|
+
/** Thrown when a `packages/host` server cannot be reached at the network level (port blocked / host not started). */
|
|
369
|
+
declare class HostUnreachableError extends Error {
|
|
370
|
+
readonly url: string;
|
|
371
|
+
constructor(url: string, cause?: unknown);
|
|
372
|
+
}
|
|
373
|
+
declare function isHostUnreachable(e: unknown): e is HostUnreachableError;
|
|
374
|
+
declare function appFrameUrl(origin: string, appId: string, query: {
|
|
375
|
+
theme: string;
|
|
376
|
+
palette: string;
|
|
377
|
+
dock: string;
|
|
378
|
+
}): string;
|
|
379
|
+
declare function parseAppsResponse(raw: unknown): AppItem[];
|
|
380
|
+
declare function hostConfigToForm(raw: unknown, cardStyle: string): Record<string, string>;
|
|
381
|
+
declare function formToHostConfigBody(form: Record<string, string>): Record<string, unknown>;
|
|
382
|
+
declare function parseCommitList(raw: unknown): Commit[];
|
|
383
|
+
declare function parseCommitDetail(raw: unknown, id: string): Commit;
|
|
384
|
+
declare function parseStorageTables(raw: unknown): StorageTable[];
|
|
385
|
+
declare function parsePalettes(raw: unknown): Palette[];
|
|
386
|
+
/** Build a `PanelHost` that talks to a `packages/host` Hono server over HTTP. */
|
|
387
|
+
declare function createRestPanelHost(opts: RestOptions): PanelHost;
|
|
388
|
+
|
|
389
|
+
declare function getPanelState(): PanelState;
|
|
390
|
+
declare function setPanelState(patch: Partial<PanelState>): PanelState;
|
|
391
|
+
declare function subscribePanel(listener: () => void): () => void;
|
|
392
|
+
declare function resetPanelState(seed?: Partial<PanelState>): PanelState;
|
|
393
|
+
declare function usePanelState(): PanelState;
|
|
394
|
+
|
|
395
|
+
/** Injected panel CSS (dsh-style data-plugin-css). Host calls injectPanelCss() on mount. */
|
|
396
|
+
declare const PANEL_CSS_TAG = "panel";
|
|
397
|
+
declare function injectPanelCss(): void;
|
|
398
|
+
|
|
399
|
+
declare const packageName = "@monkey-mini-app/panel";
|
|
400
|
+
|
|
401
|
+
export { type AppItem, AppList, Browse, type BrowseKind, type CardStyle, type Commit, type CommitFile, type CreateMiniAppPanelOptions, type DockId, type FrameController, type FrameControllerOptions, type FrameEnv, type FrameRecord, type HostShellInstance, type HostShellOptions, HostUnreachableError, type I18nParams, LOCALE_IDS, ListRegion, Loading, type LocaleId, MiniAppPanel, Modal, PANEL_CSS_TAG, type Palette, type PanelActions, type PanelCapabilities, PanelError, type PanelHost, type PanelI18n, type PanelInstance, PanelProvider, type PanelState, type RestOptions, Settings, type StorageTable, type TabItem, type TabKind, Tabs, ThemePop, type ThemeScope, TokenSet, Toolbar, activeAppFrom, appBlurb, appFrameUrl, capabilitiesOf, clampPaletteId, createFrameController, createHostShell, createMiniAppPanel, createPanelActions, createPanelI18n, createRestPanelHost, defaultHideThemePop, formToHostConfigBody, getPanelState, hostConfigToForm, hue, injectPanelCss, isHostUnreachable, monoOf, packageName, parseAppsResponse, parseCommitDetail, parseCommitList, parsePalettes, parseStorageTables, readJson, resetPanelState, resolvePanelLocale, setPanelState, subscribePanel, usePanelActions, usePanelI18n, usePanelState };
|