@momentum-design/components 0.116.2 → 0.117.1

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.
Files changed (50) hide show
  1. package/dist/browser/index.js +319 -310
  2. package/dist/browser/index.js.map +4 -4
  3. package/dist/components/icon/icon.utils.d.ts +1 -1
  4. package/dist/components/icon/icon.utils.js +2 -2
  5. package/dist/components/iconprovider/iconprovider.component.d.ts +3 -1
  6. package/dist/components/iconprovider/iconprovider.component.js +1 -1
  7. package/dist/components/iconprovider/iconprovider.constants.d.ts +0 -1
  8. package/dist/components/iconprovider/iconprovider.constants.js +0 -1
  9. package/dist/components/illustration/illustration.component.d.ts +91 -0
  10. package/dist/components/illustration/illustration.component.js +220 -0
  11. package/dist/components/illustration/illustration.constants.d.ts +5 -0
  12. package/dist/components/illustration/illustration.constants.js +6 -0
  13. package/dist/components/illustration/illustration.styles.d.ts +2 -0
  14. package/dist/components/illustration/illustration.styles.js +15 -0
  15. package/dist/components/illustration/illustration.types.d.ts +2 -0
  16. package/dist/components/illustration/illustration.types.js +1 -0
  17. package/dist/components/illustration/illustration.utils.d.ts +32 -0
  18. package/dist/components/illustration/illustration.utils.js +79 -0
  19. package/dist/components/illustration/index.d.ts +7 -0
  20. package/dist/components/illustration/index.js +4 -0
  21. package/dist/components/illustrationprovider/illustrationprovider.component.d.ts +97 -0
  22. package/dist/components/illustrationprovider/illustrationprovider.component.js +123 -0
  23. package/dist/components/illustrationprovider/illustrationprovider.constants.d.ts +7 -0
  24. package/dist/components/illustrationprovider/illustrationprovider.constants.js +8 -0
  25. package/dist/components/illustrationprovider/illustrationprovider.context.d.ts +12 -0
  26. package/dist/components/illustrationprovider/illustrationprovider.context.js +7 -0
  27. package/dist/components/illustrationprovider/illustrationprovider.types.d.ts +3 -0
  28. package/dist/components/illustrationprovider/illustrationprovider.types.js +1 -0
  29. package/dist/components/illustrationprovider/index.d.ts +7 -0
  30. package/dist/components/illustrationprovider/index.js +4 -0
  31. package/dist/components/toast/index.d.ts +0 -1
  32. package/dist/components/toast/index.js +0 -1
  33. package/dist/components/toast/toast.component.d.ts +2 -1
  34. package/dist/components/toast/toast.component.js +6 -4
  35. package/dist/custom-elements.json +1394 -1060
  36. package/dist/index.d.ts +5 -3
  37. package/dist/index.js +5 -3
  38. package/dist/react/iconprovider/index.d.ts +1 -1
  39. package/dist/react/iconprovider/index.js +1 -1
  40. package/dist/react/illustration/index.d.ts +40 -0
  41. package/dist/react/illustration/index.js +49 -0
  42. package/dist/react/illustrationprovider/index.d.ts +31 -0
  43. package/dist/react/illustrationprovider/index.js +40 -0
  44. package/dist/react/index.d.ts +3 -1
  45. package/dist/react/index.js +3 -1
  46. package/dist/react/toast/index.d.ts +0 -1
  47. package/dist/react/toast/index.js +0 -1
  48. package/dist/utils/{icon-cache → assets-cache}/index.d.ts +2 -2
  49. package/dist/utils/{icon-cache → assets-cache}/index.js +3 -3
  50. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import type { CacheStrategy } from '../../utils/icon-cache';
1
+ import type { CacheStrategy } from '../../utils/assets-cache';
2
2
  interface Args {
3
3
  url: string;
4
4
  name: string;
@@ -1,4 +1,4 @@
1
- import { iconsCache } from '../../utils/icon-cache';
1
+ import { assetsCache } from '../../utils/assets-cache';
2
2
  /**
3
3
  * Utility function for fetching the icon from the provided `request`.
4
4
  * It will throw an error if the response is not ok.
@@ -45,7 +45,7 @@ const svgFetch = async ({ url, name, fileExtension, cacheStrategy, cacheName, re
45
45
  if (!cacheName || !cacheStrategy || !['in-memory-cache', 'web-cache-api'].includes(cacheStrategy)) {
46
46
  return fetchIcon(request).then(response => response.text());
47
47
  }
48
- return iconsCache(cacheName, cacheStrategy).then(iconsCache => iconsCache
48
+ return assetsCache(cacheName, cacheStrategy).then(iconsCache => iconsCache
49
49
  .get(request)
50
50
  .then(responseFromCache => {
51
51
  // **If entry in cache, return**
@@ -8,7 +8,7 @@ import type { CacheStrategy, IconSet } from './iconprovider.types';
8
8
  * Attribute `iconSet` can be set to either `momentum-icons` or `custom-icons`.
9
9
  * If `momentum-icons` is selected, the icons will be fetched from the
10
10
  * Momentum Design System icon set per a dynamic JS Import (no need to provide a URL).
11
- * This requires the consumer to have the `@momentum-designs` package installed and the
11
+ * This requires the consumer to have the `@momentum-design/icons` package installed and the
12
12
  * build tooling needs to support dynamic imports.
13
13
  *
14
14
  * If `custom-icons` is selected, the icons will be fetched from the provided URL.
@@ -94,6 +94,8 @@ declare class IconProvider extends Provider<IconProviderContext> {
94
94
  * If provided, Icons inside the provider will be cached in the
95
95
  * cache (determined by `cache-strategy`) with the provided name.
96
96
  *
97
+ * Icons cache name must be unique, independent from other asset caches.
98
+ *
97
99
  * NOTE: `cache-name` requires `cache-strategy` to be set.
98
100
  *
99
101
  * If not provided, the icons will not be cached.
@@ -18,7 +18,7 @@ import { ALLOWED_FILE_EXTENSIONS, DEFAULTS, ALLOWED_LENGTH_UNITS } from './iconp
18
18
  * Attribute `iconSet` can be set to either `momentum-icons` or `custom-icons`.
19
19
  * If `momentum-icons` is selected, the icons will be fetched from the
20
20
  * Momentum Design System icon set per a dynamic JS Import (no need to provide a URL).
21
- * This requires the consumer to have the `@momentum-designs` package installed and the
21
+ * This requires the consumer to have the `@momentum-design/icons` package installed and the
22
22
  * build tooling needs to support dynamic imports.
23
23
  *
24
24
  * If `custom-icons` is selected, the icons will be fetched from the provided URL.
@@ -6,7 +6,6 @@ declare const DEFAULTS: {
6
6
  readonly FILE_EXTENSION: "svg";
7
7
  readonly LENGTH_UNIT: "em";
8
8
  readonly SIZE: number;
9
- readonly SHOULD_CACHE: false;
10
9
  readonly ICON_SET: "momentum-icons";
11
10
  };
12
11
  export { TAG_NAME, DEFAULTS, ALLOWED_FILE_EXTENSIONS, ALLOWED_LENGTH_UNITS, LENGTH_UNIT_SIZE };
@@ -12,7 +12,6 @@ const DEFAULTS = {
12
12
  FILE_EXTENSION: 'svg',
13
13
  LENGTH_UNIT: 'em',
14
14
  SIZE: LENGTH_UNIT_SIZE.em,
15
- SHOULD_CACHE: false,
16
15
  ICON_SET: 'momentum-icons',
17
16
  };
18
17
  export { TAG_NAME, DEFAULTS, ALLOWED_FILE_EXTENSIONS, ALLOWED_LENGTH_UNITS, LENGTH_UNIT_SIZE };
@@ -0,0 +1,91 @@
1
+ import { CSSResult } from 'lit';
2
+ import { Component } from '../../models';
3
+ import type { IllustrationNames } from './illustration.types';
4
+ /**
5
+ * Illustration component that dynamically displays SVG illustrations based on a valid name.
6
+ *
7
+ * This component must be mounted within an `IllustrationProvider` component.
8
+ *
9
+ * The `IllustrationProvider` defines the source URL from which illustrations are consumed.
10
+ * The `Illustration` component accepts a `name` attribute, which corresponds to
11
+ * the file name of the illustration to be loaded from the specified URL.
12
+ *
13
+ * Once fetched, the illustration will be rendered. If the fetching process is unsuccessful,
14
+ * no illustration will be displayed.
15
+ *
16
+ * Default sizing of the illustration is controlled by choosing a different illustration name, can be overridden with the `--mdc-illustration-size` CSS property.
17
+ * Coloring of the illustration is currently baked into the svg, meaning that the illustration name determines
18
+ * the coloring.
19
+ *
20
+ * Regarding accessibility, there are two types of illustrations: decorative and informative.
21
+ *
22
+ * ### Decorative Illustrations
23
+ * - Decorative illustrations do not convey any essential information to the content of a page.
24
+ * - They should be hidden from screen readers (SR) to prevent confusion for users.
25
+ * - For decorative illustrations, an `aria-label` is not required, and the `role` will be set to null.
26
+ *
27
+ * ### Informative Illustrations
28
+ * - Informative illustrations convey important information that is not adequately represented
29
+ * by surrounding text or components.
30
+ * - They provide valuable context and must be announced by assistive technologies.
31
+ * - For informative illustrations, an `aria-label` is required, and the `role` will be set to "img" automatically.
32
+ * - If an `aria-label` is provided, the role will be set to 'img'; if it is absent,
33
+ * the role will be unset.
34
+ *
35
+ * @tagname mdc-illustration
36
+ *
37
+ * @cssproperty --mdc-illustration-size - Allows customization of the illustration size.
38
+ *
39
+ * @csspart illustration - The svg inside the illustration element.
40
+ */
41
+ declare class Illustration extends Component {
42
+ private illustrationData?;
43
+ /**
44
+ * Name of the illustration (= filename)
45
+ */
46
+ name?: IllustrationNames;
47
+ /**
48
+ * Aria-label attribute to be set for accessibility
49
+ */
50
+ ariaLabel: string | null;
51
+ /**
52
+ * Aria-labelledby attribute to be set for accessibility
53
+ */
54
+ ariaLabelledby: string | null;
55
+ private readonly illustrationProviderContext;
56
+ private abortController?;
57
+ constructor();
58
+ /**
59
+ * Parse the illustration string to an html element, set the attributes and
60
+ * return the illustration element
61
+ *
62
+ * @param illustrationData - The illustration string to be parsed
63
+ * @returns illustrationElement
64
+ */
65
+ private prepareIllustrationElement;
66
+ /**
67
+ * Fetches the illustration (currently only svg) and sets state and attributes once fetched successfully
68
+ *
69
+ * This method uses abortController.signal to cancel the fetch request when the component is disconnected or updated.
70
+ * If the request is aborted after the fetch() call has been fulfilled but before the response body has been read,
71
+ * then attempting to read the response body will reject with an AbortError exception.
72
+ */
73
+ private getIllustrationData;
74
+ /**
75
+ * Sets the illustrationData state to the fetched illustration.
76
+ * Dispatches a 'load' event on the component once the illustration has been successfully loaded.
77
+ * @param illustrationHtml - The illustration html element which has been fetched from the illustration provider.
78
+ */
79
+ private handleIllustrationLoadedSuccess;
80
+ /**
81
+ * Dispatches an 'error' event on the component when the illustration fetching has failed.
82
+ * This event bubbles and is cancelable.
83
+ * The error detail is set to the error object.
84
+ */
85
+ private handleIllustrationLoadedFailure;
86
+ updated(changedProperties: Map<string, any>): void;
87
+ disconnectedCallback(): void;
88
+ render(): import("lit-html").TemplateResult<1>;
89
+ static styles: Array<CSSResult>;
90
+ }
91
+ export default Illustration;
@@ -0,0 +1,220 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { html } from 'lit';
11
+ import { property, state } from 'lit/decorators.js';
12
+ import { Component } from '../../models';
13
+ import providerUtils from '../../utils/provider';
14
+ import IllustrationProvider from '../illustrationprovider/illustrationprovider.component';
15
+ import styles from './illustration.styles';
16
+ import { svgFetch } from './illustration.utils';
17
+ import { DEFAULTS } from './illustration.constants';
18
+ /**
19
+ * Illustration component that dynamically displays SVG illustrations based on a valid name.
20
+ *
21
+ * This component must be mounted within an `IllustrationProvider` component.
22
+ *
23
+ * The `IllustrationProvider` defines the source URL from which illustrations are consumed.
24
+ * The `Illustration` component accepts a `name` attribute, which corresponds to
25
+ * the file name of the illustration to be loaded from the specified URL.
26
+ *
27
+ * Once fetched, the illustration will be rendered. If the fetching process is unsuccessful,
28
+ * no illustration will be displayed.
29
+ *
30
+ * Default sizing of the illustration is controlled by choosing a different illustration name, can be overridden with the `--mdc-illustration-size` CSS property.
31
+ * Coloring of the illustration is currently baked into the svg, meaning that the illustration name determines
32
+ * the coloring.
33
+ *
34
+ * Regarding accessibility, there are two types of illustrations: decorative and informative.
35
+ *
36
+ * ### Decorative Illustrations
37
+ * - Decorative illustrations do not convey any essential information to the content of a page.
38
+ * - They should be hidden from screen readers (SR) to prevent confusion for users.
39
+ * - For decorative illustrations, an `aria-label` is not required, and the `role` will be set to null.
40
+ *
41
+ * ### Informative Illustrations
42
+ * - Informative illustrations convey important information that is not adequately represented
43
+ * by surrounding text or components.
44
+ * - They provide valuable context and must be announced by assistive technologies.
45
+ * - For informative illustrations, an `aria-label` is required, and the `role` will be set to "img" automatically.
46
+ * - If an `aria-label` is provided, the role will be set to 'img'; if it is absent,
47
+ * the role will be unset.
48
+ *
49
+ * @tagname mdc-illustration
50
+ *
51
+ * @cssproperty --mdc-illustration-size - Allows customization of the illustration size.
52
+ *
53
+ * @csspart illustration - The svg inside the illustration element.
54
+ */
55
+ class Illustration extends Component {
56
+ constructor() {
57
+ super();
58
+ /**
59
+ * Name of the illustration (= filename)
60
+ */
61
+ this.name = DEFAULTS.NAME;
62
+ /**
63
+ * Aria-label attribute to be set for accessibility
64
+ */
65
+ this.ariaLabel = null;
66
+ /**
67
+ * Aria-labelledby attribute to be set for accessibility
68
+ */
69
+ this.ariaLabelledby = null;
70
+ this.illustrationProviderContext = providerUtils.consume({
71
+ host: this,
72
+ context: IllustrationProvider.Context,
73
+ });
74
+ this.abortController = new AbortController(); // Initialize AbortController
75
+ }
76
+ /**
77
+ * Parse the illustration string to an html element, set the attributes and
78
+ * return the illustration element
79
+ *
80
+ * @param illustrationData - The illustration string to be parsed
81
+ * @returns illustrationElement
82
+ */
83
+ prepareIllustrationElement(illustrationData) {
84
+ const illustrationElement = new DOMParser().parseFromString(illustrationData, 'text/html').body.children[0];
85
+ if (this.name) {
86
+ illustrationElement.setAttribute('data-name', this.name);
87
+ }
88
+ illustrationElement.setAttribute('part', 'illustration');
89
+ // set aria-hidden=true for SVG to avoid screen readers
90
+ illustrationElement.setAttribute('aria-hidden', 'true');
91
+ return illustrationElement;
92
+ }
93
+ /**
94
+ * Fetches the illustration (currently only svg) and sets state and attributes once fetched successfully
95
+ *
96
+ * This method uses abortController.signal to cancel the fetch request when the component is disconnected or updated.
97
+ * If the request is aborted after the fetch() call has been fulfilled but before the response body has been read,
98
+ * then attempting to read the response body will reject with an AbortError exception.
99
+ */
100
+ async getIllustrationData() {
101
+ if (this.illustrationProviderContext.value) {
102
+ const { fileExtension, url, cacheName, illustrationSet, cacheStrategy } = this.illustrationProviderContext.value;
103
+ if (illustrationSet === 'custom-illustrations' && url && fileExtension && this.name) {
104
+ // function to abort the fetch request and create a new signal
105
+ // (directly passing the abortcontroller to the fetch request per reference
106
+ // will not work due to JS call-by-sharing behavior)
107
+ const renewSignal = () => {
108
+ var _a;
109
+ (_a = this.abortController) === null || _a === void 0 ? void 0 : _a.abort();
110
+ this.abortController = new AbortController();
111
+ return this.abortController.signal;
112
+ };
113
+ // fetch illustration data (including caching logic)
114
+ return svgFetch({
115
+ url,
116
+ name: this.name,
117
+ fileExtension,
118
+ cacheName,
119
+ cacheStrategy,
120
+ renewSignal,
121
+ })
122
+ .then(illustrationData => {
123
+ // parse the fetched illustration string to an html element and set the attributes
124
+ const illustrationElement = this.prepareIllustrationElement(illustrationData);
125
+ this.handleIllustrationLoadedSuccess(illustrationElement);
126
+ })
127
+ .catch(error => {
128
+ this.handleIllustrationLoadedFailure(error);
129
+ });
130
+ }
131
+ if (illustrationSet === 'momentum-illustrations' && this.name) {
132
+ // dynamic import of the lit template from the momentum illustrations package
133
+ return import(`@momentum-design/illustrations/dist/ts/${this.name}.ts`)
134
+ .then(module => {
135
+ this.handleIllustrationLoadedSuccess(module.default());
136
+ })
137
+ .catch(error => {
138
+ this.handleIllustrationLoadedFailure(error);
139
+ });
140
+ }
141
+ }
142
+ const noIllustrationProviderError = new Error('IllustrationProvider not found or not properly set up.');
143
+ this.handleIllustrationLoadedFailure(noIllustrationProviderError);
144
+ return Promise.reject(noIllustrationProviderError);
145
+ }
146
+ /**
147
+ * Sets the illustrationData state to the fetched illustration.
148
+ * Dispatches a 'load' event on the component once the illustration has been successfully loaded.
149
+ * @param illustrationHtml - The illustration html element which has been fetched from the illustration provider.
150
+ */
151
+ handleIllustrationLoadedSuccess(illustrationHtml) {
152
+ // update illustrationData state once fetched:
153
+ this.illustrationData = illustrationHtml;
154
+ // when illustration is fetched successfully, trigger illustration load event.
155
+ const loadEvent = new Event('load', {
156
+ bubbles: true,
157
+ cancelable: true,
158
+ });
159
+ this.dispatchEvent(loadEvent);
160
+ }
161
+ /**
162
+ * Dispatches an 'error' event on the component when the illustration fetching has failed.
163
+ * This event bubbles and is cancelable.
164
+ * The error detail is set to the error object.
165
+ */
166
+ handleIllustrationLoadedFailure(error) {
167
+ const errorEvent = new CustomEvent('error', {
168
+ bubbles: true,
169
+ cancelable: true,
170
+ detail: { error },
171
+ });
172
+ this.dispatchEvent(errorEvent);
173
+ }
174
+ updated(changedProperties) {
175
+ super.updated(changedProperties);
176
+ if (changedProperties.has('name')) {
177
+ // fetch illustration data if name changes:
178
+ this.getIllustrationData().catch(err => {
179
+ if (err.name !== 'AbortError' && this.onerror) {
180
+ this.onerror(err);
181
+ }
182
+ });
183
+ }
184
+ if (changedProperties.has('ariaLabel') || changedProperties.has('ariaLabelledBy')) {
185
+ this.role = this.ariaLabel || this.ariaLabelledby ? 'img' : null;
186
+ }
187
+ }
188
+ disconnectedCallback() {
189
+ var _a;
190
+ super.disconnectedCallback();
191
+ // abort the fetch request when the component is disconnected
192
+ (_a = this.abortController) === null || _a === void 0 ? void 0 : _a.abort();
193
+ this.abortController = undefined; // reset the abort controller
194
+ }
195
+ render() {
196
+ return html ` ${this.illustrationData} `;
197
+ }
198
+ }
199
+ Illustration.styles = [...Component.styles, ...styles];
200
+ __decorate([
201
+ state(),
202
+ __metadata("design:type", HTMLElement)
203
+ ], Illustration.prototype, "illustrationData", void 0);
204
+ __decorate([
205
+ property({ type: String, reflect: true }),
206
+ __metadata("design:type", String)
207
+ ], Illustration.prototype, "name", void 0);
208
+ __decorate([
209
+ property({ type: String, attribute: 'aria-label' }),
210
+ __metadata("design:type", Object)
211
+ ], Illustration.prototype, "ariaLabel", void 0);
212
+ __decorate([
213
+ property({ type: String, attribute: 'aria-labelledby' }),
214
+ __metadata("design:type", Object)
215
+ ], Illustration.prototype, "ariaLabelledby", void 0);
216
+ __decorate([
217
+ state(),
218
+ __metadata("design:type", AbortController)
219
+ ], Illustration.prototype, "abortController", void 0);
220
+ export default Illustration;
@@ -0,0 +1,5 @@
1
+ declare const TAG_NAME: "mdc-illustration";
2
+ declare const DEFAULTS: {
3
+ readonly NAME: undefined;
4
+ };
5
+ export { TAG_NAME, DEFAULTS };
@@ -0,0 +1,6 @@
1
+ import utils from '../../utils/tag-name';
2
+ const TAG_NAME = utils.constructTagName('illustration');
3
+ const DEFAULTS = {
4
+ NAME: undefined,
5
+ };
6
+ export { TAG_NAME, DEFAULTS };
@@ -0,0 +1,2 @@
1
+ declare const styles: import("lit").CSSResult[];
2
+ export default styles;
@@ -0,0 +1,15 @@
1
+ import { css } from 'lit';
2
+ import { hostFitContentStyles } from '../../utils/styles';
3
+ const styles = [
4
+ hostFitContentStyles,
5
+ css `
6
+ :host {
7
+ --mdc-illustration-size: auto;
8
+ }
9
+ :host::part(illustration) {
10
+ height: var(--mdc-illustration-size);
11
+ width: var(--mdc-illustration-size);
12
+ }
13
+ `,
14
+ ];
15
+ export default styles;
@@ -0,0 +1,2 @@
1
+ import type IllustrationNames from '@momentum-design/illustrations/dist/types/types';
2
+ export type { IllustrationNames };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,32 @@
1
+ import type { CacheStrategy } from '../../utils/assets-cache';
2
+ interface Args {
3
+ url: string;
4
+ name: string;
5
+ fileExtension: string;
6
+ cacheStrategy?: CacheStrategy;
7
+ cacheName?: string;
8
+ renewSignal: () => AbortSignal;
9
+ }
10
+ /**
11
+ * Fetches a dynamic SVG illustration based on the provided `url`, `name` and `fileExtension`.
12
+ * The fetch is aborted if the signal is aborted.
13
+ *
14
+ * This function also includes the logic to cache the fetched illustration using the In Memory Cache or Web Cache API.
15
+ * If the `cacheStrategy` is set to `web-cache-api` or `in-memory-cache` and `cacheName` is provided,
16
+ * the fetched illustration will be cached using the respective cache.
17
+ *
18
+ * It will throw an error if the response is not ok.
19
+ *
20
+ * @param url - The base url of the illustration
21
+ * @param name - The name of the illustration
22
+ * @param fileExtension - The file extension of the illustration
23
+ * @param signal - The signal to abort the fetch.
24
+ * It is used to cancel the fetch when the component is disconnected or updated.
25
+ * @param cacheStrategy - The cache strategy to use.
26
+ * @param cacheName - The cache name to use.
27
+ *
28
+ * @returns Response string from the fetch
29
+ * @throws Error if the response is not ok
30
+ */
31
+ declare const svgFetch: ({ url, name, fileExtension, cacheStrategy, cacheName, renewSignal }: Args) => Promise<string>;
32
+ export { svgFetch };
@@ -0,0 +1,79 @@
1
+ import { assetsCache } from '../../utils/assets-cache';
2
+ /**
3
+ * Utility function for fetching the illustration from the provided `request`.
4
+ * It will throw an error if the response is not ok.
5
+ * @param request - The request object to fetch the illustration
6
+ * @returns Promise<Response> - The response from the fetch
7
+ * @throws Error if the response is not ok
8
+ */
9
+ const fetchIllustration = async (request) => fetch(request).then(response => {
10
+ if (!response.ok) {
11
+ throw new Error('There was a problem while fetching the illustration!');
12
+ }
13
+ return response;
14
+ });
15
+ /**
16
+ * Fetches a dynamic SVG illustration based on the provided `url`, `name` and `fileExtension`.
17
+ * The fetch is aborted if the signal is aborted.
18
+ *
19
+ * This function also includes the logic to cache the fetched illustration using the In Memory Cache or Web Cache API.
20
+ * If the `cacheStrategy` is set to `web-cache-api` or `in-memory-cache` and `cacheName` is provided,
21
+ * the fetched illustration will be cached using the respective cache.
22
+ *
23
+ * It will throw an error if the response is not ok.
24
+ *
25
+ * @param url - The base url of the illustration
26
+ * @param name - The name of the illustration
27
+ * @param fileExtension - The file extension of the illustration
28
+ * @param signal - The signal to abort the fetch.
29
+ * It is used to cancel the fetch when the component is disconnected or updated.
30
+ * @param cacheStrategy - The cache strategy to use.
31
+ * @param cacheName - The cache name to use.
32
+ *
33
+ * @returns Response string from the fetch
34
+ * @throws Error if the response is not ok
35
+ */
36
+ const svgFetch = async ({ url, name, fileExtension, cacheStrategy, cacheName, renewSignal }) => {
37
+ // abort the previous fetch request if it is still pending
38
+ // and create a new signal
39
+ const signal = renewSignal();
40
+ const request = new Request(`${url}/${name}.${fileExtension}`, {
41
+ signal,
42
+ });
43
+ // if there is no cache defined (cacheName and cacheStrategy properly set),
44
+ // fetch the illustration and return the response
45
+ if (!cacheName || !cacheStrategy || !['in-memory-cache', 'web-cache-api'].includes(cacheStrategy)) {
46
+ return fetchIllustration(request).then(response => response.text());
47
+ }
48
+ return assetsCache(cacheName, cacheStrategy).then(illustrationsCache => illustrationsCache
49
+ .get(request)
50
+ .then(responseFromCache => {
51
+ // **If entry in cache, return**
52
+ if (responseFromCache) {
53
+ return responseFromCache;
54
+ }
55
+ // **Otherwise, fetch and cache if successful**
56
+ // Both fetchIllustration() and illustrationsCache.set() "consume" the request,
57
+ // so we need to make a copy.
58
+ // (see https://developer.mozilla.org/en-US/docs/Web/API/Request/clone)
59
+ return fetchIllustration(request.clone()).then(response => {
60
+ var _a;
61
+ // This avoids caching responses that we know are errors
62
+ // (i.e. HTTP status code of 4xx or 5xx).
63
+ if (response.status < 400 && response.headers.has('content-type')) {
64
+ // Call .clone() on the response to save copy to cache.
65
+ // https://developer.mozilla.org/en-US/docs/Web/API/Request/clone
66
+ return (_a = illustrationsCache.set) === null || _a === void 0 ? void 0 : _a.call(illustrationsCache, request, response.clone()).then(() => response.text());
67
+ }
68
+ return response.text();
69
+ });
70
+ })
71
+ .catch(error => {
72
+ // Note that a HTTP error response (e.g. 404) will NOT trigger
73
+ // an exception.
74
+ // It will return a normal response object that has the appropriate
75
+ // error code set.
76
+ throw new Error(`Error in caching the Illustration ${name}, ${error}`);
77
+ }));
78
+ };
79
+ export { svgFetch };
@@ -0,0 +1,7 @@
1
+ import Illustration from './illustration.component';
2
+ declare global {
3
+ interface HTMLElementTagNameMap {
4
+ ['mdc-illustration']: Illustration;
5
+ }
6
+ }
7
+ export default Illustration;
@@ -0,0 +1,4 @@
1
+ import Illustration from './illustration.component';
2
+ import { TAG_NAME } from './illustration.constants';
3
+ Illustration.register(TAG_NAME);
4
+ export default Illustration;
@@ -0,0 +1,97 @@
1
+ import { Provider } from '../../models';
2
+ import IllustrationProviderContext from './illustrationprovider.context';
3
+ import type { CacheStrategy, IllustrationSet } from './illustrationprovider.types';
4
+ /**
5
+ * IllustrationProvider component, which allows to be consumed from sub components
6
+ * (see `providerUtils.consume` for how to consume)
7
+ *
8
+ * Attribute `illustrationSet` can be set to either `momentum-illustrations` or `custom-illustrations`.
9
+ * If `momentum-illustrations` is selected, the illustrations will be fetched from the
10
+ * Momentum Design System illustration set per a dynamic JS Import (no need to provide a URL).
11
+ * This requires the consumer to have the `@momentum-design/illustrations` package installed and the
12
+ * build tooling needs to support dynamic imports.
13
+ *
14
+ * If `custom-illustrations` is selected, the illustrations will be fetched from the provided URL.
15
+ * This requires the consumer to provide a URL from which the illustrations will be fetched and
16
+ * the consumer needs to make sure to bundle the illustrations in the application.
17
+ *
18
+ * If `cacheStrategy` is provided (only works with illustrationSet = `custom-illustrations`), the
19
+ * IllustrationProvider will cache the illustrations in the selected cache (either web-api-cache or in-memory-cache),
20
+ * to avoid fetching the same illustration multiple times over the network.
21
+ * This is useful when the same illustration is used multiple times in the application.
22
+ * To consider:
23
+ * - The `in-memory-cache` is not persisted and will be lost when the
24
+ * IllustrationProvider is removed from the DOM.
25
+ * - The `web-api-cache` is persisted, but only works in https environments
26
+ * (https://developer.mozilla.org/en-US/docs/Web/API/Cache).
27
+ *
28
+ * @tagname mdc-illustrationprovider
29
+ *
30
+ * @slot - children
31
+ */
32
+ declare class IllustrationProvider extends Provider<IllustrationProviderContext> {
33
+ constructor();
34
+ /**
35
+ * Context object of the IllustrationProviderContext, to be consumed by child components
36
+ */
37
+ static get Context(): {
38
+ __context__: IllustrationProviderContext;
39
+ };
40
+ /**
41
+ * Illustration set to be used
42
+ *
43
+ * If `momentum-illustrations` is selected, the illustrations will be fetched from the
44
+ * Momentum Design System illustration set per a dynamic JS Import (no need to provide a URL).
45
+ * This requires the consumer to have the `@momentum-designs` package installed and the
46
+ * build tooling needs to support dynamic imports.
47
+ *
48
+ * If `custom-illustrations` is selected, the illustrations will be fetched from the provided URL.
49
+ * This requires the consumer to provide a URL from which the illustrations will be fetched and
50
+ * the consumer needs to make sure to bundle the illustrations in the application.
51
+ *
52
+ * @default momentum-illustrations
53
+ */
54
+ illustrationSet?: IllustrationSet;
55
+ /**
56
+ * Url of where illustrations will be fetched from
57
+ * (if Illustration set is `custom-illustrations`, this will be the base url)
58
+ */
59
+ url?: string;
60
+ /**
61
+ * File extension of illustrations
62
+ * (if Illustration set is `custom-illustrations`, this will be the file extension for illustrations)
63
+ * @default svg
64
+ */
65
+ fileExtension?: string;
66
+ /**
67
+ * Illustrations Cache Strategy to use
68
+ *
69
+ * **Can only be used if Illustration set is `custom-illustrations`**
70
+ *
71
+ * Choose `in-memory-cache` to cache illustrations in a JS cache (in-memory cache).
72
+ * Choose `web-cache-api` to cache illustrations using the Web Cache API.
73
+ *
74
+ * NOTE: `cache-name` must be provided if `cache-strategy` is provided.
75
+ *
76
+ * If not provided or invalid value provided, the illustrations will not be cached.
77
+ * @default undefined
78
+ */
79
+ cacheStrategy?: CacheStrategy;
80
+ /**
81
+ * Illustrations Cache Name to use (cache strategy must be provided)
82
+ *
83
+ * If provided, Illustrations inside the provider will be cached in the
84
+ * cache (determined by `cache-strategy`) with the provided name.
85
+ *
86
+ * Illustrations cache name must be unique, independent from other asset caches.
87
+ *
88
+ * NOTE: `cache-name` requires `cache-strategy` to be set.
89
+ *
90
+ * If not provided, the illustrations will not be cached.
91
+ * @default undefined
92
+ */
93
+ cacheName?: string;
94
+ private updateValuesInContext;
95
+ protected updateContext(): void;
96
+ }
97
+ export default IllustrationProvider;