svelte-remote-image 0.2.6 → 0.3.1

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.
package/README.md CHANGED
@@ -6,7 +6,7 @@ Display optimized, responsive and progressive images for Svelte.
6
6
  With remote image URL of CDN or other means.
7
7
 
8
8
  - Fade-in and blur on image reveal.
9
- - An image URL can be set to failback if an image cannot be retrieved from the source URL due to an error.
9
+ - An image URL can be set to fallback if an image cannot be retrieved from the source URL due to an error.
10
10
  - A pre-rendered low-quality dataURI can be set as a placeholder.
11
11
 
12
12
 
@@ -21,13 +21,15 @@ $ npm i svelte-remote-image
21
21
  And import components and types.
22
22
 
23
23
  ```
24
- import { Image, type ImageSrc } from "svelte-remote-image";
24
+ import { Img, Picture, type ImgSrc, type PictureSrc } from "svelte-remote-image";
25
25
  ```
26
26
 
27
27
  ## How to use
28
28
 
29
29
  Sample code.
30
30
 
31
+ ### Img
32
+
31
33
  ```
32
34
  <script lang="ts">
33
35
  import { Image, type ImageSrc } from "svelte-remote-image";
@@ -36,46 +38,39 @@ Sample code.
36
38
  const optimazerPrefix = 'https://nostr-image-optimizer.ocknamo.com/image/';
37
39
  const originalImageUrl = 'https://ocknamo.com/static/b84d6366deec053ff3fa77df01a54464/dccd3/cat.webp'
38
40
 
39
- let src: ImageSrc = {
40
- w: 800,
41
- img: `${optimazerPrefix}width=1600,quality=70,format=webp/${originalImageUrl}`,
42
- webp: [
43
- { src: `${optimazerPrefix}width=1600,quality=50,format=webp/${originalImageUrl}`, w: 1600 },
44
- { src: `${optimazerPrefix}width=800,quality=50,format=webp/${originalImageUrl}`, w: 800 }
45
- ],
46
- jpeg: [
47
- { src: `${optimazerPrefix}width=1600,quality=50,format=jpeg/${originalImageUrl}`, w: 1600 },
48
- { src: `${optimazerPrefix}width=800,quality=50,format=jpeg/${originalImageUrl}`, w: 800 }
49
- ],
50
- failback: originalImageUrl,
51
- alt: 'blog top',
52
- placeholder: { dataUri: '', color: '#c5c5c5' },
53
- blur: true
54
- };
41
+ const imgSrc: ImgSrc = {
42
+ w: 800,
43
+ img: `https://ocknamo.com/cat.jpg`,
44
+ srssets: [
45
+ {
46
+ src: `https://ocknamo.com/cat_1600.jpg`,
47
+ w: 1600,
48
+ },
49
+ {
50
+ src: `https://ocknamo.com/cat_800.jpg`,
51
+ w: 800,
52
+ },
53
+ ],
54
+ fallback: ['https://ocknamo.com/cat_fallback.jpg'],
55
+ }
55
56
  </script>
56
57
 
57
- <Image {src} />
58
+ <Img src={imgSrc} style='max-width: 400px; max-width: 80%;' />
58
59
  ```
59
60
 
60
61
  The image component renders into:
61
62
 
62
63
  ```
63
- <picture>
64
- <source
65
- srcset="https://nostr-image-optimizer.ocknamo.com/image/width=1600,quality=50,format=webp/https://ocknamo.com/static/b84d6366deec053ff3fa77df01a54464/dccd3/cat.webp 1600w, https://nostr-image-optimizer.ocknamo.com/image/width=800,quality=50,format=webp/https://ocknamo.com/static/b84d6366deec053ff3fa77df01a54464/dccd3/cat.webp 800w"
66
- type="image/webp">
67
- <source
68
- srcset="https://nostr-image-optimizer.ocknamo.com/image/width=1600,quality=50,format=jpeg/https://ocknamo.com/static/b84d6366deec053ff3fa77df01a54464/dccd3/cat.webp 1600w, https://nostr-image-optimizer.ocknamo.com/image/width=800,quality=50,format=jpeg/https://ocknamo.com/static/b84d6366deec053ff3fa77df01a54464/dccd3/cat.webp 800w"
69
- type="image/jpeg"> <img width="800"
70
- style="max-width: 100%; background-color: '#c5c5c5'; display: inline;"
71
- class="image-blur-loaded"
72
- src="https://nostr-image-optimizer.ocknamo.com/image/width=1600,quality=70,format=webp/https://ocknamo.com/static/b84d6366deec053ff3fa77df01a54464/dccd3/cat.webp"
73
- alt="blog top" loading="lazy">
74
- </picture>
64
+ <img id="svelte-remote-image--6188058" width="800" style="max-width: 80%; visibility: hidden;"
65
+ src="https://ocknamo.com/cat_fallback.jpg" srcset="" alt="" title="" loading="lazy" class="s-6LbhuE7J5MgN">
75
66
  ```
76
67
 
77
68
  Inspired by [svelte-img](https://github.com/zerodevx/svelte-img?tab=readme-ov-file#remote-images-from-an-api).
78
69
 
70
+ ### Picture
71
+
72
+ TBD
73
+
79
74
  ## Config
80
75
 
81
76
  ### ImageSrc
@@ -92,6 +87,10 @@ Image width.
92
87
 
93
88
  Image height.
94
89
 
90
+ #### srssets: Srcset[]
91
+
92
+ Image sources for Img component.
93
+
95
94
  #### webp?: Srcset[]
96
95
 
97
96
  Image sources for webp.
@@ -104,7 +103,7 @@ Image sources for jpeg.
104
103
 
105
104
  Image sources for png.
106
105
 
107
- #### failback: string[]
106
+ #### fallback: string[]
108
107
 
109
108
  Failback image urls.
110
109
  The order is important because the images are tested in order from the top of the array.
@@ -0,0 +1,74 @@
1
+ <script>import { browser } from "$app/environment";
2
+ import { afterUpdate } from "svelte";
3
+ export let src;
4
+ export let style;
5
+ export const alt = "";
6
+ export const title = "";
7
+ const imgId = `svelte-remote-image-${alt.replaceAll(" ", "-")}-${Math.round(Math.random() * 1e7)}`;
8
+ const getImgElement = () => browser ? document.getElementById(imgId) : null;
9
+ afterUpdate(async () => {
10
+ const img = getImgElement();
11
+ if (!img) {
12
+ return;
13
+ }
14
+ if (img.naturalWidth !== 0 && img.naturalHeight !== 0) {
15
+ img.style.visibility = "visible";
16
+ } else {
17
+ handleImgError();
18
+ }
19
+ });
20
+ const handleImgError = (e) => {
21
+ if (e && e.type !== "error") {
22
+ return;
23
+ }
24
+ if (!src.fallback) {
25
+ return;
26
+ }
27
+ const img = getImgElement();
28
+ if (!img) {
29
+ return;
30
+ }
31
+ img.style.visibility = "hidden";
32
+ let fallbackUrl = void 0;
33
+ const index = src.fallback.findIndex(
34
+ (url) => new URL(url).toString() === new URL(img.src).toString()
35
+ );
36
+ if (index === -1) {
37
+ fallbackUrl = src.fallback[0];
38
+ } else {
39
+ fallbackUrl = src.fallback[index + 1];
40
+ }
41
+ if (!fallbackUrl) {
42
+ return;
43
+ }
44
+ src = {
45
+ ...src,
46
+ img: fallbackUrl,
47
+ srcsets: []
48
+ };
49
+ };
50
+ const handleLoaded = (e) => {
51
+ const img = e.currentTarget;
52
+ img.style.visibility = "visible";
53
+ };
54
+ </script>
55
+
56
+ <img
57
+ id={imgId}
58
+ width={src.w}
59
+ height={src.h}
60
+ {style}
61
+ src={src.img}
62
+ srcset={src.srcsets ? src.srcsets.map((s) => `${s.src} ${s.w}w`).join(', ') : ''}
63
+ alt={alt}
64
+ title={title}
65
+ on:error={handleImgError}
66
+ on:load={handleLoaded}
67
+ loading="lazy"
68
+ />
69
+
70
+ <style>
71
+ img {
72
+ visibility: hidden;
73
+ }
74
+ </style>
@@ -0,0 +1,24 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { ImgSrc } from './type.js';
3
+ declare const __propDef: {
4
+ props: {
5
+ src: ImgSrc;
6
+ style: any;
7
+ alt?: string | undefined;
8
+ title?: string | undefined;
9
+ };
10
+ events: {
11
+ [evt: string]: CustomEvent<any>;
12
+ };
13
+ slots: {};
14
+ exports?: {} | undefined;
15
+ bindings?: string | undefined;
16
+ };
17
+ export type ImgProps = typeof __propDef.props;
18
+ export type ImgEvents = typeof __propDef.events;
19
+ export type ImgSlots = typeof __propDef.slots;
20
+ export default class Img extends SvelteComponent<ImgProps, ImgEvents, ImgSlots> {
21
+ get alt(): string;
22
+ get title(): string;
23
+ }
24
+ export {};
@@ -38,7 +38,7 @@ const handleImgError = (e) => {
38
38
  if (e && e.type !== "error") {
39
39
  return;
40
40
  }
41
- if (!src.failback) {
41
+ if (!src.fallback) {
42
42
  return;
43
43
  }
44
44
  const img = getImgElement();
@@ -49,21 +49,21 @@ const handleImgError = (e) => {
49
49
  if (!img.complete) {
50
50
  return;
51
51
  }
52
- let failbackUrl = void 0;
53
- const index = src.failback.findIndex(
52
+ let fallbackUrl = void 0;
53
+ const index = src.fallback.findIndex(
54
54
  (url) => new URL(url).toString() === new URL(img.src).toString()
55
55
  );
56
56
  if (index === -1) {
57
- failbackUrl = src.failback[0];
57
+ fallbackUrl = src.fallback[0];
58
58
  } else {
59
- failbackUrl = src.failback[index + 1];
59
+ fallbackUrl = src.fallback[index + 1];
60
60
  }
61
- if (!failbackUrl) {
61
+ if (!fallbackUrl) {
62
62
  return;
63
63
  }
64
64
  src = {
65
65
  ...src,
66
- img: failbackUrl,
66
+ img: fallbackUrl,
67
67
  webp: [],
68
68
  jpeg: [],
69
69
  png: [],
@@ -1,8 +1,8 @@
1
1
  import { SvelteComponent } from "svelte";
2
- import type { ImageSrc } from './image.type.js';
2
+ import type { PictureSrc } from './type.js';
3
3
  declare const __propDef: {
4
4
  props: {
5
- src: ImageSrc;
5
+ src: PictureSrc;
6
6
  style?: string | undefined;
7
7
  alt?: string | undefined;
8
8
  title?: string | undefined;
@@ -14,10 +14,10 @@ declare const __propDef: {
14
14
  exports?: {} | undefined;
15
15
  bindings?: string | undefined;
16
16
  };
17
- export type ImageProps = typeof __propDef.props;
18
- export type ImageEvents = typeof __propDef.events;
19
- export type ImageSlots = typeof __propDef.slots;
20
- export default class Image extends SvelteComponent<ImageProps, ImageEvents, ImageSlots> {
17
+ export type PictureProps = typeof __propDef.props;
18
+ export type PictureEvents = typeof __propDef.events;
19
+ export type PictureSlots = typeof __propDef.slots;
20
+ export default class Picture extends SvelteComponent<PictureProps, PictureEvents, PictureSlots> {
21
21
  get alt(): string;
22
22
  get title(): string;
23
23
  }
@@ -2,17 +2,24 @@ export interface Srcset {
2
2
  src: string;
3
3
  w: number;
4
4
  }
5
- export interface ImageSrc {
5
+ export interface PictureSrc {
6
6
  img: string;
7
7
  w?: number;
8
8
  h?: number;
9
9
  webp?: Srcset[];
10
10
  jpeg?: Srcset[];
11
11
  png?: Srcset[];
12
- failback?: string[];
12
+ fallback?: string[];
13
13
  placeholder?: {
14
14
  dataUri?: string;
15
15
  color?: string;
16
16
  };
17
17
  blur?: boolean;
18
18
  }
19
+ export interface ImgSrc {
20
+ img: string;
21
+ srcsets?: Srcset[];
22
+ w?: number;
23
+ h?: number;
24
+ fallback?: string[];
25
+ }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- export * from './components/image.type'
2
- import Image from './components/Image.svelte'
1
+ export * from './components/type'
2
+ import Picture from './components/Picture.svelte'
3
+ import Img from './components/Picture.svelte'
3
4
 
4
- export { Image }
5
+ export { Picture, Img }
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  // Reexport your entry components here
2
- import Image from './components/Image.svelte';
3
- export { Image };
2
+ import Picture from './components/Picture.svelte';
3
+ import Img from './components/Img.svelte';
4
+ export { Picture, Img };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-remote-image",
3
- "version": "0.2.6",
3
+ "version": "0.3.1",
4
4
  "license": "MIT",
5
5
  "homepage": "https://github.com/ocknamo/svelte-remote-image",
6
6
  "scripts": {
@@ -27,7 +27,8 @@
27
27
  "!dist/**/*.spec.*"
28
28
  ],
29
29
  "peerDependencies": {
30
- "svelte": "^4.0.0"
30
+ "svelte": "^4.0.0",
31
+ "@sveltejs/kit": "^2.0.0"
31
32
  },
32
33
  "devDependencies": {
33
34
  "@biomejs/biome": "^1.8.1",
File without changes