diff --git a/COMPONENT_INDEX.md b/COMPONENT_INDEX.md
index e7560f4f..a1634e3c 100644
--- a/COMPONENT_INDEX.md
+++ b/COMPONENT_INDEX.md
@@ -1,6 +1,6 @@
# Component Index
-> 158 components exported from carbon-components-svelte@0.29.2.
+> 159 components exported from carbon-components-svelte@0.29.2.
## Components
@@ -61,6 +61,7 @@
- [`HeaderUtilities`](#headerutilities)
- [`Icon`](#icon)
- [`IconSkeleton`](#iconskeleton)
+- [`ImageLoader`](#imageloader)
- [`InlineLoading`](#inlineloading)
- [`InlineNotification`](#inlinenotification)
- [`Link`](#link)
@@ -1724,6 +1725,35 @@ None.
| mouseenter | forwarded | -- |
| mouseleave | forwarded | -- |
+## `ImageLoader`
+
+### Props
+
+| Prop name | Kind | Reactive | Type | Default value | Description |
+| :-------- | :----------------- | :------- | :------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
+| error | let | Yes | boolean | false | Set to `true` if an error occurs when loading the image |
+| loaded | let | Yes | boolean | false | Set to `true` when the image is loaded |
+| loading | let | Yes | boolean | false | Set to `true` when `loaded` is `true` and `error` is false |
+| src | let | No | string | "" | Specify the image source |
+| alt | let | No | string | "" | Specify the image alt text |
+| ratio | let | No | "2x1" | "16x9" | "4x3" | "1x1" | "3x4" | "9x16" | "1x2" | -- | Specify the aspect ratio for the image wrapper |
+| fadeIn | let | No | boolean | false | Set to `true` to fade in the image on load The duration uses the `fast-02` value following Carbon guidelines on motion |
+| loadImage | const | No | (url?: string) => void | (url) => { if (image != null) image = null; loaded = false; error = false; image = new Image(); image.src = url || src; image.onload = () => (loaded = true); image.onerror = () => (error = true); } | Method invoked to load the image provided a `src` value |
+
+### Slots
+
+| Slot name | Default | Props | Fallback |
+| :-------- | :------ | :---- | :------- |
+| error | No | -- | -- |
+| loading | No | -- | -- |
+
+### Events
+
+| Event name | Type | Detail |
+| :--------- | :--------- | :--------------- |
+| load | dispatched | any |
+| error | dispatched | any |
+
## `InlineLoading`
### Props
diff --git a/docs/src/COMPONENT_API.json b/docs/src/COMPONENT_API.json
index 36a178e9..cdc5beef 100644
--- a/docs/src/COMPONENT_API.json
+++ b/docs/src/COMPONENT_API.json
@@ -1,5 +1,5 @@
{
- "total": 158,
+ "total": 159,
"components": [
{
"moduleName": "Accordion",
@@ -4052,6 +4052,101 @@
"typedefs": [],
"rest_props": { "type": "Element", "name": "div" }
},
+ {
+ "moduleName": "ImageLoader",
+ "filePath": "src/ImageLoader/ImageLoader.svelte",
+ "props": [
+ {
+ "name": "src",
+ "kind": "let",
+ "description": "Specify the image source",
+ "type": "string",
+ "value": "\"\"",
+ "isFunction": false,
+ "constant": false,
+ "reactive": false
+ },
+ {
+ "name": "alt",
+ "kind": "let",
+ "description": "Specify the image alt text",
+ "type": "string",
+ "value": "\"\"",
+ "isFunction": false,
+ "constant": false,
+ "reactive": false
+ },
+ {
+ "name": "ratio",
+ "kind": "let",
+ "description": "Specify the aspect ratio for the image wrapper",
+ "type": "\"2x1\" | \"16x9\" | \"4x3\" | \"1x1\" | \"3x4\" | \"9x16\" | \"1x2\"",
+ "isFunction": false,
+ "constant": false,
+ "reactive": false
+ },
+ {
+ "name": "loading",
+ "kind": "let",
+ "description": "Set to `true` when `loaded` is `true` and `error` is false",
+ "type": "boolean",
+ "value": "false",
+ "isFunction": false,
+ "constant": false,
+ "reactive": true
+ },
+ {
+ "name": "loaded",
+ "kind": "let",
+ "description": "Set to `true` when the image is loaded",
+ "type": "boolean",
+ "value": "false",
+ "isFunction": false,
+ "constant": false,
+ "reactive": true
+ },
+ {
+ "name": "error",
+ "kind": "let",
+ "description": "Set to `true` if an error occurs when loading the image",
+ "type": "boolean",
+ "value": "false",
+ "isFunction": false,
+ "constant": false,
+ "reactive": true
+ },
+ {
+ "name": "fadeIn",
+ "kind": "let",
+ "description": "Set to `true` to fade in the image on load\nThe duration uses the `fast-02` value following Carbon guidelines on motion",
+ "type": "boolean",
+ "value": "false",
+ "isFunction": false,
+ "constant": false,
+ "reactive": false
+ },
+ {
+ "name": "loadImage",
+ "kind": "const",
+ "description": "Method invoked to load the image provided a `src` value",
+ "type": "(url?: string) => void",
+ "value": "(url) => { if (image != null) image = null; loaded = false; error = false; image = new Image(); image.src = url || src; image.onload = () => (loaded = true); image.onerror = () => (error = true); }",
+ "isFunction": true,
+ "constant": true,
+ "reactive": false
+ }
+ ],
+ "slots": [
+ { "name": "error", "default": false, "slot_props": "{}" },
+ { "name": "loading", "default": false, "slot_props": "{}" }
+ ],
+ "events": [
+ { "type": "dispatched", "name": "load", "detail": "any" },
+ { "type": "dispatched", "name": "error", "detail": "any" }
+ ],
+ "typedefs": [],
+ "rest_props": { "type": "Element", "name": "img" }
+ },
{
"moduleName": "InlineLoading",
"filePath": "src/InlineLoading/InlineLoading.svelte",
diff --git a/docs/src/pages/_layout.svelte b/docs/src/pages/_layout.svelte
index 45911b45..3dda8722 100644
--- a/docs/src/pages/_layout.svelte
+++ b/docs/src/pages/_layout.svelte
@@ -20,6 +20,7 @@
import Footer from "../components/Footer.svelte";
const deprecated = ["ToggleSmall", "Icon"];
+ const new_components = ["ImageLoader"];
let isOpen = false;
let isSideNavOpen = true;
@@ -106,6 +107,9 @@
{#if deprecated.includes(child.title)}
Deprecated
{/if}
+ {#if new_components.includes(child.title)}
+ New
+ {/if}
{/each}
diff --git a/docs/src/pages/components/AspectRatio.svx b/docs/src/pages/components/AspectRatio.svx
index e2d015cc..8b920a20 100644
--- a/docs/src/pages/components/AspectRatio.svx
+++ b/docs/src/pages/components/AspectRatio.svx
@@ -5,7 +5,7 @@
The `AspectRatio` component is useful for constraining fluid content within an aspect ratio. To demo this, resize your browser for the examples below.
-Supported aspect ratios: `"2x1"`, `"16x9"`, `"4x3"`, `"1x1"`, `"3x4"`, `"9x16"`, `"1x2"`
+Supported aspect ratios include `"2x1"`, `"16x9"`, `"4x3"`, `"1x1"`, `"3x4"`, `"9x16"` and `"1x2"`.
### Default (2x1)
diff --git a/docs/src/pages/components/ImageLoader.svx b/docs/src/pages/components/ImageLoader.svx
new file mode 100644
index 00000000..9a7057f7
--- /dev/null
+++ b/docs/src/pages/components/ImageLoader.svx
@@ -0,0 +1,46 @@
+
+
+This utility component uses the [Image API](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image) to programmatically load an image with slottable loading and error states.
+
+### Default
+
+
+
+### Slots
+
+Use the "loading" and "error" named slots to render an element when the image is loading or has an error.
+
+
+
+
+
+
+ An error occurred.
+
+
+
+### With aspect ratio
+
+If `ratio` is set, this component uses the [AspectRatio](/components/AspectRatio) to constrain the image.
+
+Supported aspect ratios include `"2x1"`, `"16x9"`, `"4x3"`, `"1x1"`, `"3x4"`, `"9x16"` and `"1x2"`.
+
+
+
+### Fade in
+
+Set `fadeIn` to `true` to fade in the image if successfully loaded.
+
+
+{#key key}{/key}
+
+### Programmatic usage
+
+In this example, a component reference is obtained to programmatically trigger the `loadImage` method.
+
+
\ No newline at end of file
diff --git a/docs/src/pages/framed/ImageLoader/ProgrammaticImageLoader.svelte b/docs/src/pages/framed/ImageLoader/ProgrammaticImageLoader.svelte
new file mode 100644
index 00000000..471a15c8
--- /dev/null
+++ b/docs/src/pages/framed/ImageLoader/ProgrammaticImageLoader.svelte
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/ImageLoader/ImageLoader.svelte b/src/ImageLoader/ImageLoader.svelte
new file mode 100644
index 00000000..b8fd4d7f
--- /dev/null
+++ b/src/ImageLoader/ImageLoader.svelte
@@ -0,0 +1,113 @@
+
+
+{#if ratio === undefined}
+ {#if loading}
+
+ {/if}
+ {#if loaded}
+
+ {/if}
+ {#if error}
+
+ {/if}
+{:else}
+
+ {#if loading}
+
+ {/if}
+ {#if loaded}
+
+ {/if}
+ {#if error}
+
+ {/if}
+
+{/if}
diff --git a/src/ImageLoader/index.js b/src/ImageLoader/index.js
new file mode 100644
index 00000000..972dca8d
--- /dev/null
+++ b/src/ImageLoader/index.js
@@ -0,0 +1 @@
+export { default as ImageLoader } from "./ImageLoader.svelte";
diff --git a/src/index.js b/src/index.js
index 2217ff9f..63f85b0b 100644
--- a/src/index.js
+++ b/src/index.js
@@ -48,6 +48,7 @@ export { FormItem } from "./FormItem";
export { FormLabel } from "./FormLabel";
export { Grid, Row, Column } from "./Grid";
export { Icon, IconSkeleton } from "./Icon";
+export { ImageLoader } from "./ImageLoader";
export { InlineLoading } from "./InlineLoading";
export { Link, OutboundLink } from "./Link";
export {
diff --git a/types/ImageLoader/ImageLoader.d.ts b/types/ImageLoader/ImageLoader.d.ts
new file mode 100644
index 00000000..688bf84c
--- /dev/null
+++ b/types/ImageLoader/ImageLoader.d.ts
@@ -0,0 +1,60 @@
+///
+import { SvelteComponentTyped } from "svelte";
+
+export interface ImageLoaderProps
+ extends svelte.JSX.HTMLAttributes {
+ /**
+ * Specify the image source
+ * @default ""
+ */
+ src?: string;
+
+ /**
+ * Specify the image alt text
+ * @default ""
+ */
+ alt?: string;
+
+ /**
+ * Specify the aspect ratio for the image wrapper
+ */
+ ratio?: "2x1" | "16x9" | "4x3" | "1x1" | "3x4" | "9x16" | "1x2";
+
+ /**
+ * Set to `true` when `loaded` is `true` and `error` is false
+ * @default false
+ */
+ loading?: boolean;
+
+ /**
+ * Set to `true` when the image is loaded
+ * @default false
+ */
+ loaded?: boolean;
+
+ /**
+ * Set to `true` if an error occurs when loading the image
+ * @default false
+ */
+ error?: boolean;
+
+ /**
+ * Set to `true` to fade in the image on load
+ * The duration uses the `fast-02` value following Carbon guidelines on motion
+ * @default false
+ */
+ fadeIn?: boolean;
+
+ /**
+ * Method invoked to load the image provided a `src` value
+ * @constant
+ * @default (url) => { if (image != null) image = null; loaded = false; error = false; image = new Image(); image.src = url || src; image.onload = () => (loaded = true); image.onerror = () => (error = true); }
+ */
+ loadImage?: (url?: string) => void;
+}
+
+export default class ImageLoader extends SvelteComponentTyped<
+ ImageLoaderProps,
+ { load: CustomEvent; error: CustomEvent },
+ { error: {}; loading: {} }
+> {}
diff --git a/types/index.d.ts b/types/index.d.ts
index 9addddc7..7c4014ea 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -57,6 +57,7 @@ export { default as Row } from "./Grid/Row";
export { default as Column } from "./Grid/Column";
export { default as Icon } from "./Icon/Icon";
export { default as IconSkeleton } from "./Icon/IconSkeleton";
+export { default as ImageLoader } from "./ImageLoader/ImageLoader";
export { default as InlineLoading } from "./InlineLoading/InlineLoading";
export { default as Link } from "./Link/Link";
export { default as OutboundLink } from "./Link/OutboundLink";