diff --git a/.eslintignore b/.eslintignore index 13a9f338ddb..d42b6783443 100644 --- a/.eslintignore +++ b/.eslintignore @@ -21,4 +21,5 @@ packages/docs/src/routes/examples/apps/**/* packages/docs/src/routes/playground/app/**/* packages/docs/src/routes/tutorial/**/* starters/apps/base +starters/apps/library vite.config.ts diff --git a/package.json b/package.json index 4fc7f7f6c90..73b57e6ece2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "qwik-monorepo", - "version": "0.0.113", + "version": "0.9.0", "scripts": { "build": "tsm scripts/index.ts --tsc --build --qwikcity --api --platform-binding-wasm-copy", "build.full": "tsm scripts/index.ts --tsc --build --api --eslint --qwikcity --qwikreact --cli --platform-binding --wasm", diff --git a/packages/create-qwik/create-app.ts b/packages/create-qwik/create-app.ts index 52e5edfa440..992870aa66a 100644 --- a/packages/create-qwik/create-app.ts +++ b/packages/create-qwik/create-app.ts @@ -92,29 +92,41 @@ export async function createApp(opts: CreateAppOptions) { }; const starterApps = (await loadIntegrations()).filter((i) => i.type === 'app'); - const baseApp = starterApps.find((a) => a.id === 'base'); - const starterApp = starterApps.find((s) => s.id === opts.starterId); - if (!baseApp) { - throw new Error(`Unable to find base app`); - } - if (!starterApp) { - throw new Error(`Invalid starter id "${opts.starterId}"`); - } - - await createFromStarter(result, baseApp, starterApp); + const isLibrary = opts.starterId === 'library'; + if (isLibrary) { + const baseApp = starterApps.find((a) => a.id === 'library'); + if (!baseApp) { + throw new Error(`Unable to find base app`); + } + await createFromStarter(result, baseApp); + } else { + const baseApp = starterApps.find((a) => a.id === 'base'); + if (!baseApp) { + throw new Error(`Unable to find base app`); + } + const starterApp = starterApps.find((s) => s.id === opts.starterId); + if (!starterApp) { + throw new Error(`Invalid starter id "${opts.starterId}"`); + } + await createFromStarter(result, baseApp, starterApp); + } return result; } async function createFromStarter( result: CreateAppResult, baseApp: IntegrationData, - starterApp: IntegrationData + starterApp?: IntegrationData ) { + const appInfo = starterApp ?? baseApp; const appPkgJson = cleanPackageJson({ - name: `my-${starterApp.pkgJson.name}`, - description: starterApp.pkgJson.description, - private: true, + ...baseApp.pkgJson, + name: `my-${appInfo.pkgJson.name}`, + description: appInfo.pkgJson.description, + scripts: undefined, + dependencies: undefined, + devDependencies: undefined, }); await writePackageJson(result.outDir, appPkgJson); @@ -128,12 +140,14 @@ async function createFromStarter( }); await baseUpdate.commit(false); - const starterUpdate = await updateApp({ - rootDir: result.outDir, - integration: starterApp.id, - installDeps: false, - }); - await starterUpdate.commit(false); + if (starterApp) { + const starterUpdate = await updateApp({ + rootDir: result.outDir, + integration: starterApp.id, + installDeps: false, + }); + await starterUpdate.commit(false); + } } function isValidOption(value: any) { diff --git a/packages/create-qwik/create-interactive.ts b/packages/create-qwik/create-interactive.ts index e7464d5ac5c..bc6234b2694 100644 --- a/packages/create-qwik/create-interactive.ts +++ b/packages/create-qwik/create-interactive.ts @@ -145,9 +145,9 @@ export async function runCreateInteractiveCli() { function checkNodeVersion() { const version = process.version; const majorVersion = Number(version.replace('v', '').split('.')[0]); - if (majorVersion < 15) { + if (majorVersion < 16) { console.error( - color.red(`Qwik requires Node.js 15 or higher. You are currently running Node.js ${version}.`) + color.red(`Qwik requires Node.js 16 or higher. You are currently running Node.js ${version}.`) ); process.exit(1); } diff --git a/packages/create-qwik/package.json b/packages/create-qwik/package.json index 4a9cb05d571..a212601814e 100644 --- a/packages/create-qwik/package.json +++ b/packages/create-qwik/package.json @@ -1,6 +1,6 @@ { "name": "create-qwik", - "version": "0.0.113", + "version": "0.9.0", "description": "Interactive CLI for create Qwik projects and adding features.", "bin": "./create-qwik.cjs", "main": "./index.cjs", diff --git a/packages/eslint-plugin-qwik/package.json b/packages/eslint-plugin-qwik/package.json index 72812098925..8c2d324d103 100644 --- a/packages/eslint-plugin-qwik/package.json +++ b/packages/eslint-plugin-qwik/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-qwik", - "version": "0.0.113", + "version": "0.9.0", "description": "An Open-Source sub-framework designed with a focus on server-side-rendering, lazy-loading, and styling/animation.", "main": "index.js", "author": "Builder Team", diff --git a/packages/qwik-react/package.json b/packages/qwik-react/package.json index b57e0e9242f..a830e3161df 100644 --- a/packages/qwik-react/package.json +++ b/packages/qwik-react/package.json @@ -1,6 +1,6 @@ { "name": "@builder.io/qwik-react", - "version": "0.0.100", + "version": "0.0.102", "description": "QwikReact allows to apply inject React component into existing Qwik application", "scripts": { "build": "npm run build.lib", diff --git a/packages/qwik-react/src/server/index.ts b/packages/qwik-react/src/server/index.ts index 1dff6d8c33f..935539a0d9e 100644 --- a/packages/qwik-react/src/server/index.ts +++ b/packages/qwik-react/src/server/index.ts @@ -34,13 +34,16 @@ export async function renderToStream( const result = await renderToString(rootNode, opts); opts.stream.write(result.html); return { - ...result, - flushes: -1, - size: -1, + prefetchResources: result.prefetchResources, + snapshotResult: result.snapshotResult, + _symbols: result._symbols, + manifest: result.manifest, + flushes: 1, + size: result.html.length, timing: { - firstFlush: -1, - render: -1, - snapshot: -1, + firstFlush: result.timing.render, + render: result.timing.render, + snapshot: result.timing.snapshot, }, }; } diff --git a/packages/qwik/package.json b/packages/qwik/package.json index 31dbf780142..04a693c155f 100644 --- a/packages/qwik/package.json +++ b/packages/qwik/package.json @@ -1,6 +1,6 @@ { "name": "@builder.io/qwik", - "version": "0.0.113", + "version": "0.9.0", "description": "An Open-Source sub-framework designed with a focus on server-side-rendering, lazy-loading, and styling/animation.", "main": "./dist/core.cjs", "types": "./dist/core.d.ts", diff --git a/packages/qwik/src/cli/build/run-build-command.ts b/packages/qwik/src/cli/build/run-build-command.ts index 9f117da3be1..e56a94908e6 100644 --- a/packages/qwik/src/cli/build/run-build-command.ts +++ b/packages/qwik/src/cli/build/run-build-command.ts @@ -11,23 +11,26 @@ export async function runBuildCommand(app: AppCommand) { } const isPreviewBuild = app.args.includes('preview'); - + const buildLibScript = pkgJsonScripts['build.lib']; + const isLibraryBuild = !!buildLibScript; const buildClientScript = pkgJsonScripts['build.client']; const buildPreviewScript = isPreviewBuild ? pkgJsonScripts['build.preview'] : undefined; const buildServerScript = !isPreviewBuild ? pkgJsonScripts['build.server'] : undefined; const buildStaticScript = pkgJsonScripts['build.static']; const runSsgScript = pkgJsonScripts['ssg']; - const typecheckScript = !isPreviewBuild ? pkgJsonScripts.typecheck : undefined; + const buildTypes = !isPreviewBuild ? pkgJsonScripts['build.types'] : undefined; const scripts = [ - typecheckScript, + buildTypes, buildClientScript, + buildLibScript, buildPreviewScript, buildServerScript, buildStaticScript, ].filter((s) => typeof s === 'string' && s.trim().length > 0)!; - if (!buildClientScript) { + if (!isLibraryBuild && !buildClientScript) { + console.log(pkgJsonScripts); throw new Error(`"build.client" script not found in package.json`); } @@ -45,8 +48,8 @@ export async function runBuildCommand(app: AppCommand) { let typecheck: Promise> | null = null; - if (typecheckScript && typecheckScript.startsWith('tsc')) { - const tscScript = parseScript(typecheckScript); + if (buildTypes && buildTypes.startsWith('tsc')) { + const tscScript = parseScript(buildTypes); if (!tscScript.flags.includes('--pretty')) { // ensures colors flow throw when we console log the stdout tscScript.flags.push('--pretty'); @@ -63,19 +66,41 @@ export async function runBuildCommand(app: AppCommand) { }); } - const clientScript = parseScript(buildClientScript); - await execa(clientScript.cmd, clientScript.flags, { - stdio: 'inherit', - cwd: app.rootDir, - }).catch(() => { - process.exit(1); - }); + if (buildClientScript) { + const clientScript = parseScript(buildClientScript); + await execa(clientScript.cmd, clientScript.flags, { + stdio: 'inherit', + cwd: app.rootDir, + }).catch(() => { + process.exit(1); + }); - console.log(``); - console.log(`${color.cyan('✓')} Built client modules`); + console.log(``); + console.log(`${color.cyan('✓')} Built client modules`); + } const step2: Promise>[] = []; + if (buildLibScript) { + const libScript = parseScript(buildLibScript); + const libBuild = execa(libScript.cmd, libScript.flags, { + cwd: app.rootDir, + env: { + FORCE_COLOR: 'true', + }, + }).catch((e) => { + console.log(``); + if (e.stderr) { + console.log(e.stderr); + } else { + console.log(e.stdout); + } + console.log(``); + process.exit(1); + }); + step2.push(libBuild); + } + if (buildPreviewScript) { const previewScript = parseScript(buildPreviewScript); const previewBuild = execa(previewScript.cmd, previewScript.flags, { @@ -142,6 +167,9 @@ export async function runBuildCommand(app: AppCommand) { if (step2.length > 0) { await Promise.all(step2).then(() => { + if (buildLibScript) { + console.log(`${color.cyan('✓')} Built library modules`); + } if (buildPreviewScript) { console.log(`${color.cyan('✓')} Built preview (ssr) modules`); } @@ -155,7 +183,7 @@ export async function runBuildCommand(app: AppCommand) { console.log(`${color.cyan('✓')} Type checked`); } - if (!isPreviewBuild && !buildServerScript && !buildStaticScript) { + if (!isPreviewBuild && !buildServerScript && !buildStaticScript && !isLibraryBuild) { const pmRun = pmRunCmd() console.log(``); console.log(`${color.bgMagenta(' Missing an integration ')}`); diff --git a/packages/qwik/src/cli/types.ts b/packages/qwik/src/cli/types.ts index 6dbefa4328f..edbe043de66 100644 --- a/packages/qwik/src/cli/types.ts +++ b/packages/qwik/src/cli/types.ts @@ -59,6 +59,13 @@ export interface IntegrationPackageJson { devDependencies?: { [k: string]: string }; engines?: { node: string }; private?: boolean; + files?: string[]; + main?: string; + exports?: any; + module?: string; + qwik?: string; + types?: string; + type?: string; __qwik__?: { priority: number; viteConfig?: ViteConfigUpdates; diff --git a/packages/qwik/src/cli/utils/utils.ts b/packages/qwik/src/cli/utils/utils.ts index 1bcfa15f702..258b61ac8d9 100644 --- a/packages/qwik/src/cli/utils/utils.ts +++ b/packages/qwik/src/cli/utils/utils.ts @@ -25,6 +25,12 @@ export function cleanPackageJson(srcPkg: IntegrationPackageJson) { scripts: srcPkg.scripts, dependencies: srcPkg.dependencies, devDependencies: srcPkg.devDependencies, + main: srcPkg.main, + qwik: srcPkg.qwik, + module: srcPkg.module, + types: srcPkg.types, + exports: srcPkg.exports, + files: srcPkg.files, engines: { node: '>=15.0.0' }, }; diff --git a/packages/qwik/src/core/import/qrl-class.ts b/packages/qwik/src/core/import/qrl-class.ts index a92aae5bc4a..312447df63b 100644 --- a/packages/qwik/src/core/import/qrl-class.ts +++ b/packages/qwik/src/core/import/qrl-class.ts @@ -166,7 +166,7 @@ export function assertQrl(qrl: QRL): asserts qrl is QRLInternal { } export const emitUsedSymbol = (symbol: string, element: Element | undefined) => { - if (!qTest && !isServer()) { + if (!qTest && !isServer() && typeof document === 'object') { document.dispatchEvent( new CustomEvent('qsymbol', { bubbles: false, diff --git a/starters/apps/base/.eslintignore b/starters/apps/base/.eslintignore index b183822b65d..039dbd26a06 100644 --- a/starters/apps/base/.eslintignore +++ b/starters/apps/base/.eslintignore @@ -12,6 +12,7 @@ bazel-testlogs dist dist-dev lib +lib-types etc external node_modules diff --git a/starters/apps/base/gitignore b/starters/apps/base/gitignore index 3ae96920d16..e95b829f189 100644 --- a/starters/apps/base/gitignore +++ b/starters/apps/base/gitignore @@ -1,6 +1,7 @@ # Build /dist /lib +/lib-types /server # Development diff --git a/starters/apps/base/package.json b/starters/apps/base/package.json index 88f223e0573..108abd05445 100644 --- a/starters/apps/base/package.json +++ b/starters/apps/base/package.json @@ -4,6 +4,7 @@ "build": "qwik build", "build.client": "vite build", "build.preview": "vite build --ssr src/entry.preview.tsx", + "build.types": "tsc --incremental --noEmit", "dev": "vite --mode ssr", "dev.debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force", "fmt": "prettier --write .", @@ -11,7 +12,6 @@ "lint": "eslint \"src/**/*.ts*\"", "preview": "qwik build preview && vite preview --open", "start": "vite --open --mode ssr", - "typecheck": "tsc --incremental --noEmit", "qwik": "qwik" }, "devDependencies": { diff --git a/starters/apps/library/.eslintignore b/starters/apps/library/.eslintignore new file mode 100644 index 00000000000..039dbd26a06 --- /dev/null +++ b/starters/apps/library/.eslintignore @@ -0,0 +1,31 @@ +**/*.log +**/.DS_Store +*. +.vscode/settings.json +.history +.yarn +bazel-* +bazel-bin +bazel-out +bazel-qwik +bazel-testlogs +dist +dist-dev +lib +lib-types +etc +external +node_modules +temp +tsc-out +tsdoc-metadata.json +target +output +rollup.config.js +build +.cache +.vscode +.rollup.cache +dist +tsconfig.tsbuildinfo +vite.config.ts diff --git a/starters/apps/library/.eslintrc.cjs b/starters/apps/library/.eslintrc.cjs new file mode 100644 index 00000000000..c31c7a947c3 --- /dev/null +++ b/starters/apps/library/.eslintrc.cjs @@ -0,0 +1,40 @@ +module.exports = { + root: true, + env: { + browser: true, + es2021: true, + node: true, + }, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:qwik/recommended', + ], + parser: '@typescript-eslint/parser', + parserOptions: { + tsconfigRootDir: __dirname, + project: ['./tsconfig.json'], + ecmaVersion: 2021, + sourceType: 'module', + ecmaFeatures: { + jsx: true, + }, + }, + plugins: ['@typescript-eslint'], + rules: { + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-inferrable-types': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-empty-interface': 'off', + '@typescript-eslint/no-namespace': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/no-this-alias': 'off', + '@typescript-eslint/ban-types': 'off', + '@typescript-eslint/ban-ts-comment': 'off', + 'prefer-spread': 'off', + 'no-case-declarations': 'off', + 'no-console': 'off', + '@typescript-eslint/no-unused-vars': ['error'], + }, +}; diff --git a/starters/apps/library/.prettierignore b/starters/apps/library/.prettierignore new file mode 100644 index 00000000000..15922481865 --- /dev/null +++ b/starters/apps/library/.prettierignore @@ -0,0 +1,6 @@ +# Files Prettier should not format +**/*.log +**/.DS_Store +*. +dist +node_modules diff --git a/starters/apps/library/README.md b/starters/apps/library/README.md new file mode 100644 index 00000000000..251b4ab2f42 --- /dev/null +++ b/starters/apps/library/README.md @@ -0,0 +1,47 @@ +# Qwik Library ⚡️ + +- [Qwik Docs](https://qwik.builder.io/) +- [Discord](https://qwik.builder.io/chat) +- [Qwik Github](https://github.com/BuilderIO/qwik) +- [@QwikDev](https://twitter.com/QwikDev) +- [Vite](https://vitejs.dev/) +- [Partytown](https://partytown.builder.io/) +- [Mitosis](https://github.com/BuilderIO/mitosis) +- [Builder.io](https://www.builder.io/) + +--- + +## Project Structure + +Inside of you project, you'll see the following directories and files: + +``` +├── public/ +│ └── ... +└── src/ + ├── components/ + │ └── ... + └── index.ts +``` + +- `src/components`: Recommended directory for components. + +- `index.ts`: This is the entry point of your component library, make sure all the public components are exported from this file. + +## Development + +Development mode uses [Vite's development server](https://vitejs.dev/). For Qwik during development, the `dev` command will also server-side render (SSR) the output. The client-side development modules loaded by the browser. + +``` +npm run dev +``` + +> Note: during dev mode, Vite will request many JS files, which does not represent a Qwik production build. + +## Production + +The production build should generate the production build of your component library in (./lib) and the typescript type definitions in (./lib-types). + +``` +npm run build +``` diff --git a/starters/apps/library/gitignore b/starters/apps/library/gitignore new file mode 100644 index 00000000000..e95b829f189 --- /dev/null +++ b/starters/apps/library/gitignore @@ -0,0 +1,38 @@ +# Build +/dist +/lib +/lib-types +/server + +# Development +node_modules + +# Cache +.cache +.mf +.vscode +.rollup.cache +tsconfig.tsbuildinfo + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +# Editor +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# Yarn +.yarn/* +!.yarn/releases diff --git a/starters/apps/library/package.json b/starters/apps/library/package.json index 13af81671fa..50537eff4b2 100644 --- a/starters/apps/library/package.json +++ b/starters/apps/library/package.json @@ -1,12 +1,12 @@ { - "name": "qwik-library-starter", + "name": "qwik-library-name", "description": "Create a component library", "version": "0.0.1", "private": false, "main": "./lib/index.qwik.cjs", "qwik": "./lib/index.qwik.mjs", "module": "./lib/index.qwik.mjs", - "types": "./lib/types/index.d.ts", + "types": "./lib-types/index.d.ts", "type": "module", "exports": { ".": { @@ -15,16 +15,35 @@ } }, "files": [ - "lib" + "lib", + "lib-types" ], "scripts": { - "build": "npm run build.lib && npm run build.types", + "build": "qwik build", "build.lib": "vite build --mode lib", "build.types": "tsc --emitDeclarationOnly", + "dev": "vite --mode ssr", + "dev.debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force", + "fmt": "prettier --write .", + "fmt.check": "prettier --check .", + "lint": "eslint \"src/**/*.ts*\"", + "start": "vite --open --mode ssr", + "qwik": "qwik", "release": "np" }, "devDependencies": { - "np": "7.6.1" + "@builder.io/qwik": "latest", + "@types/eslint": "8.4.1", + "@types/node": "latest", + "@typescript-eslint/eslint-plugin": "5.14.0", + "@typescript-eslint/parser": "5.14.0", + "eslint-plugin-qwik": "latest", + "eslint": "8.12.0", + "node-fetch": "latest", + "np": "7.6.1", + "prettier": "latest", + "typescript": "latest", + "vite": "latest" }, "__qwik__": { "priority": -1 diff --git a/starters/apps/library/src/entry.dev.tsx b/starters/apps/library/src/entry.dev.tsx new file mode 100644 index 00000000000..14352ced592 --- /dev/null +++ b/starters/apps/library/src/entry.dev.tsx @@ -0,0 +1,17 @@ +/* + * WHAT IS THIS FILE? + * + * Development entry point using only client-side modules: + * - Do not use this mode in production! + * - No SSR + * - No portion of the application is pre-rendered on the server. + * - All of the application is running eagerly in the browser. + * - More code is transferred to the browser than in SSR mode. + * - Optimizer/Serialization/Deserialization code is not exercised! + */ +import { render, RenderOptions } from '@builder.io/qwik'; +import Root from './root'; + +export default function (opts: RenderOptions) { + return render(document, , opts); +} diff --git a/starters/apps/library/src/entry.ssr.tsx b/starters/apps/library/src/entry.ssr.tsx new file mode 100644 index 00000000000..532f40868d9 --- /dev/null +++ b/starters/apps/library/src/entry.ssr.tsx @@ -0,0 +1,29 @@ +/** + * WHAT IS THIS FILE? + * + * SSR entry point, in all cases the application is render outside the browser, this + * entry point will be the common one. + * + * - Server (express, cloudflare...) + * - npm run start + * - npm run preview + * - npm run build + * + */ +import { renderToStream, RenderToStreamOptions } from '@builder.io/qwik/server'; +import { manifest } from '@qwik-client-manifest'; +import Root from './root'; + +export default function (opts: RenderToStreamOptions) { + return renderToStream(, { + manifest, + ...opts, + prefetchStrategy: { + implementation: { + linkInsert: null, + workerFetchInsert: null, + prefetchEvent: 'always', + }, + }, + }); +} diff --git a/starters/apps/library/src/root.tsx b/starters/apps/library/src/root.tsx index 91e0fc46434..55a91665010 100644 --- a/starters/apps/library/src/root.tsx +++ b/starters/apps/library/src/root.tsx @@ -3,7 +3,7 @@ import { Logo } from './components/logo/logo'; export default () => { return ( - + <> Qwik Blank App @@ -12,6 +12,6 @@ export default () => { - + ); }; diff --git a/starters/apps/library/tsconfig.json b/starters/apps/library/tsconfig.json index be000573e9c..1d9fe0a3447 100644 --- a/starters/apps/library/tsconfig.json +++ b/starters/apps/library/tsconfig.json @@ -8,7 +8,7 @@ "jsxImportSource": "@builder.io/qwik", "strict": true, "declaration": true, - "declarationDir": "lib/types", + "declarationDir": "lib-types", "resolveJsonModule": true, "moduleResolution": "node", "esModuleInterop": true, diff --git a/starters/features/qwik-react/package.json b/starters/features/qwik-react/package.json index 18b2dab88ff..1c349310f23 100644 --- a/starters/features/qwik-react/package.json +++ b/starters/features/qwik-react/package.json @@ -1,7 +1,7 @@ { "description": "Use React components into your Qwik app", "devDependencies": { - "@builder.io/qwik-react": "0.0.100", + "@builder.io/qwik-react": "0.0.102", "@emotion/react": "11.9.3", "@emotion/server": "11.4.0", "@emotion/styled": "11.9.3", diff --git a/starters/features/qwik-react/src/integrations/react/button.tsx b/starters/features/qwik-react/src/integrations/react/button.tsx new file mode 100644 index 00000000000..4066dedd03b --- /dev/null +++ b/starters/features/qwik-react/src/integrations/react/button.tsx @@ -0,0 +1,14 @@ +/** @jsxImportSource react */ + +import { qwikify$ } from '@builder.io/qwik-react'; +import { Button } from '@mui/material'; + +// qwikify$() takes a react component and returns +// a Qwik component that delivers zero JS +export const MUIButton = qwikify$(() => { + return ( + <> + + + ); +}); diff --git a/starters/features/qwik-react/src/react/app.tsx b/starters/features/qwik-react/src/react/app.tsx deleted file mode 100644 index 7ad416cbfdd..00000000000 --- a/starters/features/qwik-react/src/react/app.tsx +++ /dev/null @@ -1,14 +0,0 @@ -/** @jsxImportSource react */ - -import { qwikify$ } from '@builder.io/qwik-react'; -import { Button } from '@mui/material'; - -export function ReactCmp() { - return ( - <> - - - ); -} - -export const ReactRoot = /*#__PURE__*/ qwikify$(ReactCmp); diff --git a/starters/features/qwik-react/src/routes/react/index.tsx b/starters/features/qwik-react/src/routes/react/index.tsx new file mode 100644 index 00000000000..238ac46617f --- /dev/null +++ b/starters/features/qwik-react/src/routes/react/index.tsx @@ -0,0 +1,16 @@ +import { component$ } from '@builder.io/qwik'; +import type { DocumentHead } from '@builder.io/qwik-city'; +import { MUIButton } from '~/integrations/react/button'; + +export default component$(() => { + return ( +
+

The component below is a React MUI button:

+ +
+ ); +}); + +export const head: DocumentHead = { + title: 'Qwik React', +};