Skip to content

Commit 81fc66a

Browse files
feat: add functioa (#42)
* feat(ui): integrate devtools plugin and add dark mode support * Add light and dark mode support using Tailwind CSS * Fix ThemeToggle component and update vite.config.mts for server configuration * refactor(ui): remove unused CSS variables and streamline theme configuration Simplify the global CSS and Tailwind configuration by removing unused variables and consolidating theme-related settings. This improves maintainability and reduces redundancy in the codebase. * refactor(vite): remove dev server host and port config * refactor(vite): remove dev server host and port config The host, port, and allowedHosts configurations were removed from the dev server settings to simplify the configuration and rely on Vite's default behavior. This change reduces unnecessary customization and aligns with standard Vite practices. * feat(theme): implement theme switching with persistence - Add theme script for initial theme detection and application - Update global.css with theme variables and dark mode selector - Refactor ThemeToggle component to use localStorage for theme persistence - Modify vite config to handle build-specific alias configuration - Add type definitions path to package.json ``` The commit message follows the guidelines by: 1. Using "feat" type since it introduces new theme functionality 2. Including "(theme)" scope as it's clearly theme-related 3. Keeping description under 50 chars and starting with lowercase 4. Adding a body that summarizes the key changes without repeating the subject 5. Using imperative mood throughout 6. Focusing on the significant functional changes rather than every detail * style(ui): standardize code formatting and fix linting issues - Normalize quotes from single to double quotes - Fix missing semicolons and newlines - Reorder tailwind classes consistently - Remove unused useDark hook - Update theme script to be more reliable - Apply prettier formatting across the codebase * refactor(theme): simplify theme handling and remove unused code - Remove ThemeScript component and inline theme script logic in devtools - Remove unused useDark hook from ThemeToggle - Simplify theme toggle logic by removing dark state check * fix(devtools): remove unused ThemeScript import and fix panel visibility condition - Remove unused ThemeScript import to clean up dependencies - Fix devtools panel visibility to only show when state.isOpen.value is true * style: enforce single quotes in codebase and update prettier config Update all double quotes to single quotes across the codebase for consistency. Added 'singleQuote: true' to prettier configuration to enforce this style. This change improves code style consistency and aligns with the project's linting rules. * refactor(theme): consolidate theme handling and cleanup - Rename theme storage key for compatibility with vite-plugin-inspect - Extract theme script logic into separate component - Remove unused imports and simplify ThemeToggle component - Replace inline script with ThemeScript component in devtools * feat(ThemeToggle): add auto theme option and improve theme handling - Add 'auto' theme option that follows system preference - Replace button with select dropdown for theme selection - Improve theme script to handle auto theme case - Fix extra space in search input styling * formate * feat(ui): add ThemeToggle component with persistent theme selection * fix situation which didn't set default value * chore: update @qwik.dev/core and @qwik.dev/router to beta versions, upgrade rollup to 4.41.1, and update peer dependencies * refactor(ThemeToggle): remove console logs and improve type annotation in useTask * fix * FIX: add animation when icon switching * format * optimize * refactor(Overview): enhance click handling for navigation and improve code structure * init render tree function * layout render interface * delete redundant code, and * feat: enhance Tree component with state management and vnode utilities * feat: refactor Tree and RenderTree components for improved state management and rendering logic * feat: integrate htmlContainer utility for improved DOM handling in RenderTree and filterVnode * refactor: clean up imports and improve code formatting across multiple components * feat: enhance Tree and RenderTree components with improved node handling and rendering logic * feat: improve code consistency and readability across Tree, filterVnode, and RenderTree components * feat: add signal management and enhance button interaction in Button and RenderTree components * feat: enhance Button and Tree components with improved state management, rendering logic, and new signal handling capabilities * feat: update Button and RenderTree components with enhanced click handling, state management, and improved tree node creation logic * feat: enhance Button component with new hooks, context management, and improved styling; update RenderTree and filterVnode for better state handling and type detection * feat: update dependencies to latest versions, including Qwik and Vite; enhance devtools integration in playgrounds and improve code consistency across components * feat: enhance RenderTree and formatTreeData components with improved signal, task, and computed data handling; refactor vnode and filterVnode for better code clarity * feat: add isHover prop to Tree and TreeNode components for enhanced hover state management; refactor formatTreeData to improve data handling and naming consistency * feat: enhance RenderTree and formatTreeData with new props and listen data handling; update type utilities for better type detection * feat: add qwikDevtools plugin and enhance server functions with new module retrieval capabilities; update .gitignore and Vite configuration for improved development experience * feat: update ServerFunctions to include getModulesByPathIds for improved module retrieval; refactor RenderTree and formatTreeData for enhanced data handling and integration with new module fetching logic * refactor: clean up Button component by removing commented code and improving hook usage; streamline context and resource handling for better readability * refactor: streamline node click handling in RenderTree by utilizing a type map for improved data formatting and clarity; enhance props processing for better readability * refactor: remove commented code in RenderTree to improve code clarity and maintainability * refactor: remove commented code in RenderTree to enhance code clarity and maintainability * refactor: simplify RenderTree component by removing unnecessary return statement and optimizing JSX structure for improved readability * feat: integrate Shiki for syntax highlighting in RenderTree component; enhance code rendering with dynamic language detection and improved styling * refactor: optimize data retrieval in formatTreeData by replacing forEach with for...of loop for improved performance and readability * refactor: update RenderTree and formatTreeData to standardize naming conventions and improve tree node creation logic; enhance signal and task handling for better clarity --------- Co-authored-by: openhands <openhands@all-hands.dev>
1 parent 5b65321 commit 81fc66a

File tree

35 files changed

+2018
-402
lines changed

35 files changed

+2018
-402
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,5 @@ testem.log
6262

6363
# System Files
6464
.DS_Store
65-
Thumbs.db
65+
Thumbs.db
66+
.vite-inspect

packages/devtools/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
"README.md"
2222
],
2323
"peerDependencies": {
24-
"vite": "^6.2.6",
25-
"@qwik.dev/core": "^2.0.0-beta.1",
26-
"@qwik.dev/router": "^2.0.0-beta.1"
24+
"vite": "7.0.4",
25+
"@qwik.dev/core": "2.0.0-beta.5",
26+
"@qwik.dev/router": "2.0.0-beta.5"
2727
},
2828
"dependencies": {
2929
"birpc": "^0.2.19",

packages/kit/src/server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export function createServerRpc(functions: ServerFunctions) {
1111
post: (data) =>
1212
server.ws.send(DEVTOOLS_VITE_MESSAGING_EVENT, SuperJSON.stringify(data)),
1313
on: (fn) =>
14-
server.ws.on(DEVTOOLS_VITE_MESSAGING_EVENT, (data) => {
14+
server.ws.on(DEVTOOLS_VITE_MESSAGING_EVENT, (data: any) => {
1515
fn(SuperJSON.parse(data));
1616
}),
1717
timeout: 120_000,

packages/kit/src/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ export interface ServerFunctions {
1616
packageName: string,
1717
isDev?: boolean,
1818
) => Promise<{ success: boolean; error?: string }>;
19+
getModulesByPathIds: (pathIds: string | string[]) => Promise<{
20+
pathId: string;
21+
modules: any;
22+
error?: string;
23+
}[]>;
1924
}
2025

2126
export type ServerRpc = BirpcReturn<ClientFunctions, ServerFunctions>;

packages/playgrounds/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,17 @@
2929
"devDependencies": {
3030
"@devtools/plugin": "workspace:*",
3131
"@devtools/ui": "workspace:*",
32-
"@qwik.dev/core": "^2.0.0-beta.1",
33-
"@qwik.dev/router": "^2.0.0-beta.1",
32+
"@qwik.dev/core": "2.0.0-beta.5",
33+
"@qwik.dev/router": "2.0.0-beta.5",
3434
"@types/eslint": "8.56.10",
3535
"@types/node": "20.14.11",
3636
"@typescript-eslint/eslint-plugin": "7.16.1",
3737
"@typescript-eslint/parser": "7.16.1",
3838
"eslint": "8.57.0",
39-
"eslint-plugin-qwik": "2.0.0-alpha.9",
39+
"eslint-plugin-qwik": "2.0.0-beta.5",
4040
"prettier": "3.3.3",
4141
"typescript": "5.4.5",
42-
"vite": "^6.2.6",
42+
"vite": "7.0.4",
4343
"vite-tsconfig-paths": "^4.2.1"
4444
}
4545
}
Lines changed: 143 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,148 @@
1-
import { component$, useStore } from '@qwik.dev/core';
1+
import {
2+
component$,
3+
useStore,
4+
useSignal,
5+
useTask$,
6+
useComputed$,
7+
$,
8+
useContext,
9+
useContextProvider,
10+
useId,
11+
useOnDocument,
12+
useOnWindow,
13+
useResource$,
14+
useStyles$,
15+
useStylesScoped$,
16+
createContextId,
17+
Resource
18+
} from '@qwik.dev/core';
19+
import { _getDomContainer, isServer, useVisibleTask$ } from '@qwik.dev/core/internal';
20+
import type { QRL } from '@qwik.dev/core';
21+
22+
const ButtonContext = createContextId<{ theme: string; size: string }>('button-context');
23+
24+
interface ButtonProps {
25+
class?: string;
26+
onClick$?: QRL<() => void>;
27+
}
28+
29+
export default component$<ButtonProps>(({ class: className = '', onClick$ }) => {
230

3-
export default component$(() => {
431
const store = useStore({
532
count: 0,
633
});
7-
return <button>Click me {store.count}</button>;
34+
const signal = useSignal('111');
35+
36+
37+
useTask$(({ track }) => {
38+
track(() => store.count);
39+
signal.value = '33333'
40+
})
41+
42+
useVisibleTask$(({ track }) => {
43+
track(() => store.count);
44+
signal.value = '2227'
45+
})
46+
47+
const qwikContainer = useComputed$(() => {
48+
try {
49+
if(isServer){
50+
return null
51+
}
52+
const htmlElement = document.documentElement;
53+
return _getDomContainer(htmlElement);
54+
} catch (error) {
55+
console.error(error);
56+
return null;
57+
}
58+
});
59+
60+
const asyncComputedValue = useComputed$(() => {
61+
return `Async computed: ${store.count}`;
62+
});
63+
64+
useContextProvider(ButtonContext, {
65+
theme: 'primary',
66+
size: 'large'
67+
});
68+
const context = useContext(ButtonContext);
69+
70+
const buttonId = useId();
71+
72+
useOnDocument('keydown', $(() => {
73+
console.log('Document keydown event');
74+
}));
75+
76+
useOnWindow('resize', $(() => {
77+
console.log('Window resized');
78+
}));
79+
80+
const resourceData = useResource$(async ({ track }) => {
81+
track(() => store.count);
82+
await new Promise(resolve => setTimeout(resolve, 200));
83+
return {
84+
message: `Resource data for count: ${store.count}`,
85+
timestamp: Date.now()
86+
};
87+
});
88+
89+
useStyles$(`
90+
.custom-button {
91+
background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
92+
color: white;
93+
border: none;
94+
padding: 10px 20px;
95+
border-radius: 5px;
96+
cursor: pointer;
97+
transition: transform 0.2s;
98+
}
99+
.custom-button:hover {
100+
transform: scale(1.05);
101+
}
102+
`);
103+
104+
useStylesScoped$(`
105+
.scoped-button {
106+
background: linear-gradient(45deg, #667eea, #764ba2);
107+
color: white;
108+
border: none;
109+
padding: 8px 16px;
110+
border-radius: 3px;
111+
cursor: pointer;
112+
}
113+
`);
114+
115+
const handleClick = $(async () => {
116+
store.count++;
117+
console.log('Button clicked! Count:', store.count);
118+
119+
if (onClick$) {
120+
await onClick$();
121+
}
122+
});
123+
124+
return (
125+
<div>
126+
<button
127+
id={buttonId}
128+
class={`${className} custom-button scoped-button`}
129+
onClick$={handleClick}
130+
>
131+
Click me {store.count}{signal.value}{qwikContainer?.value?.qManifestHash}
132+
</button>
133+
134+
<div style="margin-top: 10px; font-size: 12px; color: #666;">
135+
<div>Async Computed: {asyncComputedValue.value}</div>
136+
<div>Context: {context?.theme} - {context?.size}</div>
137+
<div>Button ID: {buttonId}</div>
138+
<Resource
139+
value={resourceData}
140+
onPending={() => <div>Loading resource...</div>}
141+
onResolved={(data) => <div>Resource: {data.message}</div>}
142+
onRejected={(error) => <div>Error: {error.message}</div>}
143+
/>
144+
<div>Count: {store.count}, Signal: {signal.value}</div>
145+
</div>
146+
</div>
147+
);
8148
});

packages/playgrounds/src/routes/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ export default component$(() => {
1818
<div>
1919
<Link href="/blog">Blog</Link>
2020
</div>
21-
<Button />
21+
<Button data-testid="button" class='bg-red-500' onClick$={() => {
22+
console.log('Button clicked! Count:', count.value);
23+
}}/>
2224
</>
2325
);
2426
});

packages/plugin/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"np": "^8.0.4",
4242
"prettier": "3.3.3",
4343
"typescript": "5.4.5",
44-
"vite": "^6.2.6",
44+
"vite": "7.0.4",
4545
"vite-plugin-inspect": "^11.0.0"
4646
}
4747
}

packages/plugin/src/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ const generate = _generate.default;
1414

1515
export function qwikDevtools(): Plugin[] {
1616
let _config: ResolvedConfig;
17+
const qwikData = new Map<string, any>();
1718
const qwikDevtoolsPlugin: Plugin = {
1819
name: 'vite-plugin-qwik-devtools',
1920
apply: 'serve',
2021
configResolved(viteConfig) {
2122
_config = viteConfig;
22-
},
23-
23+
},
2424
transform: {
2525
order: 'pre',
2626
handler(code, id) {
@@ -56,9 +56,9 @@ export function qwikDevtools(): Plugin[] {
5656
},
5757
},
5858
configureServer(server) {
59-
setViteServerContext(server);
59+
setViteServerContext(server as any);
6060

61-
const rpcFunctions = getServerFunctions({ server, config: _config });
61+
const rpcFunctions = getServerFunctions({ server, config: _config, qwikData });
6262

6363
createServerRpc(rpcFunctions);
6464
},

packages/plugin/src/inspect/index.ts

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,41 @@
11
import { ServerContext } from "../types";
22

3-
export function getInspectFunctions(ctx: ServerContext) {
3+
export function getModulesContent(ctx: ServerContext) {
44
return {
5-
getComponentInfo: async (file: string, id: string) => {
6-
return { file, id };
5+
getModulesByPathIds: async (pathIds: string | string[]) => {
6+
let pathIdsList: string[] = [];
7+
8+
let isAddRoot = (pathId: string) => pathId.includes(ctx.config.root) || pathId.includes('/@fs') ? pathId : `${ctx.config.root}${pathId}`
9+
if(!pathIds || pathIds.length === 0){
10+
return []
11+
}
12+
13+
if(Array.isArray(pathIds)){
14+
pathIdsList = pathIds
15+
}else{
16+
pathIdsList = [pathIds]
17+
}
18+
const modules = await Promise.all(pathIdsList.map(async (pathId) => {
19+
try {
20+
const modules = await ctx.server.transformRequest(isAddRoot(pathId));
21+
return {
22+
pathId,
23+
modules
24+
};
25+
} catch (error) {
26+
console.log(`Failed to transform request for ${pathId}:`, error);
27+
return {
28+
pathId,
29+
modules: null,
30+
error: error instanceof Error ? error.message : String(error)
31+
};
32+
}
33+
}));
34+
35+
if (modules.length > 0) {
36+
return modules;
37+
}
38+
return [];
739
},
840
};
941
}

0 commit comments

Comments
 (0)