diff --git a/packages/react/playground/App.tsx b/packages/react/playground/App.tsx index 2a5a3f7..d03a481 100644 --- a/packages/react/playground/App.tsx +++ b/packages/react/playground/App.tsx @@ -2,17 +2,13 @@ import { LazyImage } from '../src' function App() { return ( - <> -
- -
- + ) } diff --git a/packages/react/playground/index.html b/packages/react/playground/index.html index c5fe0b2..245c7ca 100644 --- a/packages/react/playground/index.html +++ b/packages/react/playground/index.html @@ -6,7 +6,7 @@ @unlazy/react -
+
diff --git a/packages/react/playground/main.tsx b/packages/react/playground/main.tsx index 80d56b3..b476cf2 100644 --- a/packages/react/playground/main.tsx +++ b/packages/react/playground/main.tsx @@ -2,7 +2,9 @@ import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.tsx' -ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( +const app = document.getElementById('app')! + +ReactDOM.createRoot(app).render( , diff --git a/packages/react/playground/package.json b/packages/react/playground/package.json index 7ec45a7..6f106b0 100644 --- a/packages/react/playground/package.json +++ b/packages/react/playground/package.json @@ -1,6 +1,5 @@ { "type": "module", - "version": "0.4.4", "private": true, "scripts": { "dev": "vite", diff --git a/packages/solid/build.config.ts b/packages/solid/build.config.ts new file mode 100644 index 0000000..b814bc2 --- /dev/null +++ b/packages/solid/build.config.ts @@ -0,0 +1,15 @@ +import { defineBuildConfig } from 'unbuild' + +export default defineBuildConfig({ + entries: ['src/index'], + clean: true, + declaration: true, + externals: ['react', 'react-dom'], + rollup: { + emitCJS: true, + inlineDependencies: true, + resolve: { + extensions: ['.ts', '.tsx'], + }, + }, +}) diff --git a/packages/solid/package.json b/packages/solid/package.json new file mode 100644 index 0000000..fbbb444 --- /dev/null +++ b/packages/solid/package.json @@ -0,0 +1,62 @@ +{ + "name": "@unlazy/solid", + "version": "0.4.4", + "packageManager": "pnpm@8.3.0", + "description": "Solid lazy loading library for placeholder images", + "author": "Johann Schopplich ", + "license": "MIT", + "homepage": "https://unlazy.byjohann.dev", + "repository": { + "type": "git", + "url": "git+https://github.com/johannschopplich/unlazy.git", + "directory": "packages/solid" + }, + "bugs": { + "url": "https://github.com/johannschopplich/unlazy/issues" + }, + "keywords": [ + "async", + "image", + "intersection", + "lazy", + "loading", + "lozad", + "native", + "observer", + "responsive", + "react" + ], + "sideEffects": false, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "require": "./dist/index.cjs", + "import": "./dist/index.mjs" + } + }, + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "scripts": { + "build": "unbuild", + "dev": "pnpm -C playground run dev", + "dev:build": "pnpm -C playground run build", + "test:types": "tsc --noEmit" + }, + "peerDependencies": { + "fast-blurhash": "^1.1.2", + "solid-js": "^1.7.3" + }, + "dependencies": { + "unlazy": "workspace:*" + }, + "devDependencies": { + "@types/node": "^18.15.12", + "fast-blurhash": "^1.1.2", + "solid-js": "^1.7.3", + "vite-plugin-solid": "^2.7.0" + } +} diff --git a/packages/solid/playground/App.tsx b/packages/solid/playground/App.tsx new file mode 100644 index 0000000..d92b6a5 --- /dev/null +++ b/packages/solid/playground/App.tsx @@ -0,0 +1,16 @@ +/* @refresh granular */ +import { LazyImage } from '../src' + +function App() { + return ( + + ) +} + +export default App diff --git a/packages/solid/playground/index.html b/packages/solid/playground/index.html new file mode 100644 index 0000000..245f668 --- /dev/null +++ b/packages/solid/playground/index.html @@ -0,0 +1,12 @@ + + + + + + @unlazy/solid + + +
+ + + diff --git a/packages/solid/playground/main.tsx b/packages/solid/playground/main.tsx new file mode 100644 index 0000000..1875654 --- /dev/null +++ b/packages/solid/playground/main.tsx @@ -0,0 +1,7 @@ +import { render } from 'solid-js/web' +import App from './App' + +const app = document.getElementById('app') + +if (app) + render(() => , app) diff --git a/packages/solid/playground/package.json b/packages/solid/playground/package.json new file mode 100644 index 0000000..6f106b0 --- /dev/null +++ b/packages/solid/playground/package.json @@ -0,0 +1,9 @@ +{ + "type": "module", + "private": true, + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + } +} diff --git a/packages/solid/playground/vite-env.d.ts b/packages/solid/playground/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/packages/solid/playground/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/packages/solid/playground/vite.config.ts b/packages/solid/playground/vite.config.ts new file mode 100644 index 0000000..4095d9b --- /dev/null +++ b/packages/solid/playground/vite.config.ts @@ -0,0 +1,6 @@ +import { defineConfig } from 'vite' +import solid from 'vite-plugin-solid' + +export default defineConfig({ + plugins: [solid()], +}) diff --git a/packages/solid/src/index.tsx b/packages/solid/src/index.tsx new file mode 100644 index 0000000..73b0c12 --- /dev/null +++ b/packages/solid/src/index.tsx @@ -0,0 +1,38 @@ +import { createEffect, createSignal, onCleanup } from 'solid-js' +import { lazyLoad } from 'unlazy' +import type { UnLazyLoadOptions } from 'unlazy' +import type { JSX } from 'solid-js' + +interface Props + extends JSX.ImgHTMLAttributes, + Pick { + autoSizes?: boolean + blurhash?: string +} + +export function LazyImage(props: Props) { + const [target, setTarget] = createSignal(null) + + createEffect(() => { + const currentTarget = target() + if (currentTarget) { + const cleanup = lazyLoad(currentTarget, { + blurhash: props.blurhash, + blurhashSize: props.blurhashSize, + }) + + onCleanup(() => { + cleanup() + }) + } + }) + + return ( + + ) +} diff --git a/packages/solid/tsconfig.json b/packages/solid/tsconfig.json new file mode 100644 index 0000000..8c26006 --- /dev/null +++ b/packages/solid/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + /* Limit global types to those in the current package */ + "typeRoots": ["./node_modules/@types"], + "jsx": "preserve", + "jsxImportSource": "solid-js" + }, + "include": ["src", "playground"], + "exclude": ["**/dist"] +} diff --git a/packages/unlazy/package.json b/packages/unlazy/package.json index a8c4457..b0ed103 100644 --- a/packages/unlazy/package.json +++ b/packages/unlazy/package.json @@ -9,7 +9,8 @@ "homepage": "https://unlazy.byjohann.dev", "repository": { "type": "git", - "url": "git+https://github.com/johannschopplich/unlazy.git" + "url": "git+https://github.com/johannschopplich/unlazy.git", + "directory": "packages/unlazy" }, "bugs": { "url": "https://github.com/johannschopplich/unlazy/issues" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0d06da4..e404b55 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -84,6 +84,25 @@ importers: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) + packages/solid: + dependencies: + unlazy: + specifier: workspace:* + version: link:../unlazy + devDependencies: + '@types/node': + specifier: ^18.15.12 + version: 18.15.12 + fast-blurhash: + specifier: ^1.1.2 + version: 1.1.2 + solid-js: + specifier: ^1.7.3 + version: 1.7.3 + vite-plugin-solid: + specifier: ^2.7.0 + version: 2.7.0(solid-js@1.7.3)(vite@4.2.2) + packages/unlazy: dependencies: '@unlazy/core': @@ -103,6 +122,9 @@ importers: '@types/node': specifier: ^18.15.12 version: 18.15.12 + '@vitejs/plugin-vue': + specifier: ^4.1.0 + version: 4.1.0(vite@4.2.2)(vue@3.2.47) fast-blurhash: specifier: ^1.1.2 version: 1.1.2 @@ -532,6 +554,13 @@ packages: '@babel/types': 7.21.4 dev: true + /@babel/helper-module-imports@7.18.6: + resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.4 + dev: true + /@babel/helper-module-imports@7.21.4: resolution: {integrity: sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==} engines: {node: '>=6.9.0'} @@ -662,6 +691,20 @@ packages: '@babel/helper-plugin-utils': 7.20.2 dev: true + /@babel/plugin-transform-modules-commonjs@7.21.2(@babel/core@7.21.4): + resolution: {integrity: sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.4 + '@babel/helper-module-transforms': 7.21.2 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-simple-access': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/plugin-transform-react-jsx-self@7.21.0(@babel/core@7.21.4): resolution: {integrity: sha512-f/Eq+79JEu+KUANFks9UZCcvydOOGMgF7jBrcwjHa5jTZD8JivnhCJYvmlhR/WTXBWonDExPoW0eO/CR4QJirA==} engines: {node: '>=6.9.0'} @@ -697,6 +740,22 @@ packages: - supports-color dev: true + /@babel/preset-typescript@7.21.4(@babel/core@7.21.4): + resolution: {integrity: sha512-sMLNWY37TCdRH/bJ6ZeeOH1nPuanED7Ai9Y/vH31IPqalioJ6ZNFUWONsakhv4r4n+I6gm5lmoE0olkgib/j/A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.4 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-validator-option': 7.21.0 + '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.21.4) + '@babel/plugin-transform-modules-commonjs': 7.21.2(@babel/core@7.21.4) + '@babel/plugin-transform-typescript': 7.21.3(@babel/core@7.21.4) + transitivePeerDependencies: + - supports-color + dev: true + /@babel/standalone@7.21.4: resolution: {integrity: sha512-Rw4nGqH/iyVeYxARKcz7iGP+njkPsVqJ45TmXMONoGoxooWjXCAs+CUcLeAZdBGCLqgaPvHKCYvIaDT2Iq+KfA==} engines: {node: '>=6.9.0'} @@ -1455,6 +1514,35 @@ packages: engines: {node: '>=10.13.0'} dev: true + /@types/babel__core@7.20.0: + resolution: {integrity: sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==} + dependencies: + '@babel/parser': 7.21.4 + '@babel/types': 7.21.4 + '@types/babel__generator': 7.6.4 + '@types/babel__template': 7.4.1 + '@types/babel__traverse': 7.18.3 + dev: true + + /@types/babel__generator@7.6.4: + resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} + dependencies: + '@babel/types': 7.21.4 + dev: true + + /@types/babel__template@7.4.1: + resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} + dependencies: + '@babel/parser': 7.21.4 + '@babel/types': 7.21.4 + dev: true + + /@types/babel__traverse@7.18.3: + resolution: {integrity: sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==} + dependencies: + '@babel/types': 7.21.4 + dev: true + /@types/chai-subset@1.3.3: resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} dependencies: @@ -2604,6 +2692,28 @@ packages: engines: {node: '>= 0.4'} dev: true + /babel-plugin-jsx-dom-expressions@0.36.10(@babel/core@7.21.4): + resolution: {integrity: sha512-QA2k/14WGw+RgcGGnEuLWwnu4em6CGhjeXtjvgOYyFHYS2a+CzPeaVQHDOlfuiBcjq/3hWMspHMIMnPEOIzdBg==} + peerDependencies: + '@babel/core': ^7.20.12 + dependencies: + '@babel/core': 7.21.4 + '@babel/helper-module-imports': 7.18.6 + '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.21.4) + '@babel/types': 7.21.4 + html-entities: 2.3.3 + validate-html-nesting: 1.2.1 + dev: true + + /babel-preset-solid@1.7.3(@babel/core@7.21.4): + resolution: {integrity: sha512-HOdyrij99zo+CBrmtDxSexBAl54vCBCfBoyueLBvcfVniaEXNd4ftKqSN6XQcLvFfCY28UFO+DHaigXzWKOfzg==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.21.4 + babel-plugin-jsx-dom-expressions: 0.36.10(@babel/core@7.21.4) + dev: true + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true @@ -4515,6 +4625,10 @@ packages: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: true + /html-entities@2.3.3: + resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==} + dev: true + /html-tags@3.3.1: resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} engines: {node: '>=8'} @@ -4895,6 +5009,11 @@ packages: call-bind: 1.0.2 dev: true + /is-what@4.1.8: + resolution: {integrity: sha512-yq8gMao5upkPoGEU9LsB2P+K3Kt8Q3fQFCGyNCWOAnJAMzEXVV9drYb0TXr42TTliLLhKIBvulgAXgtLLnwzGA==} + engines: {node: '>=12.13'} + dev: true + /is-wsl@2.2.0: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} @@ -5261,6 +5380,13 @@ packages: readable-stream: 2.3.8 dev: true + /merge-anything@5.1.4: + resolution: {integrity: sha512-7PWKwGOs5WWcpw+/OvbiFiAvEP6bv/QHiicigpqMGKIqPPAtGhBLR8LFJW+Zu6m9TXiR/a8+AiPlGG0ko1ruoQ==} + engines: {node: '>=12.13'} + dependencies: + is-what: 4.1.8 + dev: true + /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -6778,6 +6904,11 @@ packages: randombytes: 2.1.0 dev: true + /seroval@0.5.1: + resolution: {integrity: sha512-ZfhQVB59hmIauJG5Ydynupy8KHyr5imGNtdDhbZG68Ufh1Ynkv9KOYOAABf71oVbQxJ8VkWnMHAjEHE7fWkH5g==} + engines: {node: '>=10'} + dev: true + /serve-placeholder@2.0.1: resolution: {integrity: sha512-rUzLlXk4uPFnbEaIz3SW8VISTxMuONas88nYWjAWaM2W9VDbt9tyFOr3lq8RhVOFrT3XISoBw8vni5una8qMnQ==} dependencies: @@ -6865,6 +6996,24 @@ packages: resolution: {integrity: sha512-V21+XeNni+tTyiST1MHsa84AQhT1aFZipzPpOFAVB8DkHzwJyjjAmt9bgwnuZiZWnIbMo2duE29wybxv/7HWUw==} dev: true + /solid-js@1.7.3: + resolution: {integrity: sha512-4hwaF/zV/xbNeBBIYDyu3dcReOZBECbO//mrra6GqOrKy4Soyo+fnKjpZSa0nODm6j1aL0iQRh/7ofYowH+jzw==} + dependencies: + csstype: 3.1.2 + seroval: 0.5.1 + dev: true + + /solid-refresh@0.5.2(solid-js@1.7.3): + resolution: {integrity: sha512-I69HmFj0LsGRJ3n8CEMVjyQFgVtuM2bSjznu2hCnsY+i5oOxh8ioWj00nnHBv0UYD3WpE/Sq4Q3TNw2IKmKN7A==} + peerDependencies: + solid-js: ^1.3 + dependencies: + '@babel/generator': 7.21.4 + '@babel/helper-module-imports': 7.21.4 + '@babel/types': 7.21.4 + solid-js: 1.7.3 + dev: true + /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} @@ -7552,6 +7701,10 @@ packages: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true + /validate-html-nesting@1.2.1: + resolution: {integrity: sha512-T1ab131NkP3BfXB7KUSgV7Rhu81R2id+L6NaJ7NypAAG5iV6gXnPpQE5RK1fvb+3JYsPTL+ihWna5sr5RN9gaQ==} + dev: true + /validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: @@ -7633,6 +7786,25 @@ packages: vue-tsc: 1.2.0(typescript@5.0.4) dev: true + /vite-plugin-solid@2.7.0(solid-js@1.7.3)(vite@4.2.2): + resolution: {integrity: sha512-avp/Jl5zOp/Itfo67xtDB2O61U7idviaIp4mLsjhCa13PjKNasz+IID0jYTyqUp9SFx6/PmBr6v4KgDppqompg==} + peerDependencies: + solid-js: ^1.7.2 + vite: ^3.0.0 || ^4.0.0 + dependencies: + '@babel/core': 7.21.4 + '@babel/preset-typescript': 7.21.4(@babel/core@7.21.4) + '@types/babel__core': 7.20.0 + babel-preset-solid: 1.7.3(@babel/core@7.21.4) + merge-anything: 5.1.4 + solid-js: 1.7.3 + solid-refresh: 0.5.2(solid-js@1.7.3) + vite: 4.2.2(@types/node@18.15.12) + vitefu: 0.2.4(vite@4.2.2) + transitivePeerDependencies: + - supports-color + dev: true + /vite@4.2.2(@types/node@18.15.12): resolution: {integrity: sha512-PcNtT5HeDxb3QaSqFYkEum8f5sCVe0R3WK20qxgIvNBZPXU/Obxs/+ubBMeE7nLWeCo2LDzv+8hRYSlcaSehig==} engines: {node: ^14.18.0 || >=16.0.0} @@ -7667,6 +7839,17 @@ packages: fsevents: 2.3.2 dev: true + /vitefu@0.2.4(vite@4.2.2): + resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 + peerDependenciesMeta: + vite: + optional: true + dependencies: + vite: 4.2.2(@types/node@18.15.12) + dev: true + /vitepress@1.0.0-alpha.72(@algolia/client-search@4.17.0)(@types/node@18.15.12): resolution: {integrity: sha512-Ou7fNE/OVYLrKGQMHSTVG6AcNsdv7tm4ACrdhx93SPMzEDj8UgIb4RFa5CTTowaYf3jeDGi2EAJlzXVC+IE3dg==} hasBin: true diff --git a/tsconfig.json b/tsconfig.json index 9da9f5b..07b3cd1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -28,6 +28,7 @@ "exclude": [ "node_modules", "packages/react", + "packages/solid", "packages/vue", "**/*.md", "**/dist"