create-qwik 0.0.20-2 → 0.0.20-5

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.
Files changed (42) hide show
  1. package/README.md +1 -1
  2. package/index.js +5 -5
  3. package/package.json +1 -1
  4. package/starters/apps/base/gitignore +11 -8
  5. package/starters/apps/base/package.json +4 -4
  6. package/starters/apps/{starter-partytown → base}/src/entry.dev.tsx +0 -0
  7. package/starters/apps/starter/src/components/logo/logo.tsx +2 -1
  8. package/starters/apps/starter/src/entry.ssr.tsx +15 -0
  9. package/starters/apps/starter-builder/src/entry.ssr.tsx +15 -0
  10. package/starters/apps/starter-partytown/src/{entry.server.tsx → entry.ssr.tsx} +2 -0
  11. package/starters/apps/todo/src/components/app/app.tsx +7 -5
  12. package/starters/apps/todo/src/components/body/body.tsx +5 -7
  13. package/starters/apps/todo/src/components/footer/footer.tsx +10 -8
  14. package/starters/apps/todo/src/components/header/header.tsx +5 -4
  15. package/starters/apps/todo/src/components/item/item.tsx +4 -4
  16. package/starters/apps/todo/src/entry.ssr.tsx +15 -0
  17. package/starters/apps/todo/src/state/state.ts +4 -0
  18. package/starters/apps/todo-old.test/package.json +7 -0
  19. package/starters/apps/todo-old.test/src/components/app/app.tsx +33 -0
  20. package/starters/apps/todo-old.test/src/components/app/base.css +141 -0
  21. package/starters/apps/todo-old.test/src/components/app/index.css +378 -0
  22. package/starters/apps/todo-old.test/src/components/body/body.tsx +18 -0
  23. package/starters/apps/todo-old.test/src/components/footer/footer.tsx +61 -0
  24. package/starters/apps/todo-old.test/src/components/header/header.tsx +38 -0
  25. package/starters/apps/todo-old.test/src/components/item/item.tsx +76 -0
  26. package/starters/apps/{todo → todo-old.test}/src/entry.dev.tsx +0 -0
  27. package/starters/apps/{starter-builder/src/entry.server.tsx → todo-old.test/src/entry.ssr.tsx} +0 -0
  28. package/starters/apps/todo-old.test/src/root.tsx +15 -0
  29. package/starters/apps/todo-old.test/src/state/state.ts +23 -0
  30. package/starters/features/eslint/package.json +2 -2
  31. package/starters/servers/cloudflare-pages/functions/[[path]].ts +3 -55
  32. package/starters/servers/cloudflare-pages/package.json +1 -0
  33. package/starters/servers/cloudflare-pages/src/entry.cloudflare.tsx +52 -0
  34. package/starters/servers/cloudflare-pages/vite.config.ts +22 -0
  35. package/starters/servers/express/package.json +2 -1
  36. package/starters/servers/express/src/entry.express.tsx +52 -0
  37. package/starters/servers/express/vite.config.ts +8 -0
  38. package/starters/apps/starter/src/entry.dev.tsx +0 -13
  39. package/starters/apps/starter/src/entry.server.tsx +0 -9
  40. package/starters/apps/todo/src/entry.server.tsx +0 -9
  41. package/starters/servers/express/app.js +0 -19
  42. package/starters/servers/express/src/entry.server.tsx +0 -25
package/README.md CHANGED
@@ -41,7 +41,7 @@ console.log(result);
41
41
  ## Community
42
42
 
43
43
  - Ping us at [@QwikDev](https://twitter.com/QwikDev)
44
- - Join our [Discord](https://discord.gg/bNVSQmPzqy) community.
44
+ - Join our [Discord](https://qwik.builder.io/chat) community.
45
45
  - Join our [weekly office hours](https://calendar.google.com/calendar/u/0?cid=Y180ZG91YjR2NTZ1cW43YmgzbW1oZGJ2M3R2c0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t)
46
46
 
47
47
  ## Related
package/index.js CHANGED
@@ -5,14 +5,14 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://github.com/BuilderIO/qwik/blob/main/LICENSE
7
7
  */
8
- var O=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var B=Object.getOwnPropertyNames,E=Object.getOwnPropertySymbols;var C=Object.prototype.hasOwnProperty,L=Object.prototype.propertyIsEnumerable;var I=(e,t,r)=>t in e?O(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,D=(e,t)=>{for(var r in t||(t={}))C.call(t,r)&&I(e,r,t[r]);if(E)for(var r of E(t))L.call(t,r)&&I(e,r,t[r]);return e};var T=(e,t)=>{for(var r in t)O(e,r,{get:t[r],enumerable:!0})},V=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of B(t))!C.call(e,i)&&i!==r&&O(e,i,{get:()=>t[i],enumerable:!(o=A(t,i))||o.enumerable});return e};var U=e=>V(O({},"__esModule",{value:!0}),e);var H={};T(H,{generateStarter:()=>Q,getStarters:()=>N});module.exports=U(H);var g=require("fs"),M=require("path");var c=require("fs"),u=require("path");function y(e,t,r){let o=(0,c.readdirSync)(e);for(let i of o){let s=i==="gitignore"?".gitignore":i,n=(0,u.join)(e,i),a=(0,u.join)(t,s),w=(0,c.statSync)(n);if(w.isDirectory())(0,c.mkdirSync)(a,{recursive:!0}),y(n,a,r);else if(w.isFile())if(r.length>0&&[".json",".toml",".md",".html"].includes((0,u.extname)(n))){let p=(0,c.readFileSync)(n,"utf8");for(let f of r)p=p.replace(f[0],f[1]);(0,c.writeFileSync)(a,p)}else(0,c.copyFileSync)(n,a)}}function l(e){let t=(0,u.join)(e,"package.json");return JSON.parse((0,c.readFileSync)(t,"utf-8"))}function q(e,t){let r=(0,u.join)(e,"package.json");(0,c.writeFileSync)(r,JSON.stringify(t,null,2)+`
9
- `)}function F(e){return e.toLocaleLowerCase().split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}function G(e){return e.toLocaleLowerCase().replace(/ /g,"-")}function J(e,t){["scripts","dependencies","devDependencies"].forEach(o=>{$(e,t,o)})}function $(e,t,r){if(t[r]){e[r]?Object.assign(e[r],D({},t[r])):e[r]=D({},t[r]);let o={},i=Object.keys(e[r]).sort();for(let s of i)o[s]=e[r][s];e[r]=o}}async function Q(e){if(!x(e.projectName))throw new Error("Missing project name");if(!x(e.appId))throw new Error("Missing starter id");if(!x(e.outDir))throw new Error("Missing outDir");(0,g.existsSync)(e.outDir)||(0,g.mkdirSync)(e.outDir,{recursive:!0});let t={projectName:e.projectName,appId:e.appId,serverId:e.serverId,outDir:e.outDir},r=await N(),o=r.apps.find(n=>n.id===e.appId),i=r.servers.find(n=>n.id===e.serverId),s=r.features.filter(n=>e.featureIds.includes(n.id));if(o)_(r,t,o,i,s);else throw new Error(`Invalid starter id "${e.appId}".`);return t}function _(e,t,r,o,i){let s=[[/\bqwik-project-name\b/g,t.projectName]],n=e.apps.find(d=>d.id==="base");if(!n)throw new Error("Unable to find base app.");y(n.dir,t.outDir,s),y(r.dir,t.outDir,s);let a=l(n.dir),w=l(n.dir);J(a,w);let m=n.readme.trim()+`
8
+ var O=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var B=Object.getOwnPropertyNames,I=Object.getOwnPropertySymbols;var C=Object.prototype.hasOwnProperty,L=Object.prototype.propertyIsEnumerable;var P=(e,t,r)=>t in e?O(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,k=(e,t)=>{for(var r in t||(t={}))C.call(t,r)&&P(e,r,t[r]);if(I)for(var r of I(t))L.call(t,r)&&P(e,r,t[r]);return e};var T=(e,t)=>{for(var r in t)O(e,r,{get:t[r],enumerable:!0})},U=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of B(t))!C.call(e,i)&&i!==r&&O(e,i,{get:()=>t[i],enumerable:!(o=A(t,i))||o.enumerable});return e};var V=e=>U(O({},"__esModule",{value:!0}),e);var H={};T(H,{generateStarter:()=>Q,getStarters:()=>N});module.exports=V(H);var g=require("fs"),M=require("path");var c=require("fs"),u=require("path");function y(e,t,r){let o=(0,c.readdirSync)(e);for(let i of o){let s=i==="gitignore"?".gitignore":i,n=(0,u.join)(e,i),a=(0,u.join)(t,s),w=(0,c.statSync)(n);if(w.isDirectory())(0,c.mkdirSync)(a,{recursive:!0}),y(n,a,r);else if(w.isFile())if(r.length>0&&[".json",".toml",".md",".html"].includes((0,u.extname)(n))){let p=(0,c.readFileSync)(n,"utf8");for(let f of r)p=p.replace(f[0],f[1]);(0,c.writeFileSync)(a,p)}else(0,c.copyFileSync)(n,a)}}function l(e){let t=(0,u.join)(e,"package.json");return JSON.parse((0,c.readFileSync)(t,"utf-8"))}function q(e,t){let r=(0,u.join)(e,"package.json");(0,c.writeFileSync)(r,JSON.stringify(t,null,2)+`
9
+ `)}function F(e){return e.toLocaleLowerCase().split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}function G(e){return e.toLocaleLowerCase().replace(/ /g,"-")}function J(e,t){["scripts","dependencies","devDependencies"].forEach(o=>{$(e,t,o)})}function $(e,t,r){if(t[r]){e[r]?Object.assign(e[r],k({},t[r])):e[r]=k({},t[r]);let o={},i=Object.keys(e[r]).sort();for(let s of i)o[s]=e[r][s];e[r]=o}}async function Q(e){if(!x(e.projectName))throw new Error("Missing project name");if(!x(e.appId))throw new Error("Missing starter id");if(!x(e.outDir))throw new Error("Missing outDir");(0,g.existsSync)(e.outDir)||(0,g.mkdirSync)(e.outDir,{recursive:!0});let t={projectName:e.projectName,appId:e.appId,serverId:e.serverId,outDir:e.outDir},r=await N(),o=r.apps.find(n=>n.id===e.appId),i=r.servers.find(n=>n.id===e.serverId),s=r.features.filter(n=>e.featureIds.includes(n.id));if(o)_(r,t,o,i,s);else throw new Error(`Invalid starter id "${e.appId}".`);return t}function _(e,t,r,o,i){let s=[[/\bqwik-project-name\b/g,t.projectName]],n=e.apps.find(d=>d.id==="base");if(!n)throw new Error("Unable to find base app.");y(n.dir,t.outDir,s),y(r.dir,t.outDir,s);let a=l(n.dir),w=l(n.dir);J(a,w);let m=n.readme.trim()+`
10
10
 
11
11
  `,p=[r.description,"Vite.js tooling."];if(o){y(o.dir,t.outDir,s);let d=l(o.dir);J(a,d),d.description&&p.push(d.description),o.readme&&(m+=o.readme.trim()+`
12
12
 
13
13
  `)}for(let d of i){y(d.dir,t.outDir,s);let v=l(d.dir);J(a,v),v.description&&p.push(v.description),d.readme&&(m+=d.readme.trim()+`
14
14
 
15
- `)}a.name=G(t.projectName),a.description=p.join(" ").trim();let f=(0,M.join)(t.outDir,"README.md"),k=p.map(d=>`- ${d}`).join(`
16
- `).trim(),j=[`# Qwik ${t.projectName} \u26A1\uFE0F`,"",k,"",m.trim(),"","--------------------","","## Related","","- [Qwik Docs](https://qwik.builder.io/)","- [Qwik Github](https://github.com/BuilderIO/qwik)","- [@QwikDev](https://twitter.com/QwikDev)","- [Discord](https://discord.gg/bNVSQmPzqy)","- [Vite](https://vitejs.dev/)","- [Partytown](https://partytown.builder.io/)","- [Mitosis](https://github.com/BuilderIO/mitosis)","- [Builder.io](https://www.builder.io/)"].join(`
15
+ `)}a.name=G(t.projectName),a.description=p.join(" ").trim();let f=(0,M.join)(t.outDir,"README.md"),D=p.map(d=>`- ${d}`).join(`
16
+ `).trim(),j=[`# Qwik ${t.projectName} \u26A1\uFE0F`,"",D,"",m.trim(),"","--------------------","","## Related","","- [Qwik Docs](https://qwik.builder.io/)","- [Qwik Github](https://github.com/BuilderIO/qwik)","- [@QwikDev](https://twitter.com/QwikDev)","- [Discord](https://qwik.builder.io/chat)","- [Vite](https://vitejs.dev/)","- [Partytown](https://partytown.builder.io/)","- [Mitosis](https://github.com/BuilderIO/mitosis)","- [Builder.io](https://www.builder.io/)"].join(`
17
17
  `);(0,g.writeFileSync)(f,j.trim()+`
18
- `);let b=z(a);q(t.outDir,b)}function z(e){e=D({},e);let t={name:e.name,version:e.version,description:e.description,scripts:e.scripts,dependencies:e.dependencies,devDependencies:e.devDependencies};Object.keys(t).forEach(o=>{delete e[o]}),delete e.qwik;let r=Object.keys(e).sort();for(let o of r)t[o]=e[o];return t}function x(e){return typeof e=="string"&&e.trim().length>0}var h=require("fs"),S=require("path");var P=null;async function N(){return P==null&&(P=K((0,S.join)(__dirname,"starters"))),P}function K(e){return{apps:R(e,"apps"),servers:R(e,"servers"),features:R(e,"features")}}function R(e,t){let r=(0,S.join)(e,t);return(0,h.readdirSync)(r).filter(i=>(0,h.statSync)((0,S.join)(r,i)).isDirectory()).map(i=>{var m,p,f,k,j;let s=(0,S.join)(r,i),n=l(s),a=null;try{a=(0,h.readFileSync)((0,S.join)(s,"README.md"),"utf-8")}catch{}return{id:i,name:F(i),description:(m=n.description)!=null?m:"",readme:a,dir:s,priority:(f=(p=n==null?void 0:n.qwik)==null?void 0:p.priority)!=null?f:0,featureOptions:(j=(k=n==null?void 0:n.qwik)==null?void 0:k.featureOptions)!=null?j:[]}}).sort((i,s)=>i.priority>s.priority?-1:i.priority<s.priority?1:i.name<s.name?-1:i.name>s.name?1:0)}0&&(module.exports={generateStarter,getStarters});
18
+ `);let E=K(a);q(t.outDir,E)}function K(e){e=k({},e);let t={name:e.name,version:e.version,description:e.description,scripts:e.scripts,dependencies:e.dependencies,devDependencies:e.devDependencies};Object.keys(t).forEach(o=>{delete e[o]}),delete e.qwik;let r=Object.keys(e).sort();for(let o of r)t[o]=e[o];return t}function x(e){return typeof e=="string"&&e.trim().length>0}var S=require("fs"),h=require("path");var R=null;async function N(){return R==null&&(R=z((0,h.join)(__dirname,"starters"))),R}function z(e){return{apps:b(e,"apps"),servers:b(e,"servers"),features:b(e,"features")}}function b(e,t){let r=(0,h.join)(e,t);return(0,S.readdirSync)(r).filter(i=>(0,S.statSync)((0,h.join)(r,i)).isDirectory()).map(i=>{var m,p,f,D,j;let s=(0,h.join)(r,i),n=l(s),a=null;try{a=(0,S.readFileSync)((0,h.join)(s,"README.md"),"utf-8")}catch{}return{id:i,name:F(i),description:(m=n.description)!=null?m:"",readme:a,dir:s,priority:(f=(p=n==null?void 0:n.qwik)==null?void 0:p.priority)!=null?f:0,featureOptions:(j=(D=n==null?void 0:n.qwik)==null?void 0:D.featureOptions)!=null?j:[]}}).sort((i,s)=>i.priority>s.priority?-1:i.priority<s.priority?1:i.name<s.name?-1:i.name>s.name?1:0)}0&&(module.exports={generateStarter,getStarters});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-qwik",
3
- "version": "0.0.20-2",
3
+ "version": "0.0.20-5",
4
4
  "description": "Interactive CLI and API for generating Qwik projects.",
5
5
  "bin": "create-qwik",
6
6
  "main": "index.js",
@@ -1,16 +1,19 @@
1
+ # Build
2
+ build
3
+ dist
4
+ server
5
+ functions/**/*.js
6
+
7
+ # Development
8
+ node_modules
9
+
10
+ # Cache
1
11
  .cache
2
12
  .mf
3
13
  .vscode
4
14
  .rollup.cache
5
-
6
- build
7
- dist
8
- node_modules
9
- server
10
15
  tsconfig.tsbuildinfo
11
16
 
12
- q-symbols.json
13
-
14
17
  # Logs
15
18
  logs
16
19
  *.log
@@ -20,7 +23,7 @@ yarn-error.log*
20
23
  pnpm-debug.log*
21
24
  lerna-debug.log*
22
25
 
23
- # Editor directories and files
26
+ # Editor
24
27
  !.vscode/extensions.json
25
28
  .idea
26
29
  .DS_Store
@@ -5,7 +5,7 @@
5
5
  "scripts": {
6
6
  "build": "npm run typecheck && npm run build.client && npm run build.ssr",
7
7
  "build.client": "vite build",
8
- "build.ssr": "vite build --mode ssr",
8
+ "build.ssr": "vite build --ssr src/entry.server.tsx",
9
9
  "dev": "vite",
10
10
  "dev.ssr": "vite --mode ssr",
11
11
  "dev.debug": "node --inspect-brk node_modules/vite/bin/vite.js",
@@ -13,11 +13,11 @@
13
13
  "typecheck": "tsc --noEmit"
14
14
  },
15
15
  "devDependencies": {
16
- "@builder.io/qwik": "0.0.20-2",
17
- "@types/node": "17.0.31",
16
+ "@builder.io/qwik": "0.0.20-5",
17
+ "@types/node": "17.0.34",
18
18
  "node-fetch": "2.6.7",
19
19
  "typescript": "4.6.4",
20
- "vite": "2.9.8"
20
+ "vite": "2.9.9"
21
21
  },
22
22
  "homepage": "https://qwik.builder.io/",
23
23
  "private": true,
@@ -3,10 +3,11 @@ import { component$, Host } from '@builder.io/qwik';
3
3
  export const Logo = component$(() => {
4
4
  return (
5
5
  <Host style={{ 'text-align': 'center' }}>
6
- <a href="https://github.com/builderio/qwik">
6
+ <a href="https://qwik.builder.io/">
7
7
  <img
8
8
  alt="Qwik Logo"
9
9
  width={400}
10
+ height={147}
10
11
  src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F667ab6c2283d4c4d878fb9083aacc10f"
11
12
  />
12
13
  </a>
@@ -0,0 +1,15 @@
1
+ import { renderToString, RenderToStringOptions } from '@builder.io/qwik/server';
2
+ import { manifest } from '@qwik-client-manifest';
3
+ import { Root } from './root';
4
+
5
+ /**
6
+ * Server-Side Render method to be called by a server.
7
+ */
8
+ export function render(opts?: RenderToStringOptions) {
9
+ // Render the Root component to a string
10
+ // Pass in the manifest that was generated from the client build
11
+ return renderToString(<Root />, {
12
+ ...opts,
13
+ manifest,
14
+ });
15
+ }
@@ -0,0 +1,15 @@
1
+ import { renderToString, RenderToStringOptions } from '@builder.io/qwik/server';
2
+ import { manifest } from '@qwik-client-manifest';
3
+ import { Root } from './root';
4
+
5
+ /**
6
+ * Server-Side Render method to be called by a server.
7
+ */
8
+ export function render(opts?: RenderToStringOptions) {
9
+ // Render the Root component to a string
10
+ // Pass in the manifest that was generated from the client build
11
+ return renderToString(<Root />, {
12
+ ...opts,
13
+ manifest,
14
+ });
15
+ }
@@ -1,4 +1,5 @@
1
1
  import { renderToString, RenderToStringOptions } from '@builder.io/qwik/server';
2
+ import { manifest } from '@qwik-client-manifest';
2
3
  import { Root } from './root';
3
4
 
4
5
  /**
@@ -7,6 +8,7 @@ import { Root } from './root';
7
8
  export function render(opts: RenderToStringOptions) {
8
9
  return renderToString(<Root />, {
9
10
  ...opts,
11
+ manifest,
10
12
  qwikLoader: {
11
13
  events: ['click', 'keyup', 'expensiveComputationDone'],
12
14
  },
@@ -1,8 +1,8 @@
1
- import { component$, useStyles$, useStore } from '@builder.io/qwik';
1
+ import { component$, useStyles$, useStore, useContextProvider } from '@builder.io/qwik';
2
2
  import { Footer } from '../footer/footer';
3
3
  import { Header } from '../header/header';
4
4
  import { Body } from '../body/body';
5
- import type { Todos } from '../../state/state';
5
+ import { TODOS, Todos } from '../../state/state';
6
6
  import styles from './index.css?inline';
7
7
 
8
8
  /**
@@ -23,11 +23,13 @@ export const App = component$(() => {
23
23
  { completed: false, title: 'Profit' },
24
24
  ],
25
25
  });
26
+ useContextProvider(TODOS, todos);
27
+
26
28
  return (
27
29
  <section class="todoapp">
28
- <Header todos={todos} />
29
- <Body todos={todos} />
30
- <Footer todos={todos} />
30
+ <Header />
31
+ <Body />
32
+ <Footer />
31
33
  </section>
32
34
  );
33
35
  });
@@ -1,16 +1,14 @@
1
- import { component$, Host } from '@builder.io/qwik';
2
- import { FILTERS, Todos } from '../../state/state';
1
+ import { component$, Host, useContext } from '@builder.io/qwik';
2
+ import { FILTERS, TODOS } from '../../state/state';
3
3
  import { Item } from '../item/item';
4
4
 
5
- interface BodyProps {
6
- todos: Todos;
7
- }
8
- export const Body = component$(({ todos }: BodyProps) => {
5
+ export const Body = component$(() => {
6
+ const todos = useContext(TODOS);
9
7
  return (
10
8
  <Host class="main">
11
9
  <ul class="todo-list">
12
10
  {todos.items.filter(FILTERS[todos.filter]).map((key) => (
13
- <Item item={key} todos={todos} />
11
+ <Item item={key} />
14
12
  ))}
15
13
  </ul>
16
14
  </Host>
@@ -1,5 +1,5 @@
1
- import { component$, Host } from '@builder.io/qwik';
2
- import { FILTERS, FilterStates, Todos } from '../../state/state';
1
+ import { component$, Host, useContext } from '@builder.io/qwik';
2
+ import { FILTERS, FilterStates, TODOS, Todos } from '../../state/state';
3
3
 
4
4
  /**
5
5
  * Footer showing items remaining and filtering options
@@ -7,18 +7,20 @@ import { FILTERS, FilterStates, Todos } from '../../state/state';
7
7
  * It only rerenders if the todos count changes or filters are reset.
8
8
  */
9
9
  export const Footer = component$(
10
- (props: { todos: Todos }) => {
10
+ () => {
11
11
  /**
12
12
  * Example of lite-component (it will always be included with the parent component)
13
13
  */
14
+ const todos = useContext(TODOS);
15
+
14
16
  function Filter({ filter }: { filter: FilterStates }) {
15
17
  const lMode = filter.toLowerCase();
16
18
  return (
17
19
  <li>
18
20
  <a
19
- class={{ selected: props.todos.filter == lMode }}
21
+ class={{ selected: todos.filter == lMode }}
20
22
  onClick$={() => {
21
- props.todos.filter = filter;
23
+ todos.filter = filter;
22
24
  }}
23
25
  >
24
26
  {filter[0].toUpperCase() + filter.slice(1)}
@@ -26,10 +28,10 @@ export const Footer = component$(
26
28
  </li>
27
29
  );
28
30
  }
29
- const remaining = props.todos.items.filter(FILTERS.active).length;
31
+ const remaining = todos.items.filter(FILTERS.active).length;
30
32
  return (
31
33
  <Host class="footer">
32
- {props.todos.items.length > 0 ? (
34
+ {todos.items.length > 0 ? (
33
35
  <>
34
36
  <span class="todo-count">
35
37
  <strong>{remaining}</strong>
@@ -44,7 +46,7 @@ export const Footer = component$(
44
46
  <button
45
47
  class="clear-completed"
46
48
  onClick$={() => {
47
- props.todos.items = props.todos.items.filter(FILTERS.active);
49
+ todos.items = todos.items.filter(FILTERS.active);
48
50
  }}
49
51
  >
50
52
  Clear completed
@@ -1,5 +1,5 @@
1
- import { component$, useStore } from '@builder.io/qwik';
2
- import type { Todos } from '../../state/state';
1
+ import { component$, useContext, useContextProvider, useStore } from '@builder.io/qwik';
2
+ import { TODOS, Todos } from '../../state/state';
3
3
 
4
4
  /**
5
5
  * Header component which is responsible for providing UI to ender new todo item.
@@ -7,8 +7,9 @@ import type { Todos } from '../../state/state';
7
7
  * This component only rerenders if the user interacts with it through the input.
8
8
  */
9
9
  export const Header = component$(
10
- (props: { todos: Todos }) => {
10
+ () => {
11
11
  const state = useStore({ text: '' });
12
+ const todos = useContext(TODOS);
12
13
  return (
13
14
  <>
14
15
  <h1>todos</h1>
@@ -21,7 +22,7 @@ export const Header = component$(
21
22
  const inputValue = (event.target as HTMLInputElement).value;
22
23
  state.text = inputValue;
23
24
  if (event.key === 'Enter' && inputValue) {
24
- props.todos.items.push({
25
+ todos.items.push({
25
26
  completed: false,
26
27
  title: state.text,
27
28
  });
@@ -1,6 +1,6 @@
1
- import { component$, useStore, Host, useRef, useWatch$ } from '@builder.io/qwik';
1
+ import { component$, useStore, Host, useRef, useWatch$, useContext } from '@builder.io/qwik';
2
2
 
3
- import type { TodoItem, Todos } from '../../state/state';
3
+ import { TodoItem, TODOS, Todos } from '../../state/state';
4
4
 
5
5
  /**
6
6
  * Individual items of the component.
@@ -10,13 +10,13 @@ import type { TodoItem, Todos } from '../../state/state';
10
10
 
11
11
  export interface ItemProps {
12
12
  item: TodoItem;
13
- todos: Todos;
14
13
  }
15
14
 
16
15
  export const Item = component$(
17
16
  (props: ItemProps) => {
18
17
  const state = useStore({ editing: false });
19
18
  const editInput = useRef<HTMLInputElement>();
19
+ const todos = useContext(TODOS);
20
20
 
21
21
  useWatch$((track) => {
22
22
  const current = track(editInput, 'current');
@@ -48,7 +48,7 @@ export const Item = component$(
48
48
  class="destroy"
49
49
  onClick$={() => {
50
50
  const todoItem = props.item;
51
- props.todos.items = props.todos.items.filter((i) => i != todoItem);
51
+ todos.items = todos.items.filter((i) => i != todoItem);
52
52
  }}
53
53
  />
54
54
  </div>
@@ -0,0 +1,15 @@
1
+ import { renderToString, RenderToStringOptions } from '@builder.io/qwik/server';
2
+ import { manifest } from '@qwik-client-manifest';
3
+ import { Root } from './root';
4
+
5
+ /**
6
+ * Server-Side Render method to be called by a server.
7
+ */
8
+ export function render(opts?: RenderToStringOptions) {
9
+ // Render the Root component to a string
10
+ // Pass in the manifest that was generated from the client build
11
+ return renderToString(<Root />, {
12
+ ...opts,
13
+ manifest,
14
+ });
15
+ }
@@ -2,6 +2,10 @@
2
2
  // Todo Application State Interfaces
3
3
  ////////////////////////////////////////////////////////////////////////
4
4
 
5
+ import { createContext } from '@builder.io/qwik';
6
+
7
+ export const TODOS = createContext<Todos>('TodoApp');
8
+
5
9
  export interface TodoItem {
6
10
  completed: boolean;
7
11
  title: string;
@@ -0,0 +1,7 @@
1
+ {
2
+ "description": "Qwik implementation of TodoMVC: https://todomvc.com/.",
3
+ "qwik": {
4
+ "priority": 0,
5
+ "featureOptions": []
6
+ }
7
+ }
@@ -0,0 +1,33 @@
1
+ import { component$, useStyles$, useStore } from '@builder.io/qwik';
2
+ import { Footer } from '../footer/footer';
3
+ import { Header } from '../header/header';
4
+ import { Body } from '../body/body';
5
+ import type { Todos } from '../../state/state';
6
+ import styles from './index.css?inline';
7
+
8
+ /**
9
+ * Overall application component.
10
+ *
11
+ * This component is static (meaning it will never change). Because of this
12
+ * Qwik knows that it should never need to be rerendered, and its code will never
13
+ * download to the client.
14
+ */
15
+ export const App = component$(() => {
16
+ useStyles$(styles);
17
+
18
+ const todos = useStore<Todos>({
19
+ filter: 'all',
20
+ items: [
21
+ { completed: false, title: 'Read Qwik docs' },
22
+ { completed: false, title: 'Build HelloWorld' },
23
+ { completed: false, title: 'Profit' },
24
+ ],
25
+ });
26
+ return (
27
+ <section class="todoapp">
28
+ <Header todos={todos} />
29
+ <Body todos={todos} />
30
+ <Footer todos={todos} />
31
+ </section>
32
+ );
33
+ });
@@ -0,0 +1,141 @@
1
+ hr {
2
+ margin: 20px 0;
3
+ border: 0;
4
+ border-top: 1px dashed #c5c5c5;
5
+ border-bottom: 1px dashed #f7f7f7;
6
+ }
7
+
8
+ .learn a {
9
+ font-weight: normal;
10
+ text-decoration: none;
11
+ color: #b83f45;
12
+ }
13
+
14
+ .learn a:hover {
15
+ text-decoration: underline;
16
+ color: #787e7e;
17
+ }
18
+
19
+ .learn h3,
20
+ .learn h4,
21
+ .learn h5 {
22
+ margin: 10px 0;
23
+ font-weight: 500;
24
+ line-height: 1.2;
25
+ color: #000;
26
+ }
27
+
28
+ .learn h3 {
29
+ font-size: 24px;
30
+ }
31
+
32
+ .learn h4 {
33
+ font-size: 18px;
34
+ }
35
+
36
+ .learn h5 {
37
+ margin-bottom: 0;
38
+ font-size: 14px;
39
+ }
40
+
41
+ .learn ul {
42
+ padding: 0;
43
+ margin: 0 0 30px 25px;
44
+ }
45
+
46
+ .learn li {
47
+ line-height: 20px;
48
+ }
49
+
50
+ .learn p {
51
+ font-size: 15px;
52
+ font-weight: 300;
53
+ line-height: 1.3;
54
+ margin-top: 0;
55
+ margin-bottom: 0;
56
+ }
57
+
58
+ #issue-count {
59
+ display: none;
60
+ }
61
+
62
+ .quote {
63
+ border: none;
64
+ margin: 20px 0 60px 0;
65
+ }
66
+
67
+ .quote p {
68
+ font-style: italic;
69
+ }
70
+
71
+ .quote p:before {
72
+ content: '“';
73
+ font-size: 50px;
74
+ opacity: 0.15;
75
+ position: absolute;
76
+ top: -20px;
77
+ left: 3px;
78
+ }
79
+
80
+ .quote p:after {
81
+ content: '”';
82
+ font-size: 50px;
83
+ opacity: 0.15;
84
+ position: absolute;
85
+ bottom: -42px;
86
+ right: 3px;
87
+ }
88
+
89
+ .quote footer {
90
+ position: absolute;
91
+ bottom: -40px;
92
+ right: 0;
93
+ }
94
+
95
+ .quote footer img {
96
+ border-radius: 3px;
97
+ }
98
+
99
+ .quote footer a {
100
+ margin-left: 5px;
101
+ vertical-align: middle;
102
+ }
103
+
104
+ .speech-bubble {
105
+ position: relative;
106
+ padding: 10px;
107
+ background: rgba(0, 0, 0, 0.04);
108
+ border-radius: 5px;
109
+ }
110
+
111
+ .speech-bubble:after {
112
+ content: '';
113
+ position: absolute;
114
+ top: 100%;
115
+ right: 30px;
116
+ border: 13px solid transparent;
117
+ border-top-color: rgba(0, 0, 0, 0.04);
118
+ }
119
+
120
+ .learn-bar > .learn {
121
+ position: absolute;
122
+ width: 272px;
123
+ top: 8px;
124
+ left: -300px;
125
+ padding: 10px;
126
+ border-radius: 5px;
127
+ background-color: rgba(255, 255, 255, 0.6);
128
+ transition-property: left;
129
+ transition-duration: 500ms;
130
+ }
131
+
132
+ @media (min-width: 899px) {
133
+ .learn-bar {
134
+ width: auto;
135
+ padding-left: 300px;
136
+ }
137
+
138
+ .learn-bar > .learn {
139
+ left: 8px;
140
+ }
141
+ }