@brightspace-ui/core 2.35.3 → 2.37.0

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.
@@ -1,26 +1,31 @@
1
1
  # Empty State
2
+
2
3
  Empty state components are used to convey that there is no data available to be displayed, or that a search or filter has returned no results.
3
4
 
4
5
  <!-- docs: demo align:start -->
5
6
  ```html
6
7
  <script type="module">
7
- import '@brightspace-ui/core/components/empty-state/empty-state-simple-button.js';
8
- import '@brightspace-ui/core/components/empty-state/empty-state-illustrated-button.js';
8
+ import '@brightspace-ui/core/components/empty-state/empty-state-action-link.js';
9
+ import '@brightspace-ui/core/components/empty-state/empty-state-illustrated.js';
10
+ import '@brightspace-ui/core/components/empty-state/empty-state-simple.js';
9
11
  </script>
10
12
  <style>
11
13
  body {
12
14
  overflow-y: scroll;
13
15
  }
14
- d2l-empty-state-illustrated-button,
15
- d2l-empty-state-simple-button {
16
+ d2l-empty-state-illustrated,
17
+ d2l-empty-state-simple {
16
18
  max-width: 500px;
17
19
  width: 100%;
18
20
  }
19
21
  </style>
20
22
 
21
- <d2l-empty-state-simple-button description="There are no assignments to display." action-text="Create an Assignment"></d2l-empty-state-simple-button>
22
- <d2l-empty-state-illustrated-button illustration-name="desert-road" title-text="No Learning Paths Yet" description="Get started by clicking below to create your first learning path." action-text="Create Learning Paths"> </d2l-empty-state-illustrated-button>
23
-
23
+ <d2l-empty-state-simple description="There are no assignments to display.">
24
+ <d2l-empty-state-action-link text="Create an Assignment" href="#"></d2l-empty-state-action-link>
25
+ </d2l-empty-state-simple>
26
+ <d2l-empty-state-illustrated illustration-name="desert-road" title-text="No Learning Paths Yet" description="Get started by clicking below to create your first learning path.">
27
+ <d2l-empty-state-action-link text="Create Learning Paths" href="#"></d2l-empty-state-action-link>
28
+ </d2l-empty-state-illustrated>
24
29
  ```
25
30
 
26
31
  ## Best Practices
@@ -40,67 +45,102 @@ Empty state components are used to convey that there is no data available to be
40
45
  <!-- docs: end donts -->
41
46
  <!-- docs: end best practices -->
42
47
 
43
- ## Empty State Simple Button [d2l-empty-state-simple-button]
48
+ ## Empty State Simple [d2l-empty-state-simple]
44
49
 
45
- The `d2l-empty-state-simple-button` component is an empty state component that displays a description and action button.
50
+ The `d2l-empty-state-simple` component is an empty state component that displays a description. An [empty state action component](#d2l-empty-state-action-button) can be placed inside of the default slot to add an optional action.
46
51
 
47
- <!-- docs: demo live name:d2l-empty-state-simple-button -->
52
+ <!-- docs: demo live name:d2l-empty-state-simple -->
48
53
  ```html
49
54
  <script type="module">
50
- import '@brightspace-ui/core/components/empty-state/empty-state-simple-button.js';
55
+ import '@brightspace-ui/core/components/empty-state/empty-state-simple.js';
51
56
  </script>
52
57
 
53
- <d2l-empty-state-simple-button description="There are no assignments to display." action-text="Create an Assignment"></d2l-empty-state-simple-button>
58
+ <d2l-empty-state-simple description="There are no assignments to display."></d2l-empty-state-simple>
54
59
  ```
55
60
 
56
- ## Empty State Simple Link [d2l-empty-state-simple-link]
61
+ ## Empty State Illustrated [d2l-empty-state-illustrated]
62
+
63
+ The `d2l-empty-state-illustrated` component is an empty state component that displays a title and description with an illustration. An [empty state action component](#d2l-empty-state-action-button) can be placed inside of the default slot to add an optional action.
57
64
 
58
- The `d2l-empty-state-simple-link` component is an empty state component that displays a description and action link.
65
+ The `illustration-name` property can be set to use one of the preset illustrations or a custom SVG illustration can be added in the `illustration` slot. The catalogue of preset empty state illustrations can be found [here](#preset-empty-state-illustrations).
59
66
 
60
- <!-- docs: demo live name:d2l-empty-state-simple-link -->
67
+ <!-- docs: demo live name:d2l-empty-state-illustrated -->
61
68
  ```html
62
69
  <script type="module">
63
- import '@brightspace-ui/core/components/empty-state/empty-state-simple-link.js';
70
+ import '@brightspace-ui/core/components/empty-state/empty-state-illustrated.js';
64
71
  </script>
65
-
66
- <d2l-empty-state-simple-link description="There are no assignments to display." action-text="Create an Assignment" action-href='https://d2l.com'></d2l-empty-state-simple-link>
72
+ <!-- docs: start hidden content -->
73
+ <style>
74
+ body {
75
+ overflow-y: scroll;
76
+ }
77
+ </style>
78
+ <!-- docs: end hidden content -->
79
+ <d2l-empty-state-illustrated illustration-name="desert-road" title-text="No Learning Paths Yet" description="Get started by clicking below to create your first learning path."></d2l-empty-state-illustrated>
67
80
  ```
68
- ## Empty State Illustrated Button [d2l-empty-state-illustrated-button]
69
81
 
70
- The `d2l-empty-state-illustrated-button` component is an empty state component that displays a title and description with an illustration and action button. The `illustration-name` property can be set to use one of the preset illustrations or a custom SVG illustration can be added in the default slot.
82
+ ## Empty State Action Button [d2l-empty-state-action-button]
83
+
84
+ `d2l-empty-state-action-button` is an empty state action component that can be placed inside of the default slot of `empty-state-simple` or `empty-state-illustrated` to add a button action to the component. Only a single action can be placed within an empty state component.
85
+
86
+ The `primary` attribute can be set to render a primary button in place of the default subtle button. Note that the `primary` attribute is only valid when placed within `empty-state-illustrated` components and will have no effect on `empty-state-simple`.
71
87
 
72
- <!-- docs: demo live name:d2l-empty-state-illustrated-button -->
88
+ <!-- docs: demo live name:d2l-empty-state-action-button -->
73
89
  ```html
74
90
  <script type="module">
75
- import '@brightspace-ui/core/components/empty-state/empty-state-illustrated-button.js';
91
+ import '@brightspace-ui/core/components/empty-state/empty-state-action-button.js';
92
+ import '@brightspace-ui/core/components/empty-state/empty-state-illustrated.js';
93
+ import '@brightspace-ui/core/components/empty-state/empty-state-simple.js';
76
94
  </script>
77
95
  <!-- docs: start hidden content -->
78
96
  <style>
79
97
  body {
80
98
  overflow-y: scroll;
81
99
  }
100
+ d2l-empty-state-illustrated,
101
+ d2l-empty-state-simple {
102
+ max-width: 500px;
103
+ width: 100%;
104
+ }
82
105
  </style>
83
106
  <!-- docs: end hidden content -->
84
- <d2l-empty-state-illustrated-button illustration-name="desert-road" title-text="No Learning Paths Yet" description="Get started by clicking below to create your first learning path." action-text="Create Learning Paths"></d2l-empty-state-illustrated-button>
107
+ <d2l-empty-state-simple description="There are no assignments to display.">
108
+ <d2l-empty-state-action-button text="Create an Assignment"></d2l-empty-state-action-button>
109
+ </d2l-empty-state-simple>
110
+ <d2l-empty-state-illustrated illustration-name="desert-road" title-text="No Learning Paths Yet" description="Get started by clicking below to create your first learning path.">
111
+ <d2l-empty-state-action-button text="Create Learning Paths"></d2l-empty-state-action-button>
112
+ </d2l-empty-state-illustrated>
85
113
  ```
86
114
 
87
- ## Empty State Illustrated Link [d2l-empty-state-illustrated-link]
115
+ ## Empty State Action Link [d2l-empty-state-action-link]
88
116
 
89
- The `d2l-empty-state-illustrated-link` component is an empty state component that displays a title and description with an illustration and action link. The `illustration-name` property can be set to use one of the preset illustrations or a custom SVG illustration can be added in the default slot.
117
+ `d2l-empty-state-action-link` is an empty state action component that can be placed inside of the default slot of `empty-state-simple` or `empty-state-illustrated` to add a link action to the component. Only a single action can be placed within an empty state component.
90
118
 
91
- <!-- docs: demo live name:d2l-empty-state-illustrated-link -->
119
+ <!-- docs: demo live name:d2l-empty-state-action-link -->
92
120
  ```html
93
121
  <script type="module">
94
- import '@brightspace-ui/core/components/empty-state/empty-state-illustrated-link.js';
122
+ import '@brightspace-ui/core/components/empty-state/empty-state-action-link.js';
123
+ import '@brightspace-ui/core/components/empty-state/empty-state-illustrated.js';
124
+ import '@brightspace-ui/core/components/empty-state/empty-state-simple.js';
95
125
  </script>
96
126
  <!-- docs: start hidden content -->
97
127
  <style>
98
128
  body {
99
129
  overflow-y: scroll;
100
130
  }
131
+ d2l-empty-state-illustrated,
132
+ d2l-empty-state-simple {
133
+ max-width: 500px;
134
+ width: 100%;
135
+ }
101
136
  </style>
102
137
  <!-- docs: end hidden content -->
103
- <d2l-empty-state-illustrated-link illustration-name="desert-road" title-text="No Learning Paths Yet" description="Get started by clicking below to create your first learning path." action-text="Create Learning Paths" action-href='https://d2l.com'></d2l-empty-state-illustrated-link>
138
+ <d2l-empty-state-simple description="There are no assignments to display.">
139
+ <d2l-empty-state-action-link text="Create an Assignment" href="#"></d2l-empty-state-action-link>
140
+ </d2l-empty-state-simple>
141
+ <d2l-empty-state-illustrated illustration-name="desert-road" title-text="No Learning Paths Yet" description="Get started by clicking below to create your first learning path.">
142
+ <d2l-empty-state-action-link text="Create Learning Paths" href="#"></d2l-empty-state-action-link>
143
+ </d2l-empty-state-illustrated>
104
144
  ```
105
145
 
106
146
  ## Preset Empty State Illustrations
@@ -5,46 +5,68 @@
5
5
  <meta charset="UTF-8">
6
6
  <link rel="stylesheet" href="../../demo/styles.css" type="text/css">
7
7
  <script type="module">
8
+ import '../empty-state-action-button.js';
9
+ import '../empty-state-action-link.js';
10
+ import '../empty-state-illustrated.js';
11
+ import '../empty-state-simple.js';
8
12
  import '../../demo/demo-page.js';
9
- import '../empty-state-simple-button.js';
10
- import '../empty-state-simple-link.js';
11
- import '../empty-state-illustrated-button.js';
12
- import '../empty-state-illustrated-link.js';
13
13
  </script>
14
14
  </head>
15
15
  <body unresolved>
16
16
 
17
17
  <d2l-demo-page page-title="d2l-empty-state">
18
18
 
19
- <h2>Empty State Simple Button</h2>
19
+ <h2>Empty State Simple</h2>
20
20
 
21
+ <h5>No Action</h5>
21
22
  <d2l-demo-snippet>
22
23
  <template>
23
- <d2l-empty-state-simple-button description="There are no assignments to display." action-text="Create New Assignment"></d2l-empty-state-simple-button>
24
+ <d2l-empty-state-simple description="There are no assignments to display."></d2l-empty-state-simple>
24
25
  </template>
25
26
  </d2l-demo-snippet>
26
27
 
27
- <h2>Empty State Simple Link</h2>
28
+ <h5>Empty State Action Button</h5>
29
+ <d2l-demo-snippet>
30
+ <template>
31
+ <d2l-empty-state-simple description="There are no assignments to display.">
32
+ <d2l-empty-state-action-button text="Create New Assignment"></d2l-empty-state-action-button>
33
+ </d2l-empty-state-simple>
34
+ </template>
35
+ </d2l-demo-snippet>
28
36
 
37
+ <h5>Empty State Action Link</h5>
29
38
  <d2l-demo-snippet>
30
39
  <template>
31
- <d2l-empty-state-simple-link description="There are no assignments to display." action-text="Create New Assignment" action-href="https://www.d2l.com/"></d2l-empty-state-simple-link>
40
+ <d2l-empty-state-simple description="There are no assignments to display.">
41
+ <d2l-empty-state-action-link text="Create New Assignment" href="https://d2l.com"></d2l-empty-state-action-link>
42
+ </d2l-empty-state-simple>
32
43
  </template>
33
44
  </d2l-demo-snippet>
34
45
 
35
- <h2>Empty State Illustrated Button</h2>
46
+ <h2>Empty State Illustrated</h2>
36
47
 
48
+ <h5>No Action</h5>
37
49
  <d2l-demo-snippet>
38
50
  <template>
39
- <d2l-empty-state-illustrated-button illustration-name="fish-hook" title-text="No Learning Paths Yet" description="Get started by clicking below to create your first learning path." action-text="Create Learning Paths"></d2l-empty-state-illustrated-button>
51
+ <d2l-empty-state-illustrated illustration-name="fish-hook" title-text="No Learning Paths Yet" description="Get started by clicking below to create your first learning path."></d2l-empty-state-illustrated>
40
52
  </template>
41
53
  </d2l-demo-snippet>
42
54
 
43
- <h2>Empty State Illustrated Link</h2>
55
+ <h5>Empty State Action Button</h5>
56
+ <d2l-demo-snippet>
57
+ <template>
58
+ <d2l-empty-state-illustrated illustration-name="fish-hook" title-text="No Learning Paths Yet" description="Get started by clicking below to create your first learning path.">
59
+ <d2l-empty-state-action-button text="Create Learning Paths" primary></d2l-empty-state-action-button>
60
+ </d2l-empty-state-illustrated>
61
+ </template>
62
+ </d2l-demo-snippet>
44
63
 
64
+ <h5>Empty State Action Link</h5>
45
65
  <d2l-demo-snippet>
46
66
  <template>
47
- <d2l-empty-state-illustrated-link illustration-name="desert-road" title-text="No Learning Paths Yet" description="Get started by clicking below to create your first learning path." action-text="Create Learning Paths" action-href="https://www.d2l.com/"></d2l-empty-state-illustrated-link>
67
+ <d2l-empty-state-illustrated illustration-name="fish-hook" title-text="No Learning Paths Yet" description="Get started by clicking below to create your first learning path.">
68
+ <d2l-empty-state-action-link text="Create Learning Paths" href="https://d2l.com"></d2l-empty-state-action-link>
69
+ </d2l-empty-state-illustrated>
48
70
  </template>
49
71
  </d2l-demo-snippet>
50
72
 
@@ -0,0 +1,100 @@
1
+ import '../button/button.js';
2
+ import '../button/button-subtle.js';
3
+ import { css, html, LitElement, nothing } from 'lit';
4
+
5
+ /**
6
+ * `d2l-empty-state-action-button` is an empty state action component that can be placed inside of the default slot of `empty-state-simple` or `empty-state-illustrated` to add a button action to the component.
7
+ * @fires d2l-empty-state-action - Dispatched when the action button is clicked
8
+ */
9
+ class EmptyStateActionButton extends LitElement {
10
+
11
+ static get properties() {
12
+ return {
13
+ /**
14
+ * REQUIRED: The action text to be used in the button
15
+ * @type {string}
16
+ */
17
+ text: { type: String },
18
+ /**
19
+ * This will change the action button to use a primary button instead of the default subtle button. The primary attribute is only valid when `d2l-empty-state-action-button` is placed within `d2l-empty-state-illustrated` components
20
+ * @type {boolean}
21
+ */
22
+ primary: { type: Boolean },
23
+ _illustrated: { state: true }
24
+ };
25
+ }
26
+
27
+ static get styles() {
28
+ return css`
29
+ .d2l-empty-state-action {
30
+ vertical-align: top;
31
+ }
32
+ `;
33
+ }
34
+
35
+ constructor() {
36
+ super();
37
+ this._illustrated = false;
38
+ this._missingTextErrorHasBeenThrown = false;
39
+ this._validatingTextTimeout = null;
40
+ }
41
+
42
+ connectedCallback() {
43
+ super.connectedCallback();
44
+ requestAnimationFrame(() => {
45
+ const e = new CustomEvent('d2l-empty-state-illustrated-check', {
46
+ bubbles: true,
47
+ detail: {}
48
+ });
49
+ this.dispatchEvent(e);
50
+ this._illustrated = e.detail.illustrated | false;
51
+ });
52
+ }
53
+
54
+ firstUpdated(changedProperties) {
55
+ super.firstUpdated(changedProperties);
56
+ this._validateText();
57
+ }
58
+
59
+ render() {
60
+ let actionButton = nothing;
61
+ if (this.text) {
62
+ actionButton = this._illustrated && this.primary
63
+ ? html`<d2l-button
64
+ class="d2l-empty-state-action"
65
+ @click=${this._handleActionClick}
66
+ primary>
67
+ ${this.text}
68
+ </d2l-button>`
69
+ : html`<d2l-button-subtle
70
+ class="d2l-empty-state-action"
71
+ @click=${this._handleActionClick}
72
+ ?slim=${!this._illustrated}
73
+ text=${this.text}>
74
+ </d2l-button-subtle>`;
75
+ }
76
+ return html`${actionButton}`;
77
+ }
78
+
79
+ _handleActionClick(e) {
80
+ e.stopPropagation();
81
+ this.dispatchEvent(new CustomEvent('d2l-empty-state-action'));
82
+ }
83
+
84
+ _validateText() {
85
+ clearTimeout(this._validatingTextTimeout);
86
+ // don't error immediately in case it doesn't get set immediately
87
+ this._validatingTextTimeout = setTimeout(() => {
88
+ this._validatingTextTimeout = null;
89
+ const hasText = (typeof this.text === 'string') && this.text.length > 0;
90
+
91
+ if (!hasText && !this._missingTextErrorHasBeenThrown) {
92
+ this._missingTextErrorHasBeenThrown = true;
93
+ setTimeout(() => { throw new Error('<d2l-empty-state-action-button>: missing required "text" attribute.'); });
94
+ }
95
+ }, 3000);
96
+ }
97
+
98
+ }
99
+
100
+ customElements.define('d2l-empty-state-action-button', EmptyStateActionButton);
@@ -0,0 +1,73 @@
1
+ import { html, LitElement, nothing } from 'lit';
2
+ import { bodyCompactStyles } from '../typography/styles.js';
3
+ import { linkStyles } from '../link/link.js';
4
+
5
+ /**
6
+ * `d2l-empty-state-action-link` is an empty state action component that can be placed inside of the default slot of `empty-state-simple` or `empty-state-illustrated` to add a link action to the component.
7
+ */
8
+ class EmptyStateActionLink extends LitElement {
9
+
10
+ static get properties() {
11
+ return {
12
+ /**
13
+ * REQUIRED: The action text to be used in the subtle button
14
+ * @type {string}
15
+ */
16
+ text: { type: String },
17
+ /**
18
+ * REQUIRED: The action URL or URL fragment of the link
19
+ * @type {string}
20
+ */
21
+ href: { type: String },
22
+ };
23
+ }
24
+
25
+ static get styles() {
26
+ return [bodyCompactStyles, linkStyles];
27
+ }
28
+
29
+ constructor() {
30
+ super();
31
+ this._missingHrefErrorHasBeenThrown = false;
32
+ this._missingTextErrorHasBeenThrown = false;
33
+ this._validatingAttributesTimeout = null;
34
+ }
35
+
36
+ firstUpdated(changedProperties) {
37
+ super.firstUpdated(changedProperties);
38
+ this._validateAttributes();
39
+ }
40
+
41
+ render() {
42
+ const actionLink = this.text && this.href
43
+ ? html`
44
+ <a class="d2l-body-compact d2l-link" href=${this.href}>${this.text}</a>`
45
+ : nothing;
46
+
47
+ return html`${actionLink}`;
48
+ }
49
+
50
+ _validateAttributes() {
51
+ clearTimeout(this._validatingAttributesTimeout);
52
+ // don't error immediately in case it doesn't get set immediately
53
+ this._validatingAttributesTimeout = setTimeout(() => {
54
+ this._validatingAttributesTimeout = null;
55
+
56
+ const hasHref = (typeof this.href === 'string') && this.href.length > 0;
57
+ const hasText = (typeof this.text === 'string') && this.text.length > 0;
58
+
59
+ if (!hasHref && !this._missingHrefErrorHasBeenThrown) {
60
+ this._missingHrefErrorHasBeenThrown = true;
61
+ setTimeout(() => { throw new Error('<d2l-empty-state-action-link>: missing required "href" attribute.'); });
62
+ }
63
+
64
+ if (!hasText && !this._missingTextErrorHasBeenThrown) {
65
+ this._missingTextErrorHasBeenThrown = true;
66
+ setTimeout(() => { throw new Error('<d2l-empty-state-action-link>: missing required "text" attribute.'); });
67
+ }
68
+ }, 3000);
69
+ }
70
+
71
+ }
72
+
73
+ customElements.define('d2l-empty-state-action-link', EmptyStateActionLink);
@@ -1,22 +1,24 @@
1
1
  import { emptyStateIllustratedStyles, emptyStateStyles } from './empty-state-styles.js';
2
- import { html, nothing } from 'lit';
2
+ import { html, LitElement, nothing } from 'lit';
3
3
  import { bodyCompactStyles } from '../typography/styles.js';
4
+ import { classMap } from 'lit/directives/class-map.js';
4
5
  import { loadSvg } from '../../generated/empty-state/presetIllustrationLoader.js';
5
6
  import ResizeObserver from 'resize-observer-polyfill/dist/ResizeObserver.es.js';
6
- import { RtlMixin } from '../../mixins/rtl-mixin.js';
7
+ import { runAsync } from '../../directives/run-async/run-async.js';
8
+ import { styleMap } from 'lit/directives/style-map.js';
7
9
  import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
8
10
 
9
11
  const illustrationAspectRatio = 500 / 330;
10
12
 
11
- export const EmptyStateIllustratedMixin = superclass => class extends RtlMixin(superclass) {
13
+ /**
14
+ * The `d2l-empty-state-illustrated` component is an empty state component that displays a title and description with an illustration. An empty state action component can be placed inside of the default slot to add an optional action.
15
+ * @slot - Slot for empty state actions
16
+ * @slot illustration - Slot for custom SVG content if `illustration-name` property is not set
17
+ */
18
+ class EmptyStateIllustrated extends LitElement {
12
19
 
13
20
  static get properties() {
14
21
  return {
15
- /**
16
- * The action text to be used in the subtle button
17
- * @type {string}
18
- */
19
- actionText: { type: String, attribute: 'action-text' },
20
22
  /**
21
23
  * REQUIRED: A description giving details about the empty state
22
24
  * @type {string}
@@ -33,7 +35,6 @@ export const EmptyStateIllustratedMixin = superclass => class extends RtlMixin(s
33
35
  */
34
36
  titleText: { type: String, attribute: 'title-text' },
35
37
  _contentHeight: { state: true },
36
- _illustratedComponentType: { state: true },
37
38
  _titleSmall: { state: true }
38
39
  };
39
40
  }
@@ -44,7 +45,6 @@ export const EmptyStateIllustratedMixin = superclass => class extends RtlMixin(s
44
45
 
45
46
  constructor() {
46
47
  super();
47
-
48
48
  this._contentHeight = 330;
49
49
  this._missingDescriptionErrorHasBeenThrown = false;
50
50
  this._missingTitleTextErrorHasBeenThrown = false;
@@ -55,11 +55,13 @@ export const EmptyStateIllustratedMixin = superclass => class extends RtlMixin(s
55
55
 
56
56
  connectedCallback() {
57
57
  super.connectedCallback();
58
+ this.addEventListener('d2l-empty-state-illustrated-check', this._handleEmptyStateIllustratedCheck);
58
59
  this._resizeObserver.observe(this);
59
60
  }
60
61
 
61
62
  disconnectedCallback() {
62
63
  super.disconnectedCallback();
64
+ this.removeEventListener('d2l-empty-state-illustrated-check', this._handleEmptyStateIllustratedCheck);
63
65
  this._resizeObserver.disconnect();
64
66
  }
65
67
 
@@ -68,7 +70,25 @@ export const EmptyStateIllustratedMixin = superclass => class extends RtlMixin(s
68
70
  this._validateAttributes();
69
71
  }
70
72
 
71
- async getIllustration(illustrationName) {
73
+ render() {
74
+ const illustrationContainerStyle = this._getIllustrationContainerStyle();
75
+ const titleClass = this._getTitleClass();
76
+
77
+ return html`
78
+ ${this.illustrationName
79
+ ? html`
80
+ <div style="${styleMap(illustrationContainerStyle)}">
81
+ ${runAsync(this.illustrationName, () => this._getIllustration(this.illustrationName), { success: (illustration) => illustration }, { pendingState: false })}
82
+ </div>`
83
+ : html`<slot class="illustration-slot" name="illustration"></slot>`}
84
+
85
+ <p class="${classMap(titleClass)}">${this.titleText}</p>
86
+ <p class="d2l-body-compact d2l-empty-state-description">${this.description}</p>
87
+ <slot class="action-slot"></slot>
88
+ `;
89
+ }
90
+
91
+ async _getIllustration(illustrationName) {
72
92
  if (!illustrationName) return;
73
93
 
74
94
  const svg = await loadSvg(illustrationName);
@@ -78,13 +98,13 @@ export const EmptyStateIllustratedMixin = superclass => class extends RtlMixin(s
78
98
  return svg ? html`${unsafeSVG(svg.val)}` : nothing;
79
99
  }
80
100
 
81
- getIllustrationContainerStyle() {
101
+ _getIllustrationContainerStyle() {
82
102
  return {
83
103
  height: `${this._contentHeight}px`,
84
104
  };
85
105
  }
86
106
 
87
- getTitleClass() {
107
+ _getTitleClass() {
88
108
  return {
89
109
  'd2l-empty-state-title': true,
90
110
  'd2l-empty-state-title-small': this._titleSmall,
@@ -92,6 +112,11 @@ export const EmptyStateIllustratedMixin = superclass => class extends RtlMixin(s
92
112
  };
93
113
  }
94
114
 
115
+ _handleEmptyStateIllustratedCheck(e) {
116
+ e.stopPropagation();
117
+ e.detail.illustrated = true;
118
+ }
119
+
95
120
  _onResize(entries) {
96
121
  if (!entries || entries.length === 0) return;
97
122
  const entry = entries[0];
@@ -110,17 +135,19 @@ export const EmptyStateIllustratedMixin = superclass => class extends RtlMixin(s
110
135
  if (!hasTitleText && !this._missingTitleTextErrorHasBeenThrown) {
111
136
  this._missingTitleTextErrorHasBeenThrown = true;
112
137
  setTimeout(() => {
113
- throw new Error(`<d2l-empty-state-illustrated-${this._illustratedComponentType}>: missing required "titleText" attribute.`);
138
+ throw new Error('<d2l-empty-state-illustrated>: missing required "titleText" attribute.');
114
139
  });
115
140
  }
116
141
 
117
142
  if (!hasDescription && !this._missingDescriptionErrorHasBeenThrown) {
118
143
  this._missingDescriptionErrorHasBeenThrown = true;
119
144
  setTimeout(() => {
120
- throw new Error(`<d2l-empty-state-illustrated-${this._illustratedComponentType}>: missing required "description" attribute.`);
145
+ throw new Error('<d2l-empty-state-illustrated>: missing required "description" attribute.');
121
146
  });
122
147
  }
123
148
  }, 3000);
124
149
  }
125
150
 
126
- };
151
+ }
152
+
153
+ customElements.define('d2l-empty-state-illustrated', EmptyStateIllustrated);
@@ -1,22 +1,17 @@
1
1
  import '../button/button-subtle.js';
2
2
  import { emptyStateSimpleStyles, emptyStateStyles } from './empty-state-styles.js';
3
- import { html, LitElement, nothing } from 'lit';
3
+ import { html, LitElement } from 'lit';
4
4
  import { bodyCompactStyles } from '../typography/styles.js';
5
5
  import { RtlMixin } from '../../mixins/rtl-mixin.js';
6
6
 
7
7
  /**
8
- * The `d2l-empty-state-simple-button` component is an empty state component that displays a description and action button.
9
- * @fires d2l-empty-state-action - Dispatched when the action button is clicked
8
+ * The `d2l-empty-state-simple` component is an empty state component that displays a description. An empty state action component can be placed inside of the default slot to add an optional action.
9
+ * @slot - Slot for empty state actions
10
10
  */
11
- class EmptyStateSimpleButton extends RtlMixin(LitElement) {
11
+ class EmptyStateSimple extends RtlMixin(LitElement) {
12
12
 
13
13
  static get properties() {
14
14
  return {
15
- /**
16
- * The action text to be used in the subtle button
17
- * @type {string}
18
- */
19
- actionText: { type: String, attribute: 'action-text' },
20
15
  /**
21
16
  * REQUIRED: A description giving details about the empty state
22
17
  * @type {string}
@@ -41,28 +36,12 @@ class EmptyStateSimpleButton extends RtlMixin(LitElement) {
41
36
  }
42
37
 
43
38
  render() {
44
- const actionButton = this.actionText
45
- ? html`
46
- <d2l-button-subtle
47
- class="d2l-empty-state-action"
48
- @click=${this._handleActionClick}
49
- h-align="text"
50
- text=${this.actionText}
51
- slim>
52
- </d2l-button-subtle>`
53
- : nothing;
54
-
55
39
  return html`
56
40
  <p class="d2l-body-compact d2l-empty-state-description">${this.description}</p>
57
- ${actionButton}
41
+ <slot class="action-slot"></slot>
58
42
  `;
59
43
  }
60
44
 
61
- _handleActionClick(e) {
62
- e.stopPropagation();
63
- this.dispatchEvent(new CustomEvent('d2l-empty-state-action'));
64
- }
65
-
66
45
  _validateDescription() {
67
46
  clearTimeout(this._validatingDescriptionTimeout);
68
47
  // don't error immediately in case it doesn't get set immediately
@@ -72,11 +51,11 @@ class EmptyStateSimpleButton extends RtlMixin(LitElement) {
72
51
 
73
52
  if (!hasDescription && !this._missingDescriptionErrorHasBeenThrown) {
74
53
  this._missingDescriptionErrorHasBeenThrown = true;
75
- setTimeout(() => { throw new Error('<d2l-empty-state-simple-button>: missing required "description" attribute.'); });
54
+ setTimeout(() => { throw new Error('<d2l-empty-state-simple>: missing required "description" attribute.'); });
76
55
  }
77
56
  }, 3000);
78
57
  }
79
58
 
80
59
  }
81
60
 
82
- customElements.define('d2l-empty-state-simple-button', EmptyStateSimpleButton);
61
+ customElements.define('d2l-empty-state-simple', EmptyStateSimple);
@@ -14,6 +14,15 @@ export const emptyStateStyles = css`
14
14
  display: none;
15
15
  }
16
16
 
17
+ .action-slot::slotted(*) {
18
+ display: none;
19
+ }
20
+
21
+ .action-slot::slotted(d2l-empty-state-action-button:first-child),
22
+ .action-slot::slotted(d2l-empty-state-action-link:first-child) {
23
+ display: inline-block;
24
+ }
25
+
17
26
  `;
18
27
 
19
28
  export const emptyStateSimpleStyles = css`
@@ -28,10 +37,6 @@ export const emptyStateSimpleStyles = css`
28
37
  padding-right: 0.5rem;
29
38
  }
30
39
 
31
- .d2l-empty-state-action {
32
- vertical-align: top;
33
- }
34
-
35
40
  `;
36
41
 
37
42
  export const emptyStateIllustratedStyles = css`
@@ -40,12 +45,16 @@ export const emptyStateIllustratedStyles = css`
40
45
  text-align: center;
41
46
  }
42
47
 
43
- .d2l-empty-state-action {
44
- margin-top: 0.5rem;
48
+ .illustration-slot::slotted(*) {
49
+ display: none;
45
50
  }
46
51
 
47
- .d2l-empty-state-description {
48
- margin: 0 auto 0.3rem;
52
+ .illustration-slot::slotted(svg:first-of-type) {
53
+ display: inline-block;
54
+ }
55
+
56
+ svg {
57
+ height: 100%;
49
58
  max-width: 500px;
50
59
  width: 100%;
51
60
  }
@@ -67,16 +76,8 @@ export const emptyStateIllustratedStyles = css`
67
76
  margin-top: 0.5rem;
68
77
  }
69
78
 
70
- ::slotted(*) {
71
- display: none;
72
- }
73
-
74
- ::slotted(svg:first-child) {
75
- display: inline-block;
76
- }
77
-
78
- svg {
79
- height: 100%;
79
+ .d2l-empty-state-description {
80
+ margin: 0 auto 0.8rem;
80
81
  max-width: 500px;
81
82
  width: 100%;
82
83
  }
@@ -122,6 +122,18 @@
122
122
  </template>
123
123
  </d2l-demo-snippet>
124
124
 
125
+ <h2>HTML Block (inline, no-deferred-rendering)</h2>
126
+
127
+ <d2l-demo-snippet>
128
+ <template>
129
+ <span>Here's an inline html-block:</span>
130
+ <d2l-html-block inline no-deferred-rendering>
131
+ I'm inline!
132
+ </d2l-html-block>
133
+ <span>Pretty cool!</span>
134
+ </template>
135
+ </d2l-demo-snippet>
136
+
125
137
  <h2>HTML Block (large font)</h2>
126
138
 
127
139
  <d2l-demo-snippet>
@@ -160,14 +160,14 @@ class HtmlBlock extends RtlMixin(LitElement) {
160
160
  overflow-y: hidden;
161
161
  text-align: left;
162
162
  }
163
- :host([hidden]),
164
- :host([no-deferred-rendering]) div.d2l-html-block-rendered {
165
- display: none;
166
- }
167
163
  :host([inline]),
168
164
  :host([inline]) div.d2l-html-block-rendered {
169
165
  display: inline;
170
166
  }
167
+ :host([hidden]),
168
+ :host([no-deferred-rendering]) div.d2l-html-block-rendered {
169
+ display: none;
170
+ }
171
171
  :host([dir="rtl"]) {
172
172
  text-align: right;
173
173
  }
@@ -2975,96 +2975,81 @@
2975
2975
  "path": "./components/dropdown/test/dropdown-component.js"
2976
2976
  },
2977
2977
  {
2978
- "name": "d2l-empty-state-illustrated-button",
2979
- "path": "./components/empty-state/empty-state-illustrated-button.js",
2980
- "description": "The `d2l-empty-state-illustrated-button` component is an empty state component that displays an illustration and action button. The illustration property can be set to use one of the preset illustrations or a custom SVG illustration can be added in the default slot.",
2978
+ "name": "d2l-empty-state-action-button",
2979
+ "path": "./components/empty-state/empty-state-action-button.js",
2980
+ "description": "`d2l-empty-state-action-button` is an empty state action component that can be placed inside of the default slot of `empty-state-simple` or `empty-state-illustrated` to add a button action to the component.",
2981
2981
  "attributes": [
2982
2982
  {
2983
- "name": "primary",
2984
- "description": "This will change the action button to use a primary button instead of the default subtle button",
2985
- "type": "boolean"
2986
- },
2987
- {
2988
- "name": "action-text",
2989
- "description": "The action text to be used in the subtle button",
2990
- "type": "string"
2991
- },
2992
- {
2993
- "name": "description",
2994
- "description": "REQUIRED: A description giving details about the empty state",
2995
- "type": "string"
2996
- },
2997
- {
2998
- "name": "illustration-name",
2999
- "description": "The name of the preset image you would like to display in the component",
2983
+ "name": "text",
2984
+ "description": "REQUIRED: The action text to be used in the button",
3000
2985
  "type": "string"
3001
2986
  },
3002
2987
  {
3003
- "name": "title-text",
3004
- "description": "REQUIRED: A title for the empty state",
3005
- "type": "string"
2988
+ "name": "primary",
2989
+ "description": "This will change the action button to use a primary button instead of the default subtle button. The primary attribute is only valid when `d2l-empty-state-action-button` is placed within `d2l-empty-state-illustrated` components",
2990
+ "type": "boolean"
3006
2991
  }
3007
2992
  ],
3008
2993
  "properties": [
3009
2994
  {
3010
- "name": "primary",
3011
- "attribute": "primary",
3012
- "description": "This will change the action button to use a primary button instead of the default subtle button",
3013
- "type": "boolean"
3014
- },
3015
- {
3016
- "name": "actionText",
3017
- "attribute": "action-text",
3018
- "description": "The action text to be used in the subtle button",
3019
- "type": "string"
3020
- },
3021
- {
3022
- "name": "description",
3023
- "attribute": "description",
3024
- "description": "REQUIRED: A description giving details about the empty state",
3025
- "type": "string"
3026
- },
3027
- {
3028
- "name": "illustrationName",
3029
- "attribute": "illustration-name",
3030
- "description": "The name of the preset image you would like to display in the component",
2995
+ "name": "text",
2996
+ "attribute": "text",
2997
+ "description": "REQUIRED: The action text to be used in the button",
3031
2998
  "type": "string"
3032
2999
  },
3033
3000
  {
3034
- "name": "titleText",
3035
- "attribute": "title-text",
3036
- "description": "REQUIRED: A title for the empty state",
3037
- "type": "string"
3001
+ "name": "primary",
3002
+ "attribute": "primary",
3003
+ "description": "This will change the action button to use a primary button instead of the default subtle button. The primary attribute is only valid when `d2l-empty-state-action-button` is placed within `d2l-empty-state-illustrated` components",
3004
+ "type": "boolean"
3038
3005
  }
3039
3006
  ],
3040
3007
  "events": [
3041
3008
  {
3042
3009
  "name": "d2l-empty-state-action",
3043
3010
  "description": "Dispatched when the action button is clicked"
3044
- }
3045
- ],
3046
- "slots": [
3011
+ },
3047
3012
  {
3048
- "name": "",
3049
- "description": "Custom SVG content if `illustration-name` property is not set"
3013
+ "name": "d2l-empty-state-illustrated-check"
3050
3014
  }
3051
3015
  ]
3052
3016
  },
3053
3017
  {
3054
- "name": "d2l-empty-state-illustrated-link",
3055
- "path": "./components/empty-state/empty-state-illustrated-link.js",
3056
- "description": "The `d2l-empty-state-illustrated-link` component is an empty state component that displays an illustration and action link. The illustration property can be set to use one of the preset illustrations or a custom SVG illustration can be added in the default slot.",
3018
+ "name": "d2l-empty-state-action-link",
3019
+ "path": "./components/empty-state/empty-state-action-link.js",
3020
+ "description": "`d2l-empty-state-action-link` is an empty state action component that can be placed inside of the default slot of `empty-state-simple` or `empty-state-illustrated` to add a link action to the component.",
3057
3021
  "attributes": [
3058
3022
  {
3059
- "name": "action-href",
3060
- "description": "The action URL or URL fragment of the link",
3023
+ "name": "text",
3024
+ "description": "REQUIRED: The action text to be used in the subtle button",
3061
3025
  "type": "string"
3062
3026
  },
3063
3027
  {
3064
- "name": "action-text",
3065
- "description": "The action text to be used in the subtle button",
3028
+ "name": "href",
3029
+ "description": "REQUIRED: The action URL or URL fragment of the link",
3030
+ "type": "string"
3031
+ }
3032
+ ],
3033
+ "properties": [
3034
+ {
3035
+ "name": "text",
3036
+ "attribute": "text",
3037
+ "description": "REQUIRED: The action text to be used in the subtle button",
3066
3038
  "type": "string"
3067
3039
  },
3040
+ {
3041
+ "name": "href",
3042
+ "attribute": "href",
3043
+ "description": "REQUIRED: The action URL or URL fragment of the link",
3044
+ "type": "string"
3045
+ }
3046
+ ]
3047
+ },
3048
+ {
3049
+ "name": "d2l-empty-state-illustrated",
3050
+ "path": "./components/empty-state/empty-state-illustrated.js",
3051
+ "description": "The `d2l-empty-state-illustrated` component is an empty state component that displays a title and description with an illustration. An empty state action component can be placed inside of the default slot to add an optional action.",
3052
+ "attributes": [
3068
3053
  {
3069
3054
  "name": "description",
3070
3055
  "description": "REQUIRED: A description giving details about the empty state",
@@ -3082,18 +3067,6 @@
3082
3067
  }
3083
3068
  ],
3084
3069
  "properties": [
3085
- {
3086
- "name": "actionHref",
3087
- "attribute": "action-href",
3088
- "description": "The action URL or URL fragment of the link",
3089
- "type": "string"
3090
- },
3091
- {
3092
- "name": "actionText",
3093
- "attribute": "action-text",
3094
- "description": "The action text to be used in the subtle button",
3095
- "type": "string"
3096
- },
3097
3070
  {
3098
3071
  "name": "description",
3099
3072
  "attribute": "description",
@@ -3116,20 +3089,19 @@
3116
3089
  "slots": [
3117
3090
  {
3118
3091
  "name": "",
3119
- "description": "Custom SVG content if `illustration-name` property is not set"
3092
+ "description": "Slot for empty state actions"
3093
+ },
3094
+ {
3095
+ "name": "illustration",
3096
+ "description": "Slot for custom SVG content if `illustration-name` property is not set"
3120
3097
  }
3121
3098
  ]
3122
3099
  },
3123
3100
  {
3124
- "name": "d2l-empty-state-simple-button",
3125
- "path": "./components/empty-state/empty-state-simple-button.js",
3126
- "description": "The `d2l-empty-state-simple-button` component is an empty state component that displays a description and action button.",
3101
+ "name": "d2l-empty-state-simple",
3102
+ "path": "./components/empty-state/empty-state-simple.js",
3103
+ "description": "The `d2l-empty-state-simple` component is an empty state component that displays a description. An empty state action component can be placed inside of the default slot to add an optional action.",
3127
3104
  "attributes": [
3128
- {
3129
- "name": "action-text",
3130
- "description": "The action text to be used in the subtle button",
3131
- "type": "string"
3132
- },
3133
3105
  {
3134
3106
  "name": "description",
3135
3107
  "description": "REQUIRED: A description giving details about the empty state",
@@ -3137,12 +3109,6 @@
3137
3109
  }
3138
3110
  ],
3139
3111
  "properties": [
3140
- {
3141
- "name": "actionText",
3142
- "attribute": "action-text",
3143
- "description": "The action text to be used in the subtle button",
3144
- "type": "string"
3145
- },
3146
3112
  {
3147
3113
  "name": "description",
3148
3114
  "attribute": "description",
@@ -3150,52 +3116,10 @@
3150
3116
  "type": "string"
3151
3117
  }
3152
3118
  ],
3153
- "events": [
3154
- {
3155
- "name": "d2l-empty-state-action",
3156
- "description": "Dispatched when the action button is clicked"
3157
- }
3158
- ]
3159
- },
3160
- {
3161
- "name": "d2l-empty-state-simple-link",
3162
- "path": "./components/empty-state/empty-state-simple-link.js",
3163
- "description": "The `d2l-empty-state-simple-link` component is an empty state component that displays a description and action link.",
3164
- "attributes": [
3165
- {
3166
- "name": "action-href",
3167
- "description": "The action URL or URL fragment of the link",
3168
- "type": "string"
3169
- },
3170
- {
3171
- "name": "action-text",
3172
- "description": "The action text to be used in the link",
3173
- "type": "string"
3174
- },
3175
- {
3176
- "name": "description",
3177
- "description": "REQUIRED: A description giving details about the empty state",
3178
- "type": "string"
3179
- }
3180
- ],
3181
- "properties": [
3182
- {
3183
- "name": "actionHref",
3184
- "attribute": "action-href",
3185
- "description": "The action URL or URL fragment of the link",
3186
- "type": "string"
3187
- },
3188
- {
3189
- "name": "actionText",
3190
- "attribute": "action-text",
3191
- "description": "The action text to be used in the link",
3192
- "type": "string"
3193
- },
3119
+ "slots": [
3194
3120
  {
3195
- "name": "description",
3196
- "attribute": "description",
3197
- "description": "REQUIRED: A description giving details about the empty state",
3198
- "type": "string"
3121
+ "name": "",
3122
+ "description": "Slot for empty state actions"
3199
3123
  }
3200
3124
  ]
3201
3125
  },
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  const mathjaxContextAttribute = 'data-mathjax-context';
7
- const mathjaxBaseUrl = 'https://s.brightspace.com/lib/mathjax/3.1.2';
7
+ const mathjaxBaseUrl = 'https://s.brightspace.com/lib/mathjax/3.2.2';
8
8
 
9
9
  const mathjaxFontMappings = new Map([
10
10
  ['MJXTEX', 'MathJax_Main-Regular'],
@@ -31,6 +31,7 @@ const mathjaxFontMappings = new Map([
31
31
  ]);
32
32
 
33
33
  let mathJaxLoaded;
34
+ let renderingPromise = Promise.resolve();
34
35
 
35
36
  export class HtmlBlockMathRenderer {
36
37
 
@@ -70,7 +71,8 @@ export class HtmlBlockMathRenderer {
70
71
  });
71
72
 
72
73
  await window.MathJax.startup.promise;
73
- window.MathJax.typesetShadow(elem.getRootNode(), elem);
74
+ renderingPromise = renderingPromise.then(() => window.MathJax.typesetShadow(elem.getRootNode(), elem));
75
+ await renderingPromise;
74
76
  return elem;
75
77
  }
76
78
 
@@ -82,8 +84,10 @@ export class HtmlBlockMathRenderer {
82
84
  temp.shadowRoot.innerHTML = `<div><mjx-doc><mjx-head></mjx-head><mjx-body>${inner}</mjx-body></mjx-doc></div>`;
83
85
 
84
86
  elem.appendChild(temp);
87
+
85
88
  await window.MathJax.startup.promise;
86
- window.MathJax.typesetShadow(temp.shadowRoot);
89
+ renderingPromise = renderingPromise.then(() => window.MathJax.typesetShadow(temp.shadowRoot));
90
+ await renderingPromise;
87
91
 
88
92
  return temp.shadowRoot.firstChild;
89
93
  }
@@ -94,13 +98,9 @@ export function loadMathJax(mathJaxConfig) {
94
98
 
95
99
  if (mathJaxLoaded) return mathJaxLoaded;
96
100
 
97
- const loadOptions = ['ui/menu'];
98
- if (mathJaxConfig && mathJaxConfig.renderLatex) {
99
- loadOptions.push('[tex]/all-packages');
100
- }
101
-
102
101
  window.MathJax = {
103
102
  chtml: {
103
+ adaptiveCSS: false,
104
104
  scale: (mathJaxConfig && mathJaxConfig.outputScale) || 1
105
105
  },
106
106
  options: {
@@ -108,7 +108,7 @@ export function loadMathJax(mathJaxConfig) {
108
108
  settings: { zoom: 'None' }
109
109
  }
110
110
  },
111
- loader: { load: loadOptions },
111
+ loader: { load: ['ui/menu'] },
112
112
  startup: {
113
113
  ready: () => {
114
114
 
@@ -188,15 +188,15 @@ export function loadMathJax(mathJaxConfig) {
188
188
  // renders the document. The MathDocument is returned in case
189
189
  // you need to rerender the shadowRoot later.
190
190
  //
191
- window.MathJax.typesetShadow = function(root, elem) {
191
+ window.MathJax.typesetShadow = async function(root, elem) {
192
192
  const InputJax = startup.getInputJax();
193
193
  const OutputJax = startup.getOutputJax();
194
194
  const html = mathjax.document(root, { InputJax, OutputJax });
195
195
 
196
196
  if (elem) html.options.elements = [elem];
197
197
 
198
- html.render().typeset();
199
- return html;
198
+ await mathjax.handleRetriesFor(() => html.render());
199
+ html.typeset();
200
200
  };
201
201
 
202
202
  //
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/core",
3
- "version": "2.35.3",
3
+ "version": "2.37.0",
4
4
  "description": "A collection of accessible, free, open-source web components for building Brightspace applications",
5
5
  "type": "module",
6
6
  "repository": "https://github.com/BrightspaceUI/core.git",
@@ -1,71 +0,0 @@
1
- import '../button/button.js';
2
- import '../button/button-subtle.js';
3
- import { html, LitElement, nothing } from 'lit';
4
- import { classMap } from 'lit/directives/class-map.js';
5
- import { EmptyStateIllustratedMixin } from './empty-state-illustrated-mixin.js';
6
- import { runAsync } from '../../directives/run-async/run-async.js';
7
- import { styleMap } from 'lit/directives/style-map.js';
8
-
9
- /**
10
- * The `d2l-empty-state-illustrated-button` component is an empty state component that displays an illustration and action button. The illustration property can be set to use one of the preset illustrations or a custom SVG illustration can be added in the default slot.
11
- * @fires d2l-empty-state-action - Dispatched when the action button is clicked
12
- * @slot - Custom SVG content if `illustration-name` property is not set
13
- */
14
- class EmptyStateIllustratedButton extends EmptyStateIllustratedMixin(LitElement) {
15
-
16
- static get properties() {
17
- return {
18
- /**
19
- * This will change the action button to use a primary button instead of the default subtle button
20
- * @type {boolean}
21
- */
22
- primary: { type: Boolean },
23
- };
24
- }
25
-
26
- constructor() {
27
- super();
28
- this._illustratedComponentType = 'button';
29
- }
30
-
31
- render() {
32
- const illustrationContainerStyle = this.getIllustrationContainerStyle();
33
- const titleClass = this.getTitleClass();
34
-
35
- let actionButton = nothing;
36
- if (this.actionText) {
37
- actionButton = this.primary
38
- ? html`<d2l-button
39
- class="d2l-empty-state-action"
40
- @click=${this._handleActionClick}
41
- primary>${this.actionText}
42
- </d2l-button>`
43
- : html`<d2l-button-subtle
44
- class="d2l-empty-state-action"
45
- @click=${this._handleActionClick}
46
- text=${this.actionText}>
47
- </d2l-button-subtle>`;
48
- }
49
-
50
- return html`
51
- ${this.illustrationName
52
- ? html`
53
- <div style="${styleMap(illustrationContainerStyle)}">
54
- ${runAsync(this.illustrationName, () => this.getIllustration(this.illustrationName), { success: (illustration) => illustration }, { pendingState: false })}
55
- </div>`
56
- : html`<slot></slot>`}
57
-
58
- <p class="${classMap(titleClass)}">${this.titleText}</p>
59
- <p class="d2l-body-compact d2l-empty-state-description">${this.description}</p>
60
- ${actionButton}
61
- `;
62
- }
63
-
64
- _handleActionClick(e) {
65
- e.stopPropagation();
66
- this.dispatchEvent(new CustomEvent('d2l-empty-state-action'));
67
- }
68
-
69
- }
70
-
71
- customElements.define('d2l-empty-state-illustrated-button', EmptyStateIllustratedButton);
@@ -1,57 +0,0 @@
1
- import { html, LitElement, nothing } from 'lit';
2
- import { classMap } from 'lit/directives/class-map.js';
3
- import { EmptyStateIllustratedMixin } from './empty-state-illustrated-mixin.js';
4
- import { linkStyles } from '../link/link.js';
5
- import { runAsync } from '../../directives/run-async/run-async.js';
6
- import { styleMap } from 'lit/directives/style-map.js';
7
-
8
- /**
9
- * The `d2l-empty-state-illustrated-link` component is an empty state component that displays an illustration and action link. The illustration property can be set to use one of the preset illustrations or a custom SVG illustration can be added in the default slot.
10
- * @slot - Custom SVG content if `illustration-name` property is not set
11
- */
12
- class EmptyStateIllustratedLink extends EmptyStateIllustratedMixin(LitElement) {
13
-
14
- static get properties() {
15
- return {
16
- /**
17
- * The action URL or URL fragment of the link
18
- * @type {string}
19
- */
20
- actionHref: { type: String, attribute: 'action-href' },
21
- };
22
- }
23
-
24
- static get styles() {
25
- return [super.styles, linkStyles];
26
- }
27
-
28
- constructor() {
29
- super();
30
- this._illustratedComponentType = 'link';
31
- }
32
-
33
- render() {
34
- const illustrationContainerStyle = this.getIllustrationContainerStyle();
35
- const titleClass = this.getTitleClass();
36
-
37
- const actionLink = this.actionText && this.actionHref
38
- ? html`<a class="d2l-body-compact d2l-empty-state-action d2l-link" href=${this.actionHref}>${this.actionText}</a>`
39
- : nothing;
40
-
41
- return html`
42
- ${this.illustrationName
43
- ? html`
44
- <div style="${styleMap(illustrationContainerStyle)}">
45
- ${runAsync(this.illustrationName, () => this.getIllustration(this.illustrationName), { success: (illustration) => illustration }, { pendingState: false })}
46
- </div>`
47
- : html`<slot></slot>`}
48
-
49
- <p class="${classMap(titleClass)}">${this.titleText}</p>
50
- <p class="d2l-body-compact d2l-empty-state-description">${this.description}</p>
51
- ${actionLink}
52
- `;
53
- }
54
-
55
- }
56
-
57
- customElements.define('d2l-empty-state-illustrated-link', EmptyStateIllustratedLink);
@@ -1,74 +0,0 @@
1
- import { emptyStateSimpleStyles, emptyStateStyles } from './empty-state-styles.js';
2
- import { html, LitElement, nothing } from 'lit';
3
- import { bodyCompactStyles } from '../typography/styles.js';
4
- import { linkStyles } from '../link/link.js';
5
- import { RtlMixin } from '../../mixins/rtl-mixin.js';
6
-
7
- /**
8
- * The `d2l-empty-state-simple-link` component is an empty state component that displays a description and action link.
9
- */
10
- class EmptyStateSimpleLink extends RtlMixin(LitElement) {
11
-
12
- static get properties() {
13
- return {
14
- /**
15
- * The action URL or URL fragment of the link
16
- * @type {string}
17
- */
18
- actionHref: { type: String, attribute: 'action-href' },
19
- /**
20
- * The action text to be used in the link
21
- * @type {string}
22
- */
23
- actionText: { type: String, attribute: 'action-text' },
24
- /**
25
- * REQUIRED: A description giving details about the empty state
26
- * @type {string}
27
- */
28
- description: { type: String }
29
- };
30
- }
31
-
32
- static get styles() {
33
- return [bodyCompactStyles, emptyStateStyles, emptyStateSimpleStyles, linkStyles];
34
- }
35
-
36
- constructor() {
37
- super();
38
- this._missingDescriptionErrorHasBeenThrown = false;
39
- this._validatingDescriptionTimeout = null;
40
- }
41
-
42
- firstUpdated(changedProperties) {
43
- super.firstUpdated(changedProperties);
44
- this._validateDescription();
45
- }
46
-
47
- render() {
48
- const actionLink = this.actionText && this.actionHref
49
- ? html`<a class="d2l-body-compact d2l-link" href=${this.actionHref}>${this.actionText}</a>`
50
- : nothing;
51
-
52
- return html`
53
- <p class="d2l-body-compact d2l-empty-state-description">${this.description}</p>
54
- ${actionLink}
55
- `;
56
- }
57
-
58
- _validateDescription() {
59
- clearTimeout(this._validatingDescriptionTimeout);
60
- // don't error immediately in case it doesn't get set immediately
61
- this._validatingDescriptionTimeout = setTimeout(() => {
62
- this._validatingDescriptionTimeout = null;
63
- const hasDescription = (typeof this.description === 'string') && this.description.length > 0;
64
-
65
- if (!hasDescription && !this._missingDescriptionErrorHasBeenThrown) {
66
- this._missingDescriptionErrorHasBeenThrown = true;
67
- setTimeout(() => { throw new Error('<d2l-empty-state-simple-link>: missing required "description" attribute.'); });
68
- }
69
- }, 3000);
70
- }
71
-
72
- }
73
-
74
- customElements.define('d2l-empty-state-simple-link', EmptyStateSimpleLink);