@brightspace-ui/core 2.6.1 → 2.7.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/html-block/README.md +27 -14
- package/components/html-block/demo/html-block.html +3 -2
- package/components/list/list-item-mixin.js +16 -2
- package/components/tooltip/README.md +1 -0
- package/components/tooltip/demo/tooltip.html +36 -0
- package/components/tooltip/tooltip.js +56 -2
- package/custom-elements.json +13 -0
- package/package.json +1 -1
- package/tools/mathjax-test-context.js +6 -0
|
@@ -67,6 +67,7 @@ To use `d2l-html-block` within another Lit component, use the [unsafeHTML](https
|
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
### Rendering MathML and LaTeX
|
|
70
|
+
|
|
70
71
|
Examples are provided to display how user-authored math can be embedded within your webpage.
|
|
71
72
|
|
|
72
73
|
**MathML:**
|
|
@@ -99,25 +100,13 @@ Examples are provided to display how user-authored math can be embedded within y
|
|
|
99
100
|
</d2l-html-block>
|
|
100
101
|
```
|
|
101
102
|
|
|
102
|
-
**LaTeX:** Rendering LaTeX requires the `
|
|
103
|
+
**LaTeX:** Rendering LaTeX requires the `mathjax` context to be set correctly. For testing and/or demo pages you can do the following.
|
|
103
104
|
|
|
104
105
|
<!-- docs: demo code -->
|
|
105
106
|
```html
|
|
106
107
|
<script type="module">
|
|
107
108
|
import '@brightspace-ui/core/components/html-block/html-block.js';
|
|
108
|
-
|
|
109
|
-
window.D2L = {};
|
|
110
|
-
D2L.LP = {};
|
|
111
|
-
D2L.LP.Web = {};
|
|
112
|
-
D2L.LP.Web.UI = {};
|
|
113
|
-
D2L.LP.Web.UI.Flags = {
|
|
114
|
-
Flag: (feature, defaultValue) => {
|
|
115
|
-
if (feature === 'us125413-mathjax-render-latex') return true;
|
|
116
|
-
else return defaultValue;
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
<!-- docs: start hidden content -->
|
|
120
|
-
document.getElementsByTagName('html')[0].dataset.mathjaxContext = JSON.stringify({ renderLatex: true });<!-- docs: end hidden content -->
|
|
109
|
+
import '@brightspace-ui/core/tools/mathjax-test-context.js';
|
|
121
110
|
</script>
|
|
122
111
|
<d2l-html-block>
|
|
123
112
|
<div class="latex-container">
|
|
@@ -125,3 +114,27 @@ Examples are provided to display how user-authored math can be embedded within y
|
|
|
125
114
|
</div>
|
|
126
115
|
</d2l-html-block>
|
|
127
116
|
```
|
|
117
|
+
|
|
118
|
+
### Add Context Automatically to Demos and Tests
|
|
119
|
+
|
|
120
|
+
You can automatically set-up the `mathjax` context for demo pages and unit tests when using `@web/dev-server` and `@web/test-runner` by adding the following plugin to your configuration.
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
export default {
|
|
124
|
+
...
|
|
125
|
+
plugins: [{
|
|
126
|
+
name: 'setup-mathjax-context',
|
|
127
|
+
transform(context) {
|
|
128
|
+
if (context.response.is('html')) {
|
|
129
|
+
const newBody = context.body.replace(
|
|
130
|
+
/<head>/,
|
|
131
|
+
'<head><script src="/node_modules/@brightspace-ui/core/tools/mathjax-test-context.js"></script>'
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
return { body: newBody };
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}],
|
|
138
|
+
...
|
|
139
|
+
}
|
|
140
|
+
```
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
<script type="module">
|
|
8
8
|
import '../../demo/demo-page.js';
|
|
9
9
|
import '../html-block.js';
|
|
10
|
+
|
|
10
11
|
import { provideInstance } from '../../../mixins/provider-mixin.js';
|
|
11
12
|
|
|
12
13
|
class DemoReplacementRenderer {
|
|
@@ -41,8 +42,8 @@
|
|
|
41
42
|
provideInstance(document, 'html-block-renderers', [ new DemoReplacementRenderer() ]);
|
|
42
43
|
|
|
43
44
|
</script>
|
|
44
|
-
<script>
|
|
45
|
-
|
|
45
|
+
<script type="module">
|
|
46
|
+
import '../../../tools/mathjax-test-context.js';
|
|
46
47
|
</script>
|
|
47
48
|
</head>
|
|
48
49
|
<body unresolved>
|
|
@@ -74,7 +74,9 @@ export const ListItemMixin = superclass => class extends LocalizeCoreElement(Lis
|
|
|
74
74
|
_dropdownOpen: { type: Boolean, attribute: '_dropdown-open', reflect: true },
|
|
75
75
|
_fullscreenWithin: { type: Boolean, attribute: '_fullscreen-within', reflect: true },
|
|
76
76
|
_hovering: { type: Boolean, reflect: true },
|
|
77
|
+
_hoveringPrimaryAction: { type: Boolean, attribute: '_hovering-primary-action', reflect: true },
|
|
77
78
|
_focusing: { type: Boolean, reflect: true },
|
|
79
|
+
_focusingPrimaryAction: { type: Boolean, attribute: '_focusing-primary-action', reflect: true },
|
|
78
80
|
_highlight: { type: Boolean, reflect: true },
|
|
79
81
|
_highlighting: { type: Boolean, reflect: true },
|
|
80
82
|
_tooltipShowing: { type: Boolean, attribute: '_tooltip-showing', reflect: true }
|
|
@@ -163,8 +165,8 @@ export const ListItemMixin = superclass => class extends LocalizeCoreElement(Lis
|
|
|
163
165
|
.d2l-list-item-content ::slotted(*) {
|
|
164
166
|
margin-top: 0.05rem;
|
|
165
167
|
}
|
|
166
|
-
:host([_hovering]) .d2l-list-item-content,
|
|
167
|
-
:host([_focusing]) .d2l-list-item-content {
|
|
168
|
+
:host([_hovering-primary-action]) .d2l-list-item-content,
|
|
169
|
+
:host([_focusing-primary-action]) .d2l-list-item-content {
|
|
168
170
|
--d2l-list-item-content-text-color: var(--d2l-color-celestine);
|
|
169
171
|
--d2l-list-item-content-text-decoration: underline;
|
|
170
172
|
}
|
|
@@ -511,11 +513,19 @@ export const ListItemMixin = superclass => class extends LocalizeCoreElement(Lis
|
|
|
511
513
|
hasDisplayedKeyboardTooltip = true;
|
|
512
514
|
}
|
|
513
515
|
|
|
516
|
+
_onFocusInPrimaryAction() {
|
|
517
|
+
this._focusingPrimaryAction = true;
|
|
518
|
+
}
|
|
519
|
+
|
|
514
520
|
_onFocusOut() {
|
|
515
521
|
this._focusing = false;
|
|
516
522
|
this._displayKeyboardTooltip = false;
|
|
517
523
|
}
|
|
518
524
|
|
|
525
|
+
_onFocusOutPrimaryAction() {
|
|
526
|
+
this._focusingPrimaryAction = false;
|
|
527
|
+
}
|
|
528
|
+
|
|
519
529
|
_onFullscreenWithin(e) {
|
|
520
530
|
if (e.detail.state) this._fullscreenWithinCount += 1;
|
|
521
531
|
else this._fullscreenWithinCount -= 1;
|
|
@@ -527,6 +537,7 @@ export const ListItemMixin = superclass => class extends LocalizeCoreElement(Lis
|
|
|
527
537
|
}
|
|
528
538
|
|
|
529
539
|
_onMouseEnterPrimaryAction() {
|
|
540
|
+
this._hoveringPrimaryAction = true;
|
|
530
541
|
this._hovering = true;
|
|
531
542
|
}
|
|
532
543
|
|
|
@@ -535,6 +546,7 @@ export const ListItemMixin = superclass => class extends LocalizeCoreElement(Lis
|
|
|
535
546
|
}
|
|
536
547
|
|
|
537
548
|
_onMouseLeavePrimaryAction() {
|
|
549
|
+
this._hoveringPrimaryAction = false;
|
|
538
550
|
this._hovering = false;
|
|
539
551
|
}
|
|
540
552
|
|
|
@@ -572,6 +584,8 @@ export const ListItemMixin = superclass => class extends LocalizeCoreElement(Lis
|
|
|
572
584
|
</div>` : nothing }
|
|
573
585
|
${primaryAction ? html`
|
|
574
586
|
<div slot="content-action"
|
|
587
|
+
@focusin="${this._onFocusInPrimaryAction}"
|
|
588
|
+
@focusout="${this._onFocusOutPrimaryAction}"
|
|
575
589
|
@mouseenter="${this._onMouseEnterPrimaryAction}"
|
|
576
590
|
@mouseleave="${this._onMouseLeavePrimaryAction}">
|
|
577
591
|
${primaryAction}
|
|
@@ -101,6 +101,7 @@ The `d2l-tooltip` component is used to display additional information when users
|
|
|
101
101
|
| `disable-focus-lock` | Boolean, default: `false` | Disables focus lock so that the tooltip will automatically close when no longer hovered even if it still has focus |
|
|
102
102
|
| `force-show` | Boolean, default: `false` | Force the tooltip to stay open as long as it remains `true` |
|
|
103
103
|
| `for-type` | String, default: `descriptor` | Accessibility type for the tooltip to specify whether it is the primary label for the target or a secondary descriptor. Valid values are: `label` and `descriptor`. |
|
|
104
|
+
| `show-truncated-only` | Boolean, default: `false` | Only show the tooltip if we detect the target element is truncated |
|
|
104
105
|
| `position` | String | Optionally force the tooltip to open in a certain direction. Valid values are: `top`, `bottom`, `left` and `right`. If no position is provided, the tooltip will open in the first position that has enough space for it in the order: bottom, top, right, left. |
|
|
105
106
|
|
|
106
107
|
### Events
|
|
@@ -32,6 +32,26 @@
|
|
|
32
32
|
padding: 20px;
|
|
33
33
|
width: 200px;
|
|
34
34
|
}
|
|
35
|
+
|
|
36
|
+
.truncated {
|
|
37
|
+
border: 1px solid #cdd5dc;
|
|
38
|
+
border-radius: 6px;
|
|
39
|
+
height: 200px;
|
|
40
|
+
padding: 20px;
|
|
41
|
+
width: 200px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.truncated d2l-button {
|
|
45
|
+
margin-bottom: 20px;
|
|
46
|
+
max-width: 100%;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.truncated d2l-button span {
|
|
50
|
+
display: block;
|
|
51
|
+
overflow: hidden;
|
|
52
|
+
text-overflow: ellipsis;
|
|
53
|
+
white-space: nowrap;
|
|
54
|
+
}
|
|
35
55
|
</style>
|
|
36
56
|
</head>
|
|
37
57
|
|
|
@@ -114,6 +134,22 @@
|
|
|
114
134
|
</template>
|
|
115
135
|
</d2l-demo-snippet>
|
|
116
136
|
|
|
137
|
+
<h2>Tooltip (only show if truncating)</h2>
|
|
138
|
+
<d2l-demo-snippet>
|
|
139
|
+
<template>
|
|
140
|
+
<div class="truncated">
|
|
141
|
+
<d2l-button id="tooltip-short"><span>Short Tooltip</span></d2l-button>
|
|
142
|
+
<d2l-tooltip for="tooltip-short" show-truncated-only>
|
|
143
|
+
This tooltip will not show.
|
|
144
|
+
</d2l-tooltip>
|
|
145
|
+
<d2l-button id="tooltip-long"><span>Very Very Very Very Long Tooltip</span></d2l-button>
|
|
146
|
+
<d2l-tooltip for="tooltip-long" show-truncated-only>
|
|
147
|
+
Very Very Very Very Long Tooltip - this tooltip will show because the text is truncating.
|
|
148
|
+
</d2l-tooltip>
|
|
149
|
+
</div>
|
|
150
|
+
</template>
|
|
151
|
+
</d2l-demo-snippet>
|
|
152
|
+
|
|
117
153
|
</d2l-demo-page>
|
|
118
154
|
|
|
119
155
|
</body>
|
|
@@ -148,6 +148,11 @@ class Tooltip extends RtlMixin(LitElement) {
|
|
|
148
148
|
* @type {number}
|
|
149
149
|
*/
|
|
150
150
|
offset: { type: Number }, /* tooltipOffset */
|
|
151
|
+
/**
|
|
152
|
+
* ADVANCED: Only show the tooltip if we detect the target element is truncated
|
|
153
|
+
* @type {boolean}
|
|
154
|
+
*/
|
|
155
|
+
showTruncatedOnly: { type: Boolean, attribute: 'show-truncated-only' },
|
|
151
156
|
/**
|
|
152
157
|
* ADVANCED: Force the tooltip to open in a certain direction. If no position is provided, the tooltip will open in the first position that has enough space for it in the order: bottom, top, right, left.
|
|
153
158
|
* @type {'top'|'bottom'|'left'|'right'}
|
|
@@ -390,11 +395,13 @@ class Tooltip extends RtlMixin(LitElement) {
|
|
|
390
395
|
this.forceShow = false;
|
|
391
396
|
this.forType = 'descriptor';
|
|
392
397
|
this.offset = pointerRotatedOverhang + pointerGap;
|
|
398
|
+
this.showTruncatedOnly = false;
|
|
393
399
|
this.state = 'info';
|
|
394
400
|
|
|
395
401
|
this._dismissibleId = null;
|
|
396
402
|
this._isFocusing = false;
|
|
397
403
|
this._isHovering = false;
|
|
404
|
+
this._resizeRunSinceTruncationCheck = false;
|
|
398
405
|
this._viewportMargin = defaultViewportMargin;
|
|
399
406
|
}
|
|
400
407
|
|
|
@@ -749,7 +756,12 @@ class Tooltip extends RtlMixin(LitElement) {
|
|
|
749
756
|
}
|
|
750
757
|
}
|
|
751
758
|
|
|
752
|
-
_onTargetFocus() {
|
|
759
|
+
async _onTargetFocus() {
|
|
760
|
+
if (this.showTruncatedOnly) {
|
|
761
|
+
await this._updateTruncating();
|
|
762
|
+
if (!this._truncating) return;
|
|
763
|
+
}
|
|
764
|
+
|
|
753
765
|
if (this.disableFocusLock) {
|
|
754
766
|
this.showing = true;
|
|
755
767
|
} else {
|
|
@@ -759,7 +771,12 @@ class Tooltip extends RtlMixin(LitElement) {
|
|
|
759
771
|
}
|
|
760
772
|
|
|
761
773
|
_onTargetMouseEnter() {
|
|
762
|
-
this._hoverTimeout = setTimeout(() => {
|
|
774
|
+
this._hoverTimeout = setTimeout(async() => {
|
|
775
|
+
if (this.showTruncatedOnly) {
|
|
776
|
+
await this._updateTruncating();
|
|
777
|
+
if (!this._truncating) return;
|
|
778
|
+
}
|
|
779
|
+
|
|
763
780
|
resetDelayTimeout();
|
|
764
781
|
this._isHovering = true;
|
|
765
782
|
this._updateShowing();
|
|
@@ -773,6 +790,7 @@ class Tooltip extends RtlMixin(LitElement) {
|
|
|
773
790
|
}
|
|
774
791
|
|
|
775
792
|
_onTargetResize() {
|
|
793
|
+
this._resizeRunSinceTruncationCheck = true;
|
|
776
794
|
if (!this.showing) {
|
|
777
795
|
return;
|
|
778
796
|
}
|
|
@@ -863,5 +881,41 @@ class Tooltip extends RtlMixin(LitElement) {
|
|
|
863
881
|
}
|
|
864
882
|
this._addListeners();
|
|
865
883
|
}
|
|
884
|
+
|
|
885
|
+
/**
|
|
886
|
+
* This solution appends a clone of the target to the target in order to retain target styles.
|
|
887
|
+
* A possible consequence of this is unexpected behaviours for web components that have slots.
|
|
888
|
+
* If this becomes an issue, it would also likely be possible to append the clone to document.body
|
|
889
|
+
* and get the expected styles through getComputedStyle.
|
|
890
|
+
*/
|
|
891
|
+
async _updateTruncating() {
|
|
892
|
+
// if no resize has happened since truncation was previously calculated the result will not have changed
|
|
893
|
+
if (!this._resizeRunSinceTruncationCheck || !this.showTruncatedOnly) return;
|
|
894
|
+
|
|
895
|
+
const target = this._target;
|
|
896
|
+
const cloneContainer = document.createElement('div');
|
|
897
|
+
cloneContainer.style.position = 'absolute';
|
|
898
|
+
cloneContainer.style.overflow = 'hidden';
|
|
899
|
+
cloneContainer.style.whiteSpace = 'nowrap';
|
|
900
|
+
cloneContainer.style.width = '1px';
|
|
901
|
+
|
|
902
|
+
if (this.getAttribute('dir') === 'rtl') {
|
|
903
|
+
cloneContainer.style.right = '-10000px';
|
|
904
|
+
} else {
|
|
905
|
+
cloneContainer.style.left = '-10000px';
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
const clone = target.cloneNode(true);
|
|
909
|
+
clone.removeAttribute('id');
|
|
910
|
+
clone.style.maxWidth = 'none';
|
|
911
|
+
|
|
912
|
+
cloneContainer.appendChild(clone);
|
|
913
|
+
target.appendChild(cloneContainer);
|
|
914
|
+
await this.updateComplete;
|
|
915
|
+
|
|
916
|
+
this._truncating = clone.scrollWidth > target.offsetWidth;
|
|
917
|
+
this._resizeRunSinceTruncationCheck = false;
|
|
918
|
+
target.removeChild(cloneContainer);
|
|
919
|
+
}
|
|
866
920
|
}
|
|
867
921
|
customElements.define('d2l-tooltip', Tooltip);
|
package/custom-elements.json
CHANGED
|
@@ -9919,6 +9919,12 @@
|
|
|
9919
9919
|
"description": "Adjust the size of the gap between the tooltip and its target",
|
|
9920
9920
|
"type": "number"
|
|
9921
9921
|
},
|
|
9922
|
+
{
|
|
9923
|
+
"name": "show-truncated-only",
|
|
9924
|
+
"description": "ADVANCED: Only show the tooltip if we detect the target element is truncated",
|
|
9925
|
+
"type": "boolean",
|
|
9926
|
+
"default": "false"
|
|
9927
|
+
},
|
|
9922
9928
|
{
|
|
9923
9929
|
"name": "state",
|
|
9924
9930
|
"description": "The style of the tooltip based on the type of information it displays",
|
|
@@ -9996,6 +10002,13 @@
|
|
|
9996
10002
|
"description": "Adjust the size of the gap between the tooltip and its target",
|
|
9997
10003
|
"type": "number"
|
|
9998
10004
|
},
|
|
10005
|
+
{
|
|
10006
|
+
"name": "showTruncatedOnly",
|
|
10007
|
+
"attribute": "show-truncated-only",
|
|
10008
|
+
"description": "ADVANCED: Only show the tooltip if we detect the target element is truncated",
|
|
10009
|
+
"type": "boolean",
|
|
10010
|
+
"default": "false"
|
|
10011
|
+
},
|
|
9999
10012
|
{
|
|
10000
10013
|
"name": "state",
|
|
10001
10014
|
"attribute": "state",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brightspace-ui/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.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",
|