@elench/shell 0.1.1
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 +9 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/shell.d.ts +147 -0
- package/dist/shell.d.ts.map +1 -0
- package/dist/shell.js +339 -0
- package/dist/shell.js.map +1 -0
- package/dist/styles.css +475 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# @elench/shell
|
|
2
|
+
|
|
3
|
+
`@elench/shell` is the shared Elench desktop shell. Product code supplies
|
|
4
|
+
sections, sidebar entries, tab descriptors, tab renderers, and inspector/status
|
|
5
|
+
content. The package owns the activity rail, sidebar, tab rail, main pane,
|
|
6
|
+
inspector placement, status bar, persistence, and shell actions.
|
|
7
|
+
|
|
8
|
+
The core contract is strict: domain content can only render inside an open tab.
|
|
9
|
+
The shell never calls a product renderer with a null tab.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export {
|
|
2
|
+
ShellApp,
|
|
3
|
+
ShellEmptyState,
|
|
4
|
+
ShellField,
|
|
5
|
+
ShellMetric,
|
|
6
|
+
ShellPage,
|
|
7
|
+
ShellSidebar,
|
|
8
|
+
ShellSidebarItem,
|
|
9
|
+
ShellSidebarSection,
|
|
10
|
+
defineShellApp,
|
|
11
|
+
defineShellSection,
|
|
12
|
+
defineShellTab,
|
|
13
|
+
useShellController,
|
|
14
|
+
} from "./shell.js";
|
|
15
|
+
export type {
|
|
16
|
+
DefineShellSectionInput,
|
|
17
|
+
ShellActionMeta,
|
|
18
|
+
ShellAppDefinition,
|
|
19
|
+
ShellAppProps,
|
|
20
|
+
ShellController,
|
|
21
|
+
ShellRenderContext,
|
|
22
|
+
ShellSectionDefinition,
|
|
23
|
+
ShellSidebarContext,
|
|
24
|
+
ShellTab,
|
|
25
|
+
ShellTabTarget,
|
|
26
|
+
ShellTabTone,
|
|
27
|
+
} from "./shell.js";
|
|
28
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,eAAe,EACf,UAAU,EACV,WAAW,EACX,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,uBAAuB,EACvB,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,QAAQ,EACR,cAAc,EACd,YAAY,EACb,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,eAAe,EACf,UAAU,EACV,WAAW,EACX,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EACnB,MAAM,YAAY,CAAC"}
|
package/dist/shell.d.ts
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { type CSSProperties, type ReactNode } from "react";
|
|
2
|
+
export type ShellTabTone =
|
|
3
|
+
| "neutral"
|
|
4
|
+
| "success"
|
|
5
|
+
| "warning"
|
|
6
|
+
| "danger"
|
|
7
|
+
| "info";
|
|
8
|
+
export type ShellTabTarget = {
|
|
9
|
+
kind: string;
|
|
10
|
+
[key: string]: string | number | boolean | null | undefined;
|
|
11
|
+
};
|
|
12
|
+
export type ShellTab<TTarget extends ShellTabTarget = ShellTabTarget> = {
|
|
13
|
+
id: string;
|
|
14
|
+
sectionId: string;
|
|
15
|
+
title: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
tone?: ShellTabTone;
|
|
18
|
+
preview?: boolean;
|
|
19
|
+
target: TTarget;
|
|
20
|
+
};
|
|
21
|
+
export type ShellActionMeta = {
|
|
22
|
+
preview?: boolean;
|
|
23
|
+
source?: string;
|
|
24
|
+
};
|
|
25
|
+
export type ShellController = {
|
|
26
|
+
activeSectionId: string;
|
|
27
|
+
activeTab: ShellTab | null;
|
|
28
|
+
closeAllTabs: (meta?: ShellActionMeta) => void;
|
|
29
|
+
closeOtherTabs: (tabId: string, meta?: ShellActionMeta) => void;
|
|
30
|
+
closeTab: (tabId: string, meta?: ShellActionMeta) => void;
|
|
31
|
+
isOpen: (tabId: string) => boolean;
|
|
32
|
+
isSelected: (tabId: string) => boolean;
|
|
33
|
+
openTab: (tab: ShellTab, meta?: ShellActionMeta) => void;
|
|
34
|
+
pinTab: (tabId: string, meta?: ShellActionMeta) => void;
|
|
35
|
+
selectSection: (sectionId: string, meta?: ShellActionMeta) => void;
|
|
36
|
+
selectTab: (tabId: string, meta?: ShellActionMeta) => void;
|
|
37
|
+
tabs: ShellTab[];
|
|
38
|
+
tabsForActiveSection: ShellTab[];
|
|
39
|
+
tabsForSection: (sectionId: string) => ShellTab[];
|
|
40
|
+
};
|
|
41
|
+
export type ShellSidebarContext = ShellController & {
|
|
42
|
+
section: ShellSectionDefinition;
|
|
43
|
+
};
|
|
44
|
+
export type ShellRenderContext<TTab extends ShellTab = ShellTab> =
|
|
45
|
+
ShellController & {
|
|
46
|
+
section: ShellSectionDefinition;
|
|
47
|
+
tab: TTab;
|
|
48
|
+
};
|
|
49
|
+
export type DefineShellSectionInput = {
|
|
50
|
+
id: string;
|
|
51
|
+
label: string;
|
|
52
|
+
icon: ReactNode;
|
|
53
|
+
renderSidebar: (ctx: ShellSidebarContext) => ReactNode;
|
|
54
|
+
renderTab: (ctx: ShellRenderContext) => ReactNode;
|
|
55
|
+
renderInspector?: (ctx: ShellRenderContext) => ReactNode;
|
|
56
|
+
renderStatus?: (ctx: ShellController) => ReactNode;
|
|
57
|
+
};
|
|
58
|
+
export type ShellSectionDefinition = DefineShellSectionInput;
|
|
59
|
+
export type ShellAppDefinition = {
|
|
60
|
+
id: string;
|
|
61
|
+
title: string;
|
|
62
|
+
sections: ShellSectionDefinition[];
|
|
63
|
+
storageNamespace: string;
|
|
64
|
+
};
|
|
65
|
+
export type ShellAppProps = {
|
|
66
|
+
app: ShellAppDefinition;
|
|
67
|
+
initialSectionId?: string;
|
|
68
|
+
};
|
|
69
|
+
export declare function defineShellApp(
|
|
70
|
+
app: ShellAppDefinition,
|
|
71
|
+
): ShellAppDefinition;
|
|
72
|
+
export declare function defineShellSection(
|
|
73
|
+
section: DefineShellSectionInput,
|
|
74
|
+
): ShellSectionDefinition;
|
|
75
|
+
export declare function defineShellTab<TTarget extends ShellTabTarget>(
|
|
76
|
+
tab: ShellTab<TTarget>,
|
|
77
|
+
): ShellTab<TTarget>;
|
|
78
|
+
export declare function useShellController(): ShellController;
|
|
79
|
+
export declare function ShellApp({
|
|
80
|
+
app,
|
|
81
|
+
initialSectionId,
|
|
82
|
+
}: ShellAppProps): import("react/jsx-runtime").JSX.Element;
|
|
83
|
+
export declare function ShellSidebar({
|
|
84
|
+
children,
|
|
85
|
+
title,
|
|
86
|
+
}: {
|
|
87
|
+
children: ReactNode;
|
|
88
|
+
title: string;
|
|
89
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
90
|
+
export declare function ShellSidebarSection({
|
|
91
|
+
children,
|
|
92
|
+
title,
|
|
93
|
+
}: {
|
|
94
|
+
children: ReactNode;
|
|
95
|
+
title: string;
|
|
96
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
97
|
+
export declare function ShellSidebarItem({
|
|
98
|
+
active,
|
|
99
|
+
children,
|
|
100
|
+
description,
|
|
101
|
+
icon,
|
|
102
|
+
onClick,
|
|
103
|
+
tone,
|
|
104
|
+
}: {
|
|
105
|
+
active?: boolean;
|
|
106
|
+
children: ReactNode;
|
|
107
|
+
description?: string;
|
|
108
|
+
icon?: ReactNode;
|
|
109
|
+
onClick: () => void;
|
|
110
|
+
tone?: ShellTabTone;
|
|
111
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
112
|
+
export declare function ShellPage({
|
|
113
|
+
actions,
|
|
114
|
+
children,
|
|
115
|
+
description,
|
|
116
|
+
eyebrow,
|
|
117
|
+
title,
|
|
118
|
+
}: {
|
|
119
|
+
actions?: ReactNode;
|
|
120
|
+
children: ReactNode;
|
|
121
|
+
description?: string;
|
|
122
|
+
eyebrow?: string | null;
|
|
123
|
+
title: string;
|
|
124
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
125
|
+
export declare function ShellMetric({
|
|
126
|
+
title,
|
|
127
|
+
value,
|
|
128
|
+
}: {
|
|
129
|
+
title: string;
|
|
130
|
+
value: ReactNode;
|
|
131
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
132
|
+
export declare function ShellField({
|
|
133
|
+
label,
|
|
134
|
+
value,
|
|
135
|
+
}: {
|
|
136
|
+
label: string;
|
|
137
|
+
value: ReactNode;
|
|
138
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
139
|
+
export declare function ShellEmptyState({
|
|
140
|
+
description,
|
|
141
|
+
title,
|
|
142
|
+
}: {
|
|
143
|
+
description?: string;
|
|
144
|
+
title: string;
|
|
145
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
146
|
+
export declare function createInsetStyle(value: number): CSSProperties;
|
|
147
|
+
//# sourceMappingURL=shell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../src/shell.tsx"],"names":[],"mappings":"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"}
|
package/dist/shell.js
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react";
|
|
4
|
+
import { ChevronRightIcon, PanelLeftCloseIcon, PanelLeftOpenIcon, PanelRightCloseIcon, PanelRightOpenIcon, XIcon } from "lucide-react";
|
|
5
|
+
const ShellContext = createContext(null);
|
|
6
|
+
export function defineShellApp(app) {
|
|
7
|
+
assertUnique(app.sections.map((section) => section.id), "Shell sections must have unique ids");
|
|
8
|
+
if (app.sections.length === 0) {
|
|
9
|
+
throw new Error("Shell apps must define at least one section.");
|
|
10
|
+
}
|
|
11
|
+
return app;
|
|
12
|
+
}
|
|
13
|
+
export function defineShellSection(section) {
|
|
14
|
+
return section;
|
|
15
|
+
}
|
|
16
|
+
export function defineShellTab(tab) {
|
|
17
|
+
return tab;
|
|
18
|
+
}
|
|
19
|
+
export function useShellController() {
|
|
20
|
+
return useShell();
|
|
21
|
+
}
|
|
22
|
+
export function ShellApp({ app, initialSectionId }) {
|
|
23
|
+
const defaultSectionId = resolveSectionId(app, initialSectionId);
|
|
24
|
+
const storageKey = `${app.storageNamespace}:elench-shell:v1`;
|
|
25
|
+
const initialState = useMemo(() => loadPersistedState(storageKey, app, defaultSectionId), [app, defaultSectionId, storageKey]);
|
|
26
|
+
const [activeSectionId, setActiveSectionId] = useState(initialState.activeSectionId);
|
|
27
|
+
const [activeTabIdBySection, setActiveTabIdBySection] = useState(initialState.activeTabIdBySection);
|
|
28
|
+
const [tabs, setTabs] = useState(initialState.tabs);
|
|
29
|
+
const [leftSidebarOpen, setLeftSidebarOpen] = useState(true);
|
|
30
|
+
const [rightInspectorOpen, setRightInspectorOpen] = useState(true);
|
|
31
|
+
const sectionsById = useMemo(() => new Map(app.sections.map((section) => [section.id, section])), [app.sections]);
|
|
32
|
+
const activeSection = sectionsById.get(activeSectionId) ?? app.sections[0];
|
|
33
|
+
const tabsForActiveSection = tabs.filter((tab) => tab.sectionId === activeSection.id);
|
|
34
|
+
const activeTabId = activeTabIdBySection[activeSection.id] ?? null;
|
|
35
|
+
const activeTab = tabsForActiveSection.find((tab) => tab.id === activeTabId) ?? null;
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
persistState(storageKey, {
|
|
38
|
+
activeSectionId,
|
|
39
|
+
activeTabIdBySection,
|
|
40
|
+
tabs
|
|
41
|
+
});
|
|
42
|
+
}, [activeSectionId, activeTabIdBySection, storageKey, tabs]);
|
|
43
|
+
const tabsForSection = useCallback((sectionId) => tabs.filter((tab) => tab.sectionId === sectionId), [tabs]);
|
|
44
|
+
const selectSection = useCallback((sectionId) => {
|
|
45
|
+
if (!sectionsById.has(sectionId)) {
|
|
46
|
+
throw new Error(`Unknown shell section: ${sectionId}`);
|
|
47
|
+
}
|
|
48
|
+
setActiveSectionId(sectionId);
|
|
49
|
+
}, [sectionsById]);
|
|
50
|
+
const selectTab = useCallback((tabId) => {
|
|
51
|
+
const tab = tabs.find((candidate) => candidate.id === tabId);
|
|
52
|
+
if (!tab) {
|
|
53
|
+
throw new Error(`Unknown shell tab: ${tabId}`);
|
|
54
|
+
}
|
|
55
|
+
setActiveSectionId(tab.sectionId);
|
|
56
|
+
setActiveTabIdBySection((current) => ({
|
|
57
|
+
...current,
|
|
58
|
+
[tab.sectionId]: tab.id
|
|
59
|
+
}));
|
|
60
|
+
}, [tabs]);
|
|
61
|
+
const openTab = useCallback((tab, meta) => {
|
|
62
|
+
setTabs((current) => {
|
|
63
|
+
const preview = meta?.preview === true;
|
|
64
|
+
const nextTab = preview ? { ...tab, preview: true } : tab;
|
|
65
|
+
const existing = current.some((candidate) => candidate.id === tab.id);
|
|
66
|
+
const withoutReplacedPreview = preview && !existing
|
|
67
|
+
? current.filter((candidate) => !(candidate.sectionId === tab.sectionId && candidate.preview))
|
|
68
|
+
: current;
|
|
69
|
+
return existing
|
|
70
|
+
? withoutReplacedPreview.map((candidate) => candidate.id === tab.id ? nextTab : candidate)
|
|
71
|
+
: [...withoutReplacedPreview, nextTab];
|
|
72
|
+
});
|
|
73
|
+
setActiveSectionId(tab.sectionId);
|
|
74
|
+
setActiveTabIdBySection((current) => ({
|
|
75
|
+
...current,
|
|
76
|
+
[tab.sectionId]: tab.id
|
|
77
|
+
}));
|
|
78
|
+
}, []);
|
|
79
|
+
const pinTab = useCallback((tabId) => {
|
|
80
|
+
setTabs((current) => current.map((tab) => tab.id === tabId && tab.preview ? { ...tab, preview: false } : tab));
|
|
81
|
+
}, []);
|
|
82
|
+
const closeTab = useCallback((tabId) => {
|
|
83
|
+
setTabs((currentTabs) => {
|
|
84
|
+
const closingIndex = currentTabs.findIndex((tab) => tab.id === tabId);
|
|
85
|
+
if (closingIndex === -1)
|
|
86
|
+
return currentTabs;
|
|
87
|
+
const closingTab = currentTabs[closingIndex];
|
|
88
|
+
const nextTabs = currentTabs.filter((tab) => tab.id !== tabId);
|
|
89
|
+
setActiveTabIdBySection((currentActive) => {
|
|
90
|
+
if (currentActive[closingTab.sectionId] !== tabId) {
|
|
91
|
+
return currentActive;
|
|
92
|
+
}
|
|
93
|
+
const sameSection = nextTabs.filter((tab) => tab.sectionId === closingTab.sectionId);
|
|
94
|
+
const sameSectionOriginalIndex = currentTabs
|
|
95
|
+
.filter((tab) => tab.sectionId === closingTab.sectionId)
|
|
96
|
+
.findIndex((tab) => tab.id === tabId);
|
|
97
|
+
const nextActive = sameSection[Math.min(sameSectionOriginalIndex, sameSection.length - 1)] ?? null;
|
|
98
|
+
return {
|
|
99
|
+
...currentActive,
|
|
100
|
+
[closingTab.sectionId]: nextActive?.id ?? null
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
return nextTabs;
|
|
104
|
+
});
|
|
105
|
+
}, []);
|
|
106
|
+
const closeOtherTabs = useCallback((tabId) => {
|
|
107
|
+
setTabs((current) => {
|
|
108
|
+
const tab = current.find((candidate) => candidate.id === tabId);
|
|
109
|
+
if (!tab)
|
|
110
|
+
return current;
|
|
111
|
+
setActiveSectionId(tab.sectionId);
|
|
112
|
+
setActiveTabIdBySection((active) => ({
|
|
113
|
+
...active,
|
|
114
|
+
[tab.sectionId]: tab.id
|
|
115
|
+
}));
|
|
116
|
+
return [tab];
|
|
117
|
+
});
|
|
118
|
+
}, []);
|
|
119
|
+
const closeAllTabs = useCallback(() => {
|
|
120
|
+
setTabs([]);
|
|
121
|
+
setActiveTabIdBySection({});
|
|
122
|
+
}, []);
|
|
123
|
+
const controller = useMemo(() => ({
|
|
124
|
+
activeSectionId: activeSection.id,
|
|
125
|
+
activeTab,
|
|
126
|
+
closeAllTabs,
|
|
127
|
+
closeOtherTabs,
|
|
128
|
+
closeTab,
|
|
129
|
+
isOpen: (tabId) => tabs.some((tab) => tab.id === tabId),
|
|
130
|
+
isSelected: (tabId) => activeTab?.id === tabId,
|
|
131
|
+
openTab,
|
|
132
|
+
pinTab,
|
|
133
|
+
selectSection,
|
|
134
|
+
selectTab,
|
|
135
|
+
tabs,
|
|
136
|
+
tabsForActiveSection,
|
|
137
|
+
tabsForSection
|
|
138
|
+
}), [
|
|
139
|
+
activeSection.id,
|
|
140
|
+
activeTab,
|
|
141
|
+
closeAllTabs,
|
|
142
|
+
closeOtherTabs,
|
|
143
|
+
closeTab,
|
|
144
|
+
openTab,
|
|
145
|
+
pinTab,
|
|
146
|
+
selectSection,
|
|
147
|
+
selectTab,
|
|
148
|
+
tabs,
|
|
149
|
+
tabsForActiveSection,
|
|
150
|
+
tabsForSection
|
|
151
|
+
]);
|
|
152
|
+
const value = useMemo(() => ({
|
|
153
|
+
...controller,
|
|
154
|
+
app,
|
|
155
|
+
activeSection,
|
|
156
|
+
leftSidebarOpen,
|
|
157
|
+
rightInspectorOpen,
|
|
158
|
+
setLeftSidebarOpen,
|
|
159
|
+
setRightInspectorOpen
|
|
160
|
+
}), [
|
|
161
|
+
activeSection,
|
|
162
|
+
app,
|
|
163
|
+
controller,
|
|
164
|
+
leftSidebarOpen,
|
|
165
|
+
rightInspectorOpen
|
|
166
|
+
]);
|
|
167
|
+
return (_jsx(ShellContext.Provider, { value: value, children: _jsxs("div", { className: "elench-shell", "data-left-sidebar": leftSidebarOpen ? "open" : "closed", "data-right-inspector": rightInspectorOpen ? "open" : "closed", children: [_jsx(TopBar, {}), _jsx(ActivityRail, {}), leftSidebarOpen ? _jsx(LeftSidebar, {}) : null, _jsx(MainPane, {}), rightInspectorOpen ? _jsx(RightInspector, {}) : null, _jsx(StatusBar, {})] }) }));
|
|
168
|
+
}
|
|
169
|
+
export function ShellSidebar({ children, title }) {
|
|
170
|
+
return (_jsxs("div", { className: "elench-shell-sidebar-frame", children: [_jsx("div", { className: "elench-shell-sidebar-title", children: title }), _jsx("div", { className: "elench-shell-sidebar-content", children: children })] }));
|
|
171
|
+
}
|
|
172
|
+
export function ShellSidebarSection({ children, title }) {
|
|
173
|
+
return (_jsxs("section", { className: "elench-shell-sidebar-section", children: [_jsx("h2", { children: title }), _jsx("div", { children: children })] }));
|
|
174
|
+
}
|
|
175
|
+
export function ShellSidebarItem({ active, children, description, icon, onClick, tone }) {
|
|
176
|
+
return (_jsxs("button", { "aria-selected": active ? "true" : "false", className: "elench-shell-sidebar-item", "data-tone": tone ?? "neutral", onClick: onClick, role: "tab", type: "button", children: [icon ? _jsx("span", { className: "elench-shell-sidebar-item-icon", children: icon }) : null, _jsxs("span", { className: "elench-shell-sidebar-item-text", children: [_jsx("span", { className: "elench-shell-sidebar-item-title", children: children }), description ? (_jsx("span", { className: "elench-shell-sidebar-item-description", children: description })) : null] })] }));
|
|
177
|
+
}
|
|
178
|
+
export function ShellPage({ actions, children, description, eyebrow, title }) {
|
|
179
|
+
return (_jsxs("div", { className: "elench-shell-page", children: [_jsxs("header", { className: "elench-shell-page-header", children: [_jsxs("div", { children: [eyebrow ? _jsx("div", { className: "elench-shell-page-eyebrow", children: eyebrow }) : null, _jsx("h1", { children: title }), description ? _jsx("p", { children: description }) : null] }), actions ? _jsx("div", { className: "elench-shell-page-actions", children: actions }) : null] }), children] }));
|
|
180
|
+
}
|
|
181
|
+
export function ShellMetric({ title, value }) {
|
|
182
|
+
return (_jsxs("div", { className: "elench-shell-metric", children: [_jsx("div", { children: title }), _jsx("strong", { children: value })] }));
|
|
183
|
+
}
|
|
184
|
+
export function ShellField({ label, value }) {
|
|
185
|
+
return (_jsxs("div", { className: "elench-shell-field", children: [_jsx("span", { children: label }), _jsx("strong", { children: value })] }));
|
|
186
|
+
}
|
|
187
|
+
export function ShellEmptyState({ description, title }) {
|
|
188
|
+
return (_jsxs("div", { className: "elench-shell-empty-state", children: [_jsx("strong", { children: title }), description ? _jsx("p", { children: description }) : null] }));
|
|
189
|
+
}
|
|
190
|
+
function TopBar() {
|
|
191
|
+
const { app, leftSidebarOpen, rightInspectorOpen, setLeftSidebarOpen, setRightInspectorOpen } = useShell();
|
|
192
|
+
return (_jsxs("header", { className: "elench-shell-topbar", children: [_jsx("div", { className: "elench-shell-topbar-title", children: app.title }), _jsxs("div", { className: "elench-shell-topbar-actions", children: [_jsx("button", { "aria-label": leftSidebarOpen ? "Close sidebar" : "Open sidebar", onClick: () => setLeftSidebarOpen(!leftSidebarOpen), type: "button", children: leftSidebarOpen ? _jsx(PanelLeftCloseIcon, {}) : _jsx(PanelLeftOpenIcon, {}) }), _jsx("button", { "aria-label": rightInspectorOpen ? "Close inspector" : "Open inspector", onClick: () => setRightInspectorOpen(!rightInspectorOpen), type: "button", children: rightInspectorOpen ? _jsx(PanelRightCloseIcon, {}) : _jsx(PanelRightOpenIcon, {}) })] })] }));
|
|
193
|
+
}
|
|
194
|
+
function ActivityRail() {
|
|
195
|
+
const { activeSectionId, app, selectSection } = useShell();
|
|
196
|
+
return (_jsx("nav", { "aria-label": "Activity rail", className: "elench-shell-activity-rail", children: app.sections.map((section) => (_jsx("button", { "aria-label": section.label, "aria-pressed": activeSectionId === section.id, className: "elench-shell-activity-button", onClick: () => selectSection(section.id, { source: "activity_rail" }), title: section.label, type: "button", children: section.icon }, section.id))) }));
|
|
197
|
+
}
|
|
198
|
+
function LeftSidebar() {
|
|
199
|
+
const shell = useShell();
|
|
200
|
+
const sidebarContext = {
|
|
201
|
+
...toController(shell),
|
|
202
|
+
section: shell.activeSection
|
|
203
|
+
};
|
|
204
|
+
return (_jsx("aside", { "aria-label": "Sidebar", className: "elench-shell-sidebar", children: shell.activeSection.renderSidebar(sidebarContext) }));
|
|
205
|
+
}
|
|
206
|
+
function MainPane() {
|
|
207
|
+
const shell = useShell();
|
|
208
|
+
const activeTab = shell.activeTab;
|
|
209
|
+
return (_jsxs("main", { className: "elench-shell-main", children: [_jsx(TabRail, {}), _jsx("section", { className: "elench-shell-workspace", "data-testid": "shell-workspace", children: activeTab ? (shell.activeSection.renderTab({
|
|
210
|
+
...toController(shell),
|
|
211
|
+
section: shell.activeSection,
|
|
212
|
+
tab: activeTab
|
|
213
|
+
})) : (_jsx("div", { "aria-label": "No open tab", className: "elench-shell-blank-main" })) })] }));
|
|
214
|
+
}
|
|
215
|
+
function TabRail() {
|
|
216
|
+
const { activeTab, closeTab, pinTab, selectTab, tabsForActiveSection } = useShell();
|
|
217
|
+
return (_jsx("div", { "aria-label": "Main tabs", className: "elench-shell-tab-rail", role: "tablist", children: tabsForActiveSection.map((tab) => (_jsxs("div", { "aria-selected": activeTab?.id === tab.id ? "true" : "false", className: "elench-shell-main-tab", "data-preview": tab.preview ? "true" : "false", "data-tone": tab.tone ?? "neutral", role: "tab", children: [_jsx("button", { className: "elench-shell-main-tab-select", onClick: () => selectTab(tab.id, { source: "tab_rail" }), type: "button", children: _jsx("span", { children: tab.title }) }), tab.preview ? (_jsx("button", { "aria-label": `Pin ${tab.title}`, className: "elench-shell-main-tab-icon", onClick: () => pinTab(tab.id, { source: "tab_rail" }), type: "button", children: _jsx(ChevronRightIcon, {}) })) : null, _jsx("button", { "aria-label": `Close ${tab.title}`, className: "elench-shell-main-tab-icon", onClick: () => closeTab(tab.id, { source: "tab_rail" }), type: "button", children: _jsx(XIcon, {}) })] }, tab.id))) }));
|
|
218
|
+
}
|
|
219
|
+
function RightInspector() {
|
|
220
|
+
const shell = useShell();
|
|
221
|
+
const activeTab = shell.activeTab;
|
|
222
|
+
return (_jsx("aside", { "aria-label": "Inspector", className: "elench-shell-inspector", children: activeTab && shell.activeSection.renderInspector ? (shell.activeSection.renderInspector({
|
|
223
|
+
...toController(shell),
|
|
224
|
+
section: shell.activeSection,
|
|
225
|
+
tab: activeTab
|
|
226
|
+
})) : (_jsx(ShellEmptyState, { title: "No tab selected", description: "Open a tab to inspect its details." })) }));
|
|
227
|
+
}
|
|
228
|
+
function StatusBar() {
|
|
229
|
+
const shell = useShell();
|
|
230
|
+
return (_jsxs("footer", { className: "elench-shell-statusbar", children: [_jsx("span", { children: shell.activeSection.label }), _jsxs("span", { children: [shell.tabs.length, " open tabs"] }), _jsx("div", { className: "elench-shell-statusbar-slot", children: shell.activeSection.renderStatus?.(toController(shell)) })] }));
|
|
231
|
+
}
|
|
232
|
+
function useShell() {
|
|
233
|
+
const context = useContext(ShellContext);
|
|
234
|
+
if (!context) {
|
|
235
|
+
throw new Error("Shell hooks must be used within ShellApp.");
|
|
236
|
+
}
|
|
237
|
+
return context;
|
|
238
|
+
}
|
|
239
|
+
function toController(shell) {
|
|
240
|
+
return {
|
|
241
|
+
activeSectionId: shell.activeSectionId,
|
|
242
|
+
activeTab: shell.activeTab,
|
|
243
|
+
closeAllTabs: shell.closeAllTabs,
|
|
244
|
+
closeOtherTabs: shell.closeOtherTabs,
|
|
245
|
+
closeTab: shell.closeTab,
|
|
246
|
+
isOpen: shell.isOpen,
|
|
247
|
+
isSelected: shell.isSelected,
|
|
248
|
+
openTab: shell.openTab,
|
|
249
|
+
pinTab: shell.pinTab,
|
|
250
|
+
selectSection: shell.selectSection,
|
|
251
|
+
selectTab: shell.selectTab,
|
|
252
|
+
tabs: shell.tabs,
|
|
253
|
+
tabsForActiveSection: shell.tabsForActiveSection,
|
|
254
|
+
tabsForSection: shell.tabsForSection
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
function loadPersistedState(storageKey, app, fallbackSectionId) {
|
|
258
|
+
if (typeof window === "undefined") {
|
|
259
|
+
return emptyState(fallbackSectionId);
|
|
260
|
+
}
|
|
261
|
+
try {
|
|
262
|
+
const raw = window.localStorage.getItem(storageKey);
|
|
263
|
+
if (!raw)
|
|
264
|
+
return emptyState(fallbackSectionId);
|
|
265
|
+
const parsed = JSON.parse(raw);
|
|
266
|
+
const validSections = new Set(app.sections.map((section) => section.id));
|
|
267
|
+
const tabs = Array.isArray(parsed.tabs)
|
|
268
|
+
? parsed.tabs.filter((tab) => isValidTab(tab, validSections))
|
|
269
|
+
: [];
|
|
270
|
+
const tabIds = new Set(tabs.map((tab) => tab.id));
|
|
271
|
+
const activeTabIdBySection = sanitizeActiveTabs(parsed.activeTabIdBySection, validSections, tabIds);
|
|
272
|
+
const activeSectionId = typeof parsed.activeSectionId === "string" &&
|
|
273
|
+
validSections.has(parsed.activeSectionId)
|
|
274
|
+
? parsed.activeSectionId
|
|
275
|
+
: fallbackSectionId;
|
|
276
|
+
return {
|
|
277
|
+
activeSectionId,
|
|
278
|
+
activeTabIdBySection,
|
|
279
|
+
tabs
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
return emptyState(fallbackSectionId);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function persistState(storageKey, state) {
|
|
287
|
+
if (typeof window === "undefined")
|
|
288
|
+
return;
|
|
289
|
+
window.localStorage.setItem(storageKey, JSON.stringify(state));
|
|
290
|
+
}
|
|
291
|
+
function emptyState(activeSectionId) {
|
|
292
|
+
return {
|
|
293
|
+
activeSectionId,
|
|
294
|
+
activeTabIdBySection: {},
|
|
295
|
+
tabs: []
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
function resolveSectionId(app, initialSectionId) {
|
|
299
|
+
if (initialSectionId &&
|
|
300
|
+
app.sections.some((section) => section.id === initialSectionId)) {
|
|
301
|
+
return initialSectionId;
|
|
302
|
+
}
|
|
303
|
+
return app.sections[0].id;
|
|
304
|
+
}
|
|
305
|
+
function isValidTab(value, validSections) {
|
|
306
|
+
if (typeof value !== "object" || value == null)
|
|
307
|
+
return false;
|
|
308
|
+
const tab = value;
|
|
309
|
+
return (typeof tab.id === "string" &&
|
|
310
|
+
typeof tab.sectionId === "string" &&
|
|
311
|
+
validSections.has(tab.sectionId) &&
|
|
312
|
+
typeof tab.title === "string" &&
|
|
313
|
+
typeof tab.target === "object" &&
|
|
314
|
+
tab.target != null &&
|
|
315
|
+
typeof tab.target.kind === "string");
|
|
316
|
+
}
|
|
317
|
+
function sanitizeActiveTabs(value, validSections, tabIds) {
|
|
318
|
+
if (typeof value !== "object" || value == null)
|
|
319
|
+
return {};
|
|
320
|
+
const candidate = value;
|
|
321
|
+
const result = {};
|
|
322
|
+
for (const [sectionId, tabId] of Object.entries(candidate)) {
|
|
323
|
+
if (!validSections.has(sectionId))
|
|
324
|
+
continue;
|
|
325
|
+
if (typeof tabId === "string" && tabIds.has(tabId)) {
|
|
326
|
+
result[sectionId] = tabId;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return result;
|
|
330
|
+
}
|
|
331
|
+
function assertUnique(values, message) {
|
|
332
|
+
if (new Set(values).size !== values.length) {
|
|
333
|
+
throw new Error(message);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
export function createInsetStyle(value) {
|
|
337
|
+
return { "--elench-shell-inset": `${value}px` };
|
|
338
|
+
}
|
|
339
|
+
//# sourceMappingURL=shell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../src/shell.tsx"],"names":[],"mappings":"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"}
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
.elench-shell {
|
|
2
|
+
--elench-shell-topbar-height: 36px;
|
|
3
|
+
--elench-shell-status-height: 28px;
|
|
4
|
+
--elench-shell-rail-width: 46px;
|
|
5
|
+
--elench-shell-sidebar-width: 292px;
|
|
6
|
+
--elench-shell-inspector-width: 292px;
|
|
7
|
+
display: grid;
|
|
8
|
+
grid-template-areas:
|
|
9
|
+
"topbar topbar topbar topbar"
|
|
10
|
+
"rail sidebar main inspector"
|
|
11
|
+
"status status status status";
|
|
12
|
+
grid-template-columns:
|
|
13
|
+
var(--elench-shell-rail-width)
|
|
14
|
+
var(--elench-shell-sidebar-width)
|
|
15
|
+
minmax(0, 1fr)
|
|
16
|
+
var(--elench-shell-inspector-width);
|
|
17
|
+
grid-template-rows: var(--elench-shell-topbar-height) minmax(0, 1fr) var(
|
|
18
|
+
--elench-shell-status-height
|
|
19
|
+
);
|
|
20
|
+
width: 100vw;
|
|
21
|
+
height: 100vh;
|
|
22
|
+
min-height: 0;
|
|
23
|
+
overflow: hidden;
|
|
24
|
+
background: var(--bg-primary, #0a1120);
|
|
25
|
+
color: var(--fg, #e5edf7);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.elench-shell[data-left-sidebar="closed"] {
|
|
29
|
+
grid-template-areas:
|
|
30
|
+
"topbar topbar topbar"
|
|
31
|
+
"rail main inspector"
|
|
32
|
+
"status status status";
|
|
33
|
+
grid-template-columns:
|
|
34
|
+
var(--elench-shell-rail-width)
|
|
35
|
+
minmax(0, 1fr)
|
|
36
|
+
var(--elench-shell-inspector-width);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.elench-shell[data-right-inspector="closed"] {
|
|
40
|
+
grid-template-areas:
|
|
41
|
+
"topbar topbar topbar"
|
|
42
|
+
"rail sidebar main"
|
|
43
|
+
"status status status";
|
|
44
|
+
grid-template-columns:
|
|
45
|
+
var(--elench-shell-rail-width)
|
|
46
|
+
var(--elench-shell-sidebar-width)
|
|
47
|
+
minmax(0, 1fr);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.elench-shell[data-left-sidebar="closed"][data-right-inspector="closed"] {
|
|
51
|
+
grid-template-areas:
|
|
52
|
+
"topbar topbar"
|
|
53
|
+
"rail main"
|
|
54
|
+
"status status";
|
|
55
|
+
grid-template-columns: var(--elench-shell-rail-width) minmax(0, 1fr);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.elench-shell button {
|
|
59
|
+
font: inherit;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.elench-shell-topbar {
|
|
63
|
+
grid-area: topbar;
|
|
64
|
+
display: flex;
|
|
65
|
+
align-items: center;
|
|
66
|
+
justify-content: space-between;
|
|
67
|
+
border-bottom: 1px solid var(--border, #1e2d44);
|
|
68
|
+
background: var(--bg-secondary, #0f172a);
|
|
69
|
+
padding: 0 8px 0 12px;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.elench-shell-topbar-title {
|
|
73
|
+
min-width: 0;
|
|
74
|
+
overflow: hidden;
|
|
75
|
+
color: var(--fg-secondary, #a8b5c7);
|
|
76
|
+
font-size: 12px;
|
|
77
|
+
font-weight: 650;
|
|
78
|
+
text-overflow: ellipsis;
|
|
79
|
+
white-space: nowrap;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.elench-shell-topbar-actions {
|
|
83
|
+
display: flex;
|
|
84
|
+
align-items: center;
|
|
85
|
+
gap: 2px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.elench-shell-topbar-actions button,
|
|
89
|
+
.elench-shell-activity-button,
|
|
90
|
+
.elench-shell-main-tab-icon {
|
|
91
|
+
display: inline-flex;
|
|
92
|
+
width: 28px;
|
|
93
|
+
height: 28px;
|
|
94
|
+
align-items: center;
|
|
95
|
+
justify-content: center;
|
|
96
|
+
border: 0;
|
|
97
|
+
border-radius: 6px;
|
|
98
|
+
background: transparent;
|
|
99
|
+
color: var(--fg-tertiary, #73839b);
|
|
100
|
+
cursor: pointer;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.elench-shell-topbar-actions button:hover,
|
|
104
|
+
.elench-shell-activity-button:hover,
|
|
105
|
+
.elench-shell-main-tab-icon:hover {
|
|
106
|
+
background: var(--bg-hover, #1e3050);
|
|
107
|
+
color: var(--fg, #e5edf7);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.elench-shell-topbar svg,
|
|
111
|
+
.elench-shell-activity-button svg,
|
|
112
|
+
.elench-shell-main-tab-icon svg {
|
|
113
|
+
width: 16px;
|
|
114
|
+
height: 16px;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.elench-shell-activity-rail {
|
|
118
|
+
grid-area: rail;
|
|
119
|
+
display: flex;
|
|
120
|
+
min-height: 0;
|
|
121
|
+
flex-direction: column;
|
|
122
|
+
align-items: center;
|
|
123
|
+
gap: 4px;
|
|
124
|
+
border-right: 1px solid var(--border, #1e2d44);
|
|
125
|
+
background: var(--bg-secondary, #0f172a);
|
|
126
|
+
padding: 8px 5px;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.elench-shell-activity-button {
|
|
130
|
+
width: 34px;
|
|
131
|
+
height: 34px;
|
|
132
|
+
position: relative;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.elench-shell-activity-button[aria-pressed="true"] {
|
|
136
|
+
background: var(--bg-active, #1a2d4a);
|
|
137
|
+
color: var(--fg, #e5edf7);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.elench-shell-activity-button[aria-pressed="true"]::before {
|
|
141
|
+
position: absolute;
|
|
142
|
+
left: -5px;
|
|
143
|
+
width: 2px;
|
|
144
|
+
height: 18px;
|
|
145
|
+
border-radius: 999px;
|
|
146
|
+
background: var(--primary, #3b82f6);
|
|
147
|
+
content: "";
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.elench-shell-sidebar {
|
|
151
|
+
grid-area: sidebar;
|
|
152
|
+
min-width: 0;
|
|
153
|
+
min-height: 0;
|
|
154
|
+
overflow: hidden;
|
|
155
|
+
border-right: 1px solid var(--border, #1e2d44);
|
|
156
|
+
background: var(--bg-surface, #0f172a);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.elench-shell-sidebar-frame {
|
|
160
|
+
display: flex;
|
|
161
|
+
height: 100%;
|
|
162
|
+
min-height: 0;
|
|
163
|
+
flex-direction: column;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.elench-shell-sidebar-title {
|
|
167
|
+
flex: 0 0 auto;
|
|
168
|
+
border-bottom: 1px solid var(--border, #1e2d44);
|
|
169
|
+
color: var(--fg-secondary, #a8b5c7);
|
|
170
|
+
font-size: 11px;
|
|
171
|
+
font-weight: 700;
|
|
172
|
+
letter-spacing: 0.08em;
|
|
173
|
+
padding: 10px 12px;
|
|
174
|
+
text-transform: uppercase;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.elench-shell-sidebar-content {
|
|
178
|
+
min-height: 0;
|
|
179
|
+
flex: 1;
|
|
180
|
+
overflow: auto;
|
|
181
|
+
padding: 8px;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.elench-shell-sidebar-section {
|
|
185
|
+
margin: 0 0 12px;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.elench-shell-sidebar-section h2 {
|
|
189
|
+
color: var(--fg-tertiary, #73839b);
|
|
190
|
+
font-size: 11px;
|
|
191
|
+
font-weight: 650;
|
|
192
|
+
margin: 0 0 6px;
|
|
193
|
+
padding: 0 4px;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.elench-shell-sidebar-item {
|
|
197
|
+
display: flex;
|
|
198
|
+
width: 100%;
|
|
199
|
+
min-height: 42px;
|
|
200
|
+
align-items: center;
|
|
201
|
+
gap: 8px;
|
|
202
|
+
border: 1px solid transparent;
|
|
203
|
+
border-radius: 6px;
|
|
204
|
+
background: transparent;
|
|
205
|
+
color: var(--fg-secondary, #a8b5c7);
|
|
206
|
+
cursor: pointer;
|
|
207
|
+
padding: 7px 8px;
|
|
208
|
+
text-align: left;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.elench-shell-sidebar-item:hover {
|
|
212
|
+
background: var(--bg-hover, #1e3050);
|
|
213
|
+
color: var(--fg, #e5edf7);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.elench-shell-sidebar-item[aria-selected="true"] {
|
|
217
|
+
border-color: var(--border-strong, #2a3f5f);
|
|
218
|
+
background: var(--bg-active, #1a2d4a);
|
|
219
|
+
color: var(--fg, #e5edf7);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.elench-shell-sidebar-item-icon {
|
|
223
|
+
display: inline-flex;
|
|
224
|
+
flex: 0 0 auto;
|
|
225
|
+
color: var(--fg-tertiary, #73839b);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.elench-shell-sidebar-item-icon svg {
|
|
229
|
+
width: 16px;
|
|
230
|
+
height: 16px;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.elench-shell-sidebar-item-text {
|
|
234
|
+
display: grid;
|
|
235
|
+
min-width: 0;
|
|
236
|
+
gap: 2px;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.elench-shell-sidebar-item-title,
|
|
240
|
+
.elench-shell-main-tab-select span {
|
|
241
|
+
overflow: hidden;
|
|
242
|
+
text-overflow: ellipsis;
|
|
243
|
+
white-space: nowrap;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.elench-shell-sidebar-item-title {
|
|
247
|
+
font-size: 12.5px;
|
|
248
|
+
font-weight: 600;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.elench-shell-sidebar-item-description {
|
|
252
|
+
overflow: hidden;
|
|
253
|
+
color: var(--fg-tertiary, #73839b);
|
|
254
|
+
font-size: 11.5px;
|
|
255
|
+
text-overflow: ellipsis;
|
|
256
|
+
white-space: nowrap;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.elench-shell-main {
|
|
260
|
+
grid-area: main;
|
|
261
|
+
display: grid;
|
|
262
|
+
min-width: 0;
|
|
263
|
+
min-height: 0;
|
|
264
|
+
grid-template-rows: 34px minmax(0, 1fr);
|
|
265
|
+
background: var(--bg-primary, #0a1120);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.elench-shell-tab-rail {
|
|
269
|
+
display: flex;
|
|
270
|
+
min-width: 0;
|
|
271
|
+
align-items: end;
|
|
272
|
+
overflow-x: auto;
|
|
273
|
+
border-bottom: 1px solid var(--border, #1e2d44);
|
|
274
|
+
background: var(--bg-secondary, #0f172a);
|
|
275
|
+
padding: 3px 6px 0;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.elench-shell-main-tab {
|
|
279
|
+
display: flex;
|
|
280
|
+
min-width: 132px;
|
|
281
|
+
max-width: 220px;
|
|
282
|
+
height: 31px;
|
|
283
|
+
align-items: center;
|
|
284
|
+
border: 1px solid transparent;
|
|
285
|
+
border-bottom: 0;
|
|
286
|
+
border-radius: 6px 6px 0 0;
|
|
287
|
+
color: var(--fg-tertiary, #73839b);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.elench-shell-main-tab[aria-selected="true"] {
|
|
291
|
+
border-color: var(--border, #1e2d44);
|
|
292
|
+
background: var(--bg-surface, #0f172a);
|
|
293
|
+
color: var(--fg, #e5edf7);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.elench-shell-main-tab[data-preview="true"] .elench-shell-main-tab-select {
|
|
297
|
+
font-style: italic;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.elench-shell-main-tab-select {
|
|
301
|
+
min-width: 0;
|
|
302
|
+
flex: 1;
|
|
303
|
+
border: 0;
|
|
304
|
+
background: transparent;
|
|
305
|
+
color: inherit;
|
|
306
|
+
cursor: pointer;
|
|
307
|
+
padding: 0 8px;
|
|
308
|
+
text-align: left;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.elench-shell-workspace {
|
|
312
|
+
min-width: 0;
|
|
313
|
+
min-height: 0;
|
|
314
|
+
overflow: auto;
|
|
315
|
+
background: var(--bg-surface, #0f172a);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.elench-shell-blank-main {
|
|
319
|
+
height: 100%;
|
|
320
|
+
min-height: 0;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.elench-shell-inspector {
|
|
324
|
+
grid-area: inspector;
|
|
325
|
+
min-width: 0;
|
|
326
|
+
min-height: 0;
|
|
327
|
+
overflow: auto;
|
|
328
|
+
border-left: 1px solid var(--border, #1e2d44);
|
|
329
|
+
background: var(--bg-surface, #0f172a);
|
|
330
|
+
padding: 10px;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.elench-shell-statusbar {
|
|
334
|
+
grid-area: status;
|
|
335
|
+
display: flex;
|
|
336
|
+
min-width: 0;
|
|
337
|
+
align-items: center;
|
|
338
|
+
gap: 12px;
|
|
339
|
+
border-top: 1px solid var(--border, #1e2d44);
|
|
340
|
+
background: var(--bg-secondary, #0f172a);
|
|
341
|
+
color: var(--fg-tertiary, #73839b);
|
|
342
|
+
font-size: 11.5px;
|
|
343
|
+
padding: 0 10px;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.elench-shell-statusbar-slot {
|
|
347
|
+
min-width: 0;
|
|
348
|
+
flex: 1;
|
|
349
|
+
overflow: hidden;
|
|
350
|
+
text-overflow: ellipsis;
|
|
351
|
+
white-space: nowrap;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.elench-shell-page {
|
|
355
|
+
max-width: 1160px;
|
|
356
|
+
margin: 0 auto;
|
|
357
|
+
padding: 24px;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.elench-shell-page-header {
|
|
361
|
+
display: flex;
|
|
362
|
+
align-items: flex-start;
|
|
363
|
+
justify-content: space-between;
|
|
364
|
+
gap: 16px;
|
|
365
|
+
margin-bottom: 20px;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.elench-shell-page-eyebrow {
|
|
369
|
+
color: var(--fg-tertiary, #73839b);
|
|
370
|
+
font-size: 11px;
|
|
371
|
+
font-weight: 700;
|
|
372
|
+
letter-spacing: 0.08em;
|
|
373
|
+
margin-bottom: 4px;
|
|
374
|
+
text-transform: uppercase;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
.elench-shell-page h1 {
|
|
378
|
+
color: var(--fg, #e5edf7);
|
|
379
|
+
font-size: 22px;
|
|
380
|
+
line-height: 1.2;
|
|
381
|
+
margin: 0;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
.elench-shell-page p {
|
|
385
|
+
color: var(--fg-tertiary, #73839b);
|
|
386
|
+
font-size: 13px;
|
|
387
|
+
line-height: 1.6;
|
|
388
|
+
margin: 6px 0 0;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.elench-shell-page-actions {
|
|
392
|
+
flex: 0 0 auto;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.elench-shell-metric,
|
|
396
|
+
.elench-shell-field {
|
|
397
|
+
border: 1px solid var(--border, #1e2d44);
|
|
398
|
+
border-radius: 8px;
|
|
399
|
+
background: var(--bg-card, #162236);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.elench-shell-metric {
|
|
403
|
+
padding: 12px;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.elench-shell-metric div,
|
|
407
|
+
.elench-shell-field span {
|
|
408
|
+
color: var(--fg-tertiary, #73839b);
|
|
409
|
+
font-size: 11.5px;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.elench-shell-metric strong {
|
|
413
|
+
display: block;
|
|
414
|
+
color: var(--fg, #e5edf7);
|
|
415
|
+
font-size: 22px;
|
|
416
|
+
margin-top: 6px;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
.elench-shell-field {
|
|
420
|
+
display: grid;
|
|
421
|
+
gap: 4px;
|
|
422
|
+
padding: 9px;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
.elench-shell-field strong {
|
|
426
|
+
min-width: 0;
|
|
427
|
+
overflow: hidden;
|
|
428
|
+
color: var(--fg, #e5edf7);
|
|
429
|
+
font-size: 12px;
|
|
430
|
+
font-weight: 550;
|
|
431
|
+
text-overflow: ellipsis;
|
|
432
|
+
white-space: nowrap;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.elench-shell-empty-state {
|
|
436
|
+
display: grid;
|
|
437
|
+
min-height: 120px;
|
|
438
|
+
align-content: center;
|
|
439
|
+
justify-items: center;
|
|
440
|
+
border: 1px dashed var(--border, #1e2d44);
|
|
441
|
+
border-radius: 8px;
|
|
442
|
+
color: var(--fg-tertiary, #73839b);
|
|
443
|
+
padding: 18px;
|
|
444
|
+
text-align: center;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
.elench-shell-empty-state strong {
|
|
448
|
+
color: var(--fg-secondary, #a8b5c7);
|
|
449
|
+
font-size: 13px;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
.elench-shell-empty-state p {
|
|
453
|
+
max-width: 34ch;
|
|
454
|
+
font-size: 12px;
|
|
455
|
+
line-height: 1.5;
|
|
456
|
+
margin: 6px 0 0;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
@media (max-width: 900px) {
|
|
460
|
+
.elench-shell,
|
|
461
|
+
.elench-shell[data-left-sidebar="closed"],
|
|
462
|
+
.elench-shell[data-right-inspector="closed"],
|
|
463
|
+
.elench-shell[data-left-sidebar="closed"][data-right-inspector="closed"] {
|
|
464
|
+
grid-template-areas:
|
|
465
|
+
"topbar topbar"
|
|
466
|
+
"rail main"
|
|
467
|
+
"status status";
|
|
468
|
+
grid-template-columns: var(--elench-shell-rail-width) minmax(0, 1fr);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.elench-shell-sidebar,
|
|
472
|
+
.elench-shell-inspector {
|
|
473
|
+
display: none;
|
|
474
|
+
}
|
|
475
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@elench/shell",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "A strict desktop application shell for Elench products.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"private": false,
|
|
7
|
+
"sideEffects": [
|
|
8
|
+
"./dist/styles.css"
|
|
9
|
+
],
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./styles.css": "./dist/styles.css"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "rm -rf dist && tsc -p tsconfig.json && cp src/styles.css dist/styles.css",
|
|
23
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
24
|
+
"test": "vitest run --config vitest.config.ts"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"react": "^19.0.0",
|
|
28
|
+
"react-dom": "^19.0.0"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"lucide-react": "^1.8.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
35
|
+
"@testing-library/react": "^16.3.2",
|
|
36
|
+
"@testing-library/user-event": "^14.6.1",
|
|
37
|
+
"@vitejs/plugin-react": "^6.0.1",
|
|
38
|
+
"jsdom": "^29.0.2",
|
|
39
|
+
"typescript": "^5",
|
|
40
|
+
"vitest": "^4.1.4"
|
|
41
|
+
}
|
|
42
|
+
}
|