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} + {alt} + {/if} + {#if error} + + {/if} +{:else} + + {#if loading} + + {/if} + {#if loaded} + {alt} + {/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";