Skip to content

Commit 03f68af

Browse files
committed
docs: add custom illustrations guide for ui5-illustrated-message
Add comprehensive documentation for registering and using custom illustrations in UI5 Web Components projects.
1 parent 219eb29 commit 03f68af

File tree

2 files changed

+244
-0
lines changed

2 files changed

+244
-0
lines changed
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
# Using Custom Illustrations
2+
3+
*Learn how to create and register custom illustrations for the UI5 Web Components IllustratedMessage component.*
4+
5+
The [`ui5-illustrated-message`](https://ui5.github.io/webcomponents/components/fiori/IllustratedMessage/) component enhances user experience by displaying contextual illustrations in empty states, error conditions, onboarding flows, and other scenarios where visual communication improves usability.
6+
7+
While UI5 Web Components includes a comprehensive set of [built-in illustrations](https://ui5.github.io/webcomponents/components/fiori/enums/IllustrationMessageType/), you can extend this collection by registering your own custom illustrations that match your application's brand and design requirements.
8+
9+
## Overview
10+
11+
Custom illustrations in UI5 Web Components consist of four size variants that automatically adapt to different container dimensions and [design contexts](https://ui5.github.io/webcomponents/components/fiori/enums/IllustrationMessageDesign/):
12+
13+
| Variant | Size | Breakpoint | Container Width | Current Design Name |
14+
|------------|-------------|------------|-----------------|---------------------|
15+
| **Scene** | Large | L | > 681px | Large |
16+
| **Dialog** | Medium | M | ≤ 681px | Medium |
17+
| **Spot** | Small | S | ≤ 360px | Small |
18+
| **Dot** | Extra Small | XS | ≤ 260px | ExtraSmall |
19+
20+
Each custom illustration must include all four variants to ensure optimal display across different use cases and responsive breakpoints.
21+
22+
## Prerequisites
23+
24+
Before implementing custom illustrations, ensure you have:
25+
26+
### 1. Install Required Packages
27+
28+
```bash
29+
npm install @ui5/webcomponents @ui5/webcomponents-fiori
30+
```
31+
32+
The [`@ui5/webcomponents`](https://www.npmjs.com/package/@ui5/webcomponents) package provides the base framework and asset registry functionality, while [`@ui5/webcomponents-fiori`](https://www.npmjs.com/package/@ui5/webcomponents-fiori) contains the `IllustratedMessage` component.
33+
34+
### 2. Prepare SVG Assets
35+
36+
Create four SVG files for each illustration following the naming convention:
37+
```
38+
{set}-{Variant}-{IllustrationName}.js
39+
```
40+
41+
**Example file structure:**
42+
```
43+
assets/
44+
├── custom-Scene-EmptyCart.js # Large variant
45+
├── custom-Dialog-EmptyCart.js # Medium variant
46+
├── custom-Spot-EmptyCart.js # Small variant
47+
└── custom-Dot-EmptyCart.js # Extra small variant
48+
```
49+
50+
## Implementation
51+
52+
### Registration
53+
54+
Register your custom illustration using the `registerIllustration` function:
55+
56+
**JavaScript:**
57+
```js
58+
import "@ui5/webcomponents-fiori/dist/IllustratedMessage.js";
59+
import { registerIllustration } from "@ui5/webcomponents-base/dist/asset-registries/Illustrations.js";
60+
61+
// Import SVG assets
62+
import sceneSvg from "./assets/custom-Scene-EmptyCart.js";
63+
import dialogSvg from "./assets/custom-Dialog-EmptyCart.js";
64+
import spotSvg from "./assets/custom-Spot-EmptyCart.js";
65+
import dotSvg from "./assets/custom-Dot-EmptyCart.js";
66+
67+
// Register the illustration
68+
registerIllustration("EmptyCart", {
69+
sceneSvg,
70+
dialogSvg,
71+
spotSvg,
72+
dotSvg,
73+
title: "Your cart is empty",
74+
subtitle: "Add items to get started with your order",
75+
set: "custom"
76+
});
77+
```
78+
79+
**TypeScript:**
80+
```ts
81+
import "@ui5/webcomponents-fiori/dist/IllustratedMessage.js";
82+
import { registerIllustration } from "@ui5/webcomponents-base/dist/asset-registries/Illustrations.js";
83+
import type { I18nText } from "@ui5/webcomponents-base/dist/i18nBundle.js";
84+
85+
// Import SVG assets
86+
import sceneSvg from "./assets/custom-Scene-EmptyCart.js";
87+
import dialogSvg from "./assets/custom-Dialog-EmptyCart.js";
88+
import spotSvg from "./assets/custom-Spot-EmptyCart.js";
89+
import dotSvg from "./assets/custom-Dot-EmptyCart.js";
90+
91+
// Register the illustration with proper typing
92+
registerIllustration("EmptyCart", {
93+
sceneSvg,
94+
dialogSvg,
95+
spotSvg,
96+
dotSvg,
97+
title: "Your cart is empty" as I18nText,
98+
subtitle: "Add items to get started with your order" as I18nText,
99+
set: "custom"
100+
});
101+
```
102+
103+
### SVG Asset Structure
104+
105+
Each SVG asset file should export the SVG content as a string:
106+
107+
**custom-Dialog-EmptyCart.js:**
108+
```js
109+
export default `<svg
110+
id="custom-Dialog-EmptyCart"
111+
width="160"
112+
height="120"
113+
viewBox="0 0 160 120"
114+
fill="none"
115+
xmlns="http://www.w3.org/2000/svg"
116+
>
117+
<!-- Cart outline -->
118+
<path
119+
d="M20 30h120l-8 60H28l-8-60z"
120+
stroke="var(--sapContent_Illustrative_Color1)"
121+
stroke-width="2"
122+
fill="var(--sapContent_Illustrative_Color2)"
123+
/>
124+
<!-- Cart handle -->
125+
<path
126+
d="M35 30V20a10 10 0 0 1 20 0v10"
127+
stroke="var(--sapContent_Illustrative_Color3)"
128+
stroke-width="2"
129+
/>
130+
<!-- Empty state indicator -->
131+
<circle
132+
cx="80"
133+
cy="60"
134+
r="15"
135+
fill="var(--sapContent_Illustrative_Color4)"
136+
opacity="0.3"
137+
/>
138+
</svg>`;
139+
```
140+
141+
### Design Guidelines
142+
143+
**SVG Requirements:**
144+
- Include a unique `id` attribute: `{set}-{Variant}-{IllustrationName}`
145+
- Use responsive dimensions appropriate for each variant
146+
- Implement proper `viewBox` for scalability
147+
148+
**Theming Support:**
149+
- Use CSS custom properties for colors
150+
- Avoid hard-coded colors to ensure theme compatibility
151+
- Test illustrations across different UI5 themes
152+
153+
**Security Compliance:**
154+
- ⚠️ **No inline JavaScript**: Avoid `<script>` tags or event handlers
155+
- ⚠️ **No unsafe styles**: Avoid `style` attributes that violate CSP policies
156+
-**Use CSS custom properties**: Prefer theme-aware styling
157+
-**Test with strict CSP**: Validate in CSP-enabled environments
158+
159+
## Usage
160+
161+
### Basic Implementation
162+
163+
Use your registered illustration by referencing it with the format `{set}/{name}`:
164+
165+
**HTML:**
166+
```html
167+
<ui5-illustrated-message name="custom/EmptyCart">
168+
<ui5-button design="Emphasized">Start Shopping</ui5-button>
169+
</ui5-illustrated-message>
170+
```
171+
172+
**React:**
173+
```jsx
174+
import { Button, IllustratedMessage } from '@ui5/webcomponents-react';
175+
176+
function EmptyCartView() {
177+
return (
178+
<IllustratedMessage name="custom/EmptyCart">
179+
<Button design="Emphasized">Start Shopping</Button>
180+
</IllustratedMessage>
181+
);
182+
}
183+
```
184+
185+
### Configuration
186+
187+
Control illustration size and behavior using the [`design`](https://ui5.github.io/webcomponents/components/fiori/IllustratedMessage/#design) property:
188+
189+
```html
190+
<!-- Auto-responsive (default) -->
191+
<ui5-illustrated-message name="custom/EmptyCart" design="Auto">
192+
<ui5-button>Add Items</ui5-button>
193+
</ui5-illustrated-message>
194+
195+
<!-- Fixed size -->
196+
<ui5-illustrated-message name="custom/EmptyCart" design="Large">
197+
<ui5-button>Add Items</ui5-button>
198+
</ui5-illustrated-message>
199+
```
200+
201+
### Accessibility
202+
203+
For accessibility considerations, use the [`decorative`](https://ui5.github.io/webcomponents/components/fiori/IllustratedMessage/#decorative) property when appropriate:
204+
205+
```html
206+
<!-- Decorative illustrations (no accessibility labels) -->
207+
<ui5-illustrated-message name="custom/EmptyCart" decorative>
208+
<ui5-button>Add Items</ui5-button>
209+
</ui5-illustrated-message>
210+
```
211+
212+
**Note:** Use the `decorative` property when the illustration is purely visual and doesn't convey important information. This improves accessibility by preventing screen readers from announcing decorative content.
213+
214+
## Best Practices
215+
216+
- **Consistent Design Language**: Maintain visual consistency with your application's design system
217+
- **Meaningful Illustrations**: Create illustrations that clearly communicate the intended message
218+
- **Performance**: Optimize SVG file sizes while maintaining quality
219+
- **Accessibility**: Ensure illustrations support users with visual impairments through proper titles and descriptions
220+
- **Testing**: Validate illustrations across different themes, screen sizes, and browsers

packages/base/src/asset-registries/Illustrations.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,30 @@ const processName = (name: string) => {
6565
};
6666
};
6767

68+
/**
69+
* Registers a custom illustration in the global registry.
70+
*
71+
* @param name - The name of the illustration (without set prefix)
72+
* @param data - The illustration data containing SVG variants, metadata, and set information
73+
*
74+
* @example
75+
* ```js
76+
* import { registerIllustration } from "@ui5/webcomponents-base/dist/asset-registries/Illustrations.js";
77+
*
78+
* registerIllustration("EmptyCart", {
79+
* sceneSvg: "<svg>...</svg>",
80+
* dialogSvg: "<svg>...</svg>",
81+
* spotSvg: "<svg>...</svg>",
82+
* dotSvg: "<svg>...</svg>",
83+
* title: "Your cart is empty",
84+
* subtitle: "Add items to get started",
85+
* set: "custom"
86+
* });
87+
* ```
88+
*
89+
* @public
90+
* @since 2.15.0
91+
*/
6892
const registerIllustration = (name: string, data: IllustrationData) => {
6993
const collection = data.collection || FALLBACK_COLLECTION;
7094
registry.set(`${data.set}/${collection}/${name}`, {

0 commit comments

Comments
 (0)