@momentum-design/components 0.1.8 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,24 +1,40 @@
1
1
  import { Component } from '../../models';
2
2
  /**
3
- * Icon component, which has to be mounted inside of a `IconProvider`
4
- * component.
3
+ * Icon component that dynamically displays SVG icons based on a valid name.
5
4
  *
6
- * The `IconProvider` component defines where icons should be consumed from (`url`).
7
- * This `Icon` component accepts the `name` attribute, which will be
8
- * the file name of the icon to be loaded from the given `url`.
5
+ * This component must be mounted within an `IconProvider` component.
9
6
  *
10
- * Once fetched, the icon will be mounted. If fetching wasn't successful,
11
- * nothing will be shown.
7
+ * The `IconProvider` defines the source URL from which icons are consumed.
8
+ * The `Icon` component accepts a `name` attribute, which corresponds to
9
+ * the file name of the icon to be loaded from the specified URL.
12
10
  *
13
- * The `size` attribute allows sizing the icon based on the provided
14
- * `length-unit` attribute (which will either come from the IconProvider or
15
- * could be overridden per icon). For example:
16
- * if `size = 1` and `length-unit = 'em'`, the size of the icon will be
11
+ * Once fetched, the icon will be rendered. If the fetching process is unsuccessful,
12
+ * no icon will be displayed.
13
+ *
14
+ * The `size` attribute allows for dynamic sizing of the icon based on the provided
15
+ * `length-unit` attribute. This unit can either come from the `IconProvider`
16
+ * or can be overridden for each individual icon. For example:
17
+ * if `size = 1` and `length-unit = 'em'`, the dimensions of the icon will be
17
18
  * `width: 1em; height: 1em`.
18
19
  *
19
- * For accessibility the `role` and `aria-label` of the icon can be set.
20
+ * Regarding accessibility, there are two types of icons: decorative and informative.
21
+ *
22
+ * ### Decorative Icons
23
+ * - Decorative icons 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 icons, an `aria-label` is not required, and the `role` will be set to null.
26
+ *
27
+ * ### Informative Icons
28
+ * - Informative icons 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 icons, an `aria-label` is required, and the `role` will be set to "img".
32
+ * - If an `aria-label` is provided, the role will be set to 'img'; if it is absent,
33
+ * the role will be unset.
20
34
  *
21
35
  * @tagname mdc-icon
36
+ *
37
+ * @cssproperty --mdc-icon-fill-color - Allows customization of the default fill color.
22
38
  */
23
39
  declare class Icon extends Component {
24
40
  private iconData?;
@@ -36,10 +52,6 @@ declare class Icon extends Component {
36
52
  * Length unit attribute for overriding length-unit from `IconProvider`
37
53
  */
38
54
  lengthUnit?: string;
39
- /**
40
- * Role attribute to be set for accessibility
41
- */
42
- role: string | null;
43
55
  /**
44
56
  * Aria-label attribute to be set for accessibility
45
57
  */
@@ -55,6 +67,7 @@ declare class Icon extends Component {
55
67
  */
56
68
  private updateSize;
57
69
  private setRoleOnIcon;
70
+ private setAriaHiddenOnIcon;
58
71
  private setAriaLabelOnIcon;
59
72
  private get computedIconSize();
60
73
  updated(changedProperties: Map<string, any>): void;
@@ -10,25 +10,41 @@ const iconprovider_component_1 = tslib_1.__importDefault(require("../iconprovide
10
10
  const icon_utils_1 = require("./icon.utils");
11
11
  const icon_constants_1 = require("./icon.constants");
12
12
  /**
13
- * Icon component, which has to be mounted inside of a `IconProvider`
14
- * component.
13
+ * Icon component that dynamically displays SVG icons based on a valid name.
15
14
  *
16
- * The `IconProvider` component defines where icons should be consumed from (`url`).
17
- * This `Icon` component accepts the `name` attribute, which will be
18
- * the file name of the icon to be loaded from the given `url`.
15
+ * This component must be mounted within an `IconProvider` component.
19
16
  *
20
- * Once fetched, the icon will be mounted. If fetching wasn't successful,
21
- * nothing will be shown.
17
+ * The `IconProvider` defines the source URL from which icons are consumed.
18
+ * The `Icon` component accepts a `name` attribute, which corresponds to
19
+ * the file name of the icon to be loaded from the specified URL.
22
20
  *
23
- * The `size` attribute allows sizing the icon based on the provided
24
- * `length-unit` attribute (which will either come from the IconProvider or
25
- * could be overridden per icon). For example:
26
- * if `size = 1` and `length-unit = 'em'`, the size of the icon will be
21
+ * Once fetched, the icon will be rendered. If the fetching process is unsuccessful,
22
+ * no icon will be displayed.
23
+ *
24
+ * The `size` attribute allows for dynamic sizing of the icon based on the provided
25
+ * `length-unit` attribute. This unit can either come from the `IconProvider`
26
+ * or can be overridden for each individual icon. For example:
27
+ * if `size = 1` and `length-unit = 'em'`, the dimensions of the icon will be
27
28
  * `width: 1em; height: 1em`.
28
29
  *
29
- * For accessibility the `role` and `aria-label` of the icon can be set.
30
+ * Regarding accessibility, there are two types of icons: decorative and informative.
31
+ *
32
+ * ### Decorative Icons
33
+ * - Decorative icons do not convey any essential information to the content of a page.
34
+ * - They should be hidden from screen readers (SR) to prevent confusion for users.
35
+ * - For decorative icons, an `aria-label` is not required, and the `role` will be set to null.
36
+ *
37
+ * ### Informative Icons
38
+ * - Informative icons convey important information that is not adequately represented
39
+ * by surrounding text or components.
40
+ * - They provide valuable context and must be announced by assistive technologies.
41
+ * - For informative icons, an `aria-label` is required, and the `role` will be set to "img".
42
+ * - If an `aria-label` is provided, the role will be set to 'img'; if it is absent,
43
+ * the role will be unset.
30
44
  *
31
45
  * @tagname mdc-icon
46
+ *
47
+ * @cssproperty --mdc-icon-fill-color - Allows customization of the default fill color.
32
48
  */
33
49
  class Icon extends models_1.Component {
34
50
  constructor() {
@@ -37,10 +53,6 @@ class Icon extends models_1.Component {
37
53
  * Name of the icon (= filename)
38
54
  */
39
55
  this.name = icon_constants_1.DEFAULTS.NAME;
40
- /**
41
- * Role attribute to be set for accessibility
42
- */
43
- this.role = null;
44
56
  /**
45
57
  * Aria-label attribute to be set for accessibility
46
58
  */
@@ -61,6 +73,7 @@ class Icon extends models_1.Component {
61
73
  // when icon got fetched, set role and aria-label:
62
74
  this.setRoleOnIcon();
63
75
  this.setAriaLabelOnIcon();
76
+ this.setAriaHiddenOnIcon();
64
77
  }
65
78
  }
66
79
  }
@@ -76,14 +89,12 @@ class Icon extends models_1.Component {
76
89
  }
77
90
  }
78
91
  setRoleOnIcon() {
79
- var _a, _b;
80
- if (this.role) {
81
- // pass through role attribute to svg if set on mdc-icon
82
- (_a = this.iconData) === null || _a === void 0 ? void 0 : _a.setAttribute('role', this.role);
83
- }
84
- else {
85
- (_b = this.iconData) === null || _b === void 0 ? void 0 : _b.removeAttribute('role');
86
- }
92
+ this.role = this.ariaLabel ? 'img' : null;
93
+ }
94
+ setAriaHiddenOnIcon() {
95
+ var _a;
96
+ // set aria-hidden=true for SVG to avoid screen readers
97
+ (_a = this.iconData) === null || _a === void 0 ? void 0 : _a.setAttribute('aria-hidden', 'true');
87
98
  }
88
99
  setAriaLabelOnIcon() {
89
100
  var _a, _b;
@@ -105,13 +116,12 @@ class Icon extends models_1.Component {
105
116
  if (changedProperties.has('name')) {
106
117
  // fetch icon data if name changes:
107
118
  this.getIconData().catch((err) => {
119
+ // eslint-disable-next-line no-console
108
120
  console.error(err);
109
121
  });
110
122
  }
111
- if (changedProperties.has('role')) {
112
- this.setRoleOnIcon();
113
- }
114
123
  if (changedProperties.has('ariaLabel')) {
124
+ this.setRoleOnIcon();
115
125
  this.setAriaLabelOnIcon();
116
126
  }
117
127
  if (changedProperties.has('size') || changedProperties.has('lengthUnit')) {
@@ -155,10 +165,6 @@ tslib_1.__decorate([
155
165
  (0, decorators_js_1.property)({ type: String, attribute: 'length-unit' }),
156
166
  tslib_1.__metadata("design:type", String)
157
167
  ], Icon.prototype, "lengthUnit", void 0);
158
- tslib_1.__decorate([
159
- (0, decorators_js_1.property)({ type: String }),
160
- tslib_1.__metadata("design:type", Object)
161
- ], Icon.prototype, "role", void 0);
162
168
  tslib_1.__decorate([
163
169
  (0, decorators_js_1.property)({ type: String, attribute: 'aria-label' }),
164
170
  tslib_1.__metadata("design:type", Object)
@@ -5,10 +5,13 @@ const styles_1 = require("../../utils/styles");
5
5
  const styles = [
6
6
  styles_1.hostFitContentStyles,
7
7
  (0, lit_1.css) `
8
+ :host {
9
+ --mdc-icon-fill-color: currentColor;
10
+ }
8
11
  svg {
9
12
  height: 100%;
10
13
  width: 100%;
11
- fill: currentColor;
14
+ fill: var(--mdc-icon-fill-color);
12
15
  }
13
16
  `,
14
17
  ];
@@ -1,2 +1,12 @@
1
+ /**
2
+ * Fetches a dynamic SVG icon based on the provided `url`, `name` and `fileExtension`.
3
+ * It will throw an error if the response is not ok.
4
+ *
5
+ * @param url - The base url of the icon
6
+ * @param name - The name of the icon
7
+ * @param fileExtension - The file extension of the icon
8
+ * @returns The valid icon element
9
+ * @throws Error if the response is not ok
10
+ */
1
11
  declare const dynamicSVGImport: (url: string, name: string, fileExtension: string) => Promise<Element>;
2
12
  export { dynamicSVGImport };
@@ -2,12 +2,22 @@
2
2
  /* eslint-disable implicit-arrow-linebreak */
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.dynamicSVGImport = void 0;
5
- const dynamicSVGImport = async (url, name, fileExtension) => fetch(`${url}/${name}.${fileExtension}`)
6
- .then((response) => {
5
+ /**
6
+ * Fetches a dynamic SVG icon based on the provided `url`, `name` and `fileExtension`.
7
+ * It will throw an error if the response is not ok.
8
+ *
9
+ * @param url - The base url of the icon
10
+ * @param name - The name of the icon
11
+ * @param fileExtension - The file extension of the icon
12
+ * @returns The valid icon element
13
+ * @throws Error if the response is not ok
14
+ */
15
+ const dynamicSVGImport = async (url, name, fileExtension) => {
16
+ const response = await fetch(`${url}/${name}.${fileExtension}`);
7
17
  if (!response.ok) {
8
18
  throw new Error('There was a problem while fetching the icon!');
9
19
  }
10
- return response.text();
11
- })
12
- .then((iconResponse) => new DOMParser().parseFromString(iconResponse, 'text/html').body.children[0]);
20
+ const iconResponse = await response.text();
21
+ return new DOMParser().parseFromString(iconResponse, 'text/html').body.children[0];
22
+ };
13
23
  exports.dynamicSVGImport = dynamicSVGImport;
@@ -43,6 +43,7 @@ declare class ThemeProvider extends Provider<ThemeProviderContext> {
43
43
  * Default: 'mds-theme-stable-darkWebex'
44
44
  */
45
45
  themeclass: string;
46
+ connectedCallback(): void;
46
47
  protected updated(changedProperties: Map<string, any>): void;
47
48
  /**
48
49
  * Update all observing components of this
@@ -41,7 +41,6 @@ class ThemeProvider extends models_1.Provider {
41
41
  * Default: 'mds-theme-stable-darkWebex'
42
42
  */
43
43
  this.themeclass = themeprovider_constants_1.DEFAULTS.THEMECLASS;
44
- this.classList.add(themeprovider_constants_1.DEFAULTS.TYPOGRAPHYCLASS);
45
44
  }
46
45
  /**
47
46
  * Context object of the ThemeProvider, to be consumed by child components
@@ -49,6 +48,11 @@ class ThemeProvider extends models_1.Provider {
49
48
  static get Context() {
50
49
  return themeprovider_context_1.default.context;
51
50
  }
51
+ connectedCallback() {
52
+ super.connectedCallback();
53
+ // Set the default typography class
54
+ this.classList.add(themeprovider_constants_1.DEFAULTS.TYPOGRAPHYCLASS);
55
+ }
52
56
  updated(changedProperties) {
53
57
  super.updated(changedProperties);
54
58
  if (changedProperties.has('themeclass')) {