@brightspace-ui/core 3.76.0 → 3.76.2
Sign up to get free protection for your applications and to get access to all the features.
- package/components/dropdown/dropdown-content-mixin.js +1 -1
- package/components/inputs/docs/input-search.md +1 -1
- package/components/popover/popover-mixin.js +1 -1
- package/components/tabs/tab-mixin.js +157 -0
- package/components/tabs/tab-panel-mixin.js +8 -1
- package/components/tabs/tab.js +46 -0
- package/custom-elements.json +64 -0
- package/package.json +2 -2
@@ -1134,7 +1134,7 @@ export const DropdownContentMixin = superclass => class extends LocalizeCoreElem
|
|
1134
1134
|
}
|
1135
1135
|
}
|
1136
1136
|
if (this.openedAbove) {
|
1137
|
-
position.bottom = window.innerHeight - targetRect.top + 8;
|
1137
|
+
position.bottom = window.innerHeight - targetRect.top + this._verticalOffset - 8;
|
1138
1138
|
} else {
|
1139
1139
|
position.top = targetRect.top + targetRect.height + this._verticalOffset - 7;
|
1140
1140
|
}
|
@@ -469,7 +469,7 @@ export const PopoverMixin = superclass => class extends superclass {
|
|
469
469
|
}
|
470
470
|
|
471
471
|
if (this._location === 'block-start') {
|
472
|
-
position.bottom = window.innerHeight - openerRect.top + 8;
|
472
|
+
position.bottom = window.innerHeight - openerRect.top + this._offset - 8;
|
473
473
|
} else {
|
474
474
|
position.top = openerRect.top + openerRect.height + this._offset - 7;
|
475
475
|
}
|
@@ -0,0 +1,157 @@
|
|
1
|
+
import '../colors/colors.js';
|
2
|
+
import { css, html } from 'lit';
|
3
|
+
import { SkeletonMixin } from '../skeleton/skeleton-mixin.js';
|
4
|
+
|
5
|
+
const keyCodes = {
|
6
|
+
ENTER: 13,
|
7
|
+
SPACE: 32
|
8
|
+
};
|
9
|
+
|
10
|
+
export const TabMixin = superclass => class extends SkeletonMixin(superclass) {
|
11
|
+
|
12
|
+
static get properties() {
|
13
|
+
return {
|
14
|
+
selected: { type: Boolean, reflect: true },
|
15
|
+
};
|
16
|
+
}
|
17
|
+
|
18
|
+
static get styles() {
|
19
|
+
const styles = [ css`
|
20
|
+
:host {
|
21
|
+
box-sizing: border-box;
|
22
|
+
display: inline-block;
|
23
|
+
max-width: 200px;
|
24
|
+
outline: none;
|
25
|
+
position: relative;
|
26
|
+
vertical-align: middle;
|
27
|
+
}
|
28
|
+
.d2l-tab-selected-indicator {
|
29
|
+
border-top: 4px solid var(--d2l-color-celestine);
|
30
|
+
border-top-left-radius: 4px;
|
31
|
+
border-top-right-radius: 4px;
|
32
|
+
bottom: 0;
|
33
|
+
display: none;
|
34
|
+
margin: 1px 0.6rem 0 0.6rem;
|
35
|
+
position: absolute;
|
36
|
+
transition: box-shadow 0.2s;
|
37
|
+
width: calc(100% - 1.2rem);
|
38
|
+
}
|
39
|
+
:host(:first-child) .d2l-tab-selected-indicator {
|
40
|
+
margin-inline-end: 0.6rem;
|
41
|
+
margin-inline-start: 0;
|
42
|
+
width: calc(100% - 0.6rem);
|
43
|
+
}
|
44
|
+
:host([aria-selected="true"]:focus) {
|
45
|
+
text-decoration: none;
|
46
|
+
}
|
47
|
+
:host(:hover) {
|
48
|
+
color: var(--d2l-color-celestine);
|
49
|
+
cursor: pointer;
|
50
|
+
}
|
51
|
+
:host([aria-selected="true"]:hover) {
|
52
|
+
color: inherit;
|
53
|
+
cursor: default;
|
54
|
+
}
|
55
|
+
:host([aria-selected="true"]) .d2l-tab-selected-indicator {
|
56
|
+
display: block;
|
57
|
+
}
|
58
|
+
`];
|
59
|
+
|
60
|
+
super.styles && styles.unshift(super.styles);
|
61
|
+
return styles;
|
62
|
+
}
|
63
|
+
|
64
|
+
constructor() {
|
65
|
+
super();
|
66
|
+
this.ariaSelected = false;
|
67
|
+
this.role = 'tab';
|
68
|
+
this.selected = false;
|
69
|
+
this.tabIndex = -1;
|
70
|
+
}
|
71
|
+
|
72
|
+
connectedCallback() {
|
73
|
+
super.connectedCallback();
|
74
|
+
this.#addEventHandlers();
|
75
|
+
|
76
|
+
if (!this.#resizeObserver) {
|
77
|
+
this.#resizeObserver = new ResizeObserver(() => {
|
78
|
+
this.#handleResize();
|
79
|
+
});
|
80
|
+
this.#resizeObserver.observe(this);
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
disconnectedCallback() {
|
85
|
+
super.disconnectedCallback();
|
86
|
+
this.#removeEventHandlers();
|
87
|
+
|
88
|
+
if (this.#resizeObserver) {
|
89
|
+
this.#resizeObserver.disconnect();
|
90
|
+
this.#resizeObserver = null;
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
render() {
|
95
|
+
return html`
|
96
|
+
<div class="d2l-skeletize">
|
97
|
+
${this.renderContent()}
|
98
|
+
</div>
|
99
|
+
<div class="d2l-tab-selected-indicator d2l-skeletize-container"></div>
|
100
|
+
`;
|
101
|
+
}
|
102
|
+
|
103
|
+
update(changedProperties) {
|
104
|
+
super.update(changedProperties);
|
105
|
+
changedProperties.forEach((oldVal, prop) => {
|
106
|
+
if (prop === 'selected') {
|
107
|
+
this.ariaSelected = this.selected;
|
108
|
+
if (this.selected === 'true') {
|
109
|
+
this.dispatchEvent(new CustomEvent(
|
110
|
+
'd2l-tab-selected', { bubbles: true, composed: true }
|
111
|
+
));
|
112
|
+
}
|
113
|
+
}
|
114
|
+
});
|
115
|
+
}
|
116
|
+
|
117
|
+
renderContent() {
|
118
|
+
console.warn('Subclasses to implement/override renderContent');
|
119
|
+
return html`<div>Default Tab Content</div>`;
|
120
|
+
}
|
121
|
+
|
122
|
+
#resizeObserver;
|
123
|
+
|
124
|
+
#handleClick = () => {
|
125
|
+
this.selected = true;
|
126
|
+
};
|
127
|
+
|
128
|
+
#handleKeydown = e => {
|
129
|
+
if (e.keyCode === keyCodes.SPACE || e.keyCode === keyCodes.ENTER) {
|
130
|
+
e.stopPropagation();
|
131
|
+
e.preventDefault();
|
132
|
+
}
|
133
|
+
};
|
134
|
+
|
135
|
+
#handleKeyup = e => {
|
136
|
+
if (e.keyCode === keyCodes.SPACE || e.keyCode === keyCodes.ENTER) {
|
137
|
+
this.#handleClick();
|
138
|
+
}
|
139
|
+
};
|
140
|
+
|
141
|
+
#addEventHandlers() {
|
142
|
+
this.addEventListener('click', this.#handleClick);
|
143
|
+
this.addEventListener('keydown', this.#handleKeydown);
|
144
|
+
this.addEventListener('keyup', this.#handleKeyup);
|
145
|
+
}
|
146
|
+
|
147
|
+
#handleResize() {
|
148
|
+
this.dispatchEvent(new CustomEvent('d2l-tab-resize'));
|
149
|
+
}
|
150
|
+
|
151
|
+
#removeEventHandlers() {
|
152
|
+
this.removeEventListener('click', this.#handleClick);
|
153
|
+
this.removeEventListener('keydown', this.#handleKeydown);
|
154
|
+
this.removeEventListener('keyup', this.#handleKeyup);
|
155
|
+
}
|
156
|
+
|
157
|
+
};
|
@@ -5,6 +5,11 @@ export const TabPanelMixin = superclass => class extends superclass {
|
|
5
5
|
|
6
6
|
static get properties() {
|
7
7
|
return {
|
8
|
+
/**
|
9
|
+
* Id of the tab that labels this panel
|
10
|
+
* @type {string}
|
11
|
+
*/
|
12
|
+
labelledBy: { type: String },
|
8
13
|
/**
|
9
14
|
* Opt out of default padding/whitespace around the panel
|
10
15
|
* @type {boolean}
|
@@ -61,7 +66,9 @@ export const TabPanelMixin = superclass => class extends superclass {
|
|
61
66
|
super.updated(changedProperties);
|
62
67
|
|
63
68
|
changedProperties.forEach((oldVal, prop) => {
|
64
|
-
if (prop === '
|
69
|
+
if (prop === 'labelledBy') {
|
70
|
+
this.setAttribute('aria-labelledby', this.labelledBy);
|
71
|
+
} else if (prop === 'selected') {
|
65
72
|
if (this.selected) {
|
66
73
|
requestAnimationFrame(() => {
|
67
74
|
/** Dispatched when a tab is selected */
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import { css, html, LitElement, unsafeCSS } from 'lit';
|
2
|
+
import { classMap } from 'lit/directives/class-map.js';
|
3
|
+
import { getFocusPseudoClass } from '../../helpers/focus.js';
|
4
|
+
import { TabMixin } from './tab-mixin.js';
|
5
|
+
|
6
|
+
class Tab extends TabMixin(LitElement) {
|
7
|
+
|
8
|
+
static get styles() {
|
9
|
+
const styles = [ css`
|
10
|
+
.d2l-tab-text {
|
11
|
+
margin: 0.5rem;
|
12
|
+
overflow: hidden;
|
13
|
+
padding: 0.1rem;
|
14
|
+
text-overflow: ellipsis;
|
15
|
+
white-space: nowrap;
|
16
|
+
}
|
17
|
+
:host(:first-child) .d2l-tab-text {
|
18
|
+
margin-inline-end: 0.6rem;
|
19
|
+
margin-inline-start: 0;
|
20
|
+
}
|
21
|
+
:host(:${unsafeCSS(getFocusPseudoClass())}) > .d2l-tab-text {
|
22
|
+
border-radius: 0.3rem;
|
23
|
+
box-shadow: 0 0 0 2px var(--d2l-color-celestine);
|
24
|
+
color: var(--d2l-color-celestine);
|
25
|
+
}
|
26
|
+
`];
|
27
|
+
|
28
|
+
super.styles && styles.unshift(super.styles);
|
29
|
+
return styles;
|
30
|
+
}
|
31
|
+
|
32
|
+
renderContent() {
|
33
|
+
const contentClasses = {
|
34
|
+
'd2l-tab-handler': true,
|
35
|
+
'd2l-tab-text': true,
|
36
|
+
};
|
37
|
+
|
38
|
+
return html`
|
39
|
+
<div class="${classMap(contentClasses)}">
|
40
|
+
<slot></slot>
|
41
|
+
</div>
|
42
|
+
`;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
customElements.define('d2l-tab-wip', Tab);
|
package/custom-elements.json
CHANGED
@@ -12740,6 +12740,11 @@
|
|
12740
12740
|
"path": "./components/tabs/tab-panel.js",
|
12741
12741
|
"description": "A component for tab panel content.",
|
12742
12742
|
"attributes": [
|
12743
|
+
{
|
12744
|
+
"name": "labelledBy",
|
12745
|
+
"description": "Id of the tab that labels this panel",
|
12746
|
+
"type": "string"
|
12747
|
+
},
|
12743
12748
|
{
|
12744
12749
|
"name": "text",
|
12745
12750
|
"description": "ACCESSIBILITY: REQUIRED: The text used for the tab, as well as labelling the panel",
|
@@ -12759,6 +12764,12 @@
|
|
12759
12764
|
}
|
12760
12765
|
],
|
12761
12766
|
"properties": [
|
12767
|
+
{
|
12768
|
+
"name": "labelledBy",
|
12769
|
+
"attribute": "labelledBy",
|
12770
|
+
"description": "Id of the tab that labels this panel",
|
12771
|
+
"type": "string"
|
12772
|
+
},
|
12762
12773
|
{
|
12763
12774
|
"name": "text",
|
12764
12775
|
"attribute": "text",
|
@@ -12797,6 +12808,59 @@
|
|
12797
12808
|
}
|
12798
12809
|
]
|
12799
12810
|
},
|
12811
|
+
{
|
12812
|
+
"name": "d2l-tab-wip",
|
12813
|
+
"path": "./components/tabs/tab.js",
|
12814
|
+
"attributes": [
|
12815
|
+
{
|
12816
|
+
"name": "selected",
|
12817
|
+
"type": "boolean",
|
12818
|
+
"default": "false"
|
12819
|
+
},
|
12820
|
+
{
|
12821
|
+
"name": "skeleton",
|
12822
|
+
"description": "Render the component as a [skeleton loader](https://github.com/BrightspaceUI/core/tree/main/components/skeleton).",
|
12823
|
+
"type": "boolean"
|
12824
|
+
}
|
12825
|
+
],
|
12826
|
+
"properties": [
|
12827
|
+
{
|
12828
|
+
"name": "ariaSelected",
|
12829
|
+
"type": "boolean",
|
12830
|
+
"default": "false"
|
12831
|
+
},
|
12832
|
+
{
|
12833
|
+
"name": "role",
|
12834
|
+
"type": "string",
|
12835
|
+
"default": "\"tab\""
|
12836
|
+
},
|
12837
|
+
{
|
12838
|
+
"name": "selected",
|
12839
|
+
"attribute": "selected",
|
12840
|
+
"type": "boolean",
|
12841
|
+
"default": "false"
|
12842
|
+
},
|
12843
|
+
{
|
12844
|
+
"name": "tabIndex",
|
12845
|
+
"type": "number",
|
12846
|
+
"default": "-1"
|
12847
|
+
},
|
12848
|
+
{
|
12849
|
+
"name": "skeleton",
|
12850
|
+
"attribute": "skeleton",
|
12851
|
+
"description": "Render the component as a [skeleton loader](https://github.com/BrightspaceUI/core/tree/main/components/skeleton).",
|
12852
|
+
"type": "boolean"
|
12853
|
+
}
|
12854
|
+
],
|
12855
|
+
"events": [
|
12856
|
+
{
|
12857
|
+
"name": "d2l-tab-selected"
|
12858
|
+
},
|
12859
|
+
{
|
12860
|
+
"name": "d2l-tab-resize"
|
12861
|
+
}
|
12862
|
+
]
|
12863
|
+
},
|
12800
12864
|
{
|
12801
12865
|
"name": "d2l-tabs",
|
12802
12866
|
"path": "./components/tabs/tabs.js",
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@brightspace-ui/core",
|
3
|
-
"version": "3.76.
|
3
|
+
"version": "3.76.2",
|
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",
|
@@ -48,7 +48,7 @@
|
|
48
48
|
"@brightspace-ui/stylelint-config": "^1",
|
49
49
|
"@brightspace-ui/testing": "^1",
|
50
50
|
"@rollup/plugin-dynamic-import-vars": "^2",
|
51
|
-
"@rollup/plugin-node-resolve": "^
|
51
|
+
"@rollup/plugin-node-resolve": "^16",
|
52
52
|
"@rollup/plugin-replace": "^6",
|
53
53
|
"@web/dev-server": "^0.4",
|
54
54
|
"chalk": "^5",
|