@picked/svelte 0.0.1-dev.1764287278696 → 0.0.1-dev.1764358457580

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/dist/index.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  export { adaptSvelteComponent, isValidAdaptedComponent } from './component';
2
- export type { ComponentWithProps } from './component';
3
- export { LazyImage } from './components';
2
+ export type * from './component';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{adaptSvelteComponent as o,isValidAdaptedComponent as t}from"./component.js";import{default as d}from"./components/LazyImage.svelte";export{d as LazyImage,o as adaptSvelteComponent,t as isValidAdaptedComponent};
1
+ import{adaptSvelteComponent as t,isValidAdaptedComponent as p}from"./component.js";export{t as adaptSvelteComponent,p as isValidAdaptedComponent};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@picked/svelte",
3
- "version": "0.0.1-dev.1764287278696",
3
+ "version": "0.0.1-dev.1764358457580",
4
4
  "dependencies": {
5
5
  "d3": "^7.9.0"
6
6
  },
@@ -71,7 +71,7 @@
71
71
  ],
72
72
  "module": "./dist/index.js",
73
73
  "peerDependencies": {
74
- "@picked/client": "0.0.1-dev.1764287278696",
74
+ "@picked/client": "0.0.1-dev.1764358457580",
75
75
  "effector": "^23.3.0",
76
76
  "svelte": "^5.34.3"
77
77
  },
@@ -1,196 +0,0 @@
1
- <script lang="ts">
2
- import type { HTMLImgAttributes } from 'svelte/elements'
3
- import { onMount } from 'svelte'
4
-
5
- type CommonProps = Omit<HTMLImgAttributes, 'src' | 'loading' | 'width' | 'height'> & {
6
- src: string
7
- loading?: 'eager' | 'lazy'
8
- alt: string
9
- sizes?: string
10
- objectFit?: string
11
- }
12
-
13
- type FillProps = {
14
- fill: true
15
- width?: never
16
- height?: never
17
- }
18
-
19
- type FixedSizeProps = {
20
- fill?: false
21
- width: number
22
- height: number
23
- }
24
-
25
- type Props = (CommonProps & FillProps) | (CommonProps & FixedSizeProps)
26
-
27
- const {
28
- src,
29
- width,
30
- height,
31
- loading = 'lazy',
32
- alt,
33
- sizes = '100vw',
34
- objectFit = 'cover',
35
- fill = false,
36
- ...restProps
37
- }: Props = $props()
38
-
39
- let imgElement = $state<HTMLImageElement | undefined>(undefined)
40
- let placeholderElement = $state<HTMLDivElement | undefined>(undefined)
41
- let isLoaded = $state(false)
42
- let isInView = $state(false)
43
- let observer: IntersectionObserver | undefined
44
-
45
- const aspectRatio = $derived.by(() =>
46
- !fill && typeof width === 'number' && typeof height === 'number' && height !== 0
47
- ? width / height
48
- : undefined,
49
- )
50
-
51
- const SUPPORTED_SIZES = [
52
- 16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840,
53
- ]
54
-
55
- function findClosestSize(targetSize: number): number {
56
- const roundedTargetSize = Math.round(targetSize)
57
- return SUPPORTED_SIZES.reduce(
58
- (prev, curr) =>
59
- Math.abs(curr - roundedTargetSize) < Math.abs(prev - roundedTargetSize) ? curr : prev,
60
- SUPPORTED_SIZES[0],
61
- )
62
- }
63
-
64
- function isConvincelyDomain(url: URL): boolean {
65
- try {
66
- return url.hostname.endsWith('.convincely.io')
67
- } catch {
68
- return false
69
- }
70
- }
71
-
72
- function isShopifyDomain(url: URL): boolean {
73
- try {
74
- return url.hostname === 'cdn.shopify.com'
75
- } catch {
76
- return false
77
- }
78
- }
79
-
80
- function getOptimizedImageUrl(imageSrc: string, targetWidth: number): string {
81
- try {
82
- const url = new URL(imageSrc, import.meta.url)
83
- if (isConvincelyDomain(url)) {
84
- if (
85
- import.meta.env.VERCEL_DEPLOYMENT_ID &&
86
- import.meta.env.VERCEL_SKEW_PROTECTION_ENABLED === '1'
87
- ) {
88
- url.searchParams.set('dpl', import.meta.env.VERCEL_DEPLOYMENT_ID)
89
- }
90
- const encodedUrl = encodeURIComponent(url.toString())
91
- const optimizedSize = findClosestSize(targetWidth)
92
- return `https://img.convincely.io/_next/image?url=${encodedUrl}&w=${optimizedSize}&q=75`
93
- }
94
- if (isShopifyDomain(url)) {
95
- const optimizedSize = findClosestSize(targetWidth)
96
- url.searchParams.set('width', optimizedSize.toString())
97
- return url.toString()
98
- }
99
- return getImgUrl(imageSrc)
100
- } catch {
101
- return getImgUrl(imageSrc)
102
- }
103
- }
104
-
105
- function getImgUrl(imageSrc: string): string {
106
- if (imageSrc.startsWith('data:')) {
107
- return imageSrc
108
- }
109
- const baseUrl = new URL(import.meta.url).origin
110
- return imageSrc.startsWith('http') ? imageSrc : `${baseUrl}${imageSrc}`
111
- }
112
-
113
- function handleLoad() {
114
- isLoaded = true
115
- }
116
-
117
- onMount(() => {
118
- if (loading === 'lazy') {
119
- const elementToObserve = placeholderElement || imgElement
120
- if (elementToObserve) {
121
- observer = new IntersectionObserver(
122
- (entries) => {
123
- entries.forEach((entry) => {
124
- if (entry.isIntersecting) {
125
- isInView = true
126
- observer?.unobserve(entry.target)
127
- }
128
- })
129
- },
130
- {
131
- rootMargin: '50px',
132
- },
133
- )
134
- observer.observe(elementToObserve)
135
- return () => {
136
- observer?.disconnect()
137
- }
138
- }
139
- } else if (loading === 'eager') {
140
- isInView = true
141
- }
142
- })
143
-
144
- const shouldLoadImage = $derived(loading === 'eager' || isInView)
145
-
146
- const widthCandidates = $derived.by(() => {
147
- if (typeof width === 'number' && Number.isFinite(width)) {
148
- const filtered = SUPPORTED_SIZES.filter((w) => w <= width)
149
- return filtered.length ? filtered : [width]
150
- }
151
- return SUPPORTED_SIZES
152
- })
153
-
154
- const srcSet = $derived.by(() =>
155
- widthCandidates.map((w) => `${getOptimizedImageUrl(src, w)} ${w}w`).join(', '),
156
- )
157
-
158
- const fallbackSrc = $derived.by(() =>
159
- getOptimizedImageUrl(src, widthCandidates[0]),
160
- )
161
-
162
- const fadeClasses = $derived.by(() => {
163
- if (loading === 'eager') return ''
164
- return `transition-opacity duration-300 ${isLoaded ? 'opacity-100' : 'opacity-0'}`
165
- })
166
- </script>
167
-
168
- {#if shouldLoadImage}
169
- <img
170
- {...restProps}
171
- bind:this={imgElement}
172
- src={fallbackSrc}
173
- srcset={srcSet}
174
- {sizes}
175
- width={fill ? undefined : width}
176
- height={fill ? undefined : height}
177
- {alt}
178
- style:aspect-ratio={aspectRatio}
179
- style:object-fit={objectFit}
180
- style:position={fill ? 'absolute' : undefined}
181
- style:inset={fill ? 0 : undefined}
182
- {loading}
183
- onload={handleLoad}
184
- class="{fadeClasses} {restProps.class || ''}"
185
- data-testid="lazy-image-element"
186
- />
187
- {:else}
188
- <div
189
- bind:this={placeholderElement}
190
- style:aspect-ratio={aspectRatio}
191
- style:position={fill ? 'absolute' : undefined}
192
- style:inset={fill ? 0 : undefined}
193
- aria-label={alt}
194
- data-testid="lazy-image-placeholder"
195
- ></div>
196
- {/if}
@@ -1 +0,0 @@
1
- export { default as LazyImage } from './LazyImage.svelte';
@@ -1 +0,0 @@
1
- import{default as f}from"./LazyImage.svelte";export{f as LazyImage};