-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
feat: Preact Adapter #9935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: Preact Adapter #9935
Changes from all commits
3daff38
0e40281
722e05b
78cf64a
a9c5c75
8cc6ed5
088795b
0f5bdbc
6d23454
60502ad
f2f73f9
460919e
1a3afe6
05af042
4d5a0f0
f451435
b2e95fd
34f0262
4e366c4
3c6b541
66605b1
c069be8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| # Logs | ||
| logs | ||
| *.log | ||
| npm-debug.log* | ||
| yarn-debug.log* | ||
| yarn-error.log* | ||
| pnpm-debug.log* | ||
| lerna-debug.log* | ||
|
|
||
| node_modules | ||
| dist | ||
| dist-ssr | ||
| *.local | ||
|
|
||
| # Editor directories and files | ||
| .vscode/* | ||
| !.vscode/extensions.json | ||
| .idea | ||
| .DS_Store | ||
| *.suo | ||
| *.ntvs* | ||
| *.njsproj | ||
| *.sln | ||
| *.sw? |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # `create-preact` | ||
|
|
||
| <h2 align="center"> | ||
| <img height="256" width="256" src="./src/assets/preact.svg"> | ||
| </h2> | ||
|
|
||
| <h3 align="center">Get started using Preact and Vite!</h3> | ||
|
|
||
| ## Getting Started | ||
|
|
||
| - `pnpm dev` - Starts a dev server at http://localhost:5173/ | ||
|
|
||
| - `pnpm build` - Builds for production, emitting to `dist/` | ||
|
|
||
| - `pnpm preview` - Starts a server at http://localhost:4173/ to test production build locally | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| <!doctype html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <link rel="icon" type="image/svg+xml" href="/vite.svg" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <meta name="color-scheme" content="light dark" /> | ||
| <title>Vite + Preact</title> | ||
| </head> | ||
| <body> | ||
| <div id="app"></div> | ||
| <script type="module" src="/src/index.tsx"></script> | ||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| { | ||
| "private": true, | ||
| "type": "module", | ||
| "scripts": { | ||
| "dev": "vite", | ||
| "build": "vite build", | ||
| "preview": "vite preview" | ||
| }, | ||
| "dependencies": { | ||
| "@tanstack/preact-query": "workspace:^", | ||
| "preact": "^10.26.9" | ||
| }, | ||
| "devDependencies": { | ||
| "@preact/preset-vite": "^2.10.2", | ||
| "eslint": "^9.36.0", | ||
| "eslint-config-preact": "^2.0.0", | ||
| "typescript": "^5.9.3", | ||
| "vite": "^7.0.4" | ||
| }, | ||
| "eslintConfig": { | ||
| "extends": "preact" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,45 @@ | ||||||||||||||||||||||||||||||||
| import { render } from 'preact' | ||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||
| QueryClient, | ||||||||||||||||||||||||||||||||
| QueryClientProvider, | ||||||||||||||||||||||||||||||||
| useQuery, | ||||||||||||||||||||||||||||||||
| } from '@tanstack/preact-query' | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const queryClient = new QueryClient() | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| export function App() { | ||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||
| <QueryClientProvider client={queryClient}> | ||||||||||||||||||||||||||||||||
| <Example /> | ||||||||||||||||||||||||||||||||
| </QueryClientProvider> | ||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const Example = () => { | ||||||||||||||||||||||||||||||||
| const { isPending, error, data, isFetching } = useQuery({ | ||||||||||||||||||||||||||||||||
| queryKey: ['repoData'], | ||||||||||||||||||||||||||||||||
| queryFn: async () => { | ||||||||||||||||||||||||||||||||
| const response = await fetch( | ||||||||||||||||||||||||||||||||
| 'https://api.github.com/repos/TanStack/query', | ||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||
| return await response.json() | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
|
Comment on lines
+21
to
+26
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add response status validation. The fetch call doesn't check 🔎 Proposed fix queryFn: async () => {
const response = await fetch(
'https://api.github.com/repos/TanStack/query',
)
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`)
+ }
return await response.json()
},📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if (isPending) return 'Loading...' | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if (error !== null) return 'An error has occurred: ' + error.message | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||
| <div> | ||||||||||||||||||||||||||||||||
| <h1>{data.full_name}</h1> | ||||||||||||||||||||||||||||||||
| <p>{data.description}</p> | ||||||||||||||||||||||||||||||||
| <strong>👀 {data.subscribers_count}</strong>{' '} | ||||||||||||||||||||||||||||||||
| <strong>✨ {data.stargazers_count}</strong>{' '} | ||||||||||||||||||||||||||||||||
| <strong>🍴 {data.forks_count}</strong> | ||||||||||||||||||||||||||||||||
| <div>{isFetching ? 'Updating...' : ''}</div> | ||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| render(<App />, document.getElementById('app')) | ||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| :root { | ||
| font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; | ||
| line-height: 1.5; | ||
| font-weight: 400; | ||
|
|
||
| color: #222; | ||
| background-color: #ffffff; | ||
|
|
||
| font-synthesis: none; | ||
| text-rendering: optimizeLegibility; | ||
| -webkit-font-smoothing: antialiased; | ||
| -moz-osx-font-smoothing: grayscale; | ||
| -webkit-text-size-adjust: 100%; | ||
| } | ||
|
|
||
| body { | ||
| margin: 0; | ||
| display: flex; | ||
| align-items: center; | ||
| min-height: 100vh; | ||
| } | ||
|
|
||
| #app { | ||
| max-width: 1280px; | ||
| margin: 0 auto; | ||
| text-align: center; | ||
| } | ||
|
|
||
| img { | ||
| margin-bottom: 1.5rem; | ||
| } | ||
|
|
||
| img:hover { | ||
| filter: drop-shadow(0 0 2em #673ab8aa); | ||
| } | ||
|
|
||
| section { | ||
| margin-top: 5rem; | ||
| display: grid; | ||
| grid-template-columns: repeat(3, 1fr); | ||
| column-gap: 1.5rem; | ||
| } | ||
|
|
||
| .resource { | ||
| padding: 0.75rem 1.5rem; | ||
| border-radius: 0.5rem; | ||
| text-align: left; | ||
| text-decoration: none; | ||
| color: #222; | ||
| background-color: #f1f1f1; | ||
| border: 1px solid transparent; | ||
| } | ||
|
|
||
| .resource:hover { | ||
| border: 1px solid #000; | ||
| box-shadow: 0 25px 50px -12px #673ab888; | ||
| } | ||
|
|
||
| @media (max-width: 639px) { | ||
| #app { | ||
| margin: 2rem; | ||
| } | ||
| section { | ||
| margin-top: 5rem; | ||
| grid-template-columns: 1fr; | ||
| row-gap: 1rem; | ||
| } | ||
| } | ||
|
|
||
| @media (prefers-color-scheme: dark) { | ||
| :root { | ||
| color: #ccc; | ||
| background-color: #1a1a1a; | ||
| } | ||
| .resource { | ||
| color: #ccc; | ||
| background-color: #161616; | ||
| } | ||
| .resource:hover { | ||
| border: 1px solid #bbb; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| { | ||
| "compilerOptions": { | ||
| "target": "ES2020", | ||
| "module": "ESNext", | ||
| "moduleResolution": "bundler", | ||
| "noEmit": true, | ||
| "allowJs": true, | ||
| "checkJs": true, | ||
|
|
||
| /* Preact Config */ | ||
| "jsx": "react-jsx", | ||
| "jsxImportSource": "preact", | ||
| "skipLibCheck": true, | ||
| "paths": { | ||
| "react": ["./node_modules/preact/compat/"], | ||
| "react-dom": ["./node_modules/preact/compat/"] | ||
| } | ||
| }, | ||
| "include": ["node_modules/vite/client.d.ts", "**/*"] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import { defineConfig } from 'vite' | ||
| import preact from '@preact/preset-vite' | ||
|
|
||
| // https://vitejs.dev/config/ | ||
| export default defineConfig({ | ||
| plugins: [preact()], | ||
| }) |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,48 @@ | ||||||||||||||
| <img src="https://static.scarf.sh/a.png?x-pxid=be2d8a11-9712-4c1d-9963-580b2d4fb133" /> | ||||||||||||||
|
|
||||||||||||||
|  | ||||||||||||||
|
Comment on lines
+1
to
+3
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add alt text to images. The tracking pixel (line 1) and header image (line 3) are missing alt text, which violates accessibility guidelines. 🔎 Proposed fix-<img src="https://static.scarf.sh/a.png?x-pxid=be2d8a11-9712-4c1d-9963-580b2d4fb133" />
+<img alt="Scarf analytics" src="https://static.scarf.sh/a.png?x-pxid=be2d8a11-9712-4c1d-9963-580b2d4fb133" />
📝 Committable suggestion
Suggested change
🧰 Tools🪛 markdownlint-cli2 (0.18.1)1-1: Images should have alternate text (alt text) (MD045, no-alt-text) 🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| Hooks for fetching, caching and updating asynchronous data in React | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix the framework name in the description. The description says "React" but this is the Preact adapter. Update to reflect Preact. 🔎 Proposed fix-Hooks for fetching, caching and updating asynchronous data in React
+Hooks for fetching, caching and updating asynchronous data in Preact📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| <a href="https://twitter.com/intent/tweet?button_hashtag=TanStack" target="\_parent"> | ||||||||||||||
| <img alt="#TanStack" src="https://img.shields.io/twitter/url?color=%2308a0e9&label=%23TanStack&style=social&url=https%3A%2F%2Ftwitter.com%2Fintent%2Ftweet%3Fbutton_hashtag%3DTanStack"> | ||||||||||||||
| </a><a href="https://discord.com/invite/WrRKjPJ" target="\_parent"> | ||||||||||||||
| <img alt="" src="https://img.shields.io/badge/Discord-TanStack-%235865F2" /> | ||||||||||||||
| </a><a href="https://github.com/TanStack/query/actions?query=workflow%3A%22preact-query+tests%22"> | ||||||||||||||
| <img src="https://github.com/TanStack/query/workflows/preact-query%20tests/badge.svg" /> | ||||||||||||||
| </a><a href="https://www.npmjs.com/package/@tanstack/query-core" target="\_parent"> | ||||||||||||||
| <img alt="" src="https://img.shields.io/npm/dm/@tanstack/query-core.svg" /> | ||||||||||||||
| </a><a href="https://bundlejs.com/?q=%40tanstack%2Fpreact-query&config=%7B%22esbuild%22%3A%7B%22external%22%3A%5B%22react%22%2C%22react-dom%22%5D%7D%7D&badge=" target="\_parent"> | ||||||||||||||
| <img alt="" src="https://deno.bundlejs.com/?q=@tanstack/preact-query&config={%22esbuild%22:{%22external%22:[%22react%22,%22react-dom%22]}}&badge=detailed" /> | ||||||||||||||
|
Comment on lines
+15
to
+16
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix bundle badge external dependencies configuration. The bundlejs badge configuration incorrectly specifies 🔎 Proposed fix-<a href="https://bundlejs.com/?q=%40tanstack%2Fpreact-query&config=%7B%22esbuild%22%3A%7B%22external%22%3A%5B%22react%22%2C%22react-dom%22%5D%7D%7D&badge=" target="\_parent">
- <img alt="" src="https://deno.bundlejs.com/?q=@tanstack/preact-query&config={%22esbuild%22:{%22external%22:[%22react%22,%22react-dom%22]}}&badge=detailed" />
+<a href="https://bundlejs.com/?q=%40tanstack%2Fpreact-query&config=%7B%22esbuild%22%3A%7B%22external%22%3A%5B%22preact%22%5D%7D%7D&badge=" target="\_parent">
+ <img alt="Bundle size badge" src="https://deno.bundlejs.com/?q=@tanstack/preact-query&config={%22esbuild%22:{%22external%22:[%22preact%22]}}&badge=detailed" />Note: This also adds missing alt text per the earlier fix. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| </a><a href="#badge"> | ||||||||||||||
| <img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg"> | ||||||||||||||
| </a><a href="https://github.com/TanStack/query/discussions"> | ||||||||||||||
| <img alt="Join the discussion on Github" src="https://img.shields.io/badge/Github%20Discussions%20%26%20Support-Chat%20now!-blue" /> | ||||||||||||||
| </a><a href="https://bestofjs.org/projects/tanstack-query"><img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=TanStack%2Fquery%26since=daily" /></a><a href="https://github.com/TanStack/query/" target="\_parent"> | ||||||||||||||
| <img alt="" src="https://img.shields.io/github/stars/TanStack/query.svg?style=social&label=Star" /> | ||||||||||||||
| </a><a href="https://twitter.com/tannerlinsley" target="\_parent"> | ||||||||||||||
| <img alt="" src="https://img.shields.io/twitter/follow/tannerlinsley.svg?style=social&label=Follow" /> | ||||||||||||||
| </a> <a href="https://gitpod.io/from-referrer/"> | ||||||||||||||
| <img src="https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod" alt="Gitpod Ready-to-Code"/> | ||||||||||||||
| </a> | ||||||||||||||
|
|
||||||||||||||
| Enjoy this library? Try the entire [TanStack](https://tanstack.com)! [TanStack Table](https://github.com/TanStack/table), [TanStack Router](https://github.com/tanstack/router), [TanStack Virtual](https://github.com/tanstack/virtual), [React Charts](https://github.com/TanStack/react-charts), [React Ranger](https://github.com/TanStack/ranger) | ||||||||||||||
|
|
||||||||||||||
| ## Visit [tanstack.com/query](https://tanstack.com/query) for docs, guides, API and more! | ||||||||||||||
|
|
||||||||||||||
| ## Quick Features | ||||||||||||||
|
|
||||||||||||||
| - Transport/protocol/backend agnostic data fetching (REST, GraphQL, promises, whatever!) | ||||||||||||||
| - Auto Caching + Refetching (stale-while-revalidate, Window Refocus, Polling/Realtime) | ||||||||||||||
| - Parallel + Dependent Queries | ||||||||||||||
| - Mutations + Reactive Query Refetching | ||||||||||||||
| - Multi-layer Cache + Automatic Garbage Collection | ||||||||||||||
| - Paginated + Cursor-based Queries | ||||||||||||||
| - Load-More + Infinite Scroll Queries w/ Scroll Recovery | ||||||||||||||
| - Request Cancellation | ||||||||||||||
| - [React Suspense](https://react.dev/reference/react/Suspense) + Fetch-As-You-Render Query Prefetching | ||||||||||||||
| - Dedicated Devtools | ||||||||||||||
|
|
||||||||||||||
| ### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/) | ||||||||||||||
|
|
||||||||||||||
| <!-- Use the force, Luke --> | ||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| // @ts-check | ||
|
|
||
| import rootConfig from './root.eslint.config.js' | ||
| // @ts-ignore: no types for eslint-config-preact | ||
| import preact from 'eslint-config-preact' | ||
| import tseslint from 'typescript-eslint' | ||
|
|
||
| export default [ | ||
| ...rootConfig, | ||
| ...preact, | ||
| { | ||
| files: ['**/*.{ts,tsx}'], | ||
| languageOptions: { | ||
| parser: tseslint.parser, | ||
| parserOptions: { | ||
| project: true, | ||
| }, | ||
| }, | ||
| plugins: { | ||
| 'typescript-eslint': tseslint.plugin, | ||
| }, | ||
| rules: { | ||
| // Disable base rule to prevent overload false positives | ||
| 'no-redeclare': 'off', | ||
| 'no-duplicate-imports': 'off', | ||
| // TS-aware version handles overloads correctly | ||
| '@typescript-eslint/no-redeclare': 'error', | ||
| '@typescript-eslint/no-duplicate-imports': 'error', | ||
| }, | ||
| }, | ||
| { | ||
| files: ['**/__tests__/**'], | ||
| rules: { | ||
| '@eslint-react/dom/no-missing-button-type': 'off', | ||
| '@typescript-eslint/no-unnecessary-condition': 'off', | ||
| }, | ||
| }, | ||
| ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add alt text to the image for accessibility.
The
<img>tag is missing thealtattribute, which is required for screen readers and accessibility compliance.🔎 Proposed fix
📝 Committable suggestion
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
4-4: Images should have alternate text (alt text)
(MD045, no-alt-text)
🤖 Prompt for AI Agents