Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ jobs:
- name: Build SolidStart
run: pnpm --filter @solidjs/start build

- name: Build @solidjs/image
run: pnpm --filter @solidjs/image build

- name: Build Test Project
run: pnpm --filter tests build

Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,5 @@ tsconfig.tsbuildinfo
apps/tests/**/test-results
.solid-start
.pnpm-store

.image
1 change: 1 addition & 0 deletions apps/tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"test:all": "pnpm run unit:ci && pnpm run e2e && pnpm run e2e:bundled-dev"
},
"dependencies": {
"@solidjs/image": "workspace:*",
"@solidjs/meta": "^0.29.4",
"@solidjs/router": "^0.15.4",
"@solidjs/start": "workspace:*",
Expand Down
Binary file added apps/tests/src/images/example.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions apps/tests/src/routes/image-local.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { SolidImage as Image } from "@solidjs/image";
import { type JSX, onMount, Show } from "solid-js";
import exampleImage from "../images/example.jpg?image";

interface PlaceholderProps {
show: () => void;
}

function Placeholder(props: PlaceholderProps): JSX.Element {
onMount(() => {
props.show();
});

return <div>Loading...</div>;
}

export default function App(): JSX.Element {
return (
<div style={{ width: "50vw" }}>
<Image
{...exampleImage}
alt="example"
fallback={(visible, show) => (
<Show when={visible()}>
<Placeholder show={show} />
</Show>
)}
/>
</div>
);
}
35 changes: 35 additions & 0 deletions apps/tests/src/routes/image-remote.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { SolidImage as Image } from "@solidjs/image";
import { type JSX, onMount, Show } from "solid-js";
// local
// import exampleImage from './example.jpg?image';

// remote
import exampleImage from "image:foobar";

interface PlaceholderProps {
show: () => void;
}

function Placeholder(props: PlaceholderProps): JSX.Element {
onMount(() => {
props.show();
});

return <div>Loading...</div>;
}

export default function App(): JSX.Element {
return (
<div style={{ width: "50vw" }}>
<Image
{...exampleImage}
alt="example"
fallback={(visible, show) => (
<Show when={visible()}>
<Placeholder show={show} />
</Show>
)}
/>
</div>
);
}
2 changes: 1 addition & 1 deletion apps/tests/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"allowJs": true,
"strict": true,
"noEmit": true,
"types": ["vitest/globals", "@testing-library/jest-dom", "@solidjs/start/env"],
"types": ["vitest/globals", "@testing-library/jest-dom", "@solidjs/start/env", "@solidjs/image/env"],
"isolatedModules": true,
"paths": {
"~/*": ["./src/*"],
Expand Down
41 changes: 41 additions & 0 deletions apps/tests/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { nitro } from "nitro/vite";
import { defineConfig } from "vite";
import { solidStart } from "../../packages/start/src/config";
import { imagePlugin } from '../../packages/image/src/vite';

export default defineConfig({
server: {
Expand Down Expand Up @@ -28,5 +29,45 @@ export default defineConfig({
nitro({
compressPublicAssets: true,
}),
imagePlugin({
local: {
sizes: [480, 600],
quality: 80,
publicPath: "public",
},
remote: {
transformURL(url) {
return {
src: {
source: `https://picsum.photos/seed/${url}/1200/900.webp`,
width: 1080,
height: 760,
},
variants: [
{
path: `https://picsum.photos/seed/${url}/800/600.jpg`,
width: 800,
type: "image/jpeg",
},
{
path: `https://picsum.photos/seed/${url}/400/300.jpg`,
width: 400,
type: "image/jpeg",
},
{
path: `https://picsum.photos/seed/${url}/800/600.png`,
width: 800,
type: "image/png",
},
{
path: `https://picsum.photos/seed/${url}/400/300.png`,
width: 400,
type: "image/png",
},
],
};
},
},
}),
],
});
185 changes: 185 additions & 0 deletions packages/image/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
# `@solidjs/image`

## Install

```bash
npm i @solidjs/image
```

```bash
pnpm add @solidjs/image
```

## Setup

### Vite

```ts
import { imagePlugin } from '@solidjs/image/vite';

export default defineConfig({
plugins: {
imagePlugin({
/**
* Used to process local image imports
*
* example:
* import myImage from './path/to/my-image.jpg?image';
*/
local: {
/**
* Image formats that can be processed
*/
input: ['jpeg', 'png'],
/**
* Image format for the output images.
*
* Take note that each input image will
* produce a new image for each format
*/
output: ['jpeg', 'png'],
/**
* Sizes of the output images, based on width
* while retaining the aspect ratio.
*
* This option also produces an image for
* each width and for each output format.
*/
sizes: [480, 600],
/**
* Quality of the processed images
*/
quality: 80,
/**
* Where the processed images as emitted
*/
publicPath: "public",
},
/**
* Used for remote images
*
* example:
* import myImage from 'image:my-value';
*/
remote: {
/**
* Transforms the right-hand part of the `image:*` string
*/
transformURL(url) {
return {
/**
* The default image for the given url
*/
src: {
source: `https://picsum.photos/seed/${url}/1200/900.webp`,
width: 1080,
height: 760,
},
/**
* Variants of the image (format, size) for responsiveness
*/
variants: [
{
path: `https://picsum.photos/seed/${url}/800/600.jpg`,
width: 800,
type: "image/jpeg",
},
{
path: `https://picsum.photos/seed/${url}/400/300.jpg`,
width: 400,
type: "image/jpeg",
},
{
path: `https://picsum.photos/seed/${url}/800/600.png`,
width: 800,
type: "image/png",
},
{
path: `https://picsum.photos/seed/${url}/400/300.png`,
width: 400,
type: "image/png",
},
],
};
},
},
}),
}
});
```

## Usage

### Local image

```tsx
import { SolidImage as Image } from "@solidjs/image";
import { type JSX, onMount, Show } from "solid-js";

import exampleImage from "../images/example.jpg?image";

interface PlaceholderProps {
show: () => void;
}

function Placeholder(props: PlaceholderProps): JSX.Element {
onMount(() => {
props.show();
});

return <div>Loading...</div>;
}

export default function App(): JSX.Element {
return (
<div style={{ width: "50vw" }}>
<Image
{...exampleImage}
alt="example"
fallback={(visible, show) => (
<Show when={visible()}>
<Placeholder show={show} />
</Show>
)}
/>
</div>
);
}
```

### Remote image

```tsx
import { SolidImage as Image } from "@solidjs/image";
import { type JSX, onMount, Show } from "solid-js";

import exampleImage from "image:foobar";

interface PlaceholderProps {
show: () => void;
}

function Placeholder(props: PlaceholderProps): JSX.Element {
onMount(() => {
props.show();
});

return <div>Loading...</div>;
}

export default function App(): JSX.Element {
return (
<div style={{ width: "50vw" }}>
<Image
{...exampleImage}
alt="example"
fallback={(visible, show) => (
<Show when={visible()}>
<Placeholder show={show} />
</Show>
)}
/>
</div>
);
}
```
44 changes: 44 additions & 0 deletions packages/image/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "@solidjs/image",
"type": "module",
"repository": {
"type": "git",
"url": "git+https://github.com/solidjs/solid-start.git",
"directory": "packages/image"
},
"publishConfig": {
"access": "public"
},
"files": [
"dist"
],
"scripts": {
"prepublishOnly": "tsdown",
"build": "tsdown",
"watch": "tsdown --watch",
"test": "vitest"
},
"devDependencies": {
"@tsdown/css": "^0.22.12",
"@types/node": "^25.5.0",
"solid-js": "^1.9.9",
"tsdown": "^0.22.12",
"vite": "^8.1.5",
"vite-plugin-solid": "^2.11.11",
"vitest": "^4.0.10"
},
"dependencies": {
"sharp": "^0.35.3"
},
"peerDependencies": {
"solid-js": "^1.9.9",
"vite": "^8 || ^9"
},
"exports": {
".": "./dist/index.jsx",
"./env": "./dist/env.js",
"./vite": "./dist/vite.js",
"./package.json": "./package.json",
"./style.css": "./dist/style.css"
}
}
Loading
Loading