@brightspace-ui/labs 1.2.3 → 1.3.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/package.json +9 -4
- package/src/components/community/community-base.js +27 -0
- package/src/components/community/community-button.js +27 -0
- package/src/components/community/community-link.js +19 -0
- package/src/components/community/community-url-factory.js +23 -0
- package/src/components/community/link-temp.js +192 -0
- package/src/components/opt-in-flyout/flyout-impl.js +1 -1
- package/src/components/opt-in-flyout/opt-out-dialog.js +1 -2
- package/src/components/opt-in-flyout/opt-out-reason-selector.js +6 -0
- package/src/controllers/language-listener/language-listener.js +23 -0
package/package.json
CHANGED
|
@@ -4,11 +4,15 @@
|
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": "https://github.com/BrightspaceUI/labs.git",
|
|
6
6
|
"exports": {
|
|
7
|
+
"./components/community-button.js": "./src/components/community/community-button.js",
|
|
8
|
+
"./components/community-link.js": "./src/components/community/community-link.js",
|
|
9
|
+
"./components/community-url-factory.js": "./src/components/community/community-url-factory.js",
|
|
7
10
|
"./components/opt-in-flyout.js": "./src/components/opt-in-flyout/opt-in-flyout.js",
|
|
8
11
|
"./components/opt-out-flyout.js": "./src/components/opt-in-flyout/opt-out-flyout.js",
|
|
9
12
|
"./components/opt-out-reason.js": "./src/components/opt-in-flyout/opt-out-reason.js",
|
|
10
13
|
"./controllers/computed-value.js": "./src/controllers/computed-values/computed-value.js",
|
|
11
|
-
"./controllers/computed-values.js": "./src/controllers/computed-values/computed-values.js"
|
|
14
|
+
"./controllers/computed-values.js": "./src/controllers/computed-values/computed-values.js",
|
|
15
|
+
"./controllers/language-listener.js": "./src/controllers/language-listener/language-listener.js"
|
|
12
16
|
},
|
|
13
17
|
"scripts": {
|
|
14
18
|
"lint": "npm run lint:eslint && npm run lint:style",
|
|
@@ -17,13 +21,14 @@
|
|
|
17
21
|
"start": "web-dev-server --node-resolve --open --watch",
|
|
18
22
|
"test": "npm run lint && npm run test:translations && npm run test:unit",
|
|
19
23
|
"test:translations": "mfv -e -s en -p ./lang/ -i untranslated",
|
|
20
|
-
"test:unit": "d2l-test-runner"
|
|
24
|
+
"test:unit": "d2l-test-runner",
|
|
25
|
+
"test:vdiff": "d2l-test-runner vdiff"
|
|
21
26
|
},
|
|
22
27
|
"author": "D2L Corporation",
|
|
23
28
|
"license": "Apache-2.0",
|
|
24
29
|
"devDependencies": {
|
|
25
30
|
"@brightspace-ui/stylelint-config": "^0.8",
|
|
26
|
-
"@brightspace-ui/testing": "^0.
|
|
31
|
+
"@brightspace-ui/testing": "^0.34",
|
|
27
32
|
"@web/dev-server": "^0.3",
|
|
28
33
|
"eslint": "^8",
|
|
29
34
|
"eslint-config-brightspace": "^0.25",
|
|
@@ -41,5 +46,5 @@
|
|
|
41
46
|
"@brightspace-ui/core": "^2",
|
|
42
47
|
"lit": "^2"
|
|
43
48
|
},
|
|
44
|
-
"version": "1.
|
|
49
|
+
"version": "1.3.0"
|
|
45
50
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { communityUrlFactory } from './community-url-factory.js';
|
|
2
|
+
import { LanguageListenerController } from '../../controllers/language-listener/language-listener.js';
|
|
3
|
+
|
|
4
|
+
export const CommunityBase = (superClass) => class CommunityBaseMixin extends superClass {
|
|
5
|
+
|
|
6
|
+
static get properties() {
|
|
7
|
+
return {
|
|
8
|
+
articleMap: { attribute: 'article-map', type: Object }
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
constructor() {
|
|
13
|
+
super();
|
|
14
|
+
this.langController = new LanguageListenerController(this);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
connectedCallback() {
|
|
18
|
+
super.connectedCallback();
|
|
19
|
+
this.communityArticleDirective = communityUrlFactory(this.articleMap);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
updated(changedProperties) {
|
|
23
|
+
if (changedProperties.has('articleMap')) {
|
|
24
|
+
this.communityArticleDirective = communityUrlFactory(this.articleMap);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import '@brightspace-ui/core/components/button/button-subtle.js';
|
|
2
|
+
import { html, LitElement } from 'lit';
|
|
3
|
+
import { CommunityBase } from './community-base.js';
|
|
4
|
+
|
|
5
|
+
class CommunityLink extends CommunityBase(LitElement) {
|
|
6
|
+
|
|
7
|
+
static get properties() {
|
|
8
|
+
return {
|
|
9
|
+
text: { type: String },
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
render() {
|
|
14
|
+
return html`<d2l-button-subtle
|
|
15
|
+
icon="d2l-tier1:help"
|
|
16
|
+
text=${this.text}
|
|
17
|
+
@click="${this._handleButtonClick}"
|
|
18
|
+
></d2l-button-subtle>`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
_handleButtonClick() {
|
|
22
|
+
const link = this.communityArticleDirective(this.langController.language);
|
|
23
|
+
window.open(link, '_blank');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
customElements.define('d2l-labs-community-button', CommunityLink);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import './link-temp.js';
|
|
2
|
+
import { html, LitElement } from 'lit';
|
|
3
|
+
import { CommunityBase } from './community-base.js';
|
|
4
|
+
|
|
5
|
+
class CommunityLink extends CommunityBase(LitElement) {
|
|
6
|
+
|
|
7
|
+
static get properties() {
|
|
8
|
+
return {
|
|
9
|
+
text: { type: String },
|
|
10
|
+
small: { type: Boolean }
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
render() {
|
|
15
|
+
return html`<d2l-labs-link-temp new-window href="${this.communityArticleDirective(this.langController.language)}" ?small=${this.small} >${this.text}</d2l-labs-link-temp>`;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
customElements.define('d2l-labs-community-link', CommunityLink);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
export const communityUrlFactory = (articleMap) => (langIdent) => {
|
|
3
|
+
langIdent = langIdent.toLocaleLowerCase();
|
|
4
|
+
let articleCode = articleMap[langIdent];
|
|
5
|
+
let usedLangCode = articleCode !== undefined ? langIdent : undefined;
|
|
6
|
+
if (articleCode === undefined) {
|
|
7
|
+
// try and get a region-less match
|
|
8
|
+
const regionlessLangIdent = langIdent.split('-')[0];
|
|
9
|
+
Object.entries(articleMap).forEach(([langCode, currentArticle]) => {
|
|
10
|
+
const regionlessLangCode = langCode.split('-')[0];
|
|
11
|
+
if (regionlessLangIdent === regionlessLangCode) {
|
|
12
|
+
articleCode = currentArticle;
|
|
13
|
+
usedLangCode = langCode;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
// still undefined? use en
|
|
17
|
+
if (articleCode === undefined) {
|
|
18
|
+
articleCode = articleMap['en'];
|
|
19
|
+
usedLangCode = 'en';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return `https://community.d2l.com/brightspace${usedLangCode === 'en' ? '' : `-${usedLangCode}`}/kb/articles/${articleCode}`;
|
|
23
|
+
};
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
// Delete this file once core#4001 is merged.
|
|
2
|
+
// https://github.com/BrightspaceUI/core/pull/4001
|
|
3
|
+
import '@brightspace-ui/core/components/colors/colors';
|
|
4
|
+
import '@brightspace-ui/core/components/icons/icon.js';
|
|
5
|
+
import { css, html, LitElement, nothing, unsafeCSS } from 'lit';
|
|
6
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
7
|
+
import { FocusMixin } from '@brightspace-ui/core/mixins/focus/focus-mixin.js';
|
|
8
|
+
import { getFocusPseudoClass } from '@brightspace-ui/core/helpers/focus.js';
|
|
9
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
10
|
+
import { LocalizeCoreElement } from '@brightspace-ui/core/helpers/localize-core-element.js';
|
|
11
|
+
import { offscreenStyles } from '@brightspace-ui/core/components/offscreen/offscreen.js';
|
|
12
|
+
import { styleMap } from 'lit/directives/style-map.js';
|
|
13
|
+
|
|
14
|
+
export const linkStyles = css`
|
|
15
|
+
.d2l-link, .d2l-link:visited, .d2l-link:active, .d2l-link:link {
|
|
16
|
+
color: var(--d2l-color-celestine);
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
outline-style: none;
|
|
19
|
+
text-decoration: none;
|
|
20
|
+
}
|
|
21
|
+
:host([skeleton]) .d2l-link.d2l-skeletize::before {
|
|
22
|
+
bottom: 0.2rem;
|
|
23
|
+
top: 0.2rem;
|
|
24
|
+
}
|
|
25
|
+
.d2l-link:hover {
|
|
26
|
+
color: var(--d2l-color-celestine-minus-1);
|
|
27
|
+
text-decoration: underline;
|
|
28
|
+
}
|
|
29
|
+
.d2l-link:${unsafeCSS(getFocusPseudoClass())} {
|
|
30
|
+
border-radius: 2px;
|
|
31
|
+
outline: 2px solid var(--d2l-color-celestine);
|
|
32
|
+
outline-offset: 1px;
|
|
33
|
+
text-decoration: underline;
|
|
34
|
+
}
|
|
35
|
+
.d2l-link.d2l-link-main {
|
|
36
|
+
font-weight: 700;
|
|
37
|
+
}
|
|
38
|
+
.d2l-link.d2l-link-small {
|
|
39
|
+
font-size: 0.7rem;
|
|
40
|
+
letter-spacing: 0.01rem;
|
|
41
|
+
line-height: 1.05rem;
|
|
42
|
+
}
|
|
43
|
+
:host([skeleton]) .d2l-link.d2l-link-small.d2l-skeletize::before {
|
|
44
|
+
bottom: 0.15rem;
|
|
45
|
+
top: 0.15rem;
|
|
46
|
+
}
|
|
47
|
+
@media print {
|
|
48
|
+
.d2l-link, .d2l-link:visited, .d2l-link:active, .d2l-link:link {
|
|
49
|
+
color: var(--d2l-color-ferrite);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
`;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* This component can be used just like the native anchor tag.
|
|
56
|
+
* @slot - The content (e.g., text) that when selected causes navigation
|
|
57
|
+
*/
|
|
58
|
+
class Link extends LocalizeCoreElement(FocusMixin(LitElement)) {
|
|
59
|
+
|
|
60
|
+
static get properties() {
|
|
61
|
+
return {
|
|
62
|
+
/**
|
|
63
|
+
* Sets an accessible label
|
|
64
|
+
* @type {string}
|
|
65
|
+
*/
|
|
66
|
+
ariaLabel: { type: String, attribute: 'aria-label' },
|
|
67
|
+
/**
|
|
68
|
+
* Download a URL instead of navigating to it
|
|
69
|
+
* @type {boolean}
|
|
70
|
+
*/
|
|
71
|
+
download: { type: Boolean },
|
|
72
|
+
/**
|
|
73
|
+
* REQUIRED: URL or URL fragment of the link
|
|
74
|
+
* @type {string}
|
|
75
|
+
*/
|
|
76
|
+
href: { type: String },
|
|
77
|
+
/**
|
|
78
|
+
* Whether to apply the "main" link style
|
|
79
|
+
* @type {boolean}
|
|
80
|
+
*/
|
|
81
|
+
main: { type: Boolean, reflect: true },
|
|
82
|
+
/**
|
|
83
|
+
* The number of lines to display before truncating text with an ellipsis. The text will not be truncated unless a value is specified.
|
|
84
|
+
* @type {number}
|
|
85
|
+
*/
|
|
86
|
+
lines: { type: Number },
|
|
87
|
+
/**
|
|
88
|
+
* Whether to apply the "small" link style
|
|
89
|
+
* @type {boolean}
|
|
90
|
+
*/
|
|
91
|
+
small: { type: Boolean, reflect: true },
|
|
92
|
+
/**
|
|
93
|
+
* Where to display the linked URL
|
|
94
|
+
* @type {string}
|
|
95
|
+
*/
|
|
96
|
+
target: { type: String },
|
|
97
|
+
/**
|
|
98
|
+
* Whether to display the open in new window icon
|
|
99
|
+
* @type {boolean}
|
|
100
|
+
*/
|
|
101
|
+
newWindow: { type: Boolean, attribute: 'new-window' }
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static get styles() {
|
|
106
|
+
return [ linkStyles, offscreenStyles,
|
|
107
|
+
css`
|
|
108
|
+
:host {
|
|
109
|
+
display: inline;
|
|
110
|
+
}
|
|
111
|
+
:host([hidden]) {
|
|
112
|
+
display: none;
|
|
113
|
+
}
|
|
114
|
+
:host([small]) {
|
|
115
|
+
/* needed to keep host element same height as link */
|
|
116
|
+
font-size: 0.7rem;
|
|
117
|
+
line-height: 1.05rem;
|
|
118
|
+
}
|
|
119
|
+
a {
|
|
120
|
+
display: inherit;
|
|
121
|
+
}
|
|
122
|
+
a.truncate {
|
|
123
|
+
-webkit-box-orient: vertical;
|
|
124
|
+
display: -webkit-box;
|
|
125
|
+
overflow: hidden;
|
|
126
|
+
overflow-wrap: anywhere;
|
|
127
|
+
}
|
|
128
|
+
d2l-icon.d2l-new-window {
|
|
129
|
+
color: var(--d2l-color-celestine);
|
|
130
|
+
vertical-align: inherit;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
:host([small]) d2l-icon.d2l-new-window {
|
|
134
|
+
height: 14px;
|
|
135
|
+
width: 14px;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@media print {
|
|
139
|
+
d2l-icon.d2l-new-window {
|
|
140
|
+
display: none;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
`
|
|
144
|
+
];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
constructor() {
|
|
148
|
+
super();
|
|
149
|
+
this.download = false;
|
|
150
|
+
this.main = false;
|
|
151
|
+
this.small = false;
|
|
152
|
+
this.lines = 0;
|
|
153
|
+
this.newWindow = false;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
static get focusElementSelector() {
|
|
157
|
+
return '.d2l-link';
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
render() {
|
|
161
|
+
const linkClasses = {
|
|
162
|
+
'd2l-link': true,
|
|
163
|
+
'd2l-link-main': this.main,
|
|
164
|
+
'd2l-link-small': this.small,
|
|
165
|
+
'truncate': this.lines > 0
|
|
166
|
+
};
|
|
167
|
+
const styles = (this.lines > 0) ? { '-webkit-line-clamp': this.lines } : {};
|
|
168
|
+
const target = this.newWindow && this.target === undefined
|
|
169
|
+
? '_blank'
|
|
170
|
+
: this.target;
|
|
171
|
+
/* eslint-disable indent */
|
|
172
|
+
return html`
|
|
173
|
+
<a
|
|
174
|
+
aria-label="${ifDefined(this.ariaLabel)}"
|
|
175
|
+
class="${classMap(linkClasses)}"
|
|
176
|
+
style="${styleMap(styles)}"
|
|
177
|
+
?download="${this.download}"
|
|
178
|
+
href="${ifDefined(this.href)}"
|
|
179
|
+
target="${ifDefined(target)}"
|
|
180
|
+
>
|
|
181
|
+
<span style="white-space: nowrap;">
|
|
182
|
+
<span style="white-space: normal;"><slot></slot></span>${this.newWindow ? html` <d2l-icon class="d2l-new-window" icon="tier1:new-window"></d2l-icon>`
|
|
183
|
+
: nothing}
|
|
184
|
+
${target === '_blank' ? html`<span class="d2l-offscreen">${this.localize('components.link.open-in-new-window')}</span>`
|
|
185
|
+
: nothing}
|
|
186
|
+
</span>
|
|
187
|
+
</a>`;
|
|
188
|
+
}
|
|
189
|
+
/* eslint-enable indent */
|
|
190
|
+
|
|
191
|
+
}
|
|
192
|
+
customElements.define('d2l-labs-link-temp', Link);
|
|
@@ -375,7 +375,7 @@ class FlyoutImplementation extends composeMixins(
|
|
|
375
375
|
${this._renderLinksText()}
|
|
376
376
|
</div>
|
|
377
377
|
<div class="flyout-buttons">
|
|
378
|
-
<d2l-button id="primary-button" primary
|
|
378
|
+
<d2l-button id="primary-button" primary @click="${this._clickOptIn}">${this._getPrimaryButtonText()}</d2l-button>
|
|
379
379
|
<d2l-button id="opt-out-button" @click="${this._clickOptOut}">${this._getSecondaryButtonText()}</d2l-button>
|
|
380
380
|
</div>
|
|
381
381
|
</div>
|
|
@@ -114,8 +114,7 @@ class OptOutDialog extends composeMixins(
|
|
|
114
114
|
<label id="title-label">${this.localize('components:optInFlyout:feedbackTitle')}</label>
|
|
115
115
|
<br><br>
|
|
116
116
|
<div ?hidden="${this.hideReason}">
|
|
117
|
-
<
|
|
118
|
-
<d2l-labs-opt-out-reason-selector id="reason-selector" aria-labelledby="reason-label" @selected="${this._handleSelected}">
|
|
117
|
+
<d2l-labs-opt-out-reason-selector id="reason-selector" @selected="${this._handleSelected}">
|
|
119
118
|
<slot></slot>
|
|
120
119
|
</d2l-labs-opt-out-reason-selector>
|
|
121
120
|
</div>
|
|
@@ -20,6 +20,11 @@ class OptOutReasonSelector extends composeMixins(
|
|
|
20
20
|
return [
|
|
21
21
|
inputStyles,
|
|
22
22
|
css`
|
|
23
|
+
label {
|
|
24
|
+
display: block;
|
|
25
|
+
margin-bottom: 0.5rem;
|
|
26
|
+
}
|
|
27
|
+
|
|
23
28
|
select {
|
|
24
29
|
-moz-appearance: none;
|
|
25
30
|
-webkit-appearance: none;
|
|
@@ -68,6 +73,7 @@ class OptOutReasonSelector extends composeMixins(
|
|
|
68
73
|
|
|
69
74
|
render() {
|
|
70
75
|
return html`
|
|
76
|
+
<label for="selector">${this.localize('components:optInFlyout:feedbackReasonLabel')}</label>
|
|
71
77
|
<select class="d2l-input" id="selector" @change="${this._reasonSelected}" onload="${this.focus()}">
|
|
72
78
|
<option disabled="" value="">${this.localize('components:optInFlyout:feedbackChooseReason')}</option>
|
|
73
79
|
${this._reasons.map((item) => html`<option value="${item.key}">${item.text}</option>`)}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { getDocumentLocaleSettings } from '@brightspace-ui/intl/lib/common.js';
|
|
2
|
+
|
|
3
|
+
const localeSettings = getDocumentLocaleSettings();
|
|
4
|
+
|
|
5
|
+
export class LanguageListenerController {
|
|
6
|
+
|
|
7
|
+
constructor(host) {
|
|
8
|
+
(this.host = host).addController(this);
|
|
9
|
+
this._handleLangUpdate = () => {
|
|
10
|
+
this.language = localeSettings.language;
|
|
11
|
+
this.host.requestUpdate();
|
|
12
|
+
};
|
|
13
|
+
this.language = localeSettings.language;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
hostConnected() {
|
|
17
|
+
localeSettings.addChangeListener(this._handleLangUpdate);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
hostDisconnected() {
|
|
21
|
+
localeSettings.removeChangeListener(this._handleLangUpdate);
|
|
22
|
+
}
|
|
23
|
+
}
|