Skip to content

Commit 4f78e51

Browse files
authored
chore: update Tailwind CSS packages and improve theme toggle functionality in UI (#76)
1 parent 0dc1be6 commit 4f78e51

File tree

13 files changed

+208
-109
lines changed

13 files changed

+208
-109
lines changed

.changeset/rude-tomatoes-deny.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik.dev/devtools': patch
3+
---
4+
5+
chore: update Tailwind CSS packages and improve theme toggle functionality in UI

packages/devtools/package.json

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@
1212
},
1313
"./ui": {
1414
"import": "./dist/ui/index.qwik.mjs",
15-
"require": "./dist/ui/index.qwik.cjs",
16-
"types": "./dist/ui/lib-types/ui/src/index.d.ts"
15+
"types": "./dist/ui/lib-types/ui/src/index.d.ts",
16+
"style": "./dist/ui/style.css"
17+
18+
},
19+
"./style": {
20+
"import": "./dist/ui/theme.css"
1721
}
1822
},
1923
"files": [
@@ -23,7 +27,10 @@
2327
"peerDependencies": {
2428
"@qwik.dev/core": "2.0.0-beta.11",
2529
"@qwik.dev/router": "2.0.0-beta.11",
26-
"vite": "7.1.3"
30+
"vite": "7.1.3",
31+
"@tailwindcss/postcss": "^4.1.14",
32+
"@tailwindcss/vite": "^4.1.14",
33+
"tailwindcss": "^4.1.14"
2734
},
2835
"dependencies": {
2936
"@qwikest/icons": "^0.0.13",
@@ -59,4 +66,4 @@
5966
"url": "https://github.com/QwikDev/devtools/issues"
6067
},
6168
"homepage": "https://github.com/QwikDev/devtools#readme"
62-
}
69+
}

packages/playgrounds/src/root.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
} from '@qwik.dev/router';
88
import { RouterHead } from './components/router-head/router-head';
99
import './global.css';
10-
10+
import '../../devtools/dist/ui/style.css';
1111
export default component$(() => {
1212
/**
1313
* The root of a QwikRouter site always start with the <QwikRouterProvider> component,

packages/plugin/src/npm/index.ts

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,35 @@ function setCachedPackage(name: string, data: any): void {
3434
});
3535
}
3636

37+
async function findNearestFileUp(startDir: string, fileName: string): Promise<string | null> {
38+
try {
39+
let currentDir = path.resolve(startDir);
40+
// Guard against infinite loops by capping directory ascents
41+
for (let i = 0; i < 100; i++) {
42+
const candidate = path.join(currentDir, fileName);
43+
const exists = await fsp
44+
.access(candidate)
45+
.then(() => true)
46+
.catch(() => false);
47+
if (exists) return candidate;
48+
49+
const parent = path.dirname(currentDir);
50+
if (parent === currentDir) break;
51+
currentDir = parent;
52+
}
53+
return null;
54+
} catch {
55+
return null;
56+
}
57+
}
58+
59+
function getProjectStartDirFromConfig(config: any): string {
60+
// Prefer Vite's resolved root; fallback to the directory of the config file; finally cwd
61+
if (config?.root) return config.root;
62+
if (config?.configFile) return path.dirname(config.configFile);
63+
return process.cwd();
64+
}
65+
3766
export async function detectPackageManager(
3867
projectRoot: string,
3968
): Promise<'npm' | 'pnpm' | 'yarn'> {
@@ -84,9 +113,8 @@ const preloadDependencies = async (config: any): Promise<any[]> => {
84113
console.log('[Qwik DevTools] Starting to preload dependencies...');
85114

86115
preloadPromise = (async () => {
87-
const pathToPackageJson = config.configFileDependencies.find(
88-
(file: string) => file.endsWith('package.json'),
89-
);
116+
const startDir = getProjectStartDirFromConfig(config);
117+
const pathToPackageJson = await findNearestFileUp(startDir, 'package.json');
90118

91119
if (!pathToPackageJson) {
92120
preloadedDependencies = [];
@@ -259,9 +287,8 @@ export async function startPreloading({ config }: { config: any }) {
259287
export function getNpmFunctions({ config }: ServerContext) {
260288
return {
261289
async getQwikPackages(): Promise<NpmInfo> {
262-
const pathToPackageJson = config.configFileDependencies.find(
263-
(file: string) => file.endsWith('package.json'),
264-
);
290+
const startDir = getProjectStartDirFromConfig(config);
291+
const pathToPackageJson = await findNearestFileUp(startDir, 'package.json');
265292
if (!pathToPackageJson) return [];
266293

267294
try {
@@ -298,7 +325,9 @@ export function getNpmFunctions({ config }: ServerContext) {
298325
isDev = true,
299326
): Promise<{ success: boolean; error?: string }> {
300327
try {
301-
const projectRoot = path.dirname(config.configFileDependencies[0]);
328+
const startDir = getProjectStartDirFromConfig(config);
329+
const pathToPackageJson = await findNearestFileUp(startDir, 'package.json');
330+
const projectRoot = pathToPackageJson ? path.dirname(pathToPackageJson) : startDir;
302331
const pm = await detectPackageManager(projectRoot);
303332
const devFlag = isDev ? (pm === 'npm' ? '--save-dev' : '-D') : '';
304333

packages/ui/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,14 @@
3434
},
3535
"peerDependencies": {
3636
"@devtools/plugin": "workspace:*",
37-
"@qwik.dev/core": "2.0.0-beta.11"
37+
"@qwik.dev/core": "2.0.0-beta.11",
38+
"@tailwindcss/postcss": "^4.1.14",
39+
"@tailwindcss/vite": "^4.1.14",
40+
"tailwindcss": "^4.1.14"
3841
},
3942
"devDependencies": {
4043
"@devtools/kit": "workspace:*",
4144
"@qwikest/icons": "^0.0.13",
42-
"@tailwindcss/postcss": "^4.0.0",
43-
"@tailwindcss/vite": "^4.0.0",
4445
"@types/eslint": "8.56.10",
4546
"@types/node": "20.14.11",
4647
"@types/react": "^18.2.28",
@@ -63,7 +64,6 @@
6364
"react-dom": "18.2.0",
6465
"shiki": "^3.8.1",
6566
"superjson": "^2.2.2",
66-
"tailwindcss": "^4.0.0",
6767
"typescript": "5.4.5",
6868
"vite": "7.1.3",
6969
"vite-hot-client": "2.0.4",

packages/ui/src/components/DevtoolsContainer/DevtoolsContainer.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import { component$, Slot } from '@qwik.dev/core';
22

33
export const DevtoolsContainer = component$(() => {
44
return (
5-
<div class="fixed bottom-0 right-0 z-[9999] font-sans" q:slot="content">
6-
<Slot />
5+
<div class="qwik-devtools">
6+
<div class="fixed bottom-0 right-0 z-[9999] font-sans" q:slot="content">
7+
<Slot />
8+
</div>
79
</div>
810
);
911
});

packages/ui/src/components/ThemeToggle/ThemeToggle.tsx renamed to packages/ui/src/components/ThemeToggle/QwikThemeToggle.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export const setTheme = (theme: ThemeName) => {
2929
localStorage.setItem(themeStorageKey, theme);
3030
};
3131

32-
export const ThemeToggle = component$(() => {
32+
export const QwikThemeToggle = component$(() => {
3333
useStyles$(themeTogglecss);
3434
const onClick$ = event$(() => {
3535
let currentTheme = getTheme();

packages/ui/src/devtools.tsx

Lines changed: 83 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import { DevtoolsContainer } from './components/DevtoolsContainer/DevtoolsContai
3838
import { DevtoolsPanel } from './components/DevtoolsPanel/DevtoolsPanel';
3939
import { Packages } from './features/Packages/Packages';
4040
import { Inspect } from './features/inspect/Inspect';
41-
import { ThemeToggle } from './components/ThemeToggle/ThemeToggle';
41+
import { QwikThemeToggle } from './components/ThemeToggle/QwikThemeToggle';
4242
import { ThemeScript as QwikThemeScript } from './components/ThemeToggle/theme-script';
4343
import { CodeBreack } from './features/CodeBreack/CodeBreack';
4444
function getClientRpcFunctions() {
@@ -60,66 +60,97 @@ export const QwikDevtools = component$(() => {
6060
isLoadingDependencies: false,
6161
});
6262

63-
useVisibleTask$(async ({ track }) => {
64-
const hot = await tryCreateHotContext(undefined, ['/']);
63+
const clientReady = useSignal(false);
6564

65+
useVisibleTask$(async () => {
66+
const hot = await tryCreateHotContext(undefined, ['/']);
6667
if (!hot) {
6768
throw new Error('Vite Hot Context not connected');
6869
}
6970

7071
setViteClientContext(hot);
7172
createClientRpc(getClientRpcFunctions());
73+
clientReady.value = true;
74+
});
7275

73-
// Start loading data immediately in background
74-
// Dependencies are already being preloaded on the server side
76+
useVisibleTask$(async ({ track }) => {
77+
track(() => clientReady.value);
78+
if (!clientReady.value) return;
7579
const rpc = getViteClientRpc();
76-
state.isLoadingDependencies = true;
80+
try {
81+
const assets = await rpc.getAssetsFromPublicDir();
82+
state.assets = assets;
83+
} catch (error) {
84+
console.error('Failed to load assets:', error);
85+
}
86+
});
7787

78-
// Preload all data in parallel immediately
79-
Promise.all([
80-
rpc.getAssetsFromPublicDir(),
81-
rpc.getComponents(),
82-
rpc.getRoutes(),
83-
rpc.getQwikPackages(),
84-
rpc.getAllDependencies(), // This returns server-preloaded data instantly
85-
])
86-
.then(([assets, components, routes, qwikPackages, allDeps]) => {
87-
state.assets = assets;
88-
state.components = components;
89-
90-
const children: RoutesInfo[] = routes?.children || [];
91-
const directories: RoutesInfo[] = children.filter(
92-
(child) => child.type === 'directory',
93-
);
94-
95-
const values: RoutesInfo[] = [
96-
{
97-
relativePath: '',
98-
name: 'index',
99-
type: RouteType.DIRECTORY,
100-
path: '',
101-
isSymbolicLink: false,
102-
children: undefined,
103-
},
104-
...directories,
105-
];
106-
107-
state.routes = noSerialize(values);
108-
state.npmPackages = qwikPackages;
109-
state.allDependencies = allDeps;
110-
state.isLoadingDependencies = false;
111-
})
112-
.catch((error) => {
113-
console.error('Failed to load devtools data:', error);
114-
state.isLoadingDependencies = false;
115-
});
116-
117-
// Track devtools open state for other purposes if needed
118-
track(() => {
119-
if (state.isOpen.value) {
120-
// Devtools is now open, data should already be loaded or loading
121-
}
122-
});
88+
useVisibleTask$(async ({ track }) => {
89+
track(() => clientReady.value);
90+
if (!clientReady.value) return;
91+
const rpc = getViteClientRpc();
92+
try {
93+
const components = await rpc.getComponents();
94+
state.components = components;
95+
} catch (error) {
96+
console.error('Failed to load components:', error);
97+
}
98+
});
99+
100+
useVisibleTask$(async ({ track }) => {
101+
track(() => clientReady.value);
102+
if (!clientReady.value) return;
103+
const rpc = getViteClientRpc();
104+
try {
105+
const routes = await rpc.getRoutes();
106+
const children: RoutesInfo[] = routes?.children || [];
107+
const directories: RoutesInfo[] = children.filter(
108+
(child) => child.type === 'directory',
109+
);
110+
111+
const values: RoutesInfo[] = [
112+
{
113+
relativePath: '',
114+
name: 'index',
115+
type: RouteType.DIRECTORY,
116+
path: '',
117+
isSymbolicLink: false,
118+
children: undefined,
119+
},
120+
...directories,
121+
];
122+
123+
state.routes = noSerialize(values);
124+
} catch (error) {
125+
console.error('Failed to load routes:', error);
126+
}
127+
});
128+
129+
useVisibleTask$(async ({ track }) => {
130+
track(() => clientReady.value);
131+
if (!clientReady.value) return;
132+
const rpc = getViteClientRpc();
133+
try {
134+
const qwikPackages = await rpc.getQwikPackages();
135+
state.npmPackages = qwikPackages;
136+
} catch (error) {
137+
console.error('Failed to load Qwik packages:', error);
138+
}
139+
});
140+
141+
useVisibleTask$(async ({ track }) => {
142+
track(() => clientReady.value);
143+
if (!clientReady.value) return;
144+
const rpc = getViteClientRpc();
145+
state.isLoadingDependencies = true;
146+
try {
147+
const allDeps = await rpc.getAllDependencies();
148+
state.allDependencies = allDeps;
149+
} catch (error) {
150+
console.error('Failed to load all dependencies:', error);
151+
} finally {
152+
state.isLoadingDependencies = false;
153+
}
123154
});
124155

125156
return (
@@ -153,7 +184,7 @@ export const QwikDevtools = component$(() => {
153184
< HiCodeBracketSolid class="h-5 w-5" />
154185
</Tab>
155186
<div class="mt-auto">
156-
<ThemeToggle />
187+
<QwikThemeToggle />
157188
</div>
158189
</div>
159190

0 commit comments

Comments
 (0)