@mohou/panel 1.0.20
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 +8 -0
- package/lib/types/chrome/hue.d.ts +3 -0
- package/lib/types/chrome/hue.d.ts.map +1 -0
- package/lib/types/gallery/card-style.d.ts +8 -0
- package/lib/types/gallery/card-style.d.ts.map +1 -0
- package/lib/types/gallery/client.d.ts +20 -0
- package/lib/types/gallery/client.d.ts.map +1 -0
- package/lib/types/gallery/desk.d.ts +16 -0
- package/lib/types/gallery/desk.d.ts.map +1 -0
- package/lib/types/gallery/list.d.ts +37 -0
- package/lib/types/gallery/list.d.ts.map +1 -0
- package/lib/types/gallery/sort.d.ts +24 -0
- package/lib/types/gallery/sort.d.ts.map +1 -0
- package/lib/types/gallery/state.d.ts +90 -0
- package/lib/types/gallery/state.d.ts.map +1 -0
- package/lib/types/gallery/tabs.d.ts +45 -0
- package/lib/types/gallery/tabs.d.ts.map +1 -0
- package/lib/types/gallery/view.d.ts +57 -0
- package/lib/types/gallery/view.d.ts.map +1 -0
- package/lib/types/history/client.d.ts +25 -0
- package/lib/types/history/client.d.ts.map +1 -0
- package/lib/types/history/state.d.ts +39 -0
- package/lib/types/history/state.d.ts.map +1 -0
- package/lib/types/history/view.d.ts +15 -0
- package/lib/types/history/view.d.ts.map +1 -0
- package/lib/types/index.d.ts +24 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/labels.d.ts +267 -0
- package/lib/types/labels.d.ts.map +1 -0
- package/lib/types/settings/author-mcp-view.d.ts +15 -0
- package/lib/types/settings/author-mcp-view.d.ts.map +1 -0
- package/lib/types/settings/author-mcp.d.ts +4 -0
- package/lib/types/settings/author-mcp.d.ts.map +1 -0
- package/lib/types/settings/client.d.ts +198 -0
- package/lib/types/settings/client.d.ts.map +1 -0
- package/lib/types/settings/credentials-view.d.ts +15 -0
- package/lib/types/settings/credentials-view.d.ts.map +1 -0
- package/lib/types/settings/form.d.ts +27 -0
- package/lib/types/settings/form.d.ts.map +1 -0
- package/lib/types/settings/install-row.d.ts +10 -0
- package/lib/types/settings/install-row.d.ts.map +1 -0
- package/lib/types/settings/mcp-view.d.ts +14 -0
- package/lib/types/settings/mcp-view.d.ts.map +1 -0
- package/lib/types/settings/skill-dirs.d.ts +6 -0
- package/lib/types/settings/skill-dirs.d.ts.map +1 -0
- package/lib/types/settings/skill-install.d.ts +13 -0
- package/lib/types/settings/skill-install.d.ts.map +1 -0
- package/lib/types/settings/state.d.ts +94 -0
- package/lib/types/settings/state.d.ts.map +1 -0
- package/lib/types/settings/update-dialog.d.ts +56 -0
- package/lib/types/settings/update-dialog.d.ts.map +1 -0
- package/lib/types/settings/view.d.ts +26 -0
- package/lib/types/settings/view.d.ts.map +1 -0
- package/lib/types/storage/client.d.ts +15 -0
- package/lib/types/storage/client.d.ts.map +1 -0
- package/lib/types/storage/state.d.ts +42 -0
- package/lib/types/storage/state.d.ts.map +1 -0
- package/lib/types/storage/view.d.ts +16 -0
- package/lib/types/storage/view.d.ts.map +1 -0
- package/lib/types/surface/state.d.ts +42 -0
- package/lib/types/surface/state.d.ts.map +1 -0
- package/lib/types/surface/view.d.ts +34 -0
- package/lib/types/surface/view.d.ts.map +1 -0
- package/lib/types/theme/client.d.ts +45 -0
- package/lib/types/theme/client.d.ts.map +1 -0
- package/lib/types/theme/menu.d.ts +25 -0
- package/lib/types/theme/menu.d.ts.map +1 -0
- package/lib/types/theme/state.d.ts +46 -0
- package/lib/types/theme/state.d.ts.map +1 -0
- package/lib/types/theme/view.d.ts +16 -0
- package/lib/types/theme/view.d.ts.map +1 -0
- package/lib/types/ui/dialog.d.ts +12 -0
- package/lib/types/ui/dialog.d.ts.map +1 -0
- package/lib/types/ui/tooltip.d.ts +12 -0
- package/lib/types/ui/tooltip.d.ts.map +1 -0
- package/package.json +38 -0
- package/src/chrome/hue.ts +6 -0
- package/src/gallery/card-style.ts +27 -0
- package/src/gallery/client.ts +26 -0
- package/src/gallery/desk.tsx +54 -0
- package/src/gallery/list.ts +54 -0
- package/src/gallery/sort.ts +72 -0
- package/src/gallery/state.ts +229 -0
- package/src/gallery/tabs.ts +85 -0
- package/src/gallery/view.tsx +501 -0
- package/src/history/client.ts +27 -0
- package/src/history/state.ts +90 -0
- package/src/history/view.tsx +131 -0
- package/src/index.ts +61 -0
- package/src/labels.ts +536 -0
- package/src/settings/author-mcp-view.tsx +154 -0
- package/src/settings/author-mcp.ts +24 -0
- package/src/settings/client.ts +205 -0
- package/src/settings/credentials-view.tsx +195 -0
- package/src/settings/form.ts +27 -0
- package/src/settings/install-row.tsx +35 -0
- package/src/settings/mcp-view.tsx +793 -0
- package/src/settings/skill-dirs.ts +41 -0
- package/src/settings/skill-install.tsx +134 -0
- package/src/settings/state.ts +225 -0
- package/src/settings/update-dialog.tsx +207 -0
- package/src/settings/view.tsx +722 -0
- package/src/storage/client.ts +16 -0
- package/src/storage/state.ts +94 -0
- package/src/storage/view.tsx +190 -0
- package/src/surface/state.ts +72 -0
- package/src/surface/view.tsx +255 -0
- package/src/theme/client.ts +34 -0
- package/src/theme/menu.tsx +286 -0
- package/src/theme/state.ts +113 -0
- package/src/theme/view.tsx +73 -0
- package/src/ui/dialog.tsx +25 -0
- package/src/ui/tooltip.tsx +19 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { PanelPolicy, PanelPolicyWrite, PanelSettingsClient } from './client.ts';
|
|
2
|
+
export interface SettingsState {
|
|
3
|
+
readonly saved?: PanelPolicy;
|
|
4
|
+
readonly theme: PanelPolicy['theme'];
|
|
5
|
+
readonly palette: string;
|
|
6
|
+
readonly locale: string;
|
|
7
|
+
readonly port: string;
|
|
8
|
+
readonly providerId: string;
|
|
9
|
+
readonly modelProvider: string;
|
|
10
|
+
readonly model: string;
|
|
11
|
+
readonly workbenchId: string;
|
|
12
|
+
readonly dirty: boolean;
|
|
13
|
+
readonly portError: boolean;
|
|
14
|
+
readonly saveError: boolean;
|
|
15
|
+
readonly saveMessage?: string;
|
|
16
|
+
readonly pending?: 'close' | 'restore';
|
|
17
|
+
readonly closed: boolean;
|
|
18
|
+
readonly restartRequired: boolean;
|
|
19
|
+
/** True when restart is required because hostPort changed (MCP URL must be refreshed). */
|
|
20
|
+
readonly restartPort: boolean;
|
|
21
|
+
/** True when restart is required because runtimeProvider.id changed. */
|
|
22
|
+
readonly restartRuntime: boolean;
|
|
23
|
+
readonly probe?: string;
|
|
24
|
+
}
|
|
25
|
+
export type SettingsAction = {
|
|
26
|
+
readonly type: 'loaded';
|
|
27
|
+
readonly policy: PanelPolicy;
|
|
28
|
+
} | {
|
|
29
|
+
readonly type: 'edit-theme';
|
|
30
|
+
readonly theme: PanelPolicy['theme'];
|
|
31
|
+
} | {
|
|
32
|
+
readonly type: 'edit-palette';
|
|
33
|
+
readonly palette: string;
|
|
34
|
+
} | {
|
|
35
|
+
readonly type: 'edit-locale';
|
|
36
|
+
readonly locale: string;
|
|
37
|
+
} | {
|
|
38
|
+
readonly type: 'edit-port';
|
|
39
|
+
readonly port: string;
|
|
40
|
+
} | {
|
|
41
|
+
readonly type: 'edit-provider';
|
|
42
|
+
readonly providerId: string;
|
|
43
|
+
} | {
|
|
44
|
+
readonly type: 'edit-model';
|
|
45
|
+
readonly provider: string;
|
|
46
|
+
readonly model: string;
|
|
47
|
+
} | {
|
|
48
|
+
readonly type: 'edit-workbench';
|
|
49
|
+
readonly workbenchId: string;
|
|
50
|
+
} | {
|
|
51
|
+
readonly type: 'saved';
|
|
52
|
+
readonly result: PanelPolicyWrite;
|
|
53
|
+
}
|
|
54
|
+
/** Host policy written elsewhere (theme menu). Keeps appearance fields in sync. */
|
|
55
|
+
| {
|
|
56
|
+
readonly type: 'host-policy';
|
|
57
|
+
readonly policy: PanelPolicy;
|
|
58
|
+
} | {
|
|
59
|
+
readonly type: 'port-invalid';
|
|
60
|
+
} | {
|
|
61
|
+
readonly type: 'save-failed';
|
|
62
|
+
readonly message?: string;
|
|
63
|
+
} | {
|
|
64
|
+
readonly type: 'escape';
|
|
65
|
+
} | {
|
|
66
|
+
readonly type: 'restore';
|
|
67
|
+
} | {
|
|
68
|
+
readonly type: 'confirm';
|
|
69
|
+
} | {
|
|
70
|
+
readonly type: 'probed';
|
|
71
|
+
readonly message: string;
|
|
72
|
+
} | {
|
|
73
|
+
readonly type: 'update-failed';
|
|
74
|
+
};
|
|
75
|
+
/** Empty form before the policy load. */
|
|
76
|
+
export declare function settingsState(): SettingsState;
|
|
77
|
+
/**
|
|
78
|
+
* Settings form transition. Port and language checks happen before a write.
|
|
79
|
+
* Escape cancels a confirm first, then closes a clean form.
|
|
80
|
+
* A dirty form asks before close and before restore.
|
|
81
|
+
* @param state - current form
|
|
82
|
+
* @param action - one edit or client result
|
|
83
|
+
*/
|
|
84
|
+
export declare function reduceSettings(state: SettingsState, action: SettingsAction): SettingsState;
|
|
85
|
+
/** Policy to write, or a port error that must not be sent. */
|
|
86
|
+
export declare function settingsDraft(state: SettingsState): {
|
|
87
|
+
ok: true;
|
|
88
|
+
policy: PanelPolicy;
|
|
89
|
+
} | {
|
|
90
|
+
ok: false;
|
|
91
|
+
};
|
|
92
|
+
/** Load policy into the form. */
|
|
93
|
+
export declare function loadSettings(client: PanelSettingsClient, dispatch: (action: SettingsAction) => void): Promise<void>;
|
|
94
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/settings/state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type PanelLabelMode, type PanelLocale } from '../labels.ts';
|
|
3
|
+
import type { PanelUpdateAttempt } from './client.ts';
|
|
4
|
+
/** The one update card. The on-open check and the settings check open this card. */
|
|
5
|
+
export type UpdateCard = {
|
|
6
|
+
readonly kind: 'offer';
|
|
7
|
+
readonly current: string;
|
|
8
|
+
readonly latest: string;
|
|
9
|
+
readonly channel?: 'registry' | 'tarball';
|
|
10
|
+
} | {
|
|
11
|
+
readonly kind: 'installing';
|
|
12
|
+
readonly version: string;
|
|
13
|
+
readonly startedAt: number;
|
|
14
|
+
} | {
|
|
15
|
+
readonly kind: 'failed';
|
|
16
|
+
readonly reason: UpdateReason;
|
|
17
|
+
readonly target?: string;
|
|
18
|
+
readonly back?: string;
|
|
19
|
+
readonly log?: string;
|
|
20
|
+
} | {
|
|
21
|
+
readonly kind: 'done';
|
|
22
|
+
readonly version: string;
|
|
23
|
+
};
|
|
24
|
+
/** A request that never reached the launcher carries its own text. A recorded outcome carries a closed code. */
|
|
25
|
+
export type UpdateReason = {
|
|
26
|
+
readonly code: 'timeout';
|
|
27
|
+
} | {
|
|
28
|
+
readonly code: 'exit';
|
|
29
|
+
readonly exitCode?: number;
|
|
30
|
+
} | {
|
|
31
|
+
readonly code: 'prepare';
|
|
32
|
+
} | {
|
|
33
|
+
readonly code: 'closed';
|
|
34
|
+
} | {
|
|
35
|
+
readonly code: 'leftover';
|
|
36
|
+
} | {
|
|
37
|
+
readonly code: 'verify';
|
|
38
|
+
} | {
|
|
39
|
+
readonly code: 'boot';
|
|
40
|
+
} | {
|
|
41
|
+
readonly text: string;
|
|
42
|
+
};
|
|
43
|
+
/** What the launcher recorded, as the card shows it. `current` is the version running now. */
|
|
44
|
+
export declare function attemptCard(attempt: PanelUpdateAttempt, current: string): UpdateCard;
|
|
45
|
+
/**
|
|
46
|
+
* One update card: offer, install in progress, failure, or the version now running.
|
|
47
|
+
* @param props - card state and the two actions the card offers
|
|
48
|
+
*/
|
|
49
|
+
export declare function UpdateDialog(props: {
|
|
50
|
+
readonly locale: PanelLocale;
|
|
51
|
+
readonly mode: PanelLabelMode;
|
|
52
|
+
readonly card: UpdateCard;
|
|
53
|
+
readonly onClose: () => void;
|
|
54
|
+
readonly onInstall: (version: string) => void;
|
|
55
|
+
}): ReactNode;
|
|
56
|
+
//# sourceMappingURL=update-dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-dialog.d.ts","sourceRoot":"","sources":["../../../src/settings/update-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAG3D,OAAO,EAAa,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AAG/E,OAAO,KAAK,EAAE,kBAAkB,EAA0B,MAAM,aAAa,CAAA;AAE7E,oFAAoF;AACpF,MAAM,MAAM,UAAU,GAClB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,SAAS,CAAA;CAAE,GACxH;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACrF;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACnI;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvD,gHAAgH;AAChH,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAiB7B,8FAA8F;AAC9F,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CAWpF;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;IAC7B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9C,GAAG,SAAS,CAYZ"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type GalleryCardStyle } from '../gallery/list.ts';
|
|
3
|
+
import { type PanelLabelMode, type PanelLocale } from '../labels.ts';
|
|
4
|
+
import type { PaletteChip } from '../theme/client.ts';
|
|
5
|
+
import type { PanelPolicy, PanelSettingsClient, PanelUpdateCheck } from './client.ts';
|
|
6
|
+
/**
|
|
7
|
+
* Settings form. Hidden when Host exposes no config client. No route string lives here.
|
|
8
|
+
* @param props - client, chrome locale, and the palette list for the appearance cards
|
|
9
|
+
*/
|
|
10
|
+
export declare function PanelSettings(props: {
|
|
11
|
+
readonly client?: PanelSettingsClient;
|
|
12
|
+
readonly locale: PanelLocale;
|
|
13
|
+
readonly mode: PanelLabelMode;
|
|
14
|
+
readonly versions?: string;
|
|
15
|
+
readonly palettes?: readonly PaletteChip[];
|
|
16
|
+
readonly cardStyle?: GalleryCardStyle;
|
|
17
|
+
readonly onCardStyle?: (style: GalleryCardStyle) => void;
|
|
18
|
+
readonly onClose?: () => void;
|
|
19
|
+
readonly onPolicy?: (policy: PanelPolicy) => void;
|
|
20
|
+
/** Live host policy from the theme menu (or other writers). */
|
|
21
|
+
readonly hostPolicy?: PanelPolicy;
|
|
22
|
+
/** Preview chrome locale while the form is open (discard restores the saved locale). */
|
|
23
|
+
readonly onPreviewLocale?: (locale: PanelLocale) => void;
|
|
24
|
+
readonly onUpdateOffer?: (update: PanelUpdateCheck) => void;
|
|
25
|
+
}): ReactNode;
|
|
26
|
+
//# sourceMappingURL=view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/settings/view.tsx"],"names":[],"mappings":"AACA,OAAO,EAAmC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAEvE,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC7E,OAAO,EAA4B,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AAE9F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGrD,OAAO,KAAK,EAAoC,WAAW,EAAgB,mBAAmB,EAAoB,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAevJ;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAA;IACrC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAA;IACrC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAA;IACxD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAA;IACjD,+DAA+D;IAC/D,QAAQ,CAAC,UAAU,CAAC,EAAE,WAAW,CAAA;IACjC,wFAAwF;IACxF,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAA;IACxD,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAA;CAC5D,GAAG,SAAS,CA4SZ"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Storage summary the browse view can show. No route string lives here. */
|
|
2
|
+
export interface StorageSummary {
|
|
3
|
+
readonly bytes: number;
|
|
4
|
+
readonly tables: readonly string[];
|
|
5
|
+
}
|
|
6
|
+
export interface StorageTable {
|
|
7
|
+
readonly rows: readonly unknown[];
|
|
8
|
+
}
|
|
9
|
+
/** Storage reads. Absent means the control is hidden. */
|
|
10
|
+
export interface StorageClient {
|
|
11
|
+
readStorage(appId: string): Promise<StorageSummary>;
|
|
12
|
+
readTable(appId: string, table: string): Promise<StorageTable>;
|
|
13
|
+
restoreStorage?(appId: string): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/storage/client.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;CAClC;AAED,yDAAyD;AACzD,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IACnD,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAC9D,cAAc,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC9C"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { StorageClient, StorageSummary, StorageTable } from './client.ts';
|
|
2
|
+
export interface StorageState {
|
|
3
|
+
readonly summary?: StorageSummary;
|
|
4
|
+
readonly failed: boolean;
|
|
5
|
+
readonly table?: string;
|
|
6
|
+
readonly rows?: StorageTable;
|
|
7
|
+
readonly tableFailed: boolean;
|
|
8
|
+
readonly noticeDismissed: boolean;
|
|
9
|
+
readonly error?: string;
|
|
10
|
+
readonly tableError?: string;
|
|
11
|
+
}
|
|
12
|
+
export type StorageAction = {
|
|
13
|
+
readonly type: 'loaded';
|
|
14
|
+
readonly summary: StorageSummary;
|
|
15
|
+
} | {
|
|
16
|
+
readonly type: 'failed';
|
|
17
|
+
readonly message?: string;
|
|
18
|
+
} | {
|
|
19
|
+
readonly type: 'select';
|
|
20
|
+
readonly table: string;
|
|
21
|
+
} | {
|
|
22
|
+
readonly type: 'table';
|
|
23
|
+
readonly rows: StorageTable;
|
|
24
|
+
} | {
|
|
25
|
+
readonly type: 'table-failed';
|
|
26
|
+
readonly message?: string;
|
|
27
|
+
} | {
|
|
28
|
+
readonly type: 'dismiss-notice';
|
|
29
|
+
};
|
|
30
|
+
/** Empty browse before the load. */
|
|
31
|
+
export declare function storageState(): StorageState;
|
|
32
|
+
/**
|
|
33
|
+
* Storage browse transition. Read-only. A size notice does not block the app.
|
|
34
|
+
* @param state - current browse
|
|
35
|
+
* @param action - one client result
|
|
36
|
+
*/
|
|
37
|
+
export declare function reduceStorage(state: StorageState, action: StorageAction): StorageState;
|
|
38
|
+
/** Load the file size and table names. A thrown error is not an empty database. */
|
|
39
|
+
export declare function loadStorage(client: StorageClient, appId: string, dispatch: (action: StorageAction) => void): Promise<void>;
|
|
40
|
+
/** Export one table. */
|
|
41
|
+
export declare function loadTable(client: StorageClient, appId: string, table: string, dispatch: (action: StorageAction) => void): Promise<void>;
|
|
42
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/storage/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE9E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAA;IACjC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,CAAA;IAC5B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAC7D;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE,GACvD;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAA;AAEvC,oCAAoC;AACpC,wBAAgB,YAAY,IAAI,YAAY,CAE3C;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,GAAG,YAAY,CAiBtF;AAED,mFAAmF;AACnF,wBAAsB,WAAW,CAC/B,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,GACxC,OAAO,CAAC,IAAI,CAAC,CAMf;AAED,wBAAwB;AACxB,wBAAsB,SAAS,CAC7B,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,GACxC,OAAO,CAAC,IAAI,CAAC,CAOf"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type PanelLabelMode, type PanelLocale } from '../labels.ts';
|
|
3
|
+
import type { StorageClient } from './client.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Read-only storage browse. Hidden when Host exposes no storage client. No route string lives here.
|
|
6
|
+
* @param props - client, app, chrome locale, the pane close control, and an optional size notice
|
|
7
|
+
*/
|
|
8
|
+
export declare function PanelStorage(props: {
|
|
9
|
+
readonly client?: StorageClient;
|
|
10
|
+
readonly appId: string;
|
|
11
|
+
readonly locale: PanelLocale;
|
|
12
|
+
readonly mode: PanelLabelMode;
|
|
13
|
+
readonly onClose?: () => void;
|
|
14
|
+
readonly notice?: string;
|
|
15
|
+
}): ReactNode;
|
|
16
|
+
//# sourceMappingURL=view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/storage/view.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAEvE,OAAO,EAAa,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AAE/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAGhD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAA;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB,GAAG,SAAS,CAsFZ"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export declare const panelSections: readonly ["gallery", "settings", "history", "storage"];
|
|
2
|
+
export type PanelSection = (typeof panelSections)[number];
|
|
3
|
+
export interface SurfaceState {
|
|
4
|
+
readonly section: PanelSection;
|
|
5
|
+
/** Palette popover is independent of the main pane so settings stays open. */
|
|
6
|
+
readonly themeOpen: boolean;
|
|
7
|
+
readonly focus?: {
|
|
8
|
+
readonly appId: string;
|
|
9
|
+
readonly title?: string;
|
|
10
|
+
};
|
|
11
|
+
readonly notice?: string;
|
|
12
|
+
readonly unavailable?: string;
|
|
13
|
+
}
|
|
14
|
+
export type SurfaceAction = {
|
|
15
|
+
readonly type: 'section';
|
|
16
|
+
readonly section: PanelSection;
|
|
17
|
+
} | {
|
|
18
|
+
readonly type: 'toggle-theme';
|
|
19
|
+
} | {
|
|
20
|
+
readonly type: 'close-theme';
|
|
21
|
+
} | {
|
|
22
|
+
readonly type: 'show-app';
|
|
23
|
+
readonly appId: string;
|
|
24
|
+
readonly title?: string;
|
|
25
|
+
} | {
|
|
26
|
+
readonly type: 'show-notice';
|
|
27
|
+
readonly appId: string;
|
|
28
|
+
readonly table: string;
|
|
29
|
+
} | {
|
|
30
|
+
readonly type: 'unavailable';
|
|
31
|
+
readonly appId: string;
|
|
32
|
+
};
|
|
33
|
+
/** The gallery section is first. */
|
|
34
|
+
export declare function surfaceState(): SurfaceState;
|
|
35
|
+
/**
|
|
36
|
+
* Which pane is visible, and which app the host asked to show.
|
|
37
|
+
* Theme popover does not replace settings / history / storage.
|
|
38
|
+
* @param state - current surface
|
|
39
|
+
* @param action - a section change or a host event applied by Shell
|
|
40
|
+
*/
|
|
41
|
+
export declare function reduceSurface(state: SurfaceState, action: SurfaceAction): SurfaceState;
|
|
42
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/surface/state.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,wDAAyD,CAAA;AAEnF,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA;AAEzD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;IAC9B,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACpE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAC9B;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GAC5D;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;CAAE,GACjC;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE,GAChC;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9E;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChF;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAE5D,oCAAoC;AACpC,wBAAgB,YAAY,IAAI,YAAY,CAE3C;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,GAAG,YAAY,CAiCtF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { PanelClient } from '../gallery/client.ts';
|
|
3
|
+
import type { HistoryClient } from '../history/client.ts';
|
|
4
|
+
import { type PanelLabelMode, type PanelLocale } from '../labels.ts';
|
|
5
|
+
import type { PanelSettingsClient } from '../settings/client.ts';
|
|
6
|
+
import type { StorageClient } from '../storage/client.ts';
|
|
7
|
+
import type { ThemeClient } from '../theme/client.ts';
|
|
8
|
+
/** Commands Shell can call. Same shape as the shell bridge. No route string lives here. */
|
|
9
|
+
export interface PanelControls {
|
|
10
|
+
showApp(appId: string, title?: string): void;
|
|
11
|
+
showNotice(appId: string, table: string): void;
|
|
12
|
+
unavailable(appId: string): void;
|
|
13
|
+
setWorkbench(appId: string): void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The panel as one surface. A missing client hides that section.
|
|
17
|
+
* @param props - injected clients and chrome locale
|
|
18
|
+
*/
|
|
19
|
+
export declare function PanelSurface(props: {
|
|
20
|
+
readonly client: PanelClient;
|
|
21
|
+
readonly settings?: PanelSettingsClient;
|
|
22
|
+
readonly history?: HistoryClient;
|
|
23
|
+
readonly storage?: StorageClient;
|
|
24
|
+
readonly theme?: ThemeClient;
|
|
25
|
+
readonly appId?: string;
|
|
26
|
+
readonly locale: PanelLocale;
|
|
27
|
+
readonly mode: PanelLabelMode;
|
|
28
|
+
readonly shell: 'standalone' | 'overlay';
|
|
29
|
+
readonly frame?: (appId: string) => ReactNode;
|
|
30
|
+
readonly onClosePanel?: () => void;
|
|
31
|
+
readonly versions?: string;
|
|
32
|
+
readonly onControls?: (controls: PanelControls) => void;
|
|
33
|
+
}): ReactNode;
|
|
34
|
+
//# sourceMappingURL=view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/surface/view.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAGvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAGvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAA4B,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AAC9F,OAAO,KAAK,EAAe,mBAAmB,EAAoB,MAAM,uBAAuB,CAAA;AAI/F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEzD,OAAO,KAAK,EAAe,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAIlE,2FAA2F;AAC3F,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5C,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9C,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAClC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAA;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAA;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAA;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAA;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;IAC7B,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,SAAS,CAAA;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,SAAS,CAAA;IAC7C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAA;CACxD,GAAG,SAAS,CAwKZ"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** One palette chip. Ignored files are not chips. */
|
|
2
|
+
export interface PaletteChip {
|
|
3
|
+
readonly id: string;
|
|
4
|
+
/** English (or sole) display name. */
|
|
5
|
+
readonly name: string;
|
|
6
|
+
/** Chinese display name when the theme file provides one. */
|
|
7
|
+
readonly nameZh?: string;
|
|
8
|
+
readonly swatch?: string;
|
|
9
|
+
readonly style?: string;
|
|
10
|
+
/** Shipped file, or a file from the themes directory. A user file that replaces a shipped id is custom. */
|
|
11
|
+
readonly origin?: 'builtin' | 'custom';
|
|
12
|
+
}
|
|
13
|
+
export interface IgnoredPalette {
|
|
14
|
+
readonly file: string;
|
|
15
|
+
readonly reason: string;
|
|
16
|
+
}
|
|
17
|
+
/** Pin the owner can set. Clear is `default`, not deletion of `theme.css`. */
|
|
18
|
+
export type ThemePin = {
|
|
19
|
+
readonly kind: 'default';
|
|
20
|
+
} | {
|
|
21
|
+
readonly kind: 'follow-host';
|
|
22
|
+
} | {
|
|
23
|
+
readonly kind: 'app-file';
|
|
24
|
+
} | {
|
|
25
|
+
readonly kind: 'palette';
|
|
26
|
+
readonly id: string;
|
|
27
|
+
};
|
|
28
|
+
/** Theme reads and pin writes. Absent means the picker is hidden. No route string lives here. */
|
|
29
|
+
export interface ThemeClient {
|
|
30
|
+
listPalettes(): Promise<{
|
|
31
|
+
palettes: readonly PaletteChip[];
|
|
32
|
+
ignored: readonly IgnoredPalette[];
|
|
33
|
+
}>;
|
|
34
|
+
readPin?(appId: string): Promise<ThemePin>;
|
|
35
|
+
setPin(appId: string, pin: ThemePin): Promise<ThemePin>;
|
|
36
|
+
appFile?(appId: string): Promise<boolean>;
|
|
37
|
+
/** Parsed `theme.css` for this app. Null when the file is missing or ignored. */
|
|
38
|
+
readAppTheme?(appId: string): Promise<{
|
|
39
|
+
name?: string;
|
|
40
|
+
nameZh?: string;
|
|
41
|
+
swatch?: string;
|
|
42
|
+
style?: string;
|
|
43
|
+
} | null>;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/theme/client.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,2GAA2G;IAC3G,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;CACvC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,8EAA8E;AAC9E,MAAM,MAAM,QAAQ,GAChB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE,GAChC;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AAErD,iGAAiG;AACjG,MAAM,WAAW,WAAW;IAC1B,YAAY,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;QAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAA;KAAE,CAAC,CAAA;IACjG,OAAO,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC1C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IACvD,OAAO,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACzC,iFAAiF;IACjF,YAAY,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAA;CAClH"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type PanelLabelMode, type PanelLocale } from '../labels.ts';
|
|
3
|
+
import type { PanelPolicy, PanelSettingsClient } from '../settings/client.ts';
|
|
4
|
+
import type { ThemeClient } from './client.ts';
|
|
5
|
+
/**
|
|
6
|
+
* Theme menu in the toolbar. Global scope writes host appearance.
|
|
7
|
+
* App scope writes that app's pin. The pressed row is the current choice.
|
|
8
|
+
* Appearance (light/dark/system) is always host-global; only palette can be per-app.
|
|
9
|
+
* @param props - theme client, settings client, the open app, and chrome locale
|
|
10
|
+
*/
|
|
11
|
+
export declare function ThemeMenu(props: {
|
|
12
|
+
readonly theme?: ThemeClient;
|
|
13
|
+
readonly settings?: PanelSettingsClient;
|
|
14
|
+
readonly locale: PanelLocale;
|
|
15
|
+
readonly mode: PanelLabelMode;
|
|
16
|
+
readonly appId?: string;
|
|
17
|
+
readonly appTitle?: string;
|
|
18
|
+
readonly hostPolicy?: PanelPolicy;
|
|
19
|
+
readonly onHostPolicy?: (policy: PanelPolicy) => void;
|
|
20
|
+
}): ReactNode;
|
|
21
|
+
/** Host-wide palette CSS preview (panel + all app iframes). */
|
|
22
|
+
export declare function paintHostStyle(style: string): void;
|
|
23
|
+
/** Paint `data-mode` on the panel document. `system` follows the OS. */
|
|
24
|
+
export declare function applyDocumentMode(theme: 'system' | 'light' | 'dark'): void;
|
|
25
|
+
//# sourceMappingURL=menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../../src/theme/menu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAG3D,OAAO,EAAa,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAC7E,OAAO,KAAK,EAAe,WAAW,EAAY,MAAM,aAAa,CAAA;AAErE;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAA;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAA;CACtD,GAAG,SAAS,CAyGZ;AA2ID,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,CAQ1E"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { PaletteChip, IgnoredPalette, ThemeClient, ThemePin } from './client.ts';
|
|
2
|
+
export interface ThemeState {
|
|
3
|
+
readonly palettes: readonly PaletteChip[];
|
|
4
|
+
readonly ignored: readonly IgnoredPalette[];
|
|
5
|
+
readonly pin: ThemePin;
|
|
6
|
+
readonly failed: boolean;
|
|
7
|
+
readonly appFile: boolean;
|
|
8
|
+
readonly error?: string;
|
|
9
|
+
}
|
|
10
|
+
export type ThemeAction = {
|
|
11
|
+
readonly type: 'loaded';
|
|
12
|
+
readonly palettes: readonly PaletteChip[];
|
|
13
|
+
readonly ignored: readonly IgnoredPalette[];
|
|
14
|
+
} | {
|
|
15
|
+
readonly type: 'failed';
|
|
16
|
+
readonly message?: string;
|
|
17
|
+
} | {
|
|
18
|
+
readonly type: 'saved';
|
|
19
|
+
readonly pin: ThemePin;
|
|
20
|
+
} | {
|
|
21
|
+
readonly type: 'save-failed';
|
|
22
|
+
readonly message?: string;
|
|
23
|
+
} | {
|
|
24
|
+
readonly type: 'app-file';
|
|
25
|
+
readonly parsed: boolean;
|
|
26
|
+
} | {
|
|
27
|
+
readonly type: 'pin';
|
|
28
|
+
readonly pin: ThemePin;
|
|
29
|
+
};
|
|
30
|
+
/** Picker before the palette list loads. */
|
|
31
|
+
export declare function themeState(): ThemeState;
|
|
32
|
+
/**
|
|
33
|
+
* Theme picker transition. A failed save leaves the previous pin.
|
|
34
|
+
* @param state - current picker
|
|
35
|
+
* @param action - one client result
|
|
36
|
+
*/
|
|
37
|
+
export declare function reduceTheme(state: ThemeState, action: ThemeAction): ThemeState;
|
|
38
|
+
/** Refetch palettes when the picker opens. */
|
|
39
|
+
export declare function loadPalettes(client: ThemeClient, dispatch: (action: ThemeAction) => void): Promise<void>;
|
|
40
|
+
/** Read the stored pin when the picker opens. A missing method leaves the default. */
|
|
41
|
+
export declare function loadPin(client: ThemeClient, appId: string, dispatch: (action: ThemeAction) => void): Promise<void>;
|
|
42
|
+
/** Ask whether this app's `theme.css` parsed. A missing method leaves the row hidden. */
|
|
43
|
+
export declare function loadAppFile(client: ThemeClient, appId: string, dispatch: (action: ThemeAction) => void): Promise<void>;
|
|
44
|
+
/** Save a pin. Failure does not change the previous pin. */
|
|
45
|
+
export declare function savePin(client: ThemeClient, appId: string, pin: ThemePin, dispatch: (action: ThemeAction) => void): Promise<void>;
|
|
46
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/theme/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAErF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAA;IACzC,QAAQ,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAA;IAC3C,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAA;CAAE,GACnH;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GACvD;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAA;CAAE,CAAA;AAEpD,4CAA4C;AAC5C,wBAAgB,UAAU,IAAI,UAAU,CAEvC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,GAAG,UAAU,CAiB9E;AAED,8CAA8C;AAC9C,wBAAsB,YAAY,CAChC,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,GACtC,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,sFAAsF;AACtF,wBAAsB,OAAO,CAC3B,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,GACtC,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,yFAAyF;AACzF,wBAAsB,WAAW,CAC/B,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,GACtC,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,4DAA4D;AAC5D,wBAAsB,OAAO,CAC3B,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,QAAQ,EACb,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,GACtC,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type PanelLabelMode, type PanelLocale } from '../labels.ts';
|
|
3
|
+
import type { ThemeClient } from './client.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Theme picker. Hidden when Host exposes no theme client. No route string lives here.
|
|
6
|
+
* The app-file row appears only in app scope when `theme.css` parsed.
|
|
7
|
+
* @param props - client, scope, and chrome locale
|
|
8
|
+
*/
|
|
9
|
+
export declare function PanelTheme(props: {
|
|
10
|
+
readonly client?: ThemeClient;
|
|
11
|
+
readonly appId?: string;
|
|
12
|
+
readonly appFile?: boolean;
|
|
13
|
+
readonly locale: PanelLocale;
|
|
14
|
+
readonly mode: PanelLabelMode;
|
|
15
|
+
}): ReactNode;
|
|
16
|
+
//# sourceMappingURL=view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/theme/view.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAE7D,OAAO,EAAa,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAY,MAAM,aAAa,CAAA;AAGxD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;CAC9B,GAAG,SAAS,CAwCZ"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* One modal. The scrim fades in and the card scales in.
|
|
4
|
+
* Callers pass content only. They do not repeat the motion classes.
|
|
5
|
+
* @param props - close handler, width, and the card body
|
|
6
|
+
*/
|
|
7
|
+
export declare function Dialog(props: {
|
|
8
|
+
readonly children: ReactNode;
|
|
9
|
+
readonly onClose: () => void;
|
|
10
|
+
readonly width?: 'sm' | 'md' | 'wide';
|
|
11
|
+
}): ReactNode;
|
|
12
|
+
//# sourceMappingURL=dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../../src/ui/dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAA;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAAA;CACtC,GAAG,SAAS,CAaZ"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Fast hover/focus hint. Native `title` is slow and easy to miss on icon chrome.
|
|
4
|
+
* @param props - hint text, the control, and optional alignment
|
|
5
|
+
*/
|
|
6
|
+
export declare function Tooltip(props: {
|
|
7
|
+
readonly text: string;
|
|
8
|
+
readonly children: ReactNode;
|
|
9
|
+
readonly align?: 'center' | 'end';
|
|
10
|
+
readonly className?: string;
|
|
11
|
+
}): ReactNode;
|
|
12
|
+
//# sourceMappingURL=tooltip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../../src/ui/tooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC;;;GAGG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAA;IACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B,GAAG,SAAS,CAOZ"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mohou/panel",
|
|
3
|
+
"version": "1.0.20",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": "^22.19.0 || >=24.0.0"
|
|
8
|
+
},
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"access": "public"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"src",
|
|
14
|
+
"lib/types",
|
|
15
|
+
"README.md",
|
|
16
|
+
"!**/*.tsbuildinfo"
|
|
17
|
+
],
|
|
18
|
+
"main": "./src/index.ts",
|
|
19
|
+
"types": "./src/index.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./src/index.ts",
|
|
23
|
+
"default": "./src/index.ts"
|
|
24
|
+
},
|
|
25
|
+
"./src/*": "./src/*",
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"lucide-react": "^0.544.0",
|
|
30
|
+
"react": "^19.3.0",
|
|
31
|
+
"react-dom": "^19.3.0",
|
|
32
|
+
"@mohou/app-view": "^1.0.20"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/react": "^19.3.0",
|
|
36
|
+
"@types/react-dom": "^19.3.0"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { galleryCardStyles, type GalleryCardStyle } from './list.ts'
|
|
2
|
+
|
|
3
|
+
const cardStyleKey = 'mini-app.panel.card-style'
|
|
4
|
+
|
|
5
|
+
/** Fallback when nothing is stored. Not a host field. */
|
|
6
|
+
export const defaultCardStyle: GalleryCardStyle = 'glass'
|
|
7
|
+
|
|
8
|
+
/** Last card style chosen in this browser. Not a host field. */
|
|
9
|
+
export function readCardStyle(): GalleryCardStyle {
|
|
10
|
+
if (typeof localStorage === 'undefined') return defaultCardStyle
|
|
11
|
+
try {
|
|
12
|
+
const value = localStorage.getItem(cardStyleKey)
|
|
13
|
+
if (value !== null && (galleryCardStyles as readonly string[]).includes(value)) return value as GalleryCardStyle
|
|
14
|
+
} catch {
|
|
15
|
+
// Private mode can reject storage reads.
|
|
16
|
+
}
|
|
17
|
+
return defaultCardStyle
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Remember the choice across panel reloads. */
|
|
21
|
+
export function writeCardStyle(style: GalleryCardStyle): void {
|
|
22
|
+
try {
|
|
23
|
+
localStorage.setItem(cardStyleKey, style)
|
|
24
|
+
} catch {
|
|
25
|
+
// A failed write still changes the current view.
|
|
26
|
+
}
|
|
27
|
+
}
|