+
);
diff --git a/packages/ui/src/features/inspect/iframe-theme.ts b/packages/ui/src/features/inspect/iframe-theme.ts
new file mode 100644
index 0000000..b97653c
--- /dev/null
+++ b/packages/ui/src/features/inspect/iframe-theme.ts
@@ -0,0 +1,68 @@
+const STYLE_ID = 'qwik-inspect-custom-style';
+
+const GLASSMORPHISM_CSS = `
+ :root {
+ --c-bg-base: transparent !important;
+ --c-bg-nav: transparent !important;
+ --c-bg-active: transparent !important;
+ --iframe-border: rgba(0, 0, 0, 0.1) !important;
+ --iframe-hover: rgba(0, 0, 0, 0.04) !important;
+ color-scheme: light;
+ }
+ html.dark {
+ --c-bg-base: transparent !important;
+ --c-bg-nav: transparent !important;
+ --c-bg-active: transparent !important;
+ --iframe-border: rgba(255, 255, 255, 0.08) !important;
+ --iframe-hover: rgba(255, 255, 255, 0.06) !important;
+ color-scheme: dark;
+ }
+ /* 仅针对主视图容器做透明处理,不再暴力让所有 div/section 变透明 */
+ html, body, #app, main, header, nav, footer { background-color: transparent !important; }
+ .bg-active, .hover\\\\:bg-active:hover, tr:hover, li:hover,
+ .hover\\\\:bg-gray-400\\\\/10:hover, a:hover { background-color: var(--iframe-hover) !important; }
+ input, button, select, [role="button"] { background-color: var(--iframe-hover) !important; }
+ .border-base, [class*="border-b"], [class*="border-r"],
+ [class*="border-t"], [class*="border-l"], .border { border-color: var(--iframe-border) !important; }
+ html.dark { color: #fafafa !important; }
+ html, body, #app { overflow-x: hidden !important; max-width: 100vw !important; }
+`;
+
+/** 在 iframe onLoad 中调用,同步父主题 + 注入透明背景样式 */
+export function setupIframeThemeSync(iframe: HTMLIFrameElement): void {
+ const doc = iframe.contentDocument;
+ const win = iframe.contentWindow;
+ if (!doc || !win) return;
+
+ const syncTheme = () => {
+ const dark =
+ document.documentElement.classList.contains('dark') ||
+ document.documentElement.getAttribute('data-theme') === 'dark';
+ win.localStorage.setItem('vueuse-color-scheme', dark ? 'dark' : 'light');
+ if (dark) {
+ doc.documentElement.classList.add('dark');
+ } else {
+ doc.documentElement.classList.remove('dark');
+ }
+ };
+
+ const ensureStyle = () => {
+ if (!doc.getElementById(STYLE_ID)) {
+ const s = doc.createElement('style');
+ s.id = STYLE_ID;
+ s.textContent = GLASSMORPHISM_CSS;
+ doc.head.appendChild(s);
+ }
+ };
+
+ syncTheme();
+ ensureStyle();
+
+ const themeObs = new MutationObserver(syncTheme);
+ themeObs.observe(document.documentElement, { attributes: true, attributeFilter: ['class', 'data-theme'] });
+
+ const styleObs = new MutationObserver(ensureStyle);
+ styleObs.observe(doc.body || doc.documentElement, { childList: true, subtree: true });
+
+ doc.defaultView?.addEventListener('unload', () => { themeObs.disconnect(); styleObs.disconnect(); });
+}
diff --git a/packages/ui/src/global.css b/packages/ui/src/global.css
index a5bb30c..63fabe3 100644
--- a/packages/ui/src/global.css
+++ b/packages/ui/src/global.css
@@ -21,104 +21,108 @@
--color-input: #e5e7eb;
--color-ring: #16b6f6;
--color-card: #f2f2f2;
+ --color-glass-border: rgba(255, 255, 255, 0.4);
+ --color-glass-bg: rgba(255, 255, 255, 0.7);
+ --color-glass-shadow: rgba(0, 0, 0, 0.05);
--color-card-item-bg: rgba(0, 0, 0, 0.02);
- --color-card-item-hover-bg: rgba(0, 0, 0, 0.03);
+ --color-card-item-hover-bg: rgba(0, 0, 0, 0.04);
}
:root {
--theme-name: 'light';
- --color-background: #ffffff;
- --color-foreground: #000000;
+ --color-background: #fdfdfd;
+ --color-foreground: #09090b;
--color-primary: #16b6f6;
- --color-primary-hover: #38bdf8; /* sky-400 */
- --color-primary-active: #0ea5e9; /* sky-500 */
- --color-secondary: #6b7280; /* Tailwind's secondary.light */
- --color-border: #e5e7eb;
- --color-card: #f2f2f2;
-
- /* Specific variables based on existing CSS (light theme equivalents) */
+ --color-primary-hover: #38bdf8;
+ --color-primary-active: #0ea5e9;
+ --color-secondary: #71717a;
+ --color-border: #e4e4e7;
+ --color-card: rgba(255, 255, 255, 0.6);
+ --color-card-item-bg: rgba(0, 0, 0, 0.02);
+ --color-card-item-hover-bg: rgba(0, 0, 0, 0.04);
- --color-card-item-bg: rgba(0, 0, 0, 0.02); /* For rgba(255,255,255,0.03) 1 */
- --color-card-item-hover-bg: rgba(
- 0,
- 0,
- 0,
- 0.03
- ); /* For rgba(255,255,255,0.05) 1*/
+ /* Glassmorphism Variables */
+ --color-glass-border: rgba(255, 255, 255, 0.6);
+ --color-glass-bg: rgba(255, 255, 255, 0.85);
+ --color-glass-panel-bg: rgba(250, 250, 250, 0.75);
+ --color-glass-shadow: rgba(0, 0, 0, 0.08);
/* Scrollbar variables */
- --color-scrollbar-thumb: #d1d5db;
- --color-scrollbar-thumb-hover: #a1a1aa;
+ --color-scrollbar-thumb: rgba(161, 161, 170, 0.5);
+ --color-scrollbar-thumb-hover: rgba(113, 113, 122, 0.7);
/* Tailwind semantic variables */
- --color-muted: #9ca3af; /* Similar to existing --color-text-subtle */
- --color-muted-foreground: #6b7280;
- --color-accent: #16b6f6; /* Accent */
- --color-input: var(--color-border); /* Alias to border */
- --color-ring: var(--color-primary); /* Alias to primary */
+ --color-muted: #a1a1aa;
+ --color-muted-foreground: #71717a;
+ --color-accent: #16b6f6;
+ --color-input: var(--color-border);
+ --color-ring: var(--color-primary);
}
-/*
- Please note: The variable definitions here should be kept consistent with the definitions
- in the @media (prefers-color-scheme: dark) block below.
-*/
:root[data-theme='dark'] {
--theme-name: 'dark';
- --color-background: #18181b;
- --color-foreground: #ffffff;
- --color-primary: #16b6f6; /* primary */
- --color-primary-hover: #38bdf8; /* hover */
- --color-primary-active: #0ea5e9; /* active */
- --color-secondary: #9ca3af; /* Tailwind's secondary.dark */
- --color-border: #374151;
- --color-card: #27272a;
-
- /* Specific variables based on existing CSS (dark theme) */
+ --color-background: #09090b;
+ --color-foreground: #fafafa;
+ --color-primary: #16b6f6;
+ --color-primary-hover: #38bdf8;
+ --color-primary-active: #0ea5e9;
+ --color-secondary: #a1a1aa;
+ --color-border: #27272a;
+ --color-card: rgba(24, 24, 27, 0.6);
--color-card-item-bg: rgba(255, 255, 255, 0.03);
- --color-card-item-hover-bg: rgba(255, 255, 255, 0.05);
+ --color-card-item-hover-bg: rgba(255, 255, 255, 0.06);
+
+ /* Glassmorphism Variables */
+ --color-glass-border: rgba(255, 255, 255, 0.08);
+ --color-glass-bg: rgba(9, 9, 11, 0.85);
+ --color-glass-panel-bg: rgba(24, 24, 27, 0.75);
+ --color-glass-shadow: rgba(0, 0, 0, 0.3);
/* Scrollbar variables */
- --color-scrollbar-thumb: #3f3f46;
- --color-scrollbar-thumb-hover: #52525b;
+ --color-scrollbar-thumb: rgba(82, 82, 91, 0.5);
+ --color-scrollbar-thumb-hover: rgba(113, 113, 122, 0.7);
/* Tailwind semantic variables */
- --color-muted: #374151; /* Similar to existing html.dark --color-border */
- --color-muted-foreground: #9ca3af; /* Similar to existing html.dark --color-secondary */
- --color-accent: #16b6f6; /* Accent */
- --color-input: var(--color-border); /* Alias to border */
- --color-ring: var(--color-primary); /* Alias to primary */
+ --color-muted: #27272a;
+ --color-muted-foreground: #a1a1aa;
+ --color-accent: #16b6f6;
+ --color-input: var(--color-border);
+ --color-ring: var(--color-primary);
}
@media (prefers-color-scheme: dark) {
- /*
- Please note: The variable definitions here should be kept consistent with the definitions
- in the :root[data-theme='dark'] block above.
- */
:root:not([data-theme]) {
--theme-name: 'dark';
- --color-background: #18181b;
- --color-foreground: #ffffff;
- --color-primary: #16b6f6; /* primary */
- --color-secondary: #9ca3af; /* Tailwind's secondary.dark */
- --color-border: #374151;
- --color-card: #27272a;
-
- /* Specific variables based on existing CSS (dark theme) */
+ --color-background: #09090b;
+ --color-foreground: #fafafa;
+ --color-primary: #16b6f6;
+ --color-primary-hover: #38bdf8;
+ --color-primary-active: #0ea5e9;
+ --color-secondary: #a1a1aa;
+ --color-border: #27272a;
+ --color-card: rgba(24, 24, 27, 0.6);
--color-card-item-bg: rgba(255, 255, 255, 0.03);
- --color-card-item-hover-bg: rgba(255, 255, 255, 0.05);
+ --color-card-item-hover-bg: rgba(255, 255, 255, 0.06);
+
+ /* Glassmorphism Variables */
+ --color-glass-border: rgba(255, 255, 255, 0.08);
+ --color-glass-bg: rgba(9, 9, 11, 0.85);
+ --color-glass-panel-bg: rgba(24, 24, 27, 0.75);
+ --color-glass-shadow: rgba(0, 0, 0, 0.3);
/* Scrollbar variables */
- --color-scrollbar-thumb: #3f3f46;
- --color-scrollbar-thumb-hover: #52525b;
+ --color-scrollbar-thumb: rgba(82, 82, 91, 0.5);
+ --color-scrollbar-thumb-hover: rgba(113, 113, 122, 0.7);
/* Tailwind semantic variables */
- --color-muted: #374151; /* Similar to existing html.dark --color-border */
- --color-muted-foreground: #9ca3af; /* Similar to existing html.dark --color-secondary */
- --color-accent: #16b6f6; /* Accent */
- --color-input: var(--color-border); /* Alias to border */
- --color-ring: var(--color-primary); /* Alias to primary */
+ --color-muted: #27272a;
+ --color-muted-foreground: #a1a1aa;
+ --color-accent: #16b6f6;
+ --color-input: var(--color-border);
+ --color-ring: var(--color-primary);
}
}
+
@layer utilities {
.custom-scrollbar {
scrollbar-width: thin;
@@ -127,6 +131,7 @@
.custom-scrollbar::-webkit-scrollbar {
width: 6px;
+ height: 6px;
}
.custom-scrollbar::-webkit-scrollbar-track {
@@ -135,10 +140,52 @@
.custom-scrollbar::-webkit-scrollbar-thumb {
background-color: var(--color-scrollbar-thumb);
- border-radius: 20px;
+ border-radius: 9999px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background-color: var(--color-scrollbar-thumb-hover);
}
+
+ .glass-panel {
+ background-color: var(--color-glass-panel-bg);
+ backdrop-filter: blur(24px);
+ -webkit-backdrop-filter: blur(24px);
+ border: 1px solid var(--color-glass-border);
+ box-shadow: 0 8px 32px 0 var(--color-glass-shadow);
+ }
+
+ .glass-button {
+ background-color: var(--color-glass-bg);
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
+ border: 1px solid var(--color-glass-border);
+ box-shadow: 0 4px 16px 0 var(--color-glass-shadow);
+ }
+}
+
+/* Animations */
+@keyframes slideUpFade {
+ from {
+ opacity: 0;
+ transform: translateY(20px) scale(0.98);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0) scale(1);
+ }
+}
+
+@keyframes pulsePulsar {
+ 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(22, 182, 246, 0.7); }
+ 70% { transform: scale(1); box-shadow: 0 0 0 10px rgba(22, 182, 246, 0); }
+ 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(22, 182, 246, 0); }
+}
+
+.animate-slide-up-fade {
+ animation: slideUpFade 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
+}
+
+.animate-pulsar {
+ animation: pulsePulsar 2s infinite;
}
diff --git a/packages/ui/src/utils/type.ts b/packages/ui/src/utils/type.ts
index fe6e54b..fbf8513 100644
--- a/packages/ui/src/utils/type.ts
+++ b/packages/ui/src/utils/type.ts
@@ -2,7 +2,7 @@ export const isListen = (str: string) => {
return /^on.*\$/.test(str);
};
-export const isValue = (value: any) => {
+export const isValue = (value: object): value is { untrackedValue: unknown; value: unknown } => {
try {
return 'untrackedValue' in value && 'value' in value;
} catch {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1b43437..f96e892 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -66,7 +66,7 @@ importers:
specifier: ^4.2.1
version: 4.2.1
vite:
- specifier: 8.0.0
+ specifier: '>=7.0.0 <9.0.0'
version: 8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)
vite-hot-client:
specifier: ^2.1.0
@@ -103,7 +103,7 @@ importers:
specifier: ^2.2.6
version: 2.2.6
vite:
- specifier: 8.0.0
+ specifier: '>=7.0.0 <9.0.0'
version: 8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)
devDependencies:
'@types/eslint':