@brightspace-ui/core 3.245.3 → 3.246.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.
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import '../colors/colors.js';
|
|
2
|
+
import '../skip-nav/skip-nav-main.js';
|
|
3
|
+
import { css, html, LitElement, nothing } from 'lit';
|
|
4
|
+
import { getNextFocusable } from '../../helpers/focus.js';
|
|
5
|
+
|
|
6
|
+
export const isWindows = window.navigator.userAgent.indexOf('Windows') > -1;
|
|
7
|
+
export const isMobile = window.navigator.userAgent.indexOf('mobile') > -1;
|
|
8
|
+
const customScroll = isWindows && !isMobile;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Generic page header layout component
|
|
12
|
+
* @slot band - Content placed inside band
|
|
13
|
+
* @slot top - Content placed inside top section of the header
|
|
14
|
+
* @slot bottom - Content placed inside bottom section of the header
|
|
15
|
+
*/
|
|
16
|
+
class PageHeaderCustom extends LitElement {
|
|
17
|
+
|
|
18
|
+
static get properties() {
|
|
19
|
+
return {
|
|
20
|
+
/**
|
|
21
|
+
* Whether to render a skip nav link
|
|
22
|
+
* @type {boolean}
|
|
23
|
+
*/
|
|
24
|
+
hasSkipNav: { type: Boolean, attribute: 'has-skip-nav', reflect: true },
|
|
25
|
+
_hasBottom: { state: true }
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static get styles() {
|
|
30
|
+
return [css`
|
|
31
|
+
:host {
|
|
32
|
+
background-color: white;
|
|
33
|
+
display: block;
|
|
34
|
+
position: relative;
|
|
35
|
+
}
|
|
36
|
+
:host([hidden]) {
|
|
37
|
+
display: none;
|
|
38
|
+
}
|
|
39
|
+
.band {
|
|
40
|
+
background: linear-gradient(180deg, var(--d2l-branding-primary-color, var(--d2l-color-celestine)) 1.5rem, #ffffff 0%);
|
|
41
|
+
line-height: 0;
|
|
42
|
+
min-height: 4px;
|
|
43
|
+
position: relative; /* Needed for Firefox */
|
|
44
|
+
}
|
|
45
|
+
.band .padding {
|
|
46
|
+
display: inline-block;
|
|
47
|
+
position: unset;
|
|
48
|
+
vertical-align: top;
|
|
49
|
+
}
|
|
50
|
+
.band-scroll {
|
|
51
|
+
overflow-x: auto;
|
|
52
|
+
overflow-y: hidden;
|
|
53
|
+
scroll-behavior: smooth;
|
|
54
|
+
}
|
|
55
|
+
@media (prefers-reduced-motion: reduce) {
|
|
56
|
+
.band-scroll {
|
|
57
|
+
scroll-behavior: auto;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
.band-scroll[data-custom-scroll] {
|
|
61
|
+
/* Firefox Styles */
|
|
62
|
+
scrollbar-color: var(--d2l-color-galena) var(--d2l-color-sylvite);
|
|
63
|
+
scrollbar-width: thin;
|
|
64
|
+
}
|
|
65
|
+
/* Webkit Styles */
|
|
66
|
+
.band-scroll[data-custom-scroll]::-webkit-scrollbar {
|
|
67
|
+
background-color: var(--d2l-color-sylvite);
|
|
68
|
+
border-radius: 8px;
|
|
69
|
+
height: 9px;
|
|
70
|
+
}
|
|
71
|
+
.band-scroll[data-custom-scroll]::-webkit-scrollbar-thumb {
|
|
72
|
+
background-color: var(--d2l-color-galena);
|
|
73
|
+
border-bottom: 1px solid var(--d2l-color-sylvite);
|
|
74
|
+
border-radius: 8px;
|
|
75
|
+
border-top: 1px solid var(--d2l-color-sylvite);
|
|
76
|
+
}
|
|
77
|
+
/* Faded edges styles */
|
|
78
|
+
.band-scroll-before,
|
|
79
|
+
.band-scroll-after {
|
|
80
|
+
height: 100%;
|
|
81
|
+
max-height: 1.5rem; /* should match linear-background height */
|
|
82
|
+
pointer-events: none;
|
|
83
|
+
position: absolute;
|
|
84
|
+
top: 0;
|
|
85
|
+
width: var(--d2l-page-padding, 30px);
|
|
86
|
+
z-index: 2;
|
|
87
|
+
}
|
|
88
|
+
.band-scroll-before {
|
|
89
|
+
background: linear-gradient(to right, var(--d2l-branding-primary-color, var(--d2l-color-celestine)), transparent);
|
|
90
|
+
left: 0;
|
|
91
|
+
}
|
|
92
|
+
.band-scroll-after {
|
|
93
|
+
background: linear-gradient(to left, var(--d2l-branding-primary-color, var(--d2l-color-celestine)), transparent);
|
|
94
|
+
right: 0;
|
|
95
|
+
}
|
|
96
|
+
@media (max-width: 615px) {
|
|
97
|
+
.band-scroll-before,
|
|
98
|
+
.band-scroll-after {
|
|
99
|
+
width: 15px;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
@media (min-width: 1230px) {
|
|
103
|
+
.band-scroll-before,
|
|
104
|
+
.band-scroll-after {
|
|
105
|
+
width: 30px;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
.bottom,
|
|
109
|
+
.top {
|
|
110
|
+
border-bottom: 1px solid rgba(124, 134, 149, 0.18);
|
|
111
|
+
}
|
|
112
|
+
.bottom {
|
|
113
|
+
background-color: var(--d2l-page-header-bottom-background-color, transparent);
|
|
114
|
+
}
|
|
115
|
+
.shadow {
|
|
116
|
+
background-color: rgba(0, 0, 0, 0.02);
|
|
117
|
+
bottom: -4px;
|
|
118
|
+
height: 4px;
|
|
119
|
+
pointer-events: none;
|
|
120
|
+
position: absolute;
|
|
121
|
+
width: 100%;
|
|
122
|
+
}
|
|
123
|
+
.max-width {
|
|
124
|
+
margin-inline: var(--d2l-page-margin-inline, auto);
|
|
125
|
+
max-width: var(--d2l-page-header-max-width, 1230px);
|
|
126
|
+
}
|
|
127
|
+
.padding {
|
|
128
|
+
padding-inline: var(--d2l-page-padding, 30px);
|
|
129
|
+
}
|
|
130
|
+
`];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
constructor() {
|
|
134
|
+
super();
|
|
135
|
+
this.hasSkipNav = false;
|
|
136
|
+
this._hasBottom = false;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
render() {
|
|
140
|
+
return [
|
|
141
|
+
this.#renderSkipNav(),
|
|
142
|
+
this.#renderBand(),
|
|
143
|
+
this.#renderTop(),
|
|
144
|
+
this.#renderBottom(),
|
|
145
|
+
html`<div class="shadow"></div>`
|
|
146
|
+
];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
#handleBandScrollRequest(e) {
|
|
150
|
+
e.stopPropagation();
|
|
151
|
+
const dir = document.documentElement.getAttribute('dir') || 'ltr';
|
|
152
|
+
if (dir.toLowerCase() === 'rtl') {
|
|
153
|
+
return; // We turn off this feature in RTL due to browser inconsistencies
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const scroll = this.shadowRoot.querySelector('.band-scroll');
|
|
157
|
+
requestAnimationFrame(() => {
|
|
158
|
+
scroll.scrollLeft = e.detail.pointToCenter - 0.5 * scroll.offsetWidth;
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
#handleBottomSlotChange(e) {
|
|
163
|
+
this._hasBottom = (e.target.assignedNodes().length !== 0);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
#handleSkipNavFail() {
|
|
167
|
+
const nextFocusable = getNextFocusable(this.shadowRoot.querySelector('.shadow'));
|
|
168
|
+
if (nextFocusable) {
|
|
169
|
+
nextFocusable.focus();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
#renderBand() {
|
|
174
|
+
return html`
|
|
175
|
+
<div class="band" @d2l-page-band-slot-scroll-request="${this.#handleBandScrollRequest}">
|
|
176
|
+
<div class="max-width">
|
|
177
|
+
<div class="band-scroll" ?data-custom-scroll="${customScroll}">
|
|
178
|
+
<div class="band-scroll-before"></div>
|
|
179
|
+
<div class="band-scroll-after"></div>
|
|
180
|
+
<div class="padding">
|
|
181
|
+
<slot name="band"></slot>
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
#renderBottom() {
|
|
190
|
+
return html`
|
|
191
|
+
<div class="bottom" ?hidden="${!this._hasBottom}">
|
|
192
|
+
<div class="max-width">
|
|
193
|
+
<div class="padding">
|
|
194
|
+
<slot name="bottom" @slotchange="${this.#handleBottomSlotChange}"></slot>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
</div>
|
|
198
|
+
`;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
#renderSkipNav() {
|
|
202
|
+
if (!this.hasSkipNav) return nothing;
|
|
203
|
+
return html`
|
|
204
|
+
<d2l-skip-nav-main @d2l-skip-nav-main-fail="${this.#handleSkipNavFail}"></d2l-skip-nav-main>
|
|
205
|
+
`;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
#renderTop() {
|
|
209
|
+
return html`
|
|
210
|
+
<div class="top">
|
|
211
|
+
<div class="max-width">
|
|
212
|
+
<div class="padding">
|
|
213
|
+
<slot name="top"></slot>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
</div>
|
|
217
|
+
`;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
customElements.define('d2l-page-header-custom', PageHeaderCustom);
|
package/custom-elements.json
CHANGED
|
@@ -12347,6 +12347,42 @@
|
|
|
12347
12347
|
}
|
|
12348
12348
|
]
|
|
12349
12349
|
},
|
|
12350
|
+
{
|
|
12351
|
+
"name": "d2l-page-header-custom",
|
|
12352
|
+
"path": "./components/page/page-header-custom.js",
|
|
12353
|
+
"description": "Generic page header layout component",
|
|
12354
|
+
"attributes": [
|
|
12355
|
+
{
|
|
12356
|
+
"name": "has-skip-nav",
|
|
12357
|
+
"description": "Whether to render a skip nav link",
|
|
12358
|
+
"type": "boolean",
|
|
12359
|
+
"default": "false"
|
|
12360
|
+
}
|
|
12361
|
+
],
|
|
12362
|
+
"properties": [
|
|
12363
|
+
{
|
|
12364
|
+
"name": "hasSkipNav",
|
|
12365
|
+
"attribute": "has-skip-nav",
|
|
12366
|
+
"description": "Whether to render a skip nav link",
|
|
12367
|
+
"type": "boolean",
|
|
12368
|
+
"default": "false"
|
|
12369
|
+
}
|
|
12370
|
+
],
|
|
12371
|
+
"slots": [
|
|
12372
|
+
{
|
|
12373
|
+
"name": "band",
|
|
12374
|
+
"description": "Content placed inside band"
|
|
12375
|
+
},
|
|
12376
|
+
{
|
|
12377
|
+
"name": "top",
|
|
12378
|
+
"description": "Content placed inside top section of the header"
|
|
12379
|
+
},
|
|
12380
|
+
{
|
|
12381
|
+
"name": "bottom",
|
|
12382
|
+
"description": "Content placed inside bottom section of the header"
|
|
12383
|
+
}
|
|
12384
|
+
]
|
|
12385
|
+
},
|
|
12350
12386
|
{
|
|
12351
12387
|
"name": "d2l-page-main",
|
|
12352
12388
|
"path": "./components/page/page-main.js",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brightspace-ui/core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.246.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",
|