Skip to content

Commit

Permalink
feat: add CImage
Browse files Browse the repository at this point in the history
  • Loading branch information
Blackman99 committed Aug 14, 2023
1 parent 24491dd commit 83fd8b2
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/twenty-forks-burn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@casual-ui/svelte': minor
---

feat: add CImage
1 change: 1 addition & 0 deletions packages/docs/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ declare global {
const CExpansion: typeof import("@casual-ui/svelte")["CExpansion"]
const CForm: typeof import("@casual-ui/svelte")["CForm"]
const CFormItem: typeof import("@casual-ui/svelte")["CFormItem"]
const CImage: typeof import("@casual-ui/svelte")["CImage"]
const CInfoItem: typeof import("@casual-ui/svelte")["CInfoItem"]
const CInput: typeof import("@casual-ui/svelte")["CInput"]
const CList: typeof import("@casual-ui/svelte")["CList"]
Expand Down
4 changes: 4 additions & 0 deletions packages/docs/config/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ export default {
title: 'Icon',
to: '/features/components/basic/icon/',
},
{
title: 'Image',
to: '/features/components/basic/image/',
},
],
},
{
Expand Down
60 changes: 60 additions & 0 deletions packages/docs/src/routes/features/components/basic/image/+page.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
title: Image
componentName: CImage
---

## Basic

```svelte live
<script>
let src = 'https://picsum.photos/500/300'
const toggle = () => {
src = `https://picsum.photos/500/300?t=${Math.random()}`
}
</script>
<CButton label="Toggle image" on:click={toggle} />
<CImage width="500px" height="300px" {src} />
```

## Custom placeholder

```svelte live
<script>
let show = true
</script>
<CButton label="Toggle image" on:click={() => show = !show} />
{#if show}
<CImage width="500px" height="300px" src="https://picsum.photos/500/300" placeholderSrc="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMzIgMzIiPjxwYXRoIGZpbGw9IiMyZGNjOWYiIGQ9Ik0zMCA1Ljg1MXYyMC4yOThIMlY1Ljg1MWgyOCIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0yNC4yMzIgOC41NDFhMi4yIDIuMiAwIDEgMCAxLjEyNy42MjNhMi4yMTIgMi4yMTIgMCAwIDAtMS4xMjctLjYyM00xOC4xMTEgMjAuMXEtMi43MjQtMy43ODgtNS40NS03LjU3NUw0LjU3OSAyMy43NjZoMTAuOXExLjMxNi0xLjgzMiAyLjYzNC0zLjY2M00yMi4wNTcgMTZxLTIuNzkzIDMuODgyLTUuNTg0IDcuNzY1aDExLjE2OVEyNC44NTEgMTkuODgyIDIyLjA1NyAxNloiLz48L3N2Zz4=" />
{/if}
```

## Custom loading

```svelte live
<script>
let src = 'https://picsum.photos/500/300'
const toggle = () => {
src = `https://picsum.photos/500/300?t=${Math.random()}`
}
</script>
<CButton label="Toggle image" on:click={toggle} />
<div class="flex gap-4 mt-4">
<CImage width="100px" height="100px" {src}>
<div class="text-white">
<CLoadingLattice slot="loading" />
</div>
</CImage>
<CImage width="100px" height="100px" {src}>
<CLoadingPuff slot="loading" />
</CImage>
<CImage width="100px" height="100px" {src}>
<CLoadingPie slot="loading" />
</CImage>
</div>
```

:::important[Img native attrs]
All the props pass to `CImage` that not in prop list would directly add to `<img />` tag. You can add `decoding`, `draggable`, etc..
:::
1 change: 1 addition & 0 deletions packages/docs/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ export default defineConfig({
'CPagination',
'CTabs',
'CTabItem',
'CImage',
],
defaultImport: false,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/ui/import-icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,15 @@ import CCarouselSlider from './src/components/carousel/CCarouselSlider.svelte'
import CTree from './src/components/tree/CTree.svelte'
import CTabItem from './src/components/tabs/CTabItem.svelte'
import { attributeAtom } from './src/utils/attributeAtom'
import CImage from './src/components/CImage.svelte'

export { useFormProps } from './src/hooks/useForm'

export {
attributeAtom,
CCarouselSlider,
CTree,
CImage,
CTabItem,
CCarousel,
CTable,
Expand Down
2 changes: 2 additions & 0 deletions packages/ui/import-style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,13 @@ import CCarouselSlider from './src/components/carousel/CCarouselSlider.svelte'
import CTree from './src/components/tree/CTree.svelte'
import { attributeAtom } from './src/utils/attributeAtom'
import CTabItem from './src/components/tabs/CTabItem.svelte'
import CImage from './src/components/CImage.svelte'

export { useFormProps } from './src/hooks/useForm'

export {
attributeAtom,
CImage,
CCarouselSlider,
CTree,
CTabItem,
Expand Down
102 changes: 102 additions & 0 deletions packages/ui/src/components/CImage.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<script>
import { onMount } from 'svelte'
import CLoading from './CLoading.svelte'
/**
* The image src
* @type {string}
*/
export let src
/**
* The default image src
* @type
*/
export let placeholderSrc =
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMTYgMTYiPjxnIGZpbGw9ImN1cnJlbnRDb2xvciI+PHBhdGggZD0iTTYuMDAyIDUuNWExLjUgMS41IDAgMSAxLTMgMGExLjUgMS41IDAgMCAxIDMgMHoiLz48cGF0aCBkPSJNMi4wMDIgMWEyIDIgMCAwIDAtMiAydjEwYTIgMiAwIDAgMCAyIDJoMTJhMiAyIDAgMCAwIDItMlYzYTIgMiAwIDAgMC0yLTJoLTEyem0xMiAxYTEgMSAwIDAgMSAxIDF2Ni41bC0zLjc3Ny0xLjk0N2EuNS41IDAgMCAwLS41NzcuMDkzbC0zLjcxIDMuNzFsLTIuNjYtMS43NzJhLjUuNSAwIDAgMC0uNjMuMDYyTDEuMDAyIDEyVjNhMSAxIDAgMCAxIDEtMWgxMnoiLz48L2c+PC9zdmc+'
/**
* The image width
* @type {string}
*/
export let width = '100%'
/**
* The image height
* @type {string}
*/
export let height = '300px'
/**
* The alt prop
* @type {string}
*/
export let alt = ''
/**
* The class that apply to img tag
* @type {string}
*/
export let imgClass = ''
/**
* Custom image request headers
* @type {object}
*/
export let customHeaders = {}
/**
* The last successfully loaded image src
*/
let lastSrc = placeholderSrc
let mounted = false
const fetchImage = () => {
if (!mounted) return
return fetch(src, {
method: 'GET',
headers: customHeaders,
})
.then(r => r.blob())
.then(blob => {
lastSrc = URL.createObjectURL(blob)
return lastSrc
})
}
let imagePromise
onMount(() => {
mounted = true
imagePromise = fetchImage()
})
$: {
src
imagePromise = fetchImage()
}
</script>

<div
class="c-image"
style:width
style:height
style:background-image="url({lastSrc})"
>
{#if imagePromise}
{#await imagePromise}
<div class="c-image--loading">
<slot name="loading">
<CLoading />
</slot>
</div>
{:then src}
<img {src} {alt} {width} class="{imgClass}" {...$$restProps} />
{:catch err}
<slot name="err" {err}>
<div>
{err}
</div>
</slot>
{/await}
{/if}
</div>
2 changes: 2 additions & 0 deletions packages/ui/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import CImage from './components/CImage.svelte'
import CButton from './components/CButton.svelte'
import CAjaxBar from './components/CAjaxBar.svelte'
import CExpansion from './components/CExpansion.svelte'
Expand Down Expand Up @@ -61,6 +62,7 @@ export { useFormProps } from './hooks/useForm'
export {
attributeAtom,
CTabItem,
CImage,
CPagination,
CTree,
CParallax,
Expand Down

0 comments on commit 83fd8b2

Please sign in to comment.