@brightspace-ui/core 2.164.0 → 2.166.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.
- package/components/button/button-add.js +127 -0
- package/components/button/demo/button-add.html +73 -0
- package/components/empty-state/empty-state-action-button.js +3 -23
- package/components/empty-state/empty-state-action-link.js +4 -36
- package/components/empty-state/empty-state-illustrated.js +4 -35
- package/components/empty-state/empty-state-simple.js +3 -27
- package/components/inputs/input-text.js +14 -21
- package/custom-elements.json +37 -0
- package/lang/ar.js +1 -0
- package/lang/cy.js +1 -0
- package/lang/da.js +1 -0
- package/lang/de.js +1 -0
- package/lang/en-gb.js +1 -0
- package/lang/en.js +1 -0
- package/lang/es-es.js +1 -0
- package/lang/es.js +1 -0
- package/lang/fr-fr.js +1 -0
- package/lang/fr.js +1 -0
- package/lang/hi.js +1 -0
- package/lang/ja.js +1 -0
- package/lang/ko.js +1 -0
- package/lang/nl.js +1 -0
- package/lang/pt.js +1 -0
- package/lang/sv.js +1 -0
- package/lang/tr.js +1 -0
- package/lang/zh-cn.js +1 -0
- package/lang/zh-tw.js +1 -0
- package/package.json +1 -1
@@ -0,0 +1,127 @@
|
|
1
|
+
import '../colors/colors.js';
|
2
|
+
import '../icons/icon.js';
|
3
|
+
import '../tooltip/tooltip.js';
|
4
|
+
import { css, html, LitElement, unsafeCSS } from 'lit';
|
5
|
+
import { FocusMixin } from '../../mixins/focus/focus-mixin.js';
|
6
|
+
import { getFocusPseudoClass } from '../../helpers/focus.js';
|
7
|
+
import { getUniqueId } from '../../helpers/uniqueId.js';
|
8
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
9
|
+
import { LocalizeCoreElement } from '../../helpers/localize-core-element.js';
|
10
|
+
import { PropertyRequiredMixin } from '../../mixins/property-required/property-required-mixin.js';
|
11
|
+
|
12
|
+
/**
|
13
|
+
* A component for quickly adding items to a specific locaiton.
|
14
|
+
*/
|
15
|
+
class ButtonAdd extends PropertyRequiredMixin(FocusMixin(LocalizeCoreElement(LitElement))) {
|
16
|
+
static get properties() {
|
17
|
+
return {
|
18
|
+
/**
|
19
|
+
* When text-visible is true, the text to show in the button. When text-visible is false, the text to show in the tooltip.
|
20
|
+
* @type {string}
|
21
|
+
*/
|
22
|
+
text: { type: String, required: true },
|
23
|
+
/**
|
24
|
+
* When true, show the button with icon and visible text. When false, only show icon.
|
25
|
+
* @type {boolean}
|
26
|
+
*/
|
27
|
+
textVisible: { type: Boolean, reflect: true, attribute: 'text-visible' }
|
28
|
+
};
|
29
|
+
}
|
30
|
+
|
31
|
+
static get styles() {
|
32
|
+
return css`
|
33
|
+
:host {
|
34
|
+
--d2l-button-add-line-style: solid;
|
35
|
+
}
|
36
|
+
button {
|
37
|
+
align-items: center;
|
38
|
+
background-color: transparent;
|
39
|
+
border: 0;
|
40
|
+
box-shadow: none;
|
41
|
+
cursor: pointer;
|
42
|
+
display: flex;
|
43
|
+
font-family: inherit;
|
44
|
+
justify-content: center;
|
45
|
+
outline: none;
|
46
|
+
padding: 0;
|
47
|
+
position: relative;
|
48
|
+
user-select: none;
|
49
|
+
white-space: nowrap;
|
50
|
+
width: 100%;
|
51
|
+
}
|
52
|
+
|
53
|
+
.line {
|
54
|
+
border-top: 1px var(--d2l-button-add-line-style) var(--d2l-color-mica);
|
55
|
+
margin: 3px 0; /** hover/click target */
|
56
|
+
width: 100%;
|
57
|
+
}
|
58
|
+
button:hover .line,
|
59
|
+
button:${unsafeCSS(getFocusPseudoClass())} .line {
|
60
|
+
border-top-color: var(--d2l-color-celestine);
|
61
|
+
}
|
62
|
+
|
63
|
+
.content {
|
64
|
+
align-items: center;
|
65
|
+
background-color: white;
|
66
|
+
display: flex;
|
67
|
+
position: absolute;
|
68
|
+
}
|
69
|
+
:host([text-visible]) .content {
|
70
|
+
color: var(--d2l-color-celestine);
|
71
|
+
height: 1.5rem;
|
72
|
+
padding: 0 0.3rem;
|
73
|
+
}
|
74
|
+
|
75
|
+
:host([text-visible]) d2l-icon,
|
76
|
+
:host(:not([text-visible])) button:hover d2l-icon,
|
77
|
+
:host(:not([text-visible])) button:${unsafeCSS(getFocusPseudoClass())} d2l-icon {
|
78
|
+
color: var(--d2l-color-celestine);
|
79
|
+
}
|
80
|
+
:host(:not([text-visible])) d2l-icon {
|
81
|
+
color: var(--d2l-color-galena);
|
82
|
+
margin: -3px; /** hover/click target */
|
83
|
+
padding: 3px; /** hover/click target */
|
84
|
+
}
|
85
|
+
:host([text-visible]) d2l-icon {
|
86
|
+
padding-inline-end: 0.2rem;
|
87
|
+
}
|
88
|
+
|
89
|
+
span {
|
90
|
+
font-size: 0.7rem;
|
91
|
+
font-weight: 700;
|
92
|
+
letter-spacing: 0.2px;
|
93
|
+
line-height: 1rem;
|
94
|
+
}
|
95
|
+
`;
|
96
|
+
}
|
97
|
+
|
98
|
+
constructor() {
|
99
|
+
super();
|
100
|
+
|
101
|
+
this.textVisible = false;
|
102
|
+
this._buttonId = getUniqueId();
|
103
|
+
}
|
104
|
+
|
105
|
+
static get focusElementSelector() {
|
106
|
+
return 'button';
|
107
|
+
}
|
108
|
+
|
109
|
+
render() {
|
110
|
+
const text = this.text || this.localize('components.button-add.addItem');
|
111
|
+
const id = !this.textVisible ? this._buttonId : undefined;
|
112
|
+
|
113
|
+
return html`
|
114
|
+
<button class="d2l-label-text" id="${ifDefined(id)}">
|
115
|
+
<div class="line"></div>
|
116
|
+
<div class="content">
|
117
|
+
<d2l-icon icon="tier1:plus-default"></d2l-icon>
|
118
|
+
${this.textVisible
|
119
|
+
? html`<span>${text}</span>`
|
120
|
+
: html`<d2l-tooltip class="vdiff-target" offset="18" for="${this._buttonId}" for-type="label">${text}</d2l-tooltip>`}
|
121
|
+
</div>
|
122
|
+
</button>
|
123
|
+
`;
|
124
|
+
}
|
125
|
+
}
|
126
|
+
customElements.define('d2l-button-add', ButtonAdd);
|
127
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
5
|
+
<meta charset="UTF-8">
|
6
|
+
<link rel="stylesheet" href="../../demo/styles.css" type="text/css">
|
7
|
+
<script type="module">
|
8
|
+
import '../../demo/demo-page.js';
|
9
|
+
import '../button-add.js';
|
10
|
+
</script>
|
11
|
+
<style>
|
12
|
+
.d2l-button-add-dashed {
|
13
|
+
--d2l-button-add-line-style: dashed;
|
14
|
+
}
|
15
|
+
</style>
|
16
|
+
</head>
|
17
|
+
<body unresolved>
|
18
|
+
|
19
|
+
<d2l-demo-page page-title="d2l-button-add">
|
20
|
+
|
21
|
+
<h2>Add Button</h2>
|
22
|
+
|
23
|
+
<d2l-demo-snippet>
|
24
|
+
<template>
|
25
|
+
<d2l-button-add></d2l-button-add>
|
26
|
+
</template>
|
27
|
+
</d2l-demo-snippet>
|
28
|
+
|
29
|
+
<h2>Add Button, dashed line</h2>
|
30
|
+
|
31
|
+
<d2l-demo-snippet>
|
32
|
+
<template>
|
33
|
+
<d2l-button-add class="d2l-button-add-dashed"></d2l-button-add>
|
34
|
+
</template>
|
35
|
+
</d2l-demo-snippet>
|
36
|
+
|
37
|
+
<h2>Add Button, custom text</h2>
|
38
|
+
|
39
|
+
<d2l-demo-snippet>
|
40
|
+
<template>
|
41
|
+
<d2l-button-add text="Custom Tooltip"></d2l-button-add>
|
42
|
+
</template>
|
43
|
+
</d2l-demo-snippet>
|
44
|
+
|
45
|
+
|
46
|
+
<h2>Add Button, text-visible</h2>
|
47
|
+
|
48
|
+
<d2l-demo-snippet>
|
49
|
+
<template>
|
50
|
+
<d2l-button-add text-visible></d2l-button-add>
|
51
|
+
</template>
|
52
|
+
</d2l-demo-snippet>
|
53
|
+
|
54
|
+
|
55
|
+
<h2>Add Button, text-visible, custom text</h2>
|
56
|
+
|
57
|
+
<d2l-demo-snippet>
|
58
|
+
<template>
|
59
|
+
<d2l-button-add text-visible text="Custom Text"></d2l-button-add>
|
60
|
+
</template>
|
61
|
+
</d2l-demo-snippet>
|
62
|
+
|
63
|
+
</d2l-demo-page>
|
64
|
+
|
65
|
+
<script>
|
66
|
+
document.addEventListener('click', e => {
|
67
|
+
if (e.target.tagName !== 'D2L-BUTTON-ADD') return;
|
68
|
+
console.log('add button clicked', e.target);
|
69
|
+
});
|
70
|
+
</script>
|
71
|
+
|
72
|
+
</body>
|
73
|
+
</html>
|
@@ -2,13 +2,14 @@ import '../button/button.js';
|
|
2
2
|
import '../button/button-subtle.js';
|
3
3
|
import { css, html, LitElement, nothing } from 'lit';
|
4
4
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
5
|
+
import { PropertyRequiredMixin } from '../../mixins/property-required/property-required-mixin.js';
|
5
6
|
|
6
7
|
/**
|
7
8
|
* `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.
|
8
9
|
* @fires d2l-empty-state-action - Dispatched when the action button is clicked
|
9
10
|
* @fires d2l-empty-state-illustrated-check - Internal event
|
10
11
|
*/
|
11
|
-
class EmptyStateActionButton extends LitElement {
|
12
|
+
class EmptyStateActionButton extends PropertyRequiredMixin(LitElement) {
|
12
13
|
|
13
14
|
static get properties() {
|
14
15
|
return {
|
@@ -16,7 +17,7 @@ class EmptyStateActionButton extends LitElement {
|
|
16
17
|
* REQUIRED: The action text to be used in the button
|
17
18
|
* @type {string}
|
18
19
|
*/
|
19
|
-
text: { type: String },
|
20
|
+
text: { type: String, required: true },
|
20
21
|
/**
|
21
22
|
* 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
|
22
23
|
* @type {boolean}
|
@@ -37,8 +38,6 @@ class EmptyStateActionButton extends LitElement {
|
|
37
38
|
constructor() {
|
38
39
|
super();
|
39
40
|
this._illustrated = false;
|
40
|
-
this._missingTextErrorHasBeenThrown = false;
|
41
|
-
this._validatingTextTimeout = null;
|
42
41
|
}
|
43
42
|
|
44
43
|
connectedCallback() {
|
@@ -53,11 +52,6 @@ class EmptyStateActionButton extends LitElement {
|
|
53
52
|
});
|
54
53
|
}
|
55
54
|
|
56
|
-
firstUpdated(changedProperties) {
|
57
|
-
super.firstUpdated(changedProperties);
|
58
|
-
this._validateText();
|
59
|
-
}
|
60
|
-
|
61
55
|
render() {
|
62
56
|
let actionButton = nothing;
|
63
57
|
if (this.text) {
|
@@ -84,20 +78,6 @@ class EmptyStateActionButton extends LitElement {
|
|
84
78
|
this.dispatchEvent(new CustomEvent('d2l-empty-state-action'));
|
85
79
|
}
|
86
80
|
|
87
|
-
_validateText() {
|
88
|
-
clearTimeout(this._validatingTextTimeout);
|
89
|
-
// don't error immediately in case it doesn't get set immediately
|
90
|
-
this._validatingTextTimeout = setTimeout(() => {
|
91
|
-
this._validatingTextTimeout = null;
|
92
|
-
const hasText = (typeof this.text === 'string') && this.text.length > 0;
|
93
|
-
|
94
|
-
if (!hasText && !this._missingTextErrorHasBeenThrown) {
|
95
|
-
this._missingTextErrorHasBeenThrown = true;
|
96
|
-
setTimeout(() => { throw new Error('<d2l-empty-state-action-button>: missing required "text" attribute.'); });
|
97
|
-
}
|
98
|
-
}, 3000);
|
99
|
-
}
|
100
|
-
|
101
81
|
}
|
102
82
|
|
103
83
|
customElements.define('d2l-empty-state-action-button', EmptyStateActionButton);
|
@@ -1,11 +1,12 @@
|
|
1
1
|
import { html, LitElement, nothing } from 'lit';
|
2
2
|
import { bodyCompactStyles } from '../typography/styles.js';
|
3
3
|
import { linkStyles } from '../link/link.js';
|
4
|
+
import { PropertyRequiredMixin } from '../../mixins/property-required/property-required-mixin.js';
|
4
5
|
|
5
6
|
/**
|
6
7
|
* `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
|
*/
|
8
|
-
class EmptyStateActionLink extends LitElement {
|
9
|
+
class EmptyStateActionLink extends PropertyRequiredMixin(LitElement) {
|
9
10
|
|
10
11
|
static get properties() {
|
11
12
|
return {
|
@@ -13,12 +14,12 @@ class EmptyStateActionLink extends LitElement {
|
|
13
14
|
* REQUIRED: The action text to be used in the subtle button
|
14
15
|
* @type {string}
|
15
16
|
*/
|
16
|
-
text: { type: String },
|
17
|
+
text: { type: String, required: true },
|
17
18
|
/**
|
18
19
|
* REQUIRED: The action URL or URL fragment of the link
|
19
20
|
* @type {string}
|
20
21
|
*/
|
21
|
-
href: { type: String },
|
22
|
+
href: { type: String, required: true },
|
22
23
|
};
|
23
24
|
}
|
24
25
|
|
@@ -26,18 +27,6 @@ class EmptyStateActionLink extends LitElement {
|
|
26
27
|
return [bodyCompactStyles, linkStyles];
|
27
28
|
}
|
28
29
|
|
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
30
|
render() {
|
42
31
|
const actionLink = this.text && this.href
|
43
32
|
? html`
|
@@ -47,27 +36,6 @@ class EmptyStateActionLink extends LitElement {
|
|
47
36
|
return html`${actionLink}`;
|
48
37
|
}
|
49
38
|
|
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
39
|
}
|
72
40
|
|
73
41
|
customElements.define('d2l-empty-state-action-link', EmptyStateActionLink);
|
@@ -3,6 +3,7 @@ import { html, LitElement, nothing } from 'lit';
|
|
3
3
|
import { bodyCompactStyles } from '../typography/styles.js';
|
4
4
|
import { classMap } from 'lit/directives/class-map.js';
|
5
5
|
import { loadSvg } from '../../generated/empty-state/presetIllustrationLoader.js';
|
6
|
+
import { PropertyRequiredMixin } from '../../mixins/property-required/property-required-mixin.js';
|
6
7
|
import ResizeObserver from 'resize-observer-polyfill/dist/ResizeObserver.es.js';
|
7
8
|
import { runAsync } from '../../directives/run-async/run-async.js';
|
8
9
|
import { styleMap } from 'lit/directives/style-map.js';
|
@@ -15,7 +16,7 @@ const illustrationAspectRatio = 500 / 330;
|
|
15
16
|
* @slot - Slot for empty state actions
|
16
17
|
* @slot illustration - Slot for custom SVG content if `illustration-name` property is not set
|
17
18
|
*/
|
18
|
-
class EmptyStateIllustrated extends LitElement {
|
19
|
+
class EmptyStateIllustrated extends PropertyRequiredMixin(LitElement) {
|
19
20
|
|
20
21
|
static get properties() {
|
21
22
|
return {
|
@@ -23,7 +24,7 @@ class EmptyStateIllustrated extends LitElement {
|
|
23
24
|
* REQUIRED: A description giving details about the empty state
|
24
25
|
* @type {string}
|
25
26
|
*/
|
26
|
-
description: { type: String },
|
27
|
+
description: { type: String, required: true },
|
27
28
|
/**
|
28
29
|
* The name of the preset image you would like to display in the component
|
29
30
|
* @type {string}
|
@@ -33,7 +34,7 @@ class EmptyStateIllustrated extends LitElement {
|
|
33
34
|
* REQUIRED: A title for the empty state
|
34
35
|
* @type {string}
|
35
36
|
*/
|
36
|
-
titleText: { type: String, attribute: 'title-text' },
|
37
|
+
titleText: { type: String, attribute: 'title-text', required: true },
|
37
38
|
_contentHeight: { state: true },
|
38
39
|
_titleSmall: { state: true }
|
39
40
|
};
|
@@ -46,11 +47,8 @@ class EmptyStateIllustrated extends LitElement {
|
|
46
47
|
constructor() {
|
47
48
|
super();
|
48
49
|
this._contentHeight = 330;
|
49
|
-
this._missingDescriptionErrorHasBeenThrown = false;
|
50
|
-
this._missingTitleTextErrorHasBeenThrown = false;
|
51
50
|
this._resizeObserver = new ResizeObserver(this._onResize.bind(this));
|
52
51
|
this._titleSmall = false;
|
53
|
-
this._validatingAttributesTimeout = null;
|
54
52
|
}
|
55
53
|
|
56
54
|
connectedCallback() {
|
@@ -65,11 +63,6 @@ class EmptyStateIllustrated extends LitElement {
|
|
65
63
|
this._resizeObserver.disconnect();
|
66
64
|
}
|
67
65
|
|
68
|
-
firstUpdated(changedProperties) {
|
69
|
-
super.firstUpdated(changedProperties);
|
70
|
-
this._validateAttributes();
|
71
|
-
}
|
72
|
-
|
73
66
|
render() {
|
74
67
|
const illustrationContainerStyle = this._getIllustrationContainerStyle();
|
75
68
|
const titleClass = this._getTitleClass();
|
@@ -126,30 +119,6 @@ class EmptyStateIllustrated extends LitElement {
|
|
126
119
|
});
|
127
120
|
}
|
128
121
|
|
129
|
-
_validateAttributes() {
|
130
|
-
clearTimeout(this._validatingAttributesTimeout);
|
131
|
-
// don't error immediately in case it doesn't get set immediately
|
132
|
-
this._validatingAttributesTimeout = setTimeout(() => {
|
133
|
-
this._validatingAttributesTimeout = null;
|
134
|
-
const hasTitleText = (typeof this.titleText === 'string') && this.titleText.length > 0;
|
135
|
-
const hasDescription = (typeof this.description === 'string') && this.description.length > 0;
|
136
|
-
|
137
|
-
if (!hasTitleText && !this._missingTitleTextErrorHasBeenThrown) {
|
138
|
-
this._missingTitleTextErrorHasBeenThrown = true;
|
139
|
-
setTimeout(() => {
|
140
|
-
throw new Error('<d2l-empty-state-illustrated>: missing required "titleText" attribute.');
|
141
|
-
});
|
142
|
-
}
|
143
|
-
|
144
|
-
if (!hasDescription && !this._missingDescriptionErrorHasBeenThrown) {
|
145
|
-
this._missingDescriptionErrorHasBeenThrown = true;
|
146
|
-
setTimeout(() => {
|
147
|
-
throw new Error('<d2l-empty-state-illustrated>: missing required "description" attribute.');
|
148
|
-
});
|
149
|
-
}
|
150
|
-
}, 3000);
|
151
|
-
}
|
152
|
-
|
153
122
|
}
|
154
123
|
|
155
124
|
customElements.define('d2l-empty-state-illustrated', EmptyStateIllustrated);
|
@@ -2,13 +2,14 @@ import '../button/button-subtle.js';
|
|
2
2
|
import { emptyStateSimpleStyles, emptyStateStyles } from './empty-state-styles.js';
|
3
3
|
import { html, LitElement } from 'lit';
|
4
4
|
import { bodyCompactStyles } from '../typography/styles.js';
|
5
|
+
import { PropertyRequiredMixin } from '../../mixins/property-required/property-required-mixin.js';
|
5
6
|
import { RtlMixin } from '../../mixins/rtl/rtl-mixin.js';
|
6
7
|
|
7
8
|
/**
|
8
9
|
* 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
10
|
* @slot - Slot for empty state actions
|
10
11
|
*/
|
11
|
-
class EmptyStateSimple extends RtlMixin(LitElement) {
|
12
|
+
class EmptyStateSimple extends PropertyRequiredMixin(RtlMixin(LitElement)) {
|
12
13
|
|
13
14
|
static get properties() {
|
14
15
|
return {
|
@@ -16,7 +17,7 @@ class EmptyStateSimple extends RtlMixin(LitElement) {
|
|
16
17
|
* REQUIRED: A description giving details about the empty state
|
17
18
|
* @type {string}
|
18
19
|
*/
|
19
|
-
description: { type: String },
|
20
|
+
description: { type: String, required: true },
|
20
21
|
};
|
21
22
|
}
|
22
23
|
|
@@ -24,17 +25,6 @@ class EmptyStateSimple extends RtlMixin(LitElement) {
|
|
24
25
|
return [bodyCompactStyles, emptyStateStyles, emptyStateSimpleStyles];
|
25
26
|
}
|
26
27
|
|
27
|
-
constructor() {
|
28
|
-
super();
|
29
|
-
this._missingDescriptionErrorHasBeenThrown = false;
|
30
|
-
this._validatingDescriptionTimeout = null;
|
31
|
-
}
|
32
|
-
|
33
|
-
firstUpdated(changedProperties) {
|
34
|
-
super.firstUpdated(changedProperties);
|
35
|
-
this._validateDescription();
|
36
|
-
}
|
37
|
-
|
38
28
|
render() {
|
39
29
|
return html`
|
40
30
|
<p class="d2l-body-compact d2l-empty-state-description">${this.description}</p>
|
@@ -42,20 +32,6 @@ class EmptyStateSimple extends RtlMixin(LitElement) {
|
|
42
32
|
`;
|
43
33
|
}
|
44
34
|
|
45
|
-
_validateDescription() {
|
46
|
-
clearTimeout(this._validatingDescriptionTimeout);
|
47
|
-
// don't error immediately in case it doesn't get set immediately
|
48
|
-
this._validatingDescriptionTimeout = setTimeout(() => {
|
49
|
-
this._validatingDescriptionTimeout = null;
|
50
|
-
const hasDescription = (typeof this.description === 'string') && this.description.length > 0;
|
51
|
-
|
52
|
-
if (!hasDescription && !this._missingDescriptionErrorHasBeenThrown) {
|
53
|
-
this._missingDescriptionErrorHasBeenThrown = true;
|
54
|
-
setTimeout(() => { throw new Error('<d2l-empty-state-simple>: missing required "description" attribute.'); });
|
55
|
-
}
|
56
|
-
}, 3000);
|
57
|
-
}
|
58
|
-
|
59
35
|
}
|
60
36
|
|
61
37
|
customElements.define('d2l-empty-state-simple', EmptyStateSimple);
|
@@ -12,6 +12,7 @@ import { inputStyles } from './input-styles.js';
|
|
12
12
|
import { LabelledMixin } from '../../mixins/labelled/labelled-mixin.js';
|
13
13
|
import { offscreenStyles } from '../offscreen/offscreen.js';
|
14
14
|
import { PerfMonitor } from '../../helpers/perfMonitor.js';
|
15
|
+
import { PropertyRequiredMixin } from '../../mixins/property-required/property-required-mixin.js';
|
15
16
|
import { RtlMixin } from '../../mixins/rtl/rtl-mixin.js';
|
16
17
|
import { SkeletonMixin } from '../skeleton/skeleton-mixin.js';
|
17
18
|
import { styleMap } from 'lit/directives/style-map.js';
|
@@ -24,7 +25,7 @@ import { styleMap } from 'lit/directives/style-map.js';
|
|
24
25
|
* @fires change - Dispatched when an alteration to the value is committed (typically after focus is lost) by the user
|
25
26
|
* @fires input - Dispatched immediately after changes by the user
|
26
27
|
*/
|
27
|
-
class InputText extends FocusMixin(LabelledMixin(FormElementMixin(SkeletonMixin(RtlMixin(LitElement))))) {
|
28
|
+
class InputText extends PropertyRequiredMixin(FocusMixin(LabelledMixin(FormElementMixin(SkeletonMixin(RtlMixin(LitElement)))))) {
|
28
29
|
|
29
30
|
static get properties() {
|
30
31
|
return {
|
@@ -152,7 +153,18 @@ class InputText extends FocusMixin(LabelledMixin(FormElementMixin(SkeletonMixin(
|
|
152
153
|
* Accessible label for the unit which will not be visually rendered
|
153
154
|
* @type {string}
|
154
155
|
*/
|
155
|
-
unitLabel: {
|
156
|
+
unitLabel: {
|
157
|
+
attribute: 'unit-label',
|
158
|
+
required: {
|
159
|
+
dependentProps: ['unit'],
|
160
|
+
message: (_value, elem) => `<d2l-input-text>: missing required attribute "unit-label" for unit "${elem.unit}"`,
|
161
|
+
validator: (_value, elem, hasValue) => {
|
162
|
+
const hasUnit = (typeof elem.unit === 'string') && elem.unit.length > 0;
|
163
|
+
return !(hasUnit && elem.unit !== '%' && !hasValue);
|
164
|
+
}
|
165
|
+
},
|
166
|
+
type: String
|
167
|
+
},
|
156
168
|
/**
|
157
169
|
* Value of the input
|
158
170
|
* @type {string}
|
@@ -270,7 +282,6 @@ class InputText extends FocusMixin(LabelledMixin(FormElementMixin(SkeletonMixin(
|
|
270
282
|
this._intersectionObserver = null;
|
271
283
|
this._isIntersecting = false;
|
272
284
|
this._lastSlotWidth = 0;
|
273
|
-
this._missingUnitLabelErrorHasBeenThrown = false;
|
274
285
|
this._prevValue = '';
|
275
286
|
|
276
287
|
this._handleBlur = this._handleBlur.bind(this);
|
@@ -278,7 +289,6 @@ class InputText extends FocusMixin(LabelledMixin(FormElementMixin(SkeletonMixin(
|
|
278
289
|
this._handleMouseEnter = this._handleMouseEnter.bind(this);
|
279
290
|
this._handleMouseLeave = this._handleMouseLeave.bind(this);
|
280
291
|
this._perfMonitor = new PerfMonitor(this);
|
281
|
-
this._validatingUnitTimeout = null;
|
282
292
|
}
|
283
293
|
|
284
294
|
get value() { return this._value; }
|
@@ -355,7 +365,6 @@ class InputText extends FocusMixin(LabelledMixin(FormElementMixin(SkeletonMixin(
|
|
355
365
|
super.firstUpdated(changedProperties);
|
356
366
|
|
357
367
|
this._setValue(this.value, true);
|
358
|
-
this._validateUnit();
|
359
368
|
|
360
369
|
const container = this.shadowRoot && this.shadowRoot.querySelector('.d2l-input-text-container');
|
361
370
|
if (!container) return;
|
@@ -484,7 +493,6 @@ class InputText extends FocusMixin(LabelledMixin(FormElementMixin(SkeletonMixin(
|
|
484
493
|
changedProperties.forEach((oldVal, prop) => {
|
485
494
|
if (prop === 'unit' || prop === 'unitLabel') {
|
486
495
|
this._updateInputLayout();
|
487
|
-
this._validateUnit();
|
488
496
|
} else if (prop === 'validationError') {
|
489
497
|
if (oldVal && this.validationError) {
|
490
498
|
const tooltip = this.shadowRoot.querySelector('d2l-tooltip');
|
@@ -655,20 +663,5 @@ class InputText extends FocusMixin(LabelledMixin(FormElementMixin(SkeletonMixin(
|
|
655
663
|
|
656
664
|
}
|
657
665
|
|
658
|
-
_validateUnit() {
|
659
|
-
if (this._missingUnitLabelErrorHasBeenThrown) return;
|
660
|
-
clearTimeout(this._validatingUnitTimeout);
|
661
|
-
// don't error immediately in case it doesn't get set immediately
|
662
|
-
this._validatingUnitTimeout = setTimeout(() => {
|
663
|
-
this._validatingUnitTimeout = null;
|
664
|
-
const hasUnit = (typeof this.unit === 'string') && this.unit.length > 0;
|
665
|
-
const hasUnitLabel = (typeof this.unitLabel === 'string') && this.unitLabel.length > 0;
|
666
|
-
if (hasUnit && this.unit !== '%' && !hasUnitLabel) {
|
667
|
-
this._missingUnitLabelErrorHasBeenThrown = true;
|
668
|
-
throw new Error(`<d2l-input-text>: missing required attribute "unit-label" for unit "${this.unit}"`);
|
669
|
-
}
|
670
|
-
}, 3000);
|
671
|
-
}
|
672
|
-
|
673
666
|
}
|
674
667
|
customElements.define('d2l-input-text', InputText);
|
package/custom-elements.json
CHANGED
@@ -343,6 +343,43 @@
|
|
343
343
|
}
|
344
344
|
]
|
345
345
|
},
|
346
|
+
{
|
347
|
+
"name": "d2l-button-add",
|
348
|
+
"path": "./components/button/button-add.js",
|
349
|
+
"description": "A component for quickly adding items to a specific locaiton.",
|
350
|
+
"attributes": [
|
351
|
+
{
|
352
|
+
"name": "text",
|
353
|
+
"description": "When text-visible is true, the text to show in the button. When text-visible is false, the text to show in the tooltip.",
|
354
|
+
"type": "string"
|
355
|
+
},
|
356
|
+
{
|
357
|
+
"name": "text-visible",
|
358
|
+
"description": "When true, show the button with icon and visible text. When false, only show icon.",
|
359
|
+
"type": "boolean",
|
360
|
+
"default": "false"
|
361
|
+
}
|
362
|
+
],
|
363
|
+
"properties": [
|
364
|
+
{
|
365
|
+
"name": "text",
|
366
|
+
"attribute": "text",
|
367
|
+
"description": "When text-visible is true, the text to show in the button. When text-visible is false, the text to show in the tooltip.",
|
368
|
+
"type": "string"
|
369
|
+
},
|
370
|
+
{
|
371
|
+
"name": "textVisible",
|
372
|
+
"attribute": "text-visible",
|
373
|
+
"description": "When true, show the button with icon and visible text. When false, only show icon.",
|
374
|
+
"type": "boolean",
|
375
|
+
"default": "false"
|
376
|
+
},
|
377
|
+
{
|
378
|
+
"name": "documentLocaleSettings",
|
379
|
+
"default": "\"getDocumentLocaleSettings()\""
|
380
|
+
}
|
381
|
+
]
|
382
|
+
},
|
346
383
|
{
|
347
384
|
"name": "d2l-button-icon",
|
348
385
|
"path": "./components/button/button-icon.js",
|
package/lang/ar.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "إغلاق التنبيه",
|
3
3
|
"components.breadcrumbs.breadcrumb": "شريط التنقل",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "لم يتم التحديد.",
|
5
6
|
"components.calendar.selected": "تم التحديد.",
|
6
7
|
"components.calendar.show": "إظهار {month}",
|
package/lang/cy.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "Cau Hysbysiad",
|
3
3
|
"components.breadcrumbs.breadcrumb": "Briwsionyn Bara",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "Heb ei Ddewis.",
|
5
6
|
"components.calendar.selected": "Wedi'i Ddewis.",
|
6
7
|
"components.calendar.show": "Dangos {month}",
|
package/lang/da.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "Luk besked",
|
3
3
|
"components.breadcrumbs.breadcrumb": "Brødkrumme",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "Ikke valgt.",
|
5
6
|
"components.calendar.selected": "Valgt.",
|
6
7
|
"components.calendar.show": "Vis {month}",
|
package/lang/de.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "Benachrichtigung schließen",
|
3
3
|
"components.breadcrumbs.breadcrumb": "Brotkrümelnavigation",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "Nicht ausgewählt.",
|
5
6
|
"components.calendar.selected": "Ausgewählt.",
|
6
7
|
"components.calendar.show": "{month} anzeigen",
|
package/lang/en-gb.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "Close Alert",
|
3
3
|
"components.breadcrumbs.breadcrumb": "Breadcrumb",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "Not Selected.",
|
5
6
|
"components.calendar.selected": "Selected.",
|
6
7
|
"components.calendar.show": "Show {month}",
|
package/lang/en.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "Close Alert",
|
3
3
|
"components.breadcrumbs.breadcrumb": "Breadcrumb",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "Not Selected.",
|
5
6
|
"components.calendar.selected": "Selected.",
|
6
7
|
"components.calendar.show": "Show {month}",
|
package/lang/es-es.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "Cerrar alerta",
|
3
3
|
"components.breadcrumbs.breadcrumb": "Ruta de navegación",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "No seleccionado.",
|
5
6
|
"components.calendar.selected": "Seleccionado.",
|
6
7
|
"components.calendar.show": "Mostrar {month}",
|
package/lang/es.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "Cerrar alerta",
|
3
3
|
"components.breadcrumbs.breadcrumb": "Ruta de navegación",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "No seleccionado.",
|
5
6
|
"components.calendar.selected": "Seleccionado.",
|
6
7
|
"components.calendar.show": "Mostrar {month}",
|
package/lang/fr-fr.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "Fermer l'alerte",
|
3
3
|
"components.breadcrumbs.breadcrumb": "Chemin de navigation",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "Non sélectionné.",
|
5
6
|
"components.calendar.selected": "Sélectionné.",
|
6
7
|
"components.calendar.show": "Afficher {month}",
|
package/lang/fr.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "Fermer l'alerte",
|
3
3
|
"components.breadcrumbs.breadcrumb": "Chemin de navigation",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "Non sélectionné(e)",
|
5
6
|
"components.calendar.selected": "Sélectionné(e).",
|
6
7
|
"components.calendar.show": "Afficher {month}",
|
package/lang/hi.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "अलर्ट बंद करें",
|
3
3
|
"components.breadcrumbs.breadcrumb": "ब्रेडक्रंब",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "चयनित नहीं।",
|
5
6
|
"components.calendar.selected": "चयनित।",
|
6
7
|
"components.calendar.show": "{month} दिखाएँ",
|
package/lang/ja.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "アラートを閉じる",
|
3
3
|
"components.breadcrumbs.breadcrumb": "階層",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "選択されていません。",
|
5
6
|
"components.calendar.selected": "選択されています。",
|
6
7
|
"components.calendar.show": "{month} を表示",
|
package/lang/ko.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "경보 닫기",
|
3
3
|
"components.breadcrumbs.breadcrumb": "이동 경로",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "선택되지 않음.",
|
5
6
|
"components.calendar.selected": "선택됨.",
|
6
7
|
"components.calendar.show": "{month} 표시",
|
package/lang/nl.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "Waarschuwing sluiten",
|
3
3
|
"components.breadcrumbs.breadcrumb": "Kruimelpad",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "Niet geselecteerd.",
|
5
6
|
"components.calendar.selected": "Geselecteerd.",
|
6
7
|
"components.calendar.show": "{month} weergeven",
|
package/lang/pt.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "Fechar alerta",
|
3
3
|
"components.breadcrumbs.breadcrumb": "Auxiliar de navegação",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "Não selecionado.",
|
5
6
|
"components.calendar.selected": "Selecionado.",
|
6
7
|
"components.calendar.show": "Mostrar {month}",
|
package/lang/sv.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "Stängningsvarning",
|
3
3
|
"components.breadcrumbs.breadcrumb": "Sökväg",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "Inte vald.",
|
5
6
|
"components.calendar.selected": "Markerad.",
|
6
7
|
"components.calendar.show": "Visa {month}",
|
package/lang/tr.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "Kapatma Uyarısı",
|
3
3
|
"components.breadcrumbs.breadcrumb": "İçerik Haritası",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "Seçili Değil.",
|
5
6
|
"components.calendar.selected": "Seçili.",
|
6
7
|
"components.calendar.show": "{month} Göster",
|
package/lang/zh-cn.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "关闭提醒",
|
3
3
|
"components.breadcrumbs.breadcrumb": "痕迹导航",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "未选择。",
|
5
6
|
"components.calendar.selected": "已选择。",
|
6
7
|
"components.calendar.show": "显示 {month}",
|
package/lang/zh-tw.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export default {
|
2
2
|
"components.alert.close": "關閉警示",
|
3
3
|
"components.breadcrumbs.breadcrumb": "導覽路徑",
|
4
|
+
"components.button-add.addItem": "Add Item",
|
4
5
|
"components.calendar.notSelected": "未選取。",
|
5
6
|
"components.calendar.selected": "已選取。",
|
6
7
|
"components.calendar.show": "顯示{month}",
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@brightspace-ui/core",
|
3
|
-
"version": "2.
|
3
|
+
"version": "2.166.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",
|