@peers-app/peers-ui 0.28.5 → 0.28.7

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.
@@ -1 +1,2 @@
1
+ /** Searchable overlay for launching apps, running commands, and starting threads. */
1
2
  export declare function CommandPaletteOverlay(): import("react/jsx-runtime").JSX.Element | null;
@@ -12,6 +12,7 @@ const system_apps_1 = require("../system-apps");
12
12
  const tabs_state_1 = require("../tabs-layout/tabs-state");
13
13
  const routes_loader_1 = require("../ui-router/routes-loader");
14
14
  const command_palette_1 = require("./command-palette");
15
+ /** Searchable overlay for launching apps, running commands, and starting threads. */
15
16
  function CommandPaletteOverlay() {
16
17
  const [isOpen] = (0, hooks_1.useObservable)(command_palette_1.isCommandPaletteOpen);
17
18
  const [_persistedQuery] = (0, hooks_1.useObservable)(command_palette_1.commandSearchQuery);
@@ -198,15 +199,15 @@ function CommandPaletteOverlay() {
198
199
  if (e.target === e.currentTarget) {
199
200
  (0, command_palette_1.closeCommandPalette)();
200
201
  }
201
- }, children: (0, jsx_runtime_1.jsxs)("div", { className: `${isDark ? "bg-dark text-light" : "bg-white text-dark"}`, style: {
202
+ }, children: (0, jsx_runtime_1.jsxs)("div", { className: `${isDark ? "bg-dark text-light" : "peers-surface text-body"}`, style: {
202
203
  width: "90%",
203
204
  maxWidth: "600px",
204
205
  borderRadius: "12px",
205
206
  boxShadow: isDark ? "0 20px 40px rgba(0, 0, 0, 0.5)" : "0 20px 40px rgba(0, 0, 0, 0.1)",
206
- border: isDark ? "1px solid #495057" : "1px solid #dee2e6",
207
+ border: isDark ? "1px solid #495057" : "1px solid var(--peers-surface-border)",
207
208
  overflow: "hidden",
208
209
  }, children: [(0, jsx_runtime_1.jsx)("div", { className: "p-3 border-bottom", style: {
209
- borderBottomColor: isDark ? "#495057" : "#dee2e6",
210
+ borderBottomColor: isDark ? "#495057" : "var(--peers-surface-border)",
210
211
  }, children: (0, jsx_runtime_1.jsxs)("div", { className: "position-relative", children: [(0, jsx_runtime_1.jsx)("i", { className: "bi-search position-absolute", style: {
211
212
  left: "12px",
212
213
  top: "50%",
@@ -230,7 +231,7 @@ function CommandPaletteOverlay() {
230
231
  border: "none",
231
232
  outline: "none",
232
233
  boxShadow: "none",
233
- backgroundColor: isDark ? "#343a40" : "#f8f9fa",
234
+ backgroundColor: isDark ? "#343a40" : "var(--peers-surface-bg)",
234
235
  } })] }) }), (0, jsx_runtime_1.jsx)("div", { style: {
235
236
  maxHeight: "400px",
236
237
  overflowY: "auto",
@@ -275,11 +276,13 @@ function CommandPaletteOverlay() {
275
276
  fontSize: "16px",
276
277
  color: isSelected ? (isDark ? "#ffffff" : "#0d6efd") : "#6c757d",
277
278
  minWidth: "16px",
278
- } })), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "fw-medium", children: command.label }), command.description && ((0, jsx_runtime_1.jsx)("div", { className: "small text-muted", style: { fontSize: "12px" }, children: command.description }))] })] }), command.shortcut && ((0, jsx_runtime_1.jsx)("div", { className: `small px-2 py-1 rounded ${isDark ? "bg-secondary bg-opacity-50" : "bg-light"}`, style: {
279
+ } })), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "fw-medium", children: command.label }), command.description && ((0, jsx_runtime_1.jsx)("div", { className: "small text-muted", style: { fontSize: "12px" }, children: command.description }))] })] }), command.shortcut && ((0, jsx_runtime_1.jsx)("div", { className: `small px-2 py-1 rounded ${isDark ? "bg-secondary bg-opacity-50" : "bg-body"}`, style: {
279
280
  fontSize: "11px",
280
281
  fontFamily: "monospace",
281
282
  color: isDark ? "#adb5bd" : "#6c757d",
282
- border: isDark ? "1px solid #495057" : "1px solid #dee2e6",
283
+ border: isDark
284
+ ? "1px solid #495057"
285
+ : "1px solid var(--peers-surface-border)",
283
286
  }, children: command.shortcut }))] }, command.id));
284
287
  })] }, category))), searchQuery.trim() && ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "px-3 py-1 small text-muted fw-bold text-uppercase", style: { fontSize: "11px", letterSpacing: "0.5px" }, children: "Actions" }), (0, jsx_runtime_1.jsx)("div", { className: `px-3 py-2 d-flex align-items-center ${(allItems.length === 0 || selectedIndex >= allItems.length) &&
285
288
  searchQuery.trim()
@@ -290,7 +293,7 @@ function CommandPaletteOverlay() {
290
293
  cursor: "pointer",
291
294
  transition: "background-color 0.1s ease",
292
295
  borderTop: allItems.length > 0
293
- ? `1px solid ${isDark ? "#495057" : "#dee2e6"}`
296
+ ? `1px solid ${isDark ? "#495057" : "var(--peers-surface-border)"}`
294
297
  : "none",
295
298
  marginTop: allItems.length > 0 ? "8px" : "0",
296
299
  paddingTop: allItems.length > 0 ? "12px" : "8px",
@@ -310,7 +313,7 @@ function CommandPaletteOverlay() {
310
313
  : "#6c757d",
311
314
  minWidth: "16px",
312
315
  } }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "fw-medium", children: ["Start new thread:", " ", (0, jsx_runtime_1.jsxs)("span", { className: "text-muted", children: [searchQuery.trim().slice(0, 50), searchQuery.trim().length > 50 ? "..." : ""] })] }), (0, jsx_runtime_1.jsx)("div", { className: "small text-muted", style: { fontSize: "12px" }, children: "Press Enter to create" })] })] }) })] }))] })) }), (0, jsx_runtime_1.jsxs)("div", { className: `px-3 py-2 small text-muted border-top d-flex align-items-center justify-content-between`, style: {
313
- borderTopColor: isDark ? "#495057" : "#dee2e6",
316
+ borderTopColor: isDark ? "#495057" : "var(--peers-surface-border)",
314
317
  fontSize: "11px",
315
318
  }, children: [(0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center gap-3", children: [(0, jsx_runtime_1.jsxs)("span", { children: [(0, jsx_runtime_1.jsx)("kbd", { className: "small", children: "\u21B5" }), " to select"] }), (0, jsx_runtime_1.jsxs)("span", { children: [(0, jsx_runtime_1.jsx)("kbd", { className: "small", children: "\u2191\u2193" }), " to navigate"] }), (0, jsx_runtime_1.jsxs)("span", { children: [(0, jsx_runtime_1.jsx)("kbd", { className: "small", children: "esc" }), " to close"] })] }), (0, jsx_runtime_1.jsxs)("div", { children: [allItems.length, " result", allItems.length !== 1 ? "s" : "", searchQuery.trim() && allItems.length === 0 && " • Start thread"] })] })] }) }));
316
319
  }
@@ -94,14 +94,16 @@ function GroupSwitcher({ colorMode, isMobile = false }) {
94
94
  borderRadius: "6px",
95
95
  border: "none",
96
96
  background: "transparent",
97
- color: isDark ? "#adb5bd" : "#6c757d",
97
+ color: isDark ? "#adb5bd" : "var(--peers-tab-strip-color)",
98
98
  minWidth: isMobile ? "36px" : undefined,
99
99
  }, onMouseEnter: (e) => {
100
- e.currentTarget.style.backgroundColor = isDark ? "#495057" : "#f8f9fa";
101
- e.currentTarget.style.color = isDark ? "#ffffff" : "#0d6efd";
100
+ e.currentTarget.style.backgroundColor = isDark
101
+ ? "#495057"
102
+ : "var(--peers-tab-hover-bg)";
103
+ e.currentTarget.style.color = isDark ? "#ffffff" : "var(--bs-link-color)";
102
104
  }, onMouseLeave: (e) => {
103
105
  e.currentTarget.style.backgroundColor = "transparent";
104
- e.currentTarget.style.color = isDark ? "#adb5bd" : "#6c757d";
106
+ e.currentTarget.style.color = isDark ? "#adb5bd" : "var(--peers-tab-strip-color)";
105
107
  }, children: [(0, jsx_runtime_1.jsx)("i", { className: `${getGroupIcon(currentGroup)} ${isMobile ? "" : "me-1"}`, style: { fontSize: "14px" } }), !isMobile && ((0, jsx_runtime_1.jsx)("span", { className: "text-truncate", style: { maxWidth: "80px" }, children: getGroupName(currentGroup) })), (0, jsx_runtime_1.jsx)("i", { className: "bi-chevron-down ms-1", style: { fontSize: "10px" } })] }), showDropdown && ((0, jsx_runtime_1.jsxs)("div", { className: `dropdown-menu show position-absolute ${isDark ? "dropdown-menu-dark" : ""}`, style: {
106
108
  left: 0,
107
109
  top: "100%",
@@ -222,15 +224,15 @@ function CreateGroupModal({ colorMode, userContext, onClose, onGroupCreated, })
222
224
  if (e.target === e.currentTarget) {
223
225
  onClose();
224
226
  }
225
- }, children: (0, jsx_runtime_1.jsxs)("div", { className: `${isDark ? "bg-dark text-light" : "bg-white text-dark"}`, style: {
227
+ }, children: (0, jsx_runtime_1.jsxs)("div", { className: `${isDark ? "bg-dark text-light" : "peers-surface text-body"}`, style: {
226
228
  width: "90%",
227
229
  maxWidth: "500px",
228
230
  borderRadius: "12px",
229
231
  boxShadow: isDark ? "0 20px 40px rgba(0, 0, 0, 0.5)" : "0 20px 40px rgba(0, 0, 0, 0.1)",
230
- border: isDark ? "1px solid #495057" : "1px solid #dee2e6",
232
+ border: isDark ? "1px solid #495057" : "1px solid var(--peers-surface-border)",
231
233
  overflow: "hidden",
232
234
  }, children: [(0, jsx_runtime_1.jsxs)("div", { className: "p-3 border-bottom d-flex align-items-center justify-content-between", style: {
233
- borderBottomColor: isDark ? "#495057" : "#dee2e6",
235
+ borderBottomColor: isDark ? "#495057" : "var(--peers-surface-border)",
234
236
  }, children: [(0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center", children: [(0, jsx_runtime_1.jsx)("i", { className: "bi-people-fill me-2", style: { fontSize: "20px" } }), (0, jsx_runtime_1.jsx)("h6", { className: "mb-0", children: "Create New Group" })] }), (0, jsx_runtime_1.jsx)("button", { className: "btn btn-sm p-0", style: {
235
237
  border: "none",
236
238
  background: "none",
@@ -246,18 +248,18 @@ function CreateGroupModal({ colorMode, userContext, onClose, onGroupCreated, })
246
248
  setError(null);
247
249
  }, onKeyDown: handleKeyDown, disabled: isCreating, maxLength: 100, style: {
248
250
  fontSize: "14px",
249
- backgroundColor: isDark ? "#343a40" : "#ffffff",
251
+ backgroundColor: isDark ? "#343a40" : "var(--peers-surface-bg)",
250
252
  } }), (0, jsx_runtime_1.jsxs)("small", { className: "text-muted", style: { fontSize: "11px" }, children: [groupName.length, "/100 characters"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "mb-3", children: [(0, jsx_runtime_1.jsx)("label", { className: "form-label small mb-1", children: "Icon" }), (0, jsx_runtime_1.jsxs)("div", { className: "input-group", children: [(0, jsx_runtime_1.jsx)("span", { className: `input-group-text ${isDark ? "bg-dark text-light border-secondary" : ""}`, style: { backgroundColor: isDark ? "#343a40" : undefined }, children: (0, jsx_runtime_1.jsx)("i", { className: iconClassName || "bi-people-fill" }) }), (0, jsx_runtime_1.jsx)("input", { type: "text", className: `form-control ${isDark ? "bg-dark text-light border-secondary" : ""}`, placeholder: "bi-people-fill", value: iconClassName, onChange: (e) => setIconClassName(e.target.value), onKeyDown: handleKeyDown, disabled: isCreating, style: {
251
253
  fontSize: "14px",
252
- backgroundColor: isDark ? "#343a40" : "#ffffff",
254
+ backgroundColor: isDark ? "#343a40" : "var(--peers-surface-bg)",
253
255
  } })] }), (0, jsx_runtime_1.jsx)("small", { className: "text-muted", style: { fontSize: "11px" }, children: "Bootstrap icon class name (e.g., bi-star-fill, bi-house-fill)" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "mb-3", children: [(0, jsx_runtime_1.jsx)("label", { className: "form-label small mb-1", children: "Description (optional)" }), (0, jsx_runtime_1.jsx)("textarea", { className: `form-control ${isDark ? "bg-dark text-light border-secondary" : ""}`, placeholder: "Enter group description", value: description, onChange: (e) => setDescription(e.target.value), disabled: isCreating, rows: 3, maxLength: 500, style: {
254
256
  fontSize: "14px",
255
- backgroundColor: isDark ? "#343a40" : "#ffffff",
257
+ backgroundColor: isDark ? "#343a40" : "var(--peers-surface-bg)",
256
258
  resize: "none",
257
259
  } }), (0, jsx_runtime_1.jsxs)("small", { className: "text-muted", style: { fontSize: "11px" }, children: [description.length, "/500 characters"] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "p-3 border-top d-flex justify-content-end gap-2", style: {
258
- borderTopColor: isDark ? "#495057" : "#dee2e6",
260
+ borderTopColor: isDark ? "#495057" : "var(--peers-surface-border)",
259
261
  }, children: [(0, jsx_runtime_1.jsx)("button", { className: `btn btn-sm ${isDark ? "btn-outline-light" : "btn-outline-secondary"}`, onClick: onClose, disabled: isCreating, style: { minWidth: "80px" }, children: "Cancel" }), (0, jsx_runtime_1.jsx)("button", { className: "btn btn-sm btn-primary", onClick: handleCreate, disabled: isCreating || !groupName.trim(), style: { minWidth: "80px" }, children: isCreating ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: "spinner-border spinner-border-sm me-1", role: "status", "aria-hidden": "true" }), "Creating..."] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("i", { className: "bi-plus-circle me-1" }), "Create"] })) })] }), (0, jsx_runtime_1.jsxs)("div", { className: `px-3 py-2 small text-muted border-top`, style: {
260
- borderTopColor: isDark ? "#495057" : "#dee2e6",
262
+ borderTopColor: isDark ? "#495057" : "var(--peers-surface-border)",
261
263
  fontSize: "11px",
262
264
  }, children: [(0, jsx_runtime_1.jsx)("kbd", { className: "small", children: "\u21B5" }), " to create \u2022 ", (0, jsx_runtime_1.jsx)("kbd", { className: "small", children: "esc" }), " to cancel"] })] }) }));
263
265
  }
@@ -7,5 +7,6 @@ interface IProps {
7
7
  positions?: ("right" | "bottom" | "left" | "top")[];
8
8
  genericContent?: React.ReactNode;
9
9
  }
10
+ /** Click-triggered popover containing Markdown or custom content. */
10
11
  export declare const Tooltip: (props: IProps) => import("react/jsx-runtime").JSX.Element;
11
12
  export {};
@@ -5,11 +5,12 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_tiny_popover_1 = require("react-tiny-popover");
6
6
  const hooks_1 = require("../hooks");
7
7
  const markdown_with_mentions_1 = require("./markdown-with-mentions");
8
+ /** Click-triggered popover containing Markdown or custom content. */
8
9
  const Tooltip = (props) => {
9
10
  const { handle } = props;
10
11
  let [markdownContent] = (0, hooks_1.useObservable)(props.markdownContent);
11
12
  markdownContent = markdownContent ?? "";
12
13
  const showPopover = (0, hooks_1.useObservableState)(false);
13
- return ((0, jsx_runtime_1.jsx)(react_tiny_popover_1.Popover, { isOpen: showPopover(), onClickOutside: () => showPopover(false), positions: props.positions ?? ["right", "bottom", "left", "top"], content: () => ((0, jsx_runtime_1.jsx)("div", { className: "card p-2 bg-light-subtle", style: { maxWidth: 500, maxHeight: 400, overflowY: "auto", zIndex: 1000001 }, children: props.genericContent || (0, jsx_runtime_1.jsx)(markdown_with_mentions_1.MarkdownWithMentions, { content: markdownContent }) })), children: (0, jsx_runtime_1.jsx)("span", { className: props.handleClassName ?? "p-2", onClick: () => showPopover(!showPopover()), children: handle ?? (0, jsx_runtime_1.jsx)("i", { className: "bi bi-info-circle", style: { cursor: "pointer" } }) }) }));
14
+ return ((0, jsx_runtime_1.jsx)(react_tiny_popover_1.Popover, { isOpen: showPopover(), onClickOutside: () => showPopover(false), positions: props.positions ?? ["right", "bottom", "left", "top"], content: () => ((0, jsx_runtime_1.jsx)("div", { className: "card p-2 bg-light-subtle peers-surface", style: { maxWidth: 500, maxHeight: 400, overflowY: "auto", zIndex: 1000001 }, children: props.genericContent || (0, jsx_runtime_1.jsx)(markdown_with_mentions_1.MarkdownWithMentions, { content: markdownContent }) })), children: (0, jsx_runtime_1.jsx)("span", { className: props.handleClassName ?? "p-2", onClick: () => showPopover(!showPopover()), children: handle ?? (0, jsx_runtime_1.jsx)("i", { className: "bi bi-info-circle", style: { cursor: "pointer" } }) }) }));
14
15
  };
15
16
  exports.Tooltip = Tooltip;
@@ -12,13 +12,13 @@ const operator_console_state_1 = require("./operator-console-state");
12
12
  */
13
13
  function getConsoleTheme(isDark) {
14
14
  return {
15
- bg: isDark ? "#1e1e1e" : "#ffffff",
16
- headerBg: isDark ? "#252526" : "#f3f3f3",
17
- border: isDark ? "#3c3c3c" : "#dee2e6",
18
- text: isDark ? "#cccccc" : "#1e1e1e",
19
- muted: isDark ? "#8c8c8c" : "#6c757d",
20
- hover: isDark ? "#2a2d2e" : "#e8e8e8",
21
- accent: "#0d6efd",
15
+ bg: isDark ? "#1e1e1e" : "var(--peers-surface-bg)",
16
+ headerBg: isDark ? "#252526" : "var(--bs-body-bg)",
17
+ border: isDark ? "#3c3c3c" : "var(--peers-surface-border)",
18
+ text: isDark ? "#cccccc" : "var(--bs-body-color)",
19
+ muted: isDark ? "#8c8c8c" : "var(--bs-secondary-color)",
20
+ hover: isDark ? "#2a2d2e" : "var(--peers-tab-hover-bg)",
21
+ accent: isDark ? "#0d6efd" : "var(--bs-link-color)",
22
22
  };
23
23
  }
24
24
  /**
@@ -38,11 +38,17 @@ function FullScreenLayout() {
38
38
  const isLauncher = activeTab.packageId === "launcher" || activeTab.tabId === "launcher";
39
39
  const isLight = mode === "light";
40
40
  const title = isLauncher ? "Apps" : activeTab.title;
41
- return ((0, jsx_runtime_1.jsxs)("div", { className: "d-flex flex-column", style: { height: "calc(100vh - 25px)", overflow: "hidden" }, children: [(0, jsx_runtime_1.jsxs)("div", { className: `border-bottom d-flex align-items-center px-1 ${isLight ? "bg-light" : "bg-dark"}`, style: { height: "36px", borderBottomColor: isLight ? "#dee2e6" : "#495057" }, children: [(0, jsx_runtime_1.jsx)(group_switcher_1.GroupSwitcher, { colorMode: mode, isMobile: isMobile }), (0, jsx_runtime_1.jsx)(HeaderButton, { isLight: isLight, active: isLauncher, icon: "bi-grid-3x3-gap", label: "Apps", onClick: () => (0, tabs_state_1.activeTabId)("launcher") }), (0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center flex-grow-1 overflow-hidden px-2", children: [!isLauncher && activeTab.iconClassName && ((0, jsx_runtime_1.jsx)("i", { className: `${activeTab.iconClassName} me-2` })), (0, jsx_runtime_1.jsx)("span", { className: "text-truncate fw-medium", style: { fontSize: "13px" }, children: title })] }), (0, jsx_runtime_1.jsx)(HeaderButton, { isLight: isLight, icon: "bi-search", label: `Search and navigate (${paletteHint})`, onClick: command_palette_1.openCommandPalette, children: (0, jsx_runtime_1.jsx)("span", { className: "d-none d-md-inline ms-1", style: { fontSize: "11px" }, children: paletteHint }) })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex-grow-1 overflow-hidden", children: (0, jsx_runtime_1.jsx)(tabs_layout_1.TabErrorBoundary, { tabTitle: activeTab.title, tabId: activeTab.tabId, children: (0, jsx_runtime_1.jsx)(tabs_layout_1.TabContent, { tab: activeTab, isMobile: isMobile, isActive: true }) }, activeTab.tabId) })] }));
41
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "d-flex flex-column", style: { height: "calc(100vh - 25px)", overflow: "hidden" }, children: [(0, jsx_runtime_1.jsxs)("div", { className: `border-bottom peers-tab-strip d-flex align-items-center px-1 ${isLight ? "" : "bg-dark"}`, style: { height: "36px", borderBottomColor: isLight ? "var(--peers-tab-edge)" : "#495057" }, children: [(0, jsx_runtime_1.jsx)(group_switcher_1.GroupSwitcher, { colorMode: mode, isMobile: isMobile }), (0, jsx_runtime_1.jsx)(HeaderButton, { isLight: isLight, active: isLauncher, icon: "bi-grid-3x3-gap", label: "Apps", onClick: () => (0, tabs_state_1.activeTabId)("launcher") }), (0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center flex-grow-1 overflow-hidden px-2", children: [!isLauncher && activeTab.iconClassName && ((0, jsx_runtime_1.jsx)("i", { className: `${activeTab.iconClassName} me-2` })), (0, jsx_runtime_1.jsx)("span", { className: "text-truncate fw-medium", style: { fontSize: "13px" }, children: title })] }), (0, jsx_runtime_1.jsx)(HeaderButton, { isLight: isLight, icon: "bi-search", label: `Search and navigate (${paletteHint})`, onClick: command_palette_1.openCommandPalette, children: (0, jsx_runtime_1.jsx)("span", { className: "d-none d-md-inline ms-1", style: { fontSize: "11px" }, children: paletteHint }) })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex-grow-1 overflow-hidden", children: (0, jsx_runtime_1.jsx)(tabs_layout_1.TabErrorBoundary, { tabTitle: activeTab.title, tabId: activeTab.tabId, children: (0, jsx_runtime_1.jsx)(tabs_layout_1.TabContent, { tab: activeTab, isMobile: isMobile, isActive: true }) }, activeTab.tabId) })] }));
42
42
  }
43
43
  /** A small, transparent header button matching the tabs layout's toolbar styling. */
44
44
  function HeaderButton({ isLight, icon, label, onClick, active, children }) {
45
- const baseColor = active ? (isLight ? "#0d6efd" : "#ffffff") : isLight ? "#6c757d" : "#adb5bd";
45
+ const baseColor = active
46
+ ? isLight
47
+ ? "var(--bs-link-color)"
48
+ : "#ffffff"
49
+ : isLight
50
+ ? "var(--peers-tab-icon-color)"
51
+ : "#adb5bd";
46
52
  return ((0, jsx_runtime_1.jsxs)("button", { type: "button", className: "btn btn-sm d-flex align-items-center", onClick: onClick, title: label, "aria-label": label, style: {
47
53
  padding: "4px 8px",
48
54
  fontSize: "12px",
@@ -51,8 +57,8 @@ function HeaderButton({ isLight, icon, label, onClick, active, children }) {
51
57
  background: "transparent",
52
58
  color: baseColor,
53
59
  }, onMouseEnter: (e) => {
54
- e.currentTarget.style.backgroundColor = isLight ? "#f8f9fa" : "#495057";
55
- e.currentTarget.style.color = isLight ? "#0d6efd" : "#ffffff";
60
+ e.currentTarget.style.backgroundColor = isLight ? "var(--peers-tab-hover-bg)" : "#495057";
61
+ e.currentTarget.style.color = isLight ? "var(--bs-link-color)" : "#ffffff";
56
62
  }, onMouseLeave: (e) => {
57
63
  e.currentTarget.style.backgroundColor = "transparent";
58
64
  e.currentTarget.style.color = baseColor;
@@ -1 +1,2 @@
1
+ /** Filterable console log screen with desktop columns and mobile log cards. */
1
2
  export declare const ConsoleLogsList: () => import("react/jsx-runtime").JSX.Element;
@@ -59,6 +59,7 @@ const DEFAULT_COLUMNS = [
59
59
  { key: "source", label: "Source", width: 120 },
60
60
  { key: "message", label: "Message", width: 600 },
61
61
  ];
62
+ /** Filterable console log screen with desktop columns and mobile log cards. */
62
63
  const ConsoleLogsList = () => {
63
64
  const logs = (0, hooks_1.useObservableState)([]);
64
65
  const [allLogsLoaded, setAllLogsLoaded] = (0, react_1.useState)(false);
@@ -238,7 +239,7 @@ const ConsoleLogsList = () => {
238
239
  flex: 1,
239
240
  display: "flex",
240
241
  flexDirection: "column",
241
- backgroundColor: _colorMode === "dark" ? "#1a1a1a" : "#f8f9fa",
242
+ backgroundColor: _colorMode === "dark" ? "#1a1a1a" : "var(--peers-surface-bg)",
242
243
  borderRadius: "0.25rem",
243
244
  marginBottom: "50px",
244
245
  overflow: "hidden",
@@ -257,8 +258,8 @@ const ConsoleLogsList = () => {
257
258
  left: 0,
258
259
  right: 0,
259
260
  padding: "0.5rem 1rem",
260
- backgroundColor: _colorMode === "dark" ? "#2a2a2a" : "#ffffff",
261
- borderTop: "1px solid #dee2e6",
261
+ backgroundColor: _colorMode === "dark" ? "#2a2a2a" : "var(--peers-surface-bg)",
262
+ borderTop: "1px solid var(--peers-surface-border, #dee2e6)",
262
263
  zIndex: 1000,
263
264
  display: "flex",
264
265
  justifyContent: "space-between",
@@ -3,5 +3,6 @@ interface MobileLogCardProps {
3
3
  log: IConsoleLog;
4
4
  colorMode: string;
5
5
  }
6
+ /** Compact log entry with expandable details for narrow screens. */
6
7
  export declare const MobileLogCard: ({ log, colorMode }: MobileLogCardProps) => import("react/jsx-runtime").JSX.Element;
7
8
  export {};
@@ -51,6 +51,7 @@ const getLevelIcon = (level) => {
51
51
  return "bi-chat-square-text";
52
52
  }
53
53
  };
54
+ /** Compact log entry with expandable details for narrow screens. */
54
55
  const MobileLogCard = ({ log, colorMode }) => {
55
56
  const isDark = colorMode === "dark";
56
57
  // Parse context if it's a string
@@ -63,9 +64,9 @@ const MobileLogCard = ({ log, colorMode }) => {
63
64
  }
64
65
  return ((0, jsx_runtime_1.jsxs)("div", { style: {
65
66
  padding: "10px 12px",
66
- borderBottom: `1px solid ${isDark ? "#333" : "#e9ecef"}`,
67
- backgroundColor: isDark ? "#1a1a1a" : "#fff",
68
- }, children: [(0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center gap-2 mb-1", style: { flexWrap: "wrap" }, children: [(0, jsx_runtime_1.jsx)("span", { style: { fontSize: "0.7rem", color: isDark ? "#888" : "#666" }, children: (0, moment_1.default)(log.timestamp).format("HH:mm:ss.SSS") }), (0, jsx_runtime_1.jsxs)("span", { className: "badge text-white", style: {
67
+ borderBottom: `1px solid ${isDark ? "#333" : "var(--peers-surface-border)"}`,
68
+ backgroundColor: isDark ? "#1a1a1a" : "var(--peers-surface-bg)",
69
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center gap-2 mb-1", style: { flexWrap: "wrap" }, children: [(0, jsx_runtime_1.jsx)("span", { style: { fontSize: "0.7rem", color: isDark ? "#888" : "var(--bs-secondary-color)" }, children: (0, moment_1.default)(log.timestamp).format("HH:mm:ss.SSS") }), (0, jsx_runtime_1.jsxs)("span", { className: "badge text-white", style: {
69
70
  backgroundColor: getLevelColor(log.level),
70
71
  fontSize: "0.65rem",
71
72
  padding: "2px 6px",
@@ -73,14 +74,14 @@ const MobileLogCard = ({ log, colorMode }) => {
73
74
  backgroundColor: getProcessColor(log.process),
74
75
  fontSize: "0.65rem",
75
76
  padding: "2px 6px",
76
- }, children: log.process }), log.source && ((0, jsx_runtime_1.jsx)("span", { style: { fontSize: "0.65rem", color: isDark ? "#666" : "#999" }, children: log.source }))] }), (0, jsx_runtime_1.jsx)("div", { style: {
77
+ }, children: log.process }), log.source && ((0, jsx_runtime_1.jsx)("span", { style: { fontSize: "0.65rem", color: isDark ? "#666" : "var(--bs-secondary-color)" }, children: log.source }))] }), (0, jsx_runtime_1.jsx)("div", { style: {
77
78
  fontSize: "0.8rem",
78
79
  wordBreak: "break-word",
79
- color: isDark ? "#e0e0e0" : "#333",
80
+ color: isDark ? "#e0e0e0" : "var(--bs-body-color)",
80
81
  }, children: log.message }), context && ((0, jsx_runtime_1.jsxs)("details", { className: "mt-1", children: [(0, jsx_runtime_1.jsxs)("summary", { className: "text-muted", style: { cursor: "pointer", fontSize: "0.7rem" }, children: [(0, jsx_runtime_1.jsx)("i", { className: "bi bi-code-square me-1" }), "Context"] }), (0, jsx_runtime_1.jsx)("pre", { className: "mt-1 p-2 rounded", style: {
81
82
  fontSize: "0.65rem",
82
- backgroundColor: isDark ? "#252525" : "#f8f9fa",
83
- color: isDark ? "#aaa" : "#333",
83
+ backgroundColor: isDark ? "#252525" : "var(--bs-body-bg)",
84
+ color: isDark ? "#aaa" : "var(--bs-body-color)",
84
85
  overflow: "auto",
85
86
  maxHeight: "150px",
86
87
  }, children: JSON.stringify(context, null, 2) })] })), log.stackTrace && ((0, jsx_runtime_1.jsxs)("details", { className: "mt-1", children: [(0, jsx_runtime_1.jsxs)("summary", { className: "text-danger", style: { cursor: "pointer", fontSize: "0.7rem" }, children: [(0, jsx_runtime_1.jsx)("i", { className: "bi bi-bug me-1" }), "Stack Trace"] }), (0, jsx_runtime_1.jsx)("pre", { className: "mt-1 p-2 rounded text-danger", style: {
@@ -9,5 +9,6 @@ interface ResizableTableHeaderProps {
9
9
  onColumnsChange: (columns: Column[]) => void;
10
10
  colorMode: string;
11
11
  }
12
+ /** Log table header whose drag handles resize the displayed columns. */
12
13
  export declare const ResizableTableHeader: ({ columns, onColumnsChange, colorMode, }: ResizableTableHeaderProps) => import("react/jsx-runtime").JSX.Element;
13
14
  export {};
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ResizableTableHeader = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
+ /** Log table header whose drag handles resize the displayed columns. */
6
7
  const ResizableTableHeader = ({ columns, onColumnsChange, colorMode, }) => {
7
8
  const [resizingColumn, setResizingColumn] = (0, react_1.useState)(null);
8
9
  const startXRef = (0, react_1.useRef)(0);
@@ -34,11 +35,11 @@ const ResizableTableHeader = ({ columns, onColumnsChange, colorMode, }) => {
34
35
  };
35
36
  }
36
37
  }, [resizingColumn, columns, onColumnsChange]);
37
- return ((0, jsx_runtime_1.jsx)("table", { className: "table table-sm mb-0", style: { fontSize: "0.85rem", tableLayout: "fixed", width: "100%" }, children: (0, jsx_runtime_1.jsx)("thead", { style: { backgroundColor: colorMode === "dark" ? "#2a2a2a" : "#ffffff" }, children: (0, jsx_runtime_1.jsx)("tr", { children: columns.map((column) => ((0, jsx_runtime_1.jsxs)("th", { style: {
38
+ return ((0, jsx_runtime_1.jsx)("table", { className: "table table-sm mb-0 peers-table-surface", style: { fontSize: "0.85rem", tableLayout: "fixed", width: "100%" }, children: (0, jsx_runtime_1.jsx)("thead", { style: { backgroundColor: colorMode === "dark" ? "#2a2a2a" : "var(--peers-surface-bg)" }, children: (0, jsx_runtime_1.jsx)("tr", { children: columns.map((column) => ((0, jsx_runtime_1.jsxs)("th", { style: {
38
39
  width: `${column.width}px`,
39
40
  position: "relative",
40
41
  padding: "0.5rem",
41
- borderRight: "1px solid #dee2e6",
42
+ borderRight: "1px solid var(--peers-surface-border, #dee2e6)",
42
43
  }, children: [column.label, column.key !== "message" && ((0, jsx_runtime_1.jsx)("div", { onMouseDown: (e) => handleMouseDown(e, column.key, column.width), style: {
43
44
  position: "absolute",
44
45
  right: 0,
@@ -34,7 +34,7 @@ interface IUsageGraphProps {
34
34
  */
35
35
  color?: string;
36
36
  /**
37
- * Color for the overlay text (optional, defaults to transparent white)
37
+ * Color for the overlay text (optional). Defaults to the theme's `--peers-graph-overlay-color` (a faint gray in light mode), else translucent white.
38
38
  */
39
39
  overlayTextColor?: string;
40
40
  /**
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.UsageGraph = UsageGraph;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
- function UsageGraph({ fetchUsage, label, durationMinutes = 5, updateInterval = 5000, minHeight = 80, color = "rgba(13, 110, 253, 1)", overlayTextColor = "rgba(255, 255, 255, 0.7)", minValue = 0, maxValue = 100, formatOverlayText, colorZones, }) {
6
+ function UsageGraph({ fetchUsage, label, durationMinutes = 5, updateInterval = 5000, minHeight = 80, color = "rgba(13, 110, 253, 1)", overlayTextColor = "var(--peers-graph-overlay-color, rgba(255, 255, 255, 0.7))", minValue = 0, maxValue = 100, formatOverlayText, colorZones, }) {
7
7
  const [dataPoints, setDataPoints] = (0, react_1.useState)([]);
8
8
  const [currentValue, setCurrentValue] = (0, react_1.useState)(0);
9
9
  const [width, setWidth] = (0, react_1.useState)(400);
@@ -133,8 +133,8 @@ function GlobalSearch() {
133
133
  paddingLeft: "50px",
134
134
  fontSize: "18px",
135
135
  borderRadius: "12px",
136
- backgroundColor: isDark ? "#343a40" : "#f8f9fa",
137
- border: isDark ? "2px solid #495057" : "2px solid #dee2e6",
136
+ backgroundColor: isDark ? "#343a40" : "var(--peers-surface-bg)",
137
+ border: isDark ? "2px solid #495057" : "2px solid var(--peers-surface-border)",
138
138
  } }), isSearching && ((0, jsx_runtime_1.jsx)("div", { className: "position-absolute", style: {
139
139
  right: "16px",
140
140
  top: "50%",
@@ -145,7 +145,7 @@ function GlobalSearch() {
145
145
  ? `Found ${totalResults} result${totalResults !== 1 ? "s" : ""}`
146
146
  : searchQuery.trim()
147
147
  ? "No results found"
148
- : null }))] }), searchQuery && !isSearching && ((0, jsx_runtime_1.jsx)("div", { children: searchResults.length === 0 && appResults.length === 0 ? ((0, jsx_runtime_1.jsxs)("div", { className: "text-center py-5", children: [(0, jsx_runtime_1.jsx)("i", { className: "bi-search mb-3 d-block text-muted", style: { fontSize: "48px" } }), (0, jsx_runtime_1.jsx)("h4", { className: "text-muted", children: "No results found" }), (0, jsx_runtime_1.jsx)("p", { className: "text-muted", children: "Try different keywords or check your spelling" })] })) : ((0, jsx_runtime_1.jsxs)("div", { children: [appResults.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "mb-5", children: [(0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center mb-3", children: [(0, jsx_runtime_1.jsx)("i", { className: "bi-grid-3x3-gap me-3", style: { fontSize: "20px", color: "#6c757d" } }), (0, jsx_runtime_1.jsx)("h4", { className: "mb-0 me-3", children: "Apps" }), (0, jsx_runtime_1.jsx)("span", { className: "badge bg-secondary", children: appResults.length })] }), (0, jsx_runtime_1.jsx)("div", { className: "row g-3", children: appResults.map((app) => ((0, jsx_runtime_1.jsx)("div", { className: "col-12 col-md-6 col-lg-4", children: (0, jsx_runtime_1.jsx)("div", { className: `card h-100 ${isDark ? "bg-dark border-secondary" : "bg-light"}`, style: {
148
+ : null }))] }), searchQuery && !isSearching && ((0, jsx_runtime_1.jsx)("div", { children: searchResults.length === 0 && appResults.length === 0 ? ((0, jsx_runtime_1.jsxs)("div", { className: "text-center py-5", children: [(0, jsx_runtime_1.jsx)("i", { className: "bi-search mb-3 d-block text-muted", style: { fontSize: "48px" } }), (0, jsx_runtime_1.jsx)("h4", { className: "text-muted", children: "No results found" }), (0, jsx_runtime_1.jsx)("p", { className: "text-muted", children: "Try different keywords or check your spelling" })] })) : ((0, jsx_runtime_1.jsxs)("div", { children: [appResults.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "mb-5", children: [(0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center mb-3", children: [(0, jsx_runtime_1.jsx)("i", { className: "bi-grid-3x3-gap me-3", style: { fontSize: "20px", color: "#6c757d" } }), (0, jsx_runtime_1.jsx)("h4", { className: "mb-0 me-3", children: "Apps" }), (0, jsx_runtime_1.jsx)("span", { className: "badge bg-secondary", children: appResults.length })] }), (0, jsx_runtime_1.jsx)("div", { className: "row g-3", children: appResults.map((app) => ((0, jsx_runtime_1.jsx)("div", { className: "col-12 col-md-6 col-lg-4", children: (0, jsx_runtime_1.jsx)("div", { className: `card h-100 ${isDark ? "bg-dark border-secondary" : "peers-surface"}`, style: {
149
149
  cursor: "pointer",
150
150
  transition: "all 0.15s ease",
151
151
  borderRadius: "8px",
@@ -161,7 +161,7 @@ function GlobalSearch() {
161
161
  fontSize: "16px",
162
162
  color: isDark ? "#0d6efd" : "#0d6efd",
163
163
  minWidth: "16px",
164
- } }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-grow-1", children: [(0, jsx_runtime_1.jsx)("h6", { className: "card-title mb-1 fw-medium", children: app.displayName }), (0, jsx_runtime_1.jsx)("small", { className: "text-muted text-uppercase", style: { fontSize: "11px", letterSpacing: "0.5px" }, children: app.packageId === "system-apps" ? "System App" : app.packageName })] }), (0, jsx_runtime_1.jsx)("i", { className: "bi-arrow-right text-muted", style: { fontSize: "12px" } })] }) }) }) }, `${app.packageId}-${app.path}`))) })] })), searchResults.map((result) => ((0, jsx_runtime_1.jsxs)("div", { className: "mb-5", children: [(0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center mb-3", children: [(0, jsx_runtime_1.jsx)("i", { className: `${result.config.iconClass} me-3`, style: { fontSize: "20px", color: "#6c757d" } }), (0, jsx_runtime_1.jsx)("h4", { className: "mb-0 me-3", children: result.category }), (0, jsx_runtime_1.jsx)("span", { className: "badge bg-secondary", children: result.items.length })] }), (0, jsx_runtime_1.jsx)("div", { className: "row g-3", children: result.items.map((item) => ((0, jsx_runtime_1.jsx)("div", { className: "col-12 col-md-6 col-lg-4", children: (0, jsx_runtime_1.jsx)("div", { className: `card h-100 ${isDark ? "bg-dark border-secondary" : "bg-light"}`, style: {
164
+ } }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-grow-1", children: [(0, jsx_runtime_1.jsx)("h6", { className: "card-title mb-1 fw-medium", children: app.displayName }), (0, jsx_runtime_1.jsx)("small", { className: "text-muted text-uppercase", style: { fontSize: "11px", letterSpacing: "0.5px" }, children: app.packageId === "system-apps" ? "System App" : app.packageName })] }), (0, jsx_runtime_1.jsx)("i", { className: "bi-arrow-right text-muted", style: { fontSize: "12px" } })] }) }) }) }, `${app.packageId}-${app.path}`))) })] })), searchResults.map((result) => ((0, jsx_runtime_1.jsxs)("div", { className: "mb-5", children: [(0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center mb-3", children: [(0, jsx_runtime_1.jsx)("i", { className: `${result.config.iconClass} me-3`, style: { fontSize: "20px", color: "#6c757d" } }), (0, jsx_runtime_1.jsx)("h4", { className: "mb-0 me-3", children: result.category }), (0, jsx_runtime_1.jsx)("span", { className: "badge bg-secondary", children: result.items.length })] }), (0, jsx_runtime_1.jsx)("div", { className: "row g-3", children: result.items.map((item) => ((0, jsx_runtime_1.jsx)("div", { className: "col-12 col-md-6 col-lg-4", children: (0, jsx_runtime_1.jsx)("div", { className: `card h-100 ${isDark ? "bg-dark border-secondary" : "peers-surface"}`, style: {
165
165
  cursor: "pointer",
166
166
  transition: "all 0.15s ease",
167
167
  borderRadius: "8px",
@@ -177,5 +177,5 @@ function GlobalSearch() {
177
177
  fontSize: "16px",
178
178
  color: isDark ? "#0d6efd" : "#0d6efd",
179
179
  minWidth: "16px",
180
- } }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-grow-1", children: [(0, jsx_runtime_1.jsx)("h6", { className: "card-title mb-1 fw-medium", children: item.name }), (0, jsx_runtime_1.jsx)("small", { className: "text-muted text-uppercase", style: { fontSize: "11px", letterSpacing: "0.5px" }, children: result.category.slice(0, -1) })] }), (0, jsx_runtime_1.jsx)("i", { className: "bi-arrow-right text-muted", style: { fontSize: "12px" } })] }) }) }) }, item.id))) })] }, result.category)))] })) })), !searchQuery && ((0, jsx_runtime_1.jsxs)("div", { className: "text-center py-5", children: [(0, jsx_runtime_1.jsx)("i", { className: "bi-search mb-3 d-block text-muted", style: { fontSize: "64px" } }), (0, jsx_runtime_1.jsx)("h3", { className: "text-muted mb-3", children: "Search across everything" }), (0, jsx_runtime_1.jsx)("p", { className: "text-muted mb-4", style: { maxWidth: "400px", margin: "0 auto" }, children: "Find apps, tools, assistants, workflows, types, and users all in one place." }), (0, jsx_runtime_1.jsx)("div", { className: "d-flex flex-wrap justify-content-center gap-2", children: searchConfigs.map(({ config, category }) => ((0, jsx_runtime_1.jsxs)("span", { className: `badge ${isDark ? "bg-secondary" : "bg-light text-dark"} px-3 py-2 d-flex align-items-center`, style: { fontSize: "12px" }, children: [(0, jsx_runtime_1.jsx)("i", { className: `${config.iconClass} me-2` }), category] }, category))) })] }))] }));
180
+ } }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-grow-1", children: [(0, jsx_runtime_1.jsx)("h6", { className: "card-title mb-1 fw-medium", children: item.name }), (0, jsx_runtime_1.jsx)("small", { className: "text-muted text-uppercase", style: { fontSize: "11px", letterSpacing: "0.5px" }, children: result.category.slice(0, -1) })] }), (0, jsx_runtime_1.jsx)("i", { className: "bi-arrow-right text-muted", style: { fontSize: "12px" } })] }) }) }) }, item.id))) })] }, result.category)))] })) })), !searchQuery && ((0, jsx_runtime_1.jsxs)("div", { className: "text-center py-5", children: [(0, jsx_runtime_1.jsx)("i", { className: "bi-search mb-3 d-block text-muted", style: { fontSize: "64px" } }), (0, jsx_runtime_1.jsx)("h3", { className: "text-muted mb-3", children: "Search across everything" }), (0, jsx_runtime_1.jsx)("p", { className: "text-muted mb-4", style: { maxWidth: "400px", margin: "0 auto" }, children: "Find apps, tools, assistants, workflows, types, and users all in one place." }), (0, jsx_runtime_1.jsx)("div", { className: "d-flex flex-wrap justify-content-center gap-2", children: searchConfigs.map(({ config, category }) => ((0, jsx_runtime_1.jsxs)("span", { className: `badge ${isDark ? "bg-secondary" : "peers-surface text-body"} px-3 py-2 d-flex align-items-center`, style: { fontSize: "12px" }, children: [(0, jsx_runtime_1.jsx)("i", { className: `${config.iconClass} me-2` }), category] }, category))) })] }))] }));
181
181
  }
@@ -1,5 +1,10 @@
1
+ /** Stored theme preference, optionally following the operating system. */
1
2
  export type ColorModePreference = "light" | "dark" | "auto";
3
+ /** Resolved theme applied to the page. */
2
4
  export type ColorMode = "light" | "dark";
5
+ /** Observable resolved theme for platform and package components. */
3
6
  export declare const colorMode: import("@peers-app/peers-sdk").PersistentVar<ColorMode>;
7
+ /** Persistent device preference used to select the resolved theme. */
4
8
  export declare const colorModePreference: import("@peers-app/peers-sdk").PersistentVar<ColorModePreference>;
9
+ /** Settings control for light, dark, or system-following appearance. */
5
10
  export declare const ColorModeDropdown: () => import("react/jsx-runtime").JSX.Element;
@@ -4,9 +4,11 @@ exports.ColorModeDropdown = exports.colorModePreference = exports.colorMode = vo
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const peers_sdk_1 = require("@peers-app/peers-sdk");
6
6
  const hooks_1 = require("../../hooks");
7
+ /** Observable resolved theme for platform and package components. */
7
8
  exports.colorMode = (0, peers_sdk_1.deviceVar)("colorMode", {
8
9
  defaultValue: "dark",
9
10
  });
11
+ /** Persistent device preference used to select the resolved theme. */
10
12
  exports.colorModePreference = (0, peers_sdk_1.deviceVar)("colorModePreference", {
11
13
  defaultValue: "dark",
12
14
  });
@@ -28,7 +30,7 @@ function applyColorMode(modePreference) {
28
30
  document.documentElement.setAttribute("data-bs-theme", mode);
29
31
  if (mode === "light") {
30
32
  document.documentElement.style.backgroundColor = "";
31
- document.body.style.backgroundColor = "initial";
33
+ document.body.style.backgroundColor = "";
32
34
  }
33
35
  else {
34
36
  document.documentElement.style.backgroundColor = "rgb(33, 37, 41)";
@@ -36,13 +38,17 @@ function applyColorMode(modePreference) {
36
38
  }
37
39
  const themeMeta = document.querySelector('meta[name="theme-color"]');
38
40
  if (themeMeta) {
39
- themeMeta.setAttribute("content", mode === "light" ? "#ffffff" : "#212529");
41
+ const themeColor = mode === "light"
42
+ ? getComputedStyle(document.documentElement).getPropertyValue("--peers-tab-strip-bg").trim()
43
+ : "#212529";
44
+ themeMeta.setAttribute("content", themeColor);
40
45
  }
41
46
  (0, exports.colorMode)(mode);
42
47
  exports.colorMode.notifySubscribers();
43
48
  return mode;
44
49
  }
45
50
  exports.colorModePreference.subscribe((newValue) => applyColorMode(newValue));
51
+ /** Settings control for light, dark, or system-following appearance. */
46
52
  const ColorModeDropdown = () => {
47
53
  const [modePreference] = (0, hooks_1.useObservable)(exports.colorModePreference);
48
54
  return ((0, jsx_runtime_1.jsxs)("div", { className: "dropdown", children: [(0, jsx_runtime_1.jsxs)("button", { className: "btn btn-secondary dropdown-toggle", type: "button", id: "colorModeDropdown", "data-bs-toggle": "dropdown", "aria-expanded": "false", children: ["Color Mode: ", (0, peers_sdk_1.camelCaseToSpaces)(modePreference)] }), (0, jsx_runtime_1.jsxs)("ul", { className: "dropdown-menu", "aria-labelledby": "colorModeDropdown", children: [(0, jsx_runtime_1.jsx)("li", { children: (0, jsx_runtime_1.jsxs)("button", { className: "dropdown-item", onClick: () => (0, exports.colorModePreference)("auto"), children: ["Auto ", modePreference === "auto" && "✓"] }) }), (0, jsx_runtime_1.jsx)("li", { children: (0, jsx_runtime_1.jsxs)("button", { className: "dropdown-item", onClick: () => (0, exports.colorModePreference)("light"), children: ["Light ", modePreference === "light" && "✓"] }) }), (0, jsx_runtime_1.jsx)("li", { children: (0, jsx_runtime_1.jsxs)("button", { className: "dropdown-item", onClick: () => (0, exports.colorModePreference)("dark"), children: ["Dark ", modePreference === "dark" && "✓"] }) })] })] }));
@@ -1 +1,2 @@
1
+ /** Initial account setup, recovery, and pairing with an existing device. */
1
2
  export declare const SetupUser: () => import("react/jsx-runtime").JSX.Element | null;
@@ -8,6 +8,7 @@ const hooks_1 = require("../hooks");
8
8
  const device_pairing_1 = require("./device-pairing");
9
9
  const identity_ipc_1 = require("./device-pairing/identity-ipc");
10
10
  const color_mode_dropdown_1 = require("./settings/color-mode-dropdown");
11
+ /** Initial account setup, recovery, and pairing with an existing device. */
11
12
  const SetupUser = () => {
12
13
  const [_colorMode] = (0, hooks_1.useObservable)(color_mode_dropdown_1.colorMode);
13
14
  const [step, _setStep] = (0, react_1.useState)("select-user-type");
@@ -68,34 +69,34 @@ const SetupUser = () => {
68
69
  }
69
70
  };
70
71
  if (showPairing) {
71
- return ((0, jsx_runtime_1.jsx)("div", { className: "container-fluid d-flex align-items-start justify-content-center", style: { paddingTop: "20px", backgroundColor: isDark ? "#212529" : "#f8f9fa" }, children: (0, jsx_runtime_1.jsx)("div", { className: "card shadow", style: {
72
+ return ((0, jsx_runtime_1.jsx)("div", { className: "container-fluid d-flex align-items-start justify-content-center", style: { paddingTop: "20px", backgroundColor: isDark ? "#212529" : "var(--bs-body-bg)" }, children: (0, jsx_runtime_1.jsx)("div", { className: "card shadow", style: {
72
73
  maxWidth: "560px",
73
74
  width: "100%",
74
- backgroundColor: isDark ? "#2d3238" : "#ffffff",
75
+ backgroundColor: isDark ? "#2d3238" : "var(--peers-surface-bg)",
75
76
  }, children: (0, jsx_runtime_1.jsx)("div", { className: "card-body p-4 p-md-5", children: (0, jsx_runtime_1.jsx)(device_pairing_1.DestinationDevicePairing, { onBack: () => setShowPairing(false) }) }) }) }));
76
77
  }
77
78
  // Step 1: Select User Type
78
79
  if (step === "select-user-type" && isExistingUser === null) {
79
- return ((0, jsx_runtime_1.jsx)("div", { className: "container-fluid d-flex align-items-start justify-content-center", style: { paddingTop: "20px", backgroundColor: isDark ? "#212529" : "#f8f9fa" }, children: (0, jsx_runtime_1.jsx)("div", { className: "card shadow", style: {
80
+ return ((0, jsx_runtime_1.jsx)("div", { className: "container-fluid d-flex align-items-start justify-content-center", style: { paddingTop: "20px", backgroundColor: isDark ? "#212529" : "var(--bs-body-bg)" }, children: (0, jsx_runtime_1.jsx)("div", { className: "card shadow", style: {
80
81
  maxWidth: "500px",
81
82
  width: "100%",
82
- backgroundColor: isDark ? "#2d3238" : "#ffffff",
83
+ backgroundColor: isDark ? "#2d3238" : "var(--peers-surface-bg)",
83
84
  }, children: (0, jsx_runtime_1.jsxs)("div", { className: "card-body p-4 p-md-5", children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-center mb-4", children: [(0, jsx_runtime_1.jsx)("h2", { className: `fw-bold mb-2 ${isDark ? "text-light" : ""}`, children: "Welcome to Peers" }), (0, jsx_runtime_1.jsx)("p", { className: isDark ? "text-light opacity-75" : "text-muted", children: "Let's get you set up" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "d-grid gap-3", children: [(0, jsx_runtime_1.jsx)("button", { className: "btn btn-lg btn-primary py-3", onClick: () => setIsExistingUser(false), children: (0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center justify-content-center", children: [(0, jsx_runtime_1.jsx)("i", { className: "bi bi-person-plus fs-4 me-2" }), (0, jsx_runtime_1.jsxs)("div", { className: "text-start", children: [(0, jsx_runtime_1.jsx)("div", { className: "fw-semibold", children: "New account" }), (0, jsx_runtime_1.jsx)("small", { className: "opacity-75", children: "Create a new account on this device" })] })] }) }), (0, jsx_runtime_1.jsx)("button", { className: `btn btn-lg py-3 ${isDark ? "btn-outline-light" : "btn-outline-primary"}`, onClick: () => setShowPairing(true), children: (0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center justify-content-center", children: [(0, jsx_runtime_1.jsx)("i", { className: "bi bi-phone fs-4 me-2" }), (0, jsx_runtime_1.jsxs)("div", { className: "text-start", children: [(0, jsx_runtime_1.jsx)("div", { className: "fw-semibold", children: "Sign in from another device" }), (0, jsx_runtime_1.jsx)("small", { className: "opacity-75", children: "Show a code to a device that is already signed in" })] })] }) }), (0, jsx_runtime_1.jsxs)("details", { className: "text-center mt-2", children: [(0, jsx_runtime_1.jsx)("summary", { className: `small ${isDark ? "text-light opacity-75" : "text-muted"}`, style: { cursor: "pointer" }, children: "Advanced" }), (0, jsx_runtime_1.jsxs)("button", { type: "button", className: `btn btn-sm mt-2 ${isDark ? "btn-outline-light" : "btn-outline-secondary"}`, onClick: () => setIsExistingUser(true), children: [(0, jsx_runtime_1.jsx)("i", { className: "bi bi-key me-1" }), "Enter a user ID and secret key"] })] })] })] }) }) }));
84
85
  }
85
86
  // Step 2: New User Confirmation
86
87
  if (isExistingUser === false) {
87
- return ((0, jsx_runtime_1.jsx)("div", { className: "container-fluid d-flex align-items-start justify-content-center", style: { paddingTop: "20px", backgroundColor: isDark ? "#212529" : "#f8f9fa" }, children: (0, jsx_runtime_1.jsx)("div", { className: "card shadow", style: {
88
+ return ((0, jsx_runtime_1.jsx)("div", { className: "container-fluid d-flex align-items-start justify-content-center", style: { paddingTop: "20px", backgroundColor: isDark ? "#212529" : "var(--bs-body-bg)" }, children: (0, jsx_runtime_1.jsx)("div", { className: "card shadow", style: {
88
89
  maxWidth: "500px",
89
90
  width: "100%",
90
- backgroundColor: isDark ? "#2d3238" : "#ffffff",
91
+ backgroundColor: isDark ? "#2d3238" : "var(--peers-surface-bg)",
91
92
  }, children: (0, jsx_runtime_1.jsxs)("div", { className: "card-body p-4 p-md-5", children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-center mb-4", children: [(0, jsx_runtime_1.jsx)("i", { className: "bi bi-person-plus-fill text-primary fs-1 mb-3 d-block" }), (0, jsx_runtime_1.jsx)("h3", { className: `fw-bold mb-2 ${isDark ? "text-light" : ""}`, children: "Create New Account" }), (0, jsx_runtime_1.jsx)("p", { className: isDark ? "text-light opacity-75" : "text-muted", children: "We'll generate secure credentials for you" })] }), error && ((0, jsx_runtime_1.jsxs)("div", { className: "alert alert-danger", role: "alert", children: [(0, jsx_runtime_1.jsx)("i", { className: "bi bi-exclamation-triangle me-2" }), error] })), (0, jsx_runtime_1.jsxs)("div", { className: "d-grid gap-2", children: [(0, jsx_runtime_1.jsx)("button", { className: "btn btn-lg btn-primary", onClick: handleNewUser, disabled: isValidating, children: isValidating ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: "spinner-border spinner-border-sm me-2" }), "Creating Account..."] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("i", { className: "bi bi-check-circle me-2" }), "Create Account"] })) }), (0, jsx_runtime_1.jsxs)("button", { className: "btn btn-outline-secondary", onClick: () => setIsExistingUser(null), disabled: isValidating, children: [(0, jsx_runtime_1.jsx)("i", { className: "bi bi-arrow-left me-2" }), "Back"] })] })] }) }) }));
92
93
  }
93
94
  // Step 3: Existing User Sign In
94
95
  if (isExistingUser === true) {
95
- return ((0, jsx_runtime_1.jsx)("div", { className: "container-fluid d-flex align-items-start justify-content-center", style: { paddingTop: "20px", backgroundColor: isDark ? "#212529" : "#f8f9fa" }, children: (0, jsx_runtime_1.jsx)("div", { className: "card shadow", style: {
96
+ return ((0, jsx_runtime_1.jsx)("div", { className: "container-fluid d-flex align-items-start justify-content-center", style: { paddingTop: "20px", backgroundColor: isDark ? "#212529" : "var(--bs-body-bg)" }, children: (0, jsx_runtime_1.jsx)("div", { className: "card shadow", style: {
96
97
  maxWidth: "500px",
97
98
  width: "100%",
98
- backgroundColor: isDark ? "#2d3238" : "#ffffff",
99
+ backgroundColor: isDark ? "#2d3238" : "var(--peers-surface-bg)",
99
100
  }, children: (0, jsx_runtime_1.jsxs)("div", { className: "card-body p-4 p-md-5", children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-center mb-2", children: [(0, jsx_runtime_1.jsxs)("h3", { className: `fw-bold mb-2 ${isDark ? "text-light" : ""}`, children: [(0, jsx_runtime_1.jsx)("span", { children: "Sign In" }), "\u00A0\u00A0", (0, jsx_runtime_1.jsx)("i", { className: "bi bi-box-arrow-in-right text-primary" })] }), (0, jsx_runtime_1.jsx)("p", { className: isDark ? "text-light opacity-75" : "text-muted", children: "Paste your user ID and secret key. If you have another signed-in device, \u201CSign in from another device\u201D is easier and safer." })] }), error && ((0, jsx_runtime_1.jsxs)("div", { className: "alert alert-danger", role: "alert", children: [(0, jsx_runtime_1.jsx)("i", { className: "bi bi-exclamation-triangle me-2" }), error] })), (0, jsx_runtime_1.jsxs)("form", { onSubmit: (e) => {
100
101
  e.preventDefault();
101
102
  handleExistingUser();
@@ -108,33 +108,33 @@ function WelcomeModal({ colorMode, onClose }) {
108
108
  backgroundColor: "rgba(0, 0, 0, 0.5)",
109
109
  backdropFilter: "blur(4px)",
110
110
  paddingTop: "10vh",
111
- }, children: (0, jsx_runtime_1.jsxs)("div", { className: `${isDark ? "bg-dark text-light" : "bg-white text-dark"}`, style: {
111
+ }, children: (0, jsx_runtime_1.jsxs)("div", { className: `${isDark ? "bg-dark text-light" : "peers-surface text-body"}`, style: {
112
112
  width: "90%",
113
113
  maxWidth: "500px",
114
114
  borderRadius: "12px",
115
115
  boxShadow: isDark ? "0 20px 40px rgba(0, 0, 0, 0.5)" : "0 20px 40px rgba(0, 0, 0, 0.1)",
116
- border: isDark ? "1px solid #495057" : "1px solid #dee2e6",
116
+ border: isDark ? "1px solid #495057" : "1px solid var(--peers-surface-border)",
117
117
  overflow: "hidden",
118
118
  }, children: [(0, jsx_runtime_1.jsxs)("div", { className: "p-4 text-center", style: {
119
- borderBottom: `1px solid ${isDark ? "#495057" : "#dee2e6"}`,
119
+ borderBottom: `1px solid ${isDark ? "#495057" : "var(--peers-surface-border)"}`,
120
120
  }, children: [(0, jsx_runtime_1.jsx)("i", { className: "bi-person-circle text-primary d-block mb-3", style: { fontSize: "48px" } }), (0, jsx_runtime_1.jsx)("h4", { className: "mb-2", children: "Welcome to Peers!" }), (0, jsx_runtime_1.jsx)("p", { className: `mb-0 ${isDark ? "text-light opacity-75" : "text-muted"}`, style: { fontSize: "14px" }, children: "Let's personalize your experience. You can change these anytime in Settings." })] }), (0, jsx_runtime_1.jsxs)("div", { className: "p-4", children: [error && ((0, jsx_runtime_1.jsxs)("div", { className: "alert alert-danger py-2 px-3 mb-3", style: { fontSize: "14px" }, children: [(0, jsx_runtime_1.jsx)("i", { className: "bi-exclamation-triangle me-2" }), error] })), (0, jsx_runtime_1.jsxs)("div", { className: "mb-3", children: [(0, jsx_runtime_1.jsxs)("label", { className: "form-label fw-semibold mb-1", children: [(0, jsx_runtime_1.jsx)("i", { className: "bi-person me-2" }), "Display Name"] }), (0, jsx_runtime_1.jsx)("input", { type: "text", className: `form-control ${isDark ? "bg-dark text-light border-secondary" : ""}`, maxLength: peers_sdk_1.DISPLAY_NAME_MAX_LENGTH, placeholder: "How should others see you?", value: displayName, onChange: (e) => {
121
121
  setDisplayName(e.target.value);
122
122
  setError(null);
123
123
  }, onKeyDown: handleKeyDown, disabled: isSaving, style: {
124
124
  fontSize: "14px",
125
- backgroundColor: isDark ? "#343a40" : "#ffffff",
125
+ backgroundColor: isDark ? "#343a40" : "var(--peers-surface-bg)",
126
126
  } }), (0, jsx_runtime_1.jsx)("small", { className: isDark ? "text-light opacity-50" : "text-muted", style: { fontSize: "11px" }, children: "This name will be visible to others when you connect" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "mb-3", children: [(0, jsx_runtime_1.jsxs)("label", { className: "form-label fw-semibold mb-1", children: [(0, jsx_runtime_1.jsx)("i", { className: "bi-laptop me-2" }), "Device Name"] }), (0, jsx_runtime_1.jsx)("input", { type: "text", className: `form-control ${isDark ? "bg-dark text-light border-secondary" : ""}`, maxLength: peers_sdk_1.DISPLAY_NAME_MAX_LENGTH, placeholder: "e.g., My Laptop, Work Computer", value: deviceName, onChange: (e) => {
127
127
  setDeviceName(e.target.value);
128
128
  setError(null);
129
129
  }, onKeyDown: handleKeyDown, disabled: isSaving, style: {
130
130
  fontSize: "14px",
131
- backgroundColor: isDark ? "#343a40" : "#ffffff",
131
+ backgroundColor: isDark ? "#343a40" : "var(--peers-surface-bg)",
132
132
  } }), (0, jsx_runtime_1.jsx)("small", { className: isDark ? "text-light opacity-50" : "text-muted", style: { fontSize: "11px" }, children: "Helps you identify this device when syncing across multiple devices" })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "p-3 d-flex justify-content-between align-items-center", style: {
133
- borderTop: `1px solid ${isDark ? "#495057" : "#dee2e6"}`,
134
- backgroundColor: isDark ? "#2d3238" : "#f8f9fa",
133
+ borderTop: `1px solid ${isDark ? "#495057" : "var(--peers-surface-border)"}`,
134
+ backgroundColor: isDark ? "#2d3238" : "var(--peers-surface-bg)",
135
135
  }, children: [(0, jsx_runtime_1.jsx)("button", { className: `btn btn-sm ${isDark ? "btn-outline-light" : "btn-outline-secondary"}`, onClick: handleSkip, disabled: isSaving, children: "Skip for now" }), (0, jsx_runtime_1.jsx)("button", { className: "btn btn-sm btn-primary", onClick: handleSave, disabled: isSaving, style: { minWidth: "100px" }, children: isSaving ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: "spinner-border spinner-border-sm me-1", role: "status", "aria-hidden": "true" }), "Saving..."] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("i", { className: "bi-check-lg me-1" }), "Get Started"] })) })] }), (0, jsx_runtime_1.jsxs)("div", { className: `px-3 py-2 small text-center ${isDark ? "text-light opacity-50" : "text-muted"}`, style: {
136
- borderTop: `1px solid ${isDark ? "#495057" : "#dee2e6"}`,
136
+ borderTop: `1px solid ${isDark ? "#495057" : "var(--peers-surface-border)"}`,
137
137
  fontSize: "11px",
138
- backgroundColor: isDark ? "#212529" : "#ffffff",
138
+ backgroundColor: isDark ? "#212529" : "var(--peers-surface-bg)",
139
139
  }, children: [(0, jsx_runtime_1.jsx)("kbd", { className: "small", children: "\u21B5" }), " to save \u2022 ", (0, jsx_runtime_1.jsx)("kbd", { className: "small", children: "esc" }), " to skip"] })] }) }));
140
140
  }
@@ -148,25 +148,26 @@ function TabsLayoutInternal({ fillContainer = false } = {}) {
148
148
  display: "flex",
149
149
  alignItems: "center",
150
150
  justifyContent: "center",
151
- backgroundColor: _colorMode === "light" ? "rgba(255,255,255,0.85)" : "rgba(0,0,0,0.85)",
152
- }, children: (0, jsx_runtime_1.jsxs)("div", { className: "text-center", children: [(0, jsx_runtime_1.jsx)("div", { className: "spinner-border text-secondary mb-3", role: "status" }), (0, jsx_runtime_1.jsx)("div", { className: `small ${_colorMode === "light" ? "text-muted" : "text-secondary"}`, children: "Switching group..." })] }) })), (0, jsx_runtime_1.jsx)("div", { className: "border-bottom", style: {
153
- backgroundColor: "var(--bs-secondary-bg)",
151
+ backgroundColor: _colorMode === "light" ? "rgba(var(--bs-body-bg-rgb), 0.85)" : "rgba(0,0,0,0.85)",
152
+ }, children: (0, jsx_runtime_1.jsxs)("div", { className: "text-center", children: [(0, jsx_runtime_1.jsx)("div", { className: "spinner-border text-secondary mb-3", role: "status" }), (0, jsx_runtime_1.jsx)("div", { className: `small ${_colorMode === "light" ? "text-muted" : "text-secondary"}`, children: "Switching group..." })] }) })), (0, jsx_runtime_1.jsx)("div", { className: `border-bottom peers-tab-strip ${_colorMode === "light" ? "" : "bg-dark"}`, style: {
154
153
  borderBottomWidth: "1px",
155
- borderBottomColor: _colorMode === "light" ? "#dee2e6" : "#495057",
154
+ borderBottomColor: _colorMode === "light" ? "var(--peers-tab-edge)" : "#495057",
156
155
  }, children: isMobile ? ((0, jsx_runtime_1.jsx)(MobileTabsHeader, { tabs: tabs, activeTab: activeTab, onSwitch: switchTab, onClose: closeTab, colorMode: _colorMode })) : ((0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center px-1", style: { height: "36px" }, children: [(0, jsx_runtime_1.jsx)(group_switcher_1.GroupSwitcher, { colorMode: _colorMode, isMobile: false }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "btn btn-sm me-2 d-flex align-items-center", onClick: command_palette_1.openCommandPalette, title: "Search everything (Cmd+K)", style: {
157
156
  padding: "4px 8px",
158
157
  fontSize: "12px",
159
158
  borderRadius: "6px",
160
159
  border: "none",
161
160
  background: "transparent",
162
- color: _colorMode === "light" ? "#6c757d" : "#adb5bd",
161
+ color: _colorMode === "light" ? "var(--peers-tab-icon-color)" : "#adb5bd",
163
162
  }, onMouseEnter: (e) => {
164
163
  e.currentTarget.style.backgroundColor =
165
- _colorMode === "light" ? "#f8f9fa" : "#495057";
166
- e.currentTarget.style.color = _colorMode === "light" ? "#0d6efd" : "#ffffff";
164
+ _colorMode === "light" ? "var(--peers-tab-hover-bg)" : "#495057";
165
+ e.currentTarget.style.color =
166
+ _colorMode === "light" ? "var(--bs-link-color)" : "#ffffff";
167
167
  }, onMouseLeave: (e) => {
168
168
  e.currentTarget.style.backgroundColor = "transparent";
169
- e.currentTarget.style.color = _colorMode === "light" ? "#6c757d" : "#adb5bd";
169
+ e.currentTarget.style.color =
170
+ _colorMode === "light" ? "var(--peers-tab-icon-color)" : "#adb5bd";
170
171
  }, children: (0, jsx_runtime_1.jsx)("i", { className: "bi-search", style: { fontSize: "14px" } }) }), (0, jsx_runtime_1.jsx)("div", { className: "d-flex flex-grow-1 overflow-auto", style: {
171
172
  scrollbarWidth: "none",
172
173
  msOverflowStyle: "none",
@@ -206,39 +207,31 @@ function MobileTabsHeader({ tabs, activeTab, onSwitch, onClose, colorMode, }) {
206
207
  }, children: (0, jsx_runtime_1.jsx)("i", { className: "bi-x" }) })] }, tab.tabId)))] }))] })] }), showMenuDropdown && ((0, jsx_runtime_1.jsx)("div", { className: "position-fixed w-100 h-100", style: { top: 0, left: 0, zIndex: 999 }, onClick: () => setShowMenuDropdown(false) }))] }));
207
208
  }
208
209
  function TabHeader({ tab, isActive, onSwitch, onClose, colorMode }) {
209
- const activeClass = isActive
210
- ? colorMode === "light"
211
- ? "bg-white"
212
- : "bg-secondary"
213
- : colorMode === "light"
214
- ? "bg-light"
215
- : "bg-dark";
216
- return ((0, jsx_runtime_1.jsxs)("div", { className: `d-flex align-items-center px-2 py-1 user-select-none ${activeClass}`, style: {
210
+ const isLight = colorMode === "light";
211
+ const activeClass = isLight ? "" : isActive ? "bg-secondary" : "bg-dark";
212
+ return ((0, jsx_runtime_1.jsxs)("div", { className: `peers-tab ${isActive ? "peers-tab-active" : ""} d-flex align-items-center px-2 py-1 user-select-none ${activeClass}`, style: {
217
213
  cursor: "pointer",
218
214
  minWidth: "100px",
219
215
  maxWidth: "180px",
220
216
  height: "34px",
221
217
  fontSize: "13px",
222
- borderTop: isActive ? "2px solid #0d6efd" : "2px solid transparent",
223
- borderLeft: "1px solid transparent",
224
- borderRight: `1px solid ${colorMode === "light" ? "#dee2e6" : "#495057"}`,
225
- borderBottom: isActive
226
- ? colorMode === "light"
227
- ? "1px solid white"
228
- : "1px solid #343a40"
229
- : "none",
218
+ backgroundColor: isLight ? "var(--peers-tab-bg)" : undefined,
219
+ borderTop: isLight ? undefined : isActive ? "2px solid #0d6efd" : "2px solid transparent",
220
+ borderLeft: isLight ? undefined : "1px solid transparent",
221
+ borderRight: isLight ? undefined : "1px solid #495057",
222
+ borderBottom: isLight ? undefined : isActive ? "1px solid #343a40" : "none",
230
223
  marginBottom: isActive ? "-1px" : "0",
231
224
  borderRadius: isActive ? "6px 6px 0 0" : "0",
232
225
  transition: "all 0.15s ease",
233
226
  zIndex: isActive ? 1 : 0,
234
- boxShadow: isActive ? "0 2px 4px rgba(0,0,0,0.1)" : "none",
227
+ boxShadow: isLight ? undefined : isActive ? "0 2px 4px rgba(0,0,0,0.1)" : "none",
235
228
  }, onMouseEnter: (e) => {
236
- if (!isActive) {
237
- e.currentTarget.style.backgroundColor = colorMode === "light" ? "#f8f9fa" : "#495057";
229
+ if (!isActive && !isLight) {
230
+ e.currentTarget.style.backgroundColor = "#495057";
238
231
  }
239
232
  }, onMouseLeave: (e) => {
240
- if (!isActive) {
241
- e.currentTarget.style.backgroundColor = colorMode === "light" ? "#f1f3f4" : "#343a40";
233
+ if (!isActive && !isLight) {
234
+ e.currentTarget.style.backgroundColor = "#343a40";
242
235
  }
243
236
  }, onClick: () => onSwitch(tab.tabId), children: [tab.iconClassName && (0, jsx_runtime_1.jsx)("i", { className: `${tab.iconClassName} me-2` }), (0, jsx_runtime_1.jsx)("span", { className: "text-truncate", style: { maxWidth: "120px", fontSize: "12px" }, children: tab.title }), tab.tabId !== "launcher" && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "btn p-0 ms-1 opacity-75 hover-opacity-100", style: {
244
237
  width: "14px",
@@ -396,15 +389,15 @@ function AppCard({ appItem, onOpenApp, isMobile }) {
396
389
  }, onClick: () => onOpenApp(appItem), children: [(0, jsx_runtime_1.jsx)("div", { className: "d-flex align-items-center justify-content-center mb-2", style: {
397
390
  width: isMobile ? "64px" : "72px",
398
391
  height: isMobile ? "64px" : "72px",
399
- backgroundColor: isDark ? "#343a40" : "#f8f9fa",
392
+ backgroundColor: isDark ? "#343a40" : "var(--peers-surface-bg)",
400
393
  borderRadius: "12px",
401
- border: `1px solid ${isDark ? "#495057" : "#e9ecef"}`,
394
+ border: `1px solid ${isDark ? "#495057" : "var(--peers-surface-border)"}`,
402
395
  boxShadow: isDark ? "0 2px 4px rgba(0,0,0,0.3)" : "0 2px 4px rgba(0,0,0,0.08)",
403
396
  transition: "all 0.15s ease",
404
397
  }, children: (0, jsx_runtime_1.jsx)("i", { className: appItem.iconClassName, style: {
405
398
  fontSize: isMobile ? "28px" : "32px",
406
399
  color: isDark ? "#0d6efd" : "#0d6efd",
407
- } }) }), (0, jsx_runtime_1.jsx)("span", { className: isDark ? "text-light" : "text-dark", style: {
400
+ } }) }), (0, jsx_runtime_1.jsx)("span", { className: isDark ? "text-light" : "text-body", style: {
408
401
  fontSize: isMobile ? "11px" : "12px",
409
402
  fontWeight: "500",
410
403
  lineHeight: "1.2",
package/dist/theme.css ADDED
@@ -0,0 +1,126 @@
1
+ /* Shared light palette. Import after Bootstrap in every platform host. */
2
+ [data-bs-theme="light"] {
3
+ --bs-body-bg: #e5e9ed;
4
+ --bs-body-bg-rgb: 229, 233, 237;
5
+ --bs-body-color: #242a31;
6
+ --bs-body-color-rgb: 36, 42, 49;
7
+ --bs-secondary-color: #5f6974;
8
+ --bs-secondary-color-rgb: 95, 105, 116;
9
+ --bs-border-color: #c7ced6;
10
+ --bs-link-color: #2a63cb;
11
+ --bs-link-color-rgb: 42, 99, 203;
12
+ --bs-link-hover-color: var(--bs-link-color);
13
+ --bs-link-hover-color-rgb: var(--bs-link-color-rgb);
14
+
15
+ --peers-surface-bg: #fbfcfd;
16
+ --peers-surface-border: #d0d7de;
17
+ --peers-tab-strip-bg: #d0d6dd;
18
+ --peers-tab-edge: #b8c1ca;
19
+ --peers-tab-strip-color: #283037;
20
+ --peers-tab-icon-color: #56616d;
21
+ --peers-tab-color: #4f5a66;
22
+ --peers-tab-hover-bg: rgba(255, 255, 255, 0.42);
23
+ --peers-tab-divider: #bcc5ce;
24
+ --peers-tab-active-color: #1e242a;
25
+ --peers-tab-accent: #2f6fde;
26
+ --peers-tab-active-shadow: 0 -1px 3px rgba(30, 40, 55, 0.09);
27
+ --peers-graph-overlay-color: rgba(36, 42, 49, 0.32);
28
+ }
29
+
30
+ /* Bootstrap declares these variables locally, so override them on each component. */
31
+ [data-bs-theme="light"] .card {
32
+ --bs-card-bg: var(--peers-surface-bg);
33
+ --bs-card-border-color: var(--peers-surface-border);
34
+ }
35
+
36
+ [data-bs-theme="light"] .dropdown-menu {
37
+ --bs-dropdown-bg: var(--peers-surface-bg);
38
+ --bs-dropdown-border-color: var(--peers-surface-border);
39
+ --bs-dropdown-divider-bg: var(--peers-surface-border);
40
+ }
41
+
42
+ [data-bs-theme="light"] .modal {
43
+ --bs-modal-bg: var(--peers-surface-bg);
44
+ --bs-modal-border-color: var(--peers-surface-border);
45
+ --bs-modal-header-border-color: var(--peers-surface-border);
46
+ --bs-modal-footer-border-color: var(--peers-surface-border);
47
+ }
48
+
49
+ [data-bs-theme="light"] .list-group {
50
+ --bs-list-group-bg: var(--peers-surface-bg);
51
+ --bs-list-group-border-color: var(--peers-surface-border);
52
+ }
53
+
54
+ [data-bs-theme="light"] .popover {
55
+ --bs-popover-bg: var(--peers-surface-bg);
56
+ --bs-popover-border-color: var(--peers-surface-border);
57
+ }
58
+
59
+ [data-bs-theme="light"] .toast {
60
+ --bs-toast-bg: var(--peers-surface-bg);
61
+ --bs-toast-border-color: var(--peers-surface-border);
62
+ --bs-toast-header-bg: var(--peers-surface-bg);
63
+ --bs-toast-header-border-color: var(--peers-surface-border);
64
+ }
65
+
66
+ [data-bs-theme="light"]
67
+ :is(.offcanvas, .offcanvas-sm, .offcanvas-md, .offcanvas-lg, .offcanvas-xl, .offcanvas-xxl) {
68
+ --bs-offcanvas-bg: var(--peers-surface-bg);
69
+ --bs-offcanvas-border-color: var(--peers-surface-border);
70
+ }
71
+
72
+ [data-bs-theme="light"] :is(.form-control, .form-select):not(:disabled) {
73
+ background-color: var(--peers-surface-bg);
74
+ }
75
+
76
+ /* Keep Bootstrap's focus and validation borders. */
77
+ [data-bs-theme="light"]
78
+ :where(.form-control, .form-select):where(:not(:focus):not(.is-valid):not(.is-invalid)) {
79
+ border-color: var(--peers-surface-border);
80
+ }
81
+
82
+ [data-bs-theme="light"] .nav-tabs {
83
+ --bs-nav-tabs-link-active-bg: var(--bs-body-bg);
84
+ }
85
+
86
+ /* Custom panels that do not use Bootstrap's component markup. */
87
+ [data-bs-theme="light"] .peers-surface {
88
+ /* The tooltip also uses Bootstrap's bg-light-subtle utility. */
89
+ --bs-light-bg-subtle: var(--peers-surface-bg);
90
+ background-color: var(--peers-surface-bg);
91
+ }
92
+
93
+ [data-bs-theme="light"] .peers-table-surface {
94
+ --bs-table-bg: var(--peers-surface-bg);
95
+ }
96
+
97
+ [data-bs-theme="light"] .peers-tab-strip {
98
+ --bs-border-color: var(--peers-tab-edge);
99
+ background-color: var(--peers-tab-strip-bg);
100
+ color: var(--peers-tab-strip-color);
101
+ }
102
+
103
+ [data-bs-theme="light"] .peers-tab {
104
+ --peers-tab-bg: transparent;
105
+ background-color: var(--peers-tab-bg);
106
+ color: var(--peers-tab-color);
107
+ border-top: 2px solid transparent;
108
+ border-left: 1px solid transparent;
109
+ border-right: 1px solid var(--peers-tab-divider);
110
+ border-bottom: none;
111
+ box-shadow: none;
112
+ }
113
+
114
+ [data-bs-theme="light"] .peers-tab:not(.peers-tab-active):hover {
115
+ --peers-tab-bg: var(--peers-tab-hover-bg);
116
+ }
117
+
118
+ [data-bs-theme="light"] .peers-tab-active {
119
+ --peers-tab-bg: var(--bs-body-bg);
120
+ color: var(--peers-tab-active-color);
121
+ border-top: 2px solid var(--peers-tab-accent);
122
+ border-left-color: var(--peers-tab-edge);
123
+ border-right-color: var(--peers-tab-edge);
124
+ border-bottom: 1px solid var(--bs-body-bg);
125
+ box-shadow: var(--peers-tab-active-shadow);
126
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peers-app/peers-ui",
3
- "version": "0.28.5",
3
+ "version": "0.28.7",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/peers-app/peers-ui.git"
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "scripts": {
22
22
  "clean": "rm -rf dist",
23
- "build": "npm run clean && tsc",
23
+ "build": "npm run clean && tsc && cp src/theme.css dist/theme.css",
24
24
  "dev": "tsc -w",
25
25
  "clean:build": "npm run clean && npm run build",
26
26
  "release:guard": "node release-guard.js",
@@ -36,7 +36,7 @@
36
36
  "lint:fix": "biome check --write ."
37
37
  },
38
38
  "peerDependencies": {
39
- "@peers-app/peers-sdk": "^0.28.5",
39
+ "@peers-app/peers-sdk": "^0.28.7",
40
40
  "bootstrap": "^5.3.3",
41
41
  "react": "^18.0.0",
42
42
  "react-dom": "^18.0.0"
@@ -47,7 +47,7 @@
47
47
  "@babel/preset-react": "^7.24.1",
48
48
  "@babel/preset-typescript": "^7.27.1",
49
49
  "@biomejs/biome": "2.3.11",
50
- "@peers-app/peers-sdk": "0.28.5",
50
+ "@peers-app/peers-sdk": "0.28.7",
51
51
  "@testing-library/dom": "^10.4.0",
52
52
  "@testing-library/jest-dom": "^6.6.3",
53
53
  "@testing-library/react": "^16.3.0",