@rhc-shared-components/packages-table 0.1.0 → 0.2.3
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/dist/index.d.ts +0 -1
- package/dist/index.js +50 -3096
- package/dist/index.modern.js +45 -2725
- package/package.json +2 -5
package/dist/index.modern.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import React__default, { useState, useEffect, useCallback, cloneElement } from 'react';
|
|
3
|
-
import { setTabIndex, useOUIAProps, handleArrows, Tooltip as Tooltip$1, Button, Popover, Checkbox, Toolbar, ToolbarContent, ToolbarItem, Pagination, Bullseye, EmptyState, EmptyStateIcon,
|
|
3
|
+
import { setTabIndex, useOUIAProps, handleArrows, Tooltip as Tooltip$1, Button, Popover, Checkbox, Toolbar, ToolbarContent, ToolbarItem, Pagination, Bullseye, Title, Spinner, EmptyState, EmptyStateIcon, SearchInput, Select, SelectOption, ToggleGroup as ToggleGroup$1, ToggleGroupItem, Tabs, Tab } from '@patternfly/react-core';
|
|
4
4
|
import { sortBy, uniqueId } from 'lodash';
|
|
5
5
|
import { Tooltip } from '@patternfly/react-core/dist/esm/components/Tooltip/Tooltip';
|
|
6
6
|
import { Button as Button$1 } from '@patternfly/react-core/dist/esm/components/Button/Button';
|
|
@@ -12,2685 +12,7 @@ import { DropdownSeparator } from '@patternfly/react-core/dist/esm/components/Dr
|
|
|
12
12
|
import { DropdownPosition, DropdownDirection } from '@patternfly/react-core/dist/esm/components/Dropdown/dropdownConstants';
|
|
13
13
|
import { format } from 'date-fns';
|
|
14
14
|
|
|
15
|
-
var css_248z = ".
|
|
16
|
-
|
|
17
|
-
function _extends() {
|
|
18
|
-
_extends = Object.assign || function (target) {
|
|
19
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
20
|
-
var source = arguments[i];
|
|
21
|
-
|
|
22
|
-
for (var key in source) {
|
|
23
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
24
|
-
target[key] = source[key];
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return target;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
return _extends.apply(this, arguments);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
let logger = () => null;
|
|
36
|
-
/**
|
|
37
|
-
* Reveal web components when loading is complete by removing the unresolved attribute
|
|
38
|
-
* from the body tag; log the event.
|
|
39
|
-
* @throws debugging log indicating the reveal event
|
|
40
|
-
*/
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
function reveal() {
|
|
44
|
-
logger(`[reveal] elements ready, revealing the body`);
|
|
45
|
-
window.document.body.removeAttribute("unresolved");
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Auto-reveal functionality prevents a flash of unstyled content before components
|
|
49
|
-
* have finished loading.
|
|
50
|
-
* @param {function} logFunction
|
|
51
|
-
* @see https://github.com/github/webcomponentsjs#webcomponents-loaderjs
|
|
52
|
-
*/
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
function autoReveal(logFunction) {
|
|
56
|
-
logger = logFunction; // If Web Components are already ready, run the handler right away. If they
|
|
57
|
-
// are not yet ready, wait.
|
|
58
|
-
//
|
|
59
|
-
// see https://github.com/github/webcomponentsjs#webcomponents-loaderjs for
|
|
60
|
-
// info about web component readiness events
|
|
61
|
-
|
|
62
|
-
const polyfillPresent = window.WebComponents;
|
|
63
|
-
const polyfillReady = polyfillPresent && window.WebComponents.ready;
|
|
64
|
-
|
|
65
|
-
if (!polyfillPresent || polyfillReady) {
|
|
66
|
-
handleWebComponentsReady();
|
|
67
|
-
} else {
|
|
68
|
-
window.addEventListener("WebComponentsReady", handleWebComponentsReady);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Reveal web components when loading is complete and log event.
|
|
73
|
-
* @throws debugging log indicating the web components are ready
|
|
74
|
-
*/
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
function handleWebComponentsReady() {
|
|
78
|
-
logger("[reveal] web components ready");
|
|
79
|
-
reveal();
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Verify that a property definition's `type` field contains one of the allowed
|
|
83
|
-
* types. If the definition type resolves to falsy, assumes String type.
|
|
84
|
-
* @param {constructor} definition
|
|
85
|
-
* @default String
|
|
86
|
-
* @return {Boolean} True if the definition type is one of String, Number, or Boolean
|
|
87
|
-
*/
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
function isAllowedType(definition) {
|
|
91
|
-
return [String, Number, Boolean].includes(definition.type || String);
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Verify that a property definition's `default` value is of the correct type.
|
|
95
|
-
*
|
|
96
|
-
* A `default` value is valid if it's of the same type as the `type`
|
|
97
|
-
* definition. Or, if there is no `type` definition, then it must be a String
|
|
98
|
-
* (the default value for `type`).
|
|
99
|
-
* @param {type} definition
|
|
100
|
-
* @return {Boolean} True if the default value matches the type of the definition object.
|
|
101
|
-
*/
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
function isValidDefaultType(definition) {
|
|
105
|
-
return definition.hasOwnProperty("default") && definition.default.constructor === definition.type;
|
|
106
|
-
} // @POLYFILL Array.includes
|
|
107
|
-
|
|
108
|
-
/** @see https://tc39.github.io/ecma262/#sec-array.prototype.includes */
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (!Array.prototype.includes) {
|
|
112
|
-
Object.defineProperty(Array.prototype, "includes", {
|
|
113
|
-
value: function (valueToFind, fromIndex) {
|
|
114
|
-
if (this == null) {
|
|
115
|
-
throw new TypeError('"this" is null or not defined');
|
|
116
|
-
} // 1. Let O be ? ToObject(this value).
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
var o = Object(this); // 2. Let len be ? ToLength(? Get(O, "length")).
|
|
120
|
-
|
|
121
|
-
var len = o.length >>> 0; // 3. If len is 0, return false.
|
|
122
|
-
|
|
123
|
-
if (len === 0) {
|
|
124
|
-
return false;
|
|
125
|
-
} // 4. Let n be ? ToInteger(fromIndex).
|
|
126
|
-
// (If fromIndex is undefined, this step produces the value 0.)
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
var n = fromIndex | 0; // 5. If n ≥ 0, then
|
|
130
|
-
// a. Let k be n.
|
|
131
|
-
// 6. Else n < 0,
|
|
132
|
-
// a. Let k be len + n.
|
|
133
|
-
// b. If k < 0, let k be 0.
|
|
134
|
-
|
|
135
|
-
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
|
|
136
|
-
|
|
137
|
-
function sameValueZero(x, y) {
|
|
138
|
-
return x === y || typeof x === "number" && typeof y === "number" && isNaN(x) && isNaN(y);
|
|
139
|
-
} // 7. Repeat, while k < len
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
while (k < len) {
|
|
143
|
-
// a. Let elementK be the result of ? Get(O, ! ToString(k)).
|
|
144
|
-
// b. If SameValueZero(valueToFind, elementK) is true, return true.
|
|
145
|
-
if (sameValueZero(o[k], valueToFind)) {
|
|
146
|
-
return true;
|
|
147
|
-
} // c. Increase k by 1.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
k++;
|
|
151
|
-
} // 8. Return false
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
return false;
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
} // @POLYFILL Object.entries
|
|
158
|
-
|
|
159
|
-
/** @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries */
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if (!Object.entries) {
|
|
163
|
-
Object.entries = function (obj) {
|
|
164
|
-
var ownProps = Object.keys(obj),
|
|
165
|
-
i = ownProps.length,
|
|
166
|
-
resArray = new Array(i); // preallocate the Array
|
|
167
|
-
|
|
168
|
-
while (i--) resArray[i] = [ownProps[i], obj[ownProps[i]]];
|
|
169
|
-
|
|
170
|
-
return resArray;
|
|
171
|
-
};
|
|
172
|
-
} // @POLYFILL String.startsWith
|
|
173
|
-
|
|
174
|
-
/** @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith#polyfill */
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (!String.prototype.startsWith) {
|
|
178
|
-
Object.defineProperty(String.prototype, "startsWith", {
|
|
179
|
-
value: function (search, rawPos) {
|
|
180
|
-
var pos = rawPos > 0 ? rawPos | 0 : 0;
|
|
181
|
-
return this.substring(pos, pos + search.length) === search;
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
} // @POLYFILL Element.closest
|
|
185
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (!Element.prototype.closest) {
|
|
189
|
-
Element.prototype.closest = function (s) {
|
|
190
|
-
var el = this;
|
|
191
|
-
|
|
192
|
-
do {
|
|
193
|
-
if (el.matches(s)) return el;
|
|
194
|
-
el = el.parentElement || el.parentNode;
|
|
195
|
-
} while (el !== null && el.nodeType === 1);
|
|
196
|
-
|
|
197
|
-
return null;
|
|
198
|
-
};
|
|
199
|
-
} // @POLYFILL Element.matches
|
|
200
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
if (!Element.prototype.matches) {
|
|
204
|
-
Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
|
|
205
|
-
} // @POLYFILL Array.prototype.find
|
|
206
|
-
// https://tc39.github.io/ecma262/#sec-array.prototype.find
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
if (!Array.prototype.find) {
|
|
210
|
-
Object.defineProperty(Array.prototype, "find", {
|
|
211
|
-
value: function (predicate) {
|
|
212
|
-
// 1. Let O be ? ToObject(this value).
|
|
213
|
-
if (this == null) {
|
|
214
|
-
throw new TypeError('"this" is null or not defined');
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
var o = Object(this); // 2. Let len be ? ToLength(? Get(O, "length")).
|
|
218
|
-
|
|
219
|
-
var len = o.length >>> 0; // 3. If IsCallable(predicate) is false, throw a TypeError exception.
|
|
220
|
-
|
|
221
|
-
if (typeof predicate !== "function") {
|
|
222
|
-
throw new TypeError("predicate must be a function");
|
|
223
|
-
} // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
var thisArg = arguments[1]; // 5. Let k be 0.
|
|
227
|
-
|
|
228
|
-
var k = 0; // 6. Repeat, while k < len
|
|
229
|
-
|
|
230
|
-
while (k < len) {
|
|
231
|
-
// a. Let Pk be ! ToString(k).
|
|
232
|
-
// b. Let kValue be ? Get(O, Pk).
|
|
233
|
-
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
|
|
234
|
-
// d. If testResult is true, return kValue.
|
|
235
|
-
var kValue = o[k];
|
|
236
|
-
|
|
237
|
-
if (predicate.call(thisArg, kValue, k, o)) {
|
|
238
|
-
return kValue;
|
|
239
|
-
} // e. Increase k by 1.
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
k++;
|
|
243
|
-
} // 7. Return undefined.
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return undefined;
|
|
247
|
-
},
|
|
248
|
-
configurable: true,
|
|
249
|
-
writable: true
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
/*!
|
|
253
|
-
* PatternFly Elements: PFElement 1.12.3
|
|
254
|
-
* @license
|
|
255
|
-
* Copyright 2021 Red Hat, Inc.
|
|
256
|
-
*
|
|
257
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
258
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
259
|
-
* in the Software without restriction, including without limitation the rights
|
|
260
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
261
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
262
|
-
* furnished to do so, subject to the following conditions:
|
|
263
|
-
*
|
|
264
|
-
* The above copyright notice and this permission notice shall be included in
|
|
265
|
-
* all copies or substantial portions of the Software.
|
|
266
|
-
*
|
|
267
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
268
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
269
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
270
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
271
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
272
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
273
|
-
* SOFTWARE.
|
|
274
|
-
*
|
|
275
|
-
*/
|
|
276
|
-
// /**
|
|
277
|
-
// * Global prefix used for all components in the project.
|
|
278
|
-
// * @constant {String}
|
|
279
|
-
// * */
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
const prefix = "pfe";
|
|
283
|
-
/**
|
|
284
|
-
* @class PFElement
|
|
285
|
-
* @extends HTMLElement
|
|
286
|
-
* @version 1.12.3
|
|
287
|
-
* @classdesc Serves as the baseline for all PatternFly Element components.
|
|
288
|
-
*/
|
|
289
|
-
|
|
290
|
-
class PFElement extends HTMLElement {
|
|
291
|
-
/**
|
|
292
|
-
* A boolean value that indicates if the logging should be printed to the console; used for debugging.
|
|
293
|
-
* For use in a JS file or script tag; can also be added in the constructor of a component during development.
|
|
294
|
-
* @example PFElement.debugLog(true);
|
|
295
|
-
* @tags debug
|
|
296
|
-
*/
|
|
297
|
-
static debugLog(preference = null) {
|
|
298
|
-
if (preference !== null) {
|
|
299
|
-
// wrap localStorage references in a try/catch; merely referencing it can
|
|
300
|
-
// throw errors in some locked down environments
|
|
301
|
-
try {
|
|
302
|
-
localStorage.pfeLog = !!preference;
|
|
303
|
-
} catch (e) {
|
|
304
|
-
// if localStorage fails, fall back to PFElement._debugLog
|
|
305
|
-
PFElement._debugLog = !!preference;
|
|
306
|
-
return PFElement._debugLog;
|
|
307
|
-
}
|
|
308
|
-
} // @TODO the reference to _debugLog is for backwards compatibiilty and will be removed in 2.0
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
return localStorage.pfeLog === "true" || PFElement._debugLog;
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* A boolean value that indicates if the performance should be tracked.
|
|
315
|
-
* For use in a JS file or script tag; can also be added in the constructor of a component during development.
|
|
316
|
-
* @example PFElement._trackPerformance = true;
|
|
317
|
-
*/
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
static trackPerformance(preference = null) {
|
|
321
|
-
if (preference !== null) {
|
|
322
|
-
PFElement._trackPerformance = !!preference;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
return PFElement._trackPerformance;
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* A object that contains configuration set outside of pfe.
|
|
329
|
-
*
|
|
330
|
-
* @example const config = PFElement.config;
|
|
331
|
-
*/
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
static get config() {
|
|
335
|
-
// @TODO: Add config validation in the future.
|
|
336
|
-
return window.PfeConfig || {};
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* A logging wrapper which checks the debugLog boolean and prints to the console if true.
|
|
340
|
-
*
|
|
341
|
-
* @example PFElement.log("Hello");
|
|
342
|
-
*/
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
static log(...msgs) {
|
|
346
|
-
if (PFElement.debugLog()) {
|
|
347
|
-
console.log(...msgs);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Local logging that outputs the tag name as a prefix automatically
|
|
352
|
-
*
|
|
353
|
-
* @example this.log("Hello");
|
|
354
|
-
*/
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
log(...msgs) {
|
|
358
|
-
PFElement.log(`[${this.tag}${this.id ? `#${this.id}` : ""}]`, ...msgs);
|
|
359
|
-
}
|
|
360
|
-
/**
|
|
361
|
-
* A console warning wrapper which formats your output with useful debugging information.
|
|
362
|
-
*
|
|
363
|
-
* @example PFElement.warn("Hello");
|
|
364
|
-
*/
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
static warn(...msgs) {
|
|
368
|
-
console.warn(...msgs);
|
|
369
|
-
}
|
|
370
|
-
/**
|
|
371
|
-
* Local warning wrapper that outputs the tag name as a prefix automatically.
|
|
372
|
-
* For use inside a component's function.
|
|
373
|
-
* @example this.warn("Hello");
|
|
374
|
-
*/
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
warn(...msgs) {
|
|
378
|
-
PFElement.warn(`[${this.tag}${this.id ? `#${this.id}` : ``}]`, ...msgs);
|
|
379
|
-
}
|
|
380
|
-
/**
|
|
381
|
-
* A console error wrapper which formats your output with useful debugging information.
|
|
382
|
-
* For use inside a component's function.
|
|
383
|
-
* @example PFElement.error("Hello");
|
|
384
|
-
*/
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
static error(...msgs) {
|
|
388
|
-
throw new Error([...msgs].join(" "));
|
|
389
|
-
}
|
|
390
|
-
/**
|
|
391
|
-
* Local error wrapper that outputs the tag name as a prefix automatically.
|
|
392
|
-
* For use inside a component's function.
|
|
393
|
-
* @example this.error("Hello");
|
|
394
|
-
*/
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
error(...msgs) {
|
|
398
|
-
PFElement.error(`[${this.tag}${this.id ? `#${this.id}` : ``}]`, ...msgs);
|
|
399
|
-
}
|
|
400
|
-
/**
|
|
401
|
-
* A global definition of component types (a general way of defining the purpose of a
|
|
402
|
-
* component and how it is put together).
|
|
403
|
-
*/
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
static get PfeTypes() {
|
|
407
|
-
return {
|
|
408
|
-
Container: "container",
|
|
409
|
-
Content: "content",
|
|
410
|
-
Combo: "combo"
|
|
411
|
-
};
|
|
412
|
-
}
|
|
413
|
-
/**
|
|
414
|
-
* The current version of a component; set by the compiler using the package.json data.
|
|
415
|
-
*/
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
static get version() {
|
|
419
|
-
return "1.12.3";
|
|
420
|
-
}
|
|
421
|
-
/**
|
|
422
|
-
* A local alias to the static version.
|
|
423
|
-
* For use in the console to validate version being loaded.
|
|
424
|
-
* @example PfeAccordion.version
|
|
425
|
-
*/
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
get version() {
|
|
429
|
-
return this._pfeClass.version;
|
|
430
|
-
}
|
|
431
|
-
/**
|
|
432
|
-
* Global property definitions: properties managed by the base class that apply to all components.
|
|
433
|
-
*/
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
static get properties() {
|
|
437
|
-
return {
|
|
438
|
-
pfelement: {
|
|
439
|
-
title: "Upgraded flag",
|
|
440
|
-
type: Boolean,
|
|
441
|
-
default: true,
|
|
442
|
-
observer: "_upgradeObserver"
|
|
443
|
-
},
|
|
444
|
-
on: {
|
|
445
|
-
title: "Context",
|
|
446
|
-
description: "Describes the visual context (backgrounds).",
|
|
447
|
-
type: String,
|
|
448
|
-
values: ["light", "dark", "saturated"],
|
|
449
|
-
default: el => el.contextVariable,
|
|
450
|
-
observer: "_onObserver"
|
|
451
|
-
},
|
|
452
|
-
context: {
|
|
453
|
-
title: "Context hook",
|
|
454
|
-
description: "Lets you override the system-set context.",
|
|
455
|
-
type: String,
|
|
456
|
-
values: ["light", "dark", "saturated"],
|
|
457
|
-
observer: "_contextObserver"
|
|
458
|
-
},
|
|
459
|
-
// @TODO: Deprecated with 1.0
|
|
460
|
-
oldTheme: {
|
|
461
|
-
type: String,
|
|
462
|
-
values: ["light", "dark", "saturated"],
|
|
463
|
-
alias: "context",
|
|
464
|
-
attr: "pfe-theme"
|
|
465
|
-
},
|
|
466
|
-
_style: {
|
|
467
|
-
title: "Custom styles",
|
|
468
|
-
type: String,
|
|
469
|
-
attr: "style",
|
|
470
|
-
observer: "_inlineStyleObserver"
|
|
471
|
-
},
|
|
472
|
-
type: {
|
|
473
|
-
title: "Component type",
|
|
474
|
-
type: String,
|
|
475
|
-
values: ["container", "content", "combo"]
|
|
476
|
-
}
|
|
477
|
-
};
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
static get observedAttributes() {
|
|
481
|
-
const properties = this.allProperties;
|
|
482
|
-
|
|
483
|
-
if (properties) {
|
|
484
|
-
const oa = Object.keys(properties).filter(prop => properties[prop].observer || properties[prop].cascade || properties[prop].alias).map(p => this._convertPropNameToAttrName(p));
|
|
485
|
-
return [...oa];
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
/**
|
|
489
|
-
* A quick way to fetch a random ID value.
|
|
490
|
-
* _Note:_ All values are prefixes with `pfe` automatically to ensure an ID-safe value is returned.
|
|
491
|
-
*
|
|
492
|
-
* @example this.id = this.randomID;
|
|
493
|
-
*/
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
get randomId() {
|
|
497
|
-
return `${prefix}-` + Math.random().toString(36).substr(2, 9);
|
|
498
|
-
}
|
|
499
|
-
/**
|
|
500
|
-
* Set the --context variable with the provided value in this component.
|
|
501
|
-
*/
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
set contextVariable(value) {
|
|
505
|
-
this.cssVariable("context", value);
|
|
506
|
-
}
|
|
507
|
-
/**
|
|
508
|
-
* Get the current value of the --context variable in this component.
|
|
509
|
-
* @return {string} [dark|light|saturated]
|
|
510
|
-
*/
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
get contextVariable() {
|
|
514
|
-
/* @DEPRECATED --theme in 1.0, to be removed in 2.0 */
|
|
515
|
-
return this.cssVariable("context") || this.cssVariable("theme");
|
|
516
|
-
}
|
|
517
|
-
/**
|
|
518
|
-
* Returns a boolean statement of whether or not this component contains any light DOM.
|
|
519
|
-
* @returns {boolean}
|
|
520
|
-
* @example if(this.hasLightDOM()) this._init();
|
|
521
|
-
*/
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
hasLightDOM() {
|
|
525
|
-
return this.children.length || this.textContent.trim().length;
|
|
526
|
-
}
|
|
527
|
-
/**
|
|
528
|
-
* Returns a boolean statement of whether or not that slot exists in the light DOM.
|
|
529
|
-
*
|
|
530
|
-
* @param {String|Array} name The slot name.
|
|
531
|
-
* @example this.hasSlot("header");
|
|
532
|
-
*/
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
hasSlot(name) {
|
|
536
|
-
if (!name) {
|
|
537
|
-
this.warn(`Please provide at least one slot name for which to search.`);
|
|
538
|
-
return;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
if (typeof name === "string") {
|
|
542
|
-
return [...this.children].filter(child => child.hasAttribute("slot") && child.getAttribute("slot") === name).length > 0;
|
|
543
|
-
} else if (Array.isArray(name)) {
|
|
544
|
-
return name.reduce(n => [...this.children].filter(child => child.hasAttribute("slot") && child.getAttribute("slot") === n).length > 0);
|
|
545
|
-
} else {
|
|
546
|
-
this.warn(`Expected hasSlot argument to be a string or an array, but it was given: ${typeof name}.`);
|
|
547
|
-
return;
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
/**
|
|
551
|
-
* Given a slot name, returns elements assigned to the slot as an arry.
|
|
552
|
-
* If no value is provided (i.e., `this.getSlot()`), it returns all children not assigned to a slot (without a slot attribute).
|
|
553
|
-
*
|
|
554
|
-
* @example: `this.getSlot("header")`
|
|
555
|
-
*/
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
getSlot(name = "unassigned") {
|
|
559
|
-
if (name !== "unassigned") {
|
|
560
|
-
return [...this.children].filter(child => child.hasAttribute("slot") && child.getAttribute("slot") === name);
|
|
561
|
-
} else {
|
|
562
|
-
return [...this.children].filter(child => !child.hasAttribute("slot"));
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
cssVariable(name, value, element = this) {
|
|
567
|
-
name = name.substr(0, 2) !== "--" ? "--" + name : name;
|
|
568
|
-
|
|
569
|
-
if (value) {
|
|
570
|
-
element.style.setProperty(name, value);
|
|
571
|
-
return value;
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
return window.getComputedStyle(element).getPropertyValue(name).trim() || null;
|
|
575
|
-
}
|
|
576
|
-
/**
|
|
577
|
-
* This alerts nested components to a change in the context
|
|
578
|
-
*/
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
contextUpdate() {
|
|
582
|
-
// Loop over light DOM elements, find direct descendants that are components
|
|
583
|
-
const lightEls = [...this.querySelectorAll("*")].filter(item => item.tagName.toLowerCase().slice(0, 4) === `${prefix}-`) // Closest will return itself or it's ancestor matching that selector
|
|
584
|
-
.filter(item => {
|
|
585
|
-
// If there is no parent element, return null
|
|
586
|
-
if (!item.parentElement) return; // Otherwise, find the closest component that's this one
|
|
587
|
-
else return item.parentElement.closest(`[${this._pfeClass._getCache("prop2attr").pfelement}]`) === this;
|
|
588
|
-
}); // Loop over shadow elements, find direct descendants that are components
|
|
589
|
-
|
|
590
|
-
let shadowEls = [...this.shadowRoot.querySelectorAll("*")].filter(item => item.tagName.toLowerCase().slice(0, 4) === `${prefix}-`) // Closest will return itself or it's ancestor matching that selector
|
|
591
|
-
.filter(item => {
|
|
592
|
-
// If there is a parent element and we can find another web component in the ancestor tree
|
|
593
|
-
if (item.parentElement && item.parentElement.closest(`[${this._pfeClass._getCache("prop2attr").pfelement}]`)) {
|
|
594
|
-
return item.parentElement.closest(`[${this._pfeClass._getCache("prop2attr").pfelement}]`) === this;
|
|
595
|
-
} // Otherwise, check if the host matches this context
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
if (item.getRootNode().host === this) return true; // If neither state is true, return false
|
|
599
|
-
|
|
600
|
-
return false;
|
|
601
|
-
});
|
|
602
|
-
const nestedEls = lightEls.concat(shadowEls); // If nested elements don't exist, return without processing
|
|
603
|
-
|
|
604
|
-
if (nestedEls.length === 0) return; // Loop over the nested elements and reset their context
|
|
605
|
-
|
|
606
|
-
nestedEls.map(child => {
|
|
607
|
-
if (child.resetContext) {
|
|
608
|
-
this.log(`Update context of ${child.tagName.toLowerCase()}`); // Ask the component to recheck it's context in case it changed
|
|
609
|
-
|
|
610
|
-
child.resetContext(this.on);
|
|
611
|
-
}
|
|
612
|
-
});
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
resetContext(fallback) {
|
|
616
|
-
if (this.isIE11) return; // Priority order for context values to be pulled from:
|
|
617
|
-
//--> 1. context (OLD: pfe-theme)
|
|
618
|
-
//--> 2. --context (OLD: --theme)
|
|
619
|
-
|
|
620
|
-
let value = this.context || this.contextVariable || fallback; // Validate that the current context (this.on) and the new context (value) are the same OR
|
|
621
|
-
// no context is set and there isn't a new context being set
|
|
622
|
-
|
|
623
|
-
if (this.on === value || !this.on && !value) return;
|
|
624
|
-
this.log(`Resetting context from ${this.on} to ${value || "null"}`);
|
|
625
|
-
this.on = value;
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
constructor(pfeClass, {
|
|
629
|
-
type = null,
|
|
630
|
-
delayRender = false
|
|
631
|
-
} = {}) {
|
|
632
|
-
super();
|
|
633
|
-
this._pfeClass = pfeClass;
|
|
634
|
-
this.tag = pfeClass.tag;
|
|
635
|
-
this._parseObserver = this._parseObserver.bind(this);
|
|
636
|
-
this.isIE11 = /MSIE|Trident|Edge\//.test(window.navigator.userAgent); // Initialize the array of jump links pointers
|
|
637
|
-
// Expects items in the array to be NodeItems
|
|
638
|
-
|
|
639
|
-
if (!this._pfeClass.instances || !(this._pfeClass.instances.length >= 0)) this._pfeClass.instances = []; // Set up the mark ID based on existing ID on component if it exists
|
|
640
|
-
|
|
641
|
-
if (!this.id) {
|
|
642
|
-
this._markId = this.randomId.replace("pfe", this.tag);
|
|
643
|
-
} else if (this.id.startsWith("pfe-") && !this.id.startsWith(this.tag)) {
|
|
644
|
-
this._markId = this.id.replace("pfe", this.tag);
|
|
645
|
-
} else {
|
|
646
|
-
this._markId = `${this.tag}-${this.id}`;
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
this._markCount = 0; // TODO: Deprecated for 1.0 release
|
|
650
|
-
|
|
651
|
-
this.schemaProps = pfeClass.schemaProperties; // TODO: Migrate this out of schema for 1.0
|
|
652
|
-
|
|
653
|
-
this.slots = pfeClass.slots;
|
|
654
|
-
this.template = document.createElement("template"); // Set the default value to the passed in type
|
|
655
|
-
|
|
656
|
-
if (type && this._pfeClass.allProperties.type) this._pfeClass.allProperties.type.default = type; // Initalize the properties and attributes from the property getter
|
|
657
|
-
|
|
658
|
-
this._initializeProperties();
|
|
659
|
-
|
|
660
|
-
this.attachShadow({
|
|
661
|
-
mode: "open"
|
|
662
|
-
}); // Tracks if the component has been initially rendered. Useful if for debouncing
|
|
663
|
-
// template updates.
|
|
664
|
-
|
|
665
|
-
this._rendered = false;
|
|
666
|
-
if (!delayRender) this.render();
|
|
667
|
-
}
|
|
668
|
-
/**
|
|
669
|
-
* Standard connected callback; fires when the component is added to the DOM.
|
|
670
|
-
*/
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
connectedCallback() {
|
|
674
|
-
this._initializeAttributeDefaults();
|
|
675
|
-
|
|
676
|
-
if (window.ShadyCSS) window.ShadyCSS.styleElement(this); // Register this instance with the pointer for the scoped class and the global context
|
|
677
|
-
|
|
678
|
-
this._pfeClass.instances.push(this);
|
|
679
|
-
|
|
680
|
-
PFElement.allInstances.push(this); // If the slot definition exists, set up an observer
|
|
681
|
-
|
|
682
|
-
if (typeof this.slots === "object") {
|
|
683
|
-
this._slotsObserver = new MutationObserver(() => this._initializeSlots(this.tag, this.slots));
|
|
684
|
-
|
|
685
|
-
this._initializeSlots(this.tag, this.slots);
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
/**
|
|
689
|
-
* Standard disconnected callback; fires when a componet is removed from the DOM.
|
|
690
|
-
* Add your removeEventListeners here.
|
|
691
|
-
*/
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
disconnectedCallback() {
|
|
695
|
-
if (this._cascadeObserver) this._cascadeObserver.disconnect();
|
|
696
|
-
if (this._slotsObserver) this._slotsObserver.disconnect(); // Remove this instance from the pointer
|
|
697
|
-
|
|
698
|
-
const classIdx = this._pfeClass.instances.find(item => item !== this);
|
|
699
|
-
|
|
700
|
-
delete this._pfeClass.instances[classIdx];
|
|
701
|
-
const globalIdx = PFElement.allInstances.find(item => item !== this);
|
|
702
|
-
delete PFElement.allInstances[globalIdx];
|
|
703
|
-
}
|
|
704
|
-
/**
|
|
705
|
-
* Attribute changed callback fires when attributes are updated.
|
|
706
|
-
* This combines the global and the component-specific logic.
|
|
707
|
-
*/
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
attributeChangedCallback(attr, oldVal, newVal) {
|
|
711
|
-
if (!this._pfeClass.allProperties) return;
|
|
712
|
-
|
|
713
|
-
let propName = this._pfeClass._attr2prop(attr);
|
|
714
|
-
|
|
715
|
-
const propDef = this._pfeClass.allProperties[propName]; // If the attribute that changed derives from a property definition
|
|
716
|
-
|
|
717
|
-
if (propDef) {
|
|
718
|
-
// If the property/attribute pair has an alias, copy the new value to the alias target
|
|
719
|
-
if (propDef.alias) {
|
|
720
|
-
const aliasedPropDef = this._pfeClass.allProperties[propDef.alias];
|
|
721
|
-
|
|
722
|
-
const aliasedAttr = this._pfeClass._prop2attr(propDef.alias);
|
|
723
|
-
|
|
724
|
-
const aliasedAttrVal = this.getAttribute(aliasedAttr);
|
|
725
|
-
|
|
726
|
-
if (aliasedAttrVal !== newVal) {
|
|
727
|
-
this[propDef.alias] = this._castPropertyValue(aliasedPropDef, newVal);
|
|
728
|
-
}
|
|
729
|
-
} // If the property/attribute pair has an observer, fire it
|
|
730
|
-
// Observers receive the oldValue and the newValue from the attribute changed callback
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
if (propDef.observer) {
|
|
734
|
-
this[propDef.observer](this._castPropertyValue(propDef, oldVal), this._castPropertyValue(propDef, newVal));
|
|
735
|
-
} // If the property/attribute pair has a cascade target, copy the attribute to the matching elements
|
|
736
|
-
// Note: this handles the cascading of new/updated attributes
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
if (propDef.cascade) {
|
|
740
|
-
this._cascadeAttribute(attr, this._pfeClass._convertSelectorsToArray(propDef.cascade));
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
/**
|
|
745
|
-
* Standard render function.
|
|
746
|
-
*/
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
render() {
|
|
750
|
-
this.shadowRoot.innerHTML = "";
|
|
751
|
-
this.template.innerHTML = this.html;
|
|
752
|
-
|
|
753
|
-
if (window.ShadyCSS) {
|
|
754
|
-
window.ShadyCSS.prepareTemplate(this.template, this.tag);
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
this.shadowRoot.appendChild(this.template.content.cloneNode(true));
|
|
758
|
-
this.log(`render`); // Cascade properties to the rendered template
|
|
759
|
-
|
|
760
|
-
this.cascadeProperties(); // Update the display context
|
|
761
|
-
|
|
762
|
-
this.contextUpdate();
|
|
763
|
-
|
|
764
|
-
if (PFElement.trackPerformance()) {
|
|
765
|
-
try {
|
|
766
|
-
performance.mark(`${this._markId}-rendered`);
|
|
767
|
-
|
|
768
|
-
if (this._markCount < 1) {
|
|
769
|
-
this._markCount = this._markCount + 1; // Navigation start, i.e., the browser first sees that the user has navigated to the page
|
|
770
|
-
|
|
771
|
-
performance.measure(`${this._markId}-from-navigation-to-first-render`, undefined, `${this._markId}-rendered`); // Render is run before connection unless delayRender is used
|
|
772
|
-
|
|
773
|
-
performance.measure(`${this._markId}-from-defined-to-first-render`, `${this._markId}-defined`, `${this._markId}-rendered`);
|
|
774
|
-
}
|
|
775
|
-
} catch (err) {
|
|
776
|
-
this.log(`Performance marks are not supported by this browser.`);
|
|
777
|
-
}
|
|
778
|
-
} // If the slot definition exists, set up an observer
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
if (typeof this.slots === "object" && this._slotsObserver) {
|
|
782
|
-
this._slotsObserver.observe(this, {
|
|
783
|
-
childList: true
|
|
784
|
-
});
|
|
785
|
-
} // If an observer was defined, set it to begin observing here
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
if (this._cascadeObserver) {
|
|
789
|
-
this._cascadeObserver.observe(this, {
|
|
790
|
-
attributes: true,
|
|
791
|
-
childList: true,
|
|
792
|
-
subtree: true
|
|
793
|
-
});
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
this._rendered = true;
|
|
797
|
-
}
|
|
798
|
-
/**
|
|
799
|
-
* A wrapper around an event dispatch to standardize formatting.
|
|
800
|
-
*/
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
emitEvent(name, {
|
|
804
|
-
bubbles = true,
|
|
805
|
-
cancelable = false,
|
|
806
|
-
composed = true,
|
|
807
|
-
detail = {}
|
|
808
|
-
} = {}) {
|
|
809
|
-
if (detail) this.log(`Custom event: ${name}`, detail);else this.log(`Custom event: ${name}`);
|
|
810
|
-
this.dispatchEvent(new CustomEvent(name, {
|
|
811
|
-
bubbles,
|
|
812
|
-
cancelable,
|
|
813
|
-
composed,
|
|
814
|
-
detail
|
|
815
|
-
}));
|
|
816
|
-
}
|
|
817
|
-
/**
|
|
818
|
-
* Handles the cascading of properties to nested components when new elements are added
|
|
819
|
-
* Attribute updates/additions are handled by the attribute callback
|
|
820
|
-
*/
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
cascadeProperties(nodeList) {
|
|
824
|
-
const cascade = this._pfeClass._getCache("cascadingProperties");
|
|
825
|
-
|
|
826
|
-
if (cascade) {
|
|
827
|
-
if (this._cascadeObserver) this._cascadeObserver.disconnect();
|
|
828
|
-
let selectors = Object.keys(cascade); // Find out if anything in the nodeList matches any of the observed selectors for cacading properties
|
|
829
|
-
|
|
830
|
-
if (selectors) {
|
|
831
|
-
if (nodeList) {
|
|
832
|
-
[...nodeList].forEach(nodeItem => {
|
|
833
|
-
selectors.forEach(selector => {
|
|
834
|
-
// if this node has a match function (i.e., it's an HTMLElement, not
|
|
835
|
-
// a text node), see if it matches the selector, otherwise drop it (like it's hot).
|
|
836
|
-
if (nodeItem.matches && nodeItem.matches(selector)) {
|
|
837
|
-
let attrNames = cascade[selector]; // each selector can match multiple properties/attributes, so
|
|
838
|
-
// copy each of them
|
|
839
|
-
|
|
840
|
-
attrNames.forEach(attrName => this._copyAttribute(attrName, nodeItem));
|
|
841
|
-
}
|
|
842
|
-
});
|
|
843
|
-
});
|
|
844
|
-
} else {
|
|
845
|
-
// If a match was found, cascade each attribute to the element
|
|
846
|
-
const components = selectors.filter(item => item.slice(0, prefix.length + 1) === `${prefix}-`).map(name => customElements.whenDefined(name));
|
|
847
|
-
if (components) Promise.all(components).then(() => {
|
|
848
|
-
this._cascadeAttributes(selectors, cascade);
|
|
849
|
-
});else this._cascadeAttributes(selectors, cascade);
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
if (this._rendered && this._cascadeObserver) this._cascadeObserver.observe(this, {
|
|
854
|
-
attributes: true,
|
|
855
|
-
childList: true,
|
|
856
|
-
subtree: true
|
|
857
|
-
});
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
/* --- Observers for global properties --- */
|
|
861
|
-
|
|
862
|
-
/**
|
|
863
|
-
* This responds to changes in the pfelement attribute; indicates if the component upgraded
|
|
864
|
-
* @TODO maybe we should use just the attribute instead of the class?
|
|
865
|
-
* https://github.com/angular/angular/issues/15399#issuecomment-318785677
|
|
866
|
-
*/
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
_upgradeObserver() {
|
|
870
|
-
this.classList.add("PFElement");
|
|
871
|
-
}
|
|
872
|
-
/**
|
|
873
|
-
* This responds to changes in the context attribute; manual override tool
|
|
874
|
-
*/
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
_contextObserver(oldValue, newValue) {
|
|
878
|
-
if (newValue && (oldValue && oldValue !== newValue || !oldValue)) {
|
|
879
|
-
this.log(`Running the context observer`);
|
|
880
|
-
this.on = newValue;
|
|
881
|
-
this.cssVariable("context", newValue);
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
/**
|
|
885
|
-
* This responds to changes in the context; source of truth for components
|
|
886
|
-
*/
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
_onObserver(oldValue, newValue) {
|
|
890
|
-
if (oldValue && oldValue !== newValue || newValue && !oldValue) {
|
|
891
|
-
this.log(`Context update`); // Fire an event for child components
|
|
892
|
-
|
|
893
|
-
this.contextUpdate();
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
/**
|
|
897
|
-
* This responds to inline style changes and greps for context or theme updates.
|
|
898
|
-
* @TODO: --theme will be deprecated in 2.0
|
|
899
|
-
*/
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
_inlineStyleObserver(oldValue, newValue) {
|
|
903
|
-
if (oldValue === newValue) return; // If there are no inline styles, a context might have been deleted, so call resetContext
|
|
904
|
-
|
|
905
|
-
if (!newValue) this.resetContext();else {
|
|
906
|
-
this.log(`Style observer activated on ${this.tag}`, `${newValue || "null"}`); // Grep for context/theme
|
|
907
|
-
|
|
908
|
-
const regex = /--[\w|-]*(?:context|theme):\s*(?:\"*(light|dark|saturated)\"*)/gi;
|
|
909
|
-
let match = regex.exec(newValue); // If no match is returned, exit the observer
|
|
910
|
-
|
|
911
|
-
if (!match) return;
|
|
912
|
-
const newContext = match[1]; // If the new context value differs from the on value, update
|
|
913
|
-
|
|
914
|
-
if (newContext !== this.on && !this.context) this.on = newContext;
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
/**
|
|
918
|
-
* This is connected with a mutation observer that watches for updates to the light DOM
|
|
919
|
-
* and pushes down the cascading values
|
|
920
|
-
*/
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
_parseObserver(mutationsList) {
|
|
924
|
-
// Iterate over the mutation list, look for cascade updates
|
|
925
|
-
for (let mutation of mutationsList) {
|
|
926
|
-
// If a new node is added, attempt to cascade attributes to it
|
|
927
|
-
if (mutation.type === "childList" && mutation.addedNodes.length) {
|
|
928
|
-
const nonTextNodes = [...mutation.addedNodes].filter(n => n.nodeType !== HTMLElement.TEXT_NODE);
|
|
929
|
-
this.cascadeProperties(nonTextNodes);
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
/* --- End observers --- */
|
|
934
|
-
|
|
935
|
-
/**
|
|
936
|
-
* Validate that the property meets the requirements for type and naming.
|
|
937
|
-
*/
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
static _validateProperties() {
|
|
941
|
-
for (let propName in this.allProperties) {
|
|
942
|
-
const propDef = this.allProperties[propName]; // Verify that properties conform to the allowed data types
|
|
943
|
-
|
|
944
|
-
if (!isAllowedType(propDef)) {
|
|
945
|
-
this.error(`Property "${propName}" on ${this.name} must have type String, Number, or Boolean.`);
|
|
946
|
-
} // Verify the property name conforms to our naming rules
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
if (!/^[a-z_]/.test(propName)) {
|
|
950
|
-
this.error(`Property ${this.name}.${propName} defined, but prop names must begin with a lower-case letter or an underscore`);
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
const isFunction = typeof propDef.default === "function"; // If the default value is not the same type as defined by the property
|
|
954
|
-
// and it's not a function (we can't validate the output of the function
|
|
955
|
-
// on the class level), throw a warning
|
|
956
|
-
|
|
957
|
-
if (propDef.default && !isValidDefaultType(propDef) && !isFunction) this.error(`[${this.name}] The default value \`${propDef.default}\` does not match the assigned type ${propDef.type.name} for the \'${propName}\' property`);
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
/**
|
|
961
|
-
* Convert provided property value to the correct type as defined in the properties method.
|
|
962
|
-
*/
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
_castPropertyValue(propDef, attrValue) {
|
|
966
|
-
switch (propDef.type) {
|
|
967
|
-
case Number:
|
|
968
|
-
// map various attribute string values to their respective
|
|
969
|
-
// desired property values
|
|
970
|
-
return {
|
|
971
|
-
[attrValue]: Number(attrValue),
|
|
972
|
-
null: null,
|
|
973
|
-
NaN: NaN,
|
|
974
|
-
undefined: undefined
|
|
975
|
-
}[attrValue];
|
|
976
|
-
|
|
977
|
-
case Boolean:
|
|
978
|
-
return attrValue !== null;
|
|
979
|
-
|
|
980
|
-
case String:
|
|
981
|
-
return {
|
|
982
|
-
[attrValue]: attrValue,
|
|
983
|
-
undefined: undefined
|
|
984
|
-
}[attrValue];
|
|
985
|
-
|
|
986
|
-
default:
|
|
987
|
-
return attrValue;
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
/**
|
|
991
|
-
* Map provided value to the attribute name on the component.
|
|
992
|
-
*/
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
_assignValueToAttribute(obj, attr, value) {
|
|
996
|
-
// If the default is false and the property is boolean, we don't need to do anything
|
|
997
|
-
const isBooleanFalse = obj.type === Boolean && !value;
|
|
998
|
-
const isNull = value === null;
|
|
999
|
-
const isUndefined = typeof value === "undefined"; // If the attribute is not defined, set the default value
|
|
1000
|
-
|
|
1001
|
-
if (isBooleanFalse || isNull || isUndefined) {
|
|
1002
|
-
this.removeAttribute(attr);
|
|
1003
|
-
} else {
|
|
1004
|
-
// Boolean values get an empty string: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes
|
|
1005
|
-
if (obj.type === Boolean && typeof value === "boolean") {
|
|
1006
|
-
this.setAttribute(attr, "");
|
|
1007
|
-
} else {
|
|
1008
|
-
// Validate against the provided values
|
|
1009
|
-
if (obj.values) {
|
|
1010
|
-
this._validateAttributeValue(obj, attr, value);
|
|
1011
|
-
} // Still accept the value provided even if it's not valid
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
this.setAttribute(attr, value);
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
/**
|
|
1019
|
-
* Maps the defined slots into an object that is easier to query
|
|
1020
|
-
*/
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
_initializeSlots(tag, slots) {
|
|
1024
|
-
this.log("Validate slots...");
|
|
1025
|
-
if (this._slotsObserver) this._slotsObserver.disconnect(); // Loop over the properties provided by the schema
|
|
1026
|
-
|
|
1027
|
-
Object.keys(slots).forEach(slot => {
|
|
1028
|
-
let slotObj = slots[slot]; // Only attach the information if the data provided is a schema object
|
|
1029
|
-
|
|
1030
|
-
if (typeof slotObj === "object") {
|
|
1031
|
-
let slotExists = false;
|
|
1032
|
-
let result = []; // If it's a named slot, look for that slot definition
|
|
1033
|
-
|
|
1034
|
-
if (slotObj.namedSlot) {
|
|
1035
|
-
// Check prefixed slots
|
|
1036
|
-
result = this.getSlot(`${tag}--${slot}`);
|
|
1037
|
-
|
|
1038
|
-
if (result.length > 0) {
|
|
1039
|
-
slotObj.nodes = result;
|
|
1040
|
-
slotExists = true;
|
|
1041
|
-
} // Check for unprefixed slots
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
result = this.getSlot(`${slot}`);
|
|
1045
|
-
|
|
1046
|
-
if (result.length > 0) {
|
|
1047
|
-
slotObj.nodes = result;
|
|
1048
|
-
slotExists = true;
|
|
1049
|
-
} // If it's the default slot, look for direct children not assigned to a slot
|
|
1050
|
-
|
|
1051
|
-
} else {
|
|
1052
|
-
result = [...this.children].filter(child => !child.hasAttribute("slot"));
|
|
1053
|
-
|
|
1054
|
-
if (result.length > 0) {
|
|
1055
|
-
slotObj.nodes = result;
|
|
1056
|
-
slotExists = true;
|
|
1057
|
-
}
|
|
1058
|
-
} // If the slot exists, attach an attribute to the parent to indicate that
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
if (slotExists) {
|
|
1062
|
-
this.setAttribute(`has_${slot}`, "");
|
|
1063
|
-
} else {
|
|
1064
|
-
this.removeAttribute(`has_${slot}`);
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
});
|
|
1068
|
-
this.log("Slots validated.");
|
|
1069
|
-
if (this._slotsObserver) this._slotsObserver.observe(this, {
|
|
1070
|
-
childList: true
|
|
1071
|
-
});
|
|
1072
|
-
}
|
|
1073
|
-
/**
|
|
1074
|
-
* Sets up the property definitions based on the properties method.
|
|
1075
|
-
*/
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
_initializeProperties() {
|
|
1079
|
-
const properties = this._pfeClass.allProperties;
|
|
1080
|
-
let hasCascade = false;
|
|
1081
|
-
if (Object.keys(properties).length > 0) this.log(`Initialize properties`);
|
|
1082
|
-
|
|
1083
|
-
for (let propName in properties) {
|
|
1084
|
-
const propDef = properties[propName]; // Check if the property exists, throw a warning if it does.
|
|
1085
|
-
// HTMLElements have a LOT of properties; it wouldn't be hard
|
|
1086
|
-
// to overwrite one accidentally.
|
|
1087
|
-
|
|
1088
|
-
if (typeof this[propName] !== "undefined") {
|
|
1089
|
-
this.log(`Property "${propName}" on ${this.constructor.name} cannot be defined because the property name is reserved`);
|
|
1090
|
-
} else {
|
|
1091
|
-
const attrName = this._pfeClass._prop2attr(propName);
|
|
1092
|
-
|
|
1093
|
-
if (propDef.cascade) hasCascade = true;
|
|
1094
|
-
Object.defineProperty(this, propName, {
|
|
1095
|
-
get: () => {
|
|
1096
|
-
const attrValue = this.getAttribute(attrName);
|
|
1097
|
-
return this._castPropertyValue(propDef, attrValue);
|
|
1098
|
-
},
|
|
1099
|
-
set: rawNewVal => {
|
|
1100
|
-
// Assign the value to the attribute
|
|
1101
|
-
this._assignValueToAttribute(propDef, attrName, rawNewVal);
|
|
1102
|
-
|
|
1103
|
-
return rawNewVal;
|
|
1104
|
-
},
|
|
1105
|
-
writeable: true,
|
|
1106
|
-
enumerable: true,
|
|
1107
|
-
configurable: false
|
|
1108
|
-
});
|
|
1109
|
-
}
|
|
1110
|
-
} // If any of the properties has cascade, attach a new mutation observer to the component
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
if (hasCascade) {
|
|
1114
|
-
this._cascadeObserver = new MutationObserver(this._parseObserver);
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
/**
|
|
1118
|
-
* Intialize the default value for an attribute.
|
|
1119
|
-
*/
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
_initializeAttributeDefaults() {
|
|
1123
|
-
const properties = this._pfeClass.allProperties;
|
|
1124
|
-
|
|
1125
|
-
for (let propName in properties) {
|
|
1126
|
-
const propDef = properties[propName];
|
|
1127
|
-
|
|
1128
|
-
const attrName = this._pfeClass._prop2attr(propName);
|
|
1129
|
-
|
|
1130
|
-
if (propDef.hasOwnProperty("default")) {
|
|
1131
|
-
let value = propDef.default; // Check if default is a function
|
|
1132
|
-
|
|
1133
|
-
if (typeof propDef.default === "function") {
|
|
1134
|
-
value = propDef.default(this);
|
|
1135
|
-
} // If the attribute has not already been set, assign the default value
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
if (!this.hasAttribute(attrName)) {
|
|
1139
|
-
// Assign the value to the attribute
|
|
1140
|
-
this._assignValueToAttribute(propDef, attrName, value);
|
|
1141
|
-
}
|
|
1142
|
-
}
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1145
|
-
/**
|
|
1146
|
-
* Validate the value against provided values.
|
|
1147
|
-
*/
|
|
1148
|
-
// @TODO add support for a validation function
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
_validateAttributeValue(propDef, attr, value) {
|
|
1152
|
-
if (Array.isArray(propDef.values) && propDef.values.length > 0 && !propDef.values.includes(value) // ||
|
|
1153
|
-
// (typeof propDef.values === "string" && propDef.values !== value) ||
|
|
1154
|
-
// (typeof propDef.values === "function" && !propDef.values(value))
|
|
1155
|
-
) {
|
|
1156
|
-
this.warn(`${value} is not a valid value for ${attr}. Please provide one of the following values: ${propDef.values.join(", ")}`);
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
|
-
return value;
|
|
1160
|
-
}
|
|
1161
|
-
/**
|
|
1162
|
-
* Look up an attribute name linked to a given property name.
|
|
1163
|
-
*/
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
static _prop2attr(propName) {
|
|
1167
|
-
return this._getCache("prop2attr")[propName];
|
|
1168
|
-
}
|
|
1169
|
-
/**
|
|
1170
|
-
* Look up an property name linked to a given attribute name.
|
|
1171
|
-
*/
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
static _attr2prop(attrName) {
|
|
1175
|
-
return this._getCache("attr2prop")[attrName];
|
|
1176
|
-
}
|
|
1177
|
-
/**
|
|
1178
|
-
* Convert a property name to an attribute name.
|
|
1179
|
-
*/
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
static _convertPropNameToAttrName(propName) {
|
|
1183
|
-
const propDef = this.allProperties[propName];
|
|
1184
|
-
|
|
1185
|
-
if (propDef.attr) {
|
|
1186
|
-
return propDef.attr;
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
|
-
return propName.replace(/^_/, "").replace(/^[A-Z]/, l => l.toLowerCase()).replace(/[A-Z]/g, l => `-${l.toLowerCase()}`);
|
|
1190
|
-
}
|
|
1191
|
-
/**
|
|
1192
|
-
* Convert an attribute name to a property name.
|
|
1193
|
-
*/
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
static _convertAttrNameToPropName(attrName) {
|
|
1197
|
-
for (let prop in this.allProperties) {
|
|
1198
|
-
if (this.allProperties[prop].attr === attrName) {
|
|
1199
|
-
return prop;
|
|
1200
|
-
}
|
|
1201
|
-
} // Convert the property name to kebab case
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
const propName = attrName.replace(/-([A-Za-z])/g, l => l[1].toUpperCase());
|
|
1205
|
-
return propName;
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
|
-
_cascadeAttributes(selectors, set) {
|
|
1209
|
-
selectors.forEach(selector => {
|
|
1210
|
-
set[selector].forEach(attr => {
|
|
1211
|
-
this._cascadeAttribute(attr, selector);
|
|
1212
|
-
});
|
|
1213
|
-
});
|
|
1214
|
-
}
|
|
1215
|
-
/**
|
|
1216
|
-
* Trigger a cascade of the named attribute to any child elements that match
|
|
1217
|
-
* the `to` selector. The selector can match elements in the light DOM and
|
|
1218
|
-
* shadow DOM.
|
|
1219
|
-
* @param {String} name The name of the attribute to cascade (not necessarily the same as the property name).
|
|
1220
|
-
* @param {String} to A CSS selector that matches the elements that should received the cascaded attribute. The selector will be applied within `this` element's light and shadow DOM trees.
|
|
1221
|
-
*/
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
_cascadeAttribute(name, to) {
|
|
1225
|
-
const recipients = [...this.querySelectorAll(to), ...this.shadowRoot.querySelectorAll(to)];
|
|
1226
|
-
|
|
1227
|
-
for (const node of recipients) {
|
|
1228
|
-
this._copyAttribute(name, node);
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
/**
|
|
1232
|
-
* Copy the named attribute to a target element.
|
|
1233
|
-
*/
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
_copyAttribute(name, el) {
|
|
1237
|
-
this.log(`copying ${name} to ${el}`);
|
|
1238
|
-
const value = this.getAttribute(name);
|
|
1239
|
-
const fname = value == null ? "removeAttribute" : "setAttribute";
|
|
1240
|
-
el[fname](name, value);
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
static _convertSelectorsToArray(selectors) {
|
|
1244
|
-
if (selectors) {
|
|
1245
|
-
if (typeof selectors === "string") return selectors.split(",");else if (typeof selectors === "object") return selectors;else {
|
|
1246
|
-
this.warn(`selectors should be provided as a string, array, or object; received: ${typeof selectors}.`);
|
|
1247
|
-
}
|
|
1248
|
-
}
|
|
1249
|
-
|
|
1250
|
-
return;
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
static _parsePropertiesForCascade(mergedProperties) {
|
|
1254
|
-
let cascadingProperties = {}; // Parse the properties to pull out attributes that cascade
|
|
1255
|
-
|
|
1256
|
-
for (const [propName, config] of Object.entries(mergedProperties)) {
|
|
1257
|
-
let cascadeTo = this._convertSelectorsToArray(config.cascade); // Iterate over each node in the cascade list for this property
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
if (cascadeTo) cascadeTo.map(nodeItem => {
|
|
1261
|
-
let attr = this._prop2attr(propName); // Create an object with the node as the key and an array of attributes
|
|
1262
|
-
// that are to be cascaded down to it
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
if (!cascadingProperties[nodeItem]) cascadingProperties[nodeItem] = [attr];else cascadingProperties[nodeItem].push(attr);
|
|
1266
|
-
});
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
return cascadingProperties;
|
|
1270
|
-
}
|
|
1271
|
-
/**
|
|
1272
|
-
* Caching the attributes and properties data for efficiency
|
|
1273
|
-
*/
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
static create(pfe) {
|
|
1277
|
-
pfe._createCache();
|
|
1278
|
-
|
|
1279
|
-
pfe._populateCache(pfe);
|
|
1280
|
-
|
|
1281
|
-
pfe._validateProperties();
|
|
1282
|
-
|
|
1283
|
-
try {
|
|
1284
|
-
window.customElements.define(pfe.tag, pfe);
|
|
1285
|
-
} catch (err) {
|
|
1286
|
-
// Capture the class currently using this tag in the registry
|
|
1287
|
-
const prevDefinition = window.customElements.get(pfe.tag); // Check if the previous definition's version matches this one
|
|
1288
|
-
|
|
1289
|
-
if (prevDefinition && prevDefinition.version !== pfe.version) {
|
|
1290
|
-
this.warn(`${pfe.tag} was registered at version ${prevDefinition.version}; cannot register version ${pfe.version}.`);
|
|
1291
|
-
} // @TODO Should this error be reported to the console?
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
if (err && err.message) this.log(err.message);
|
|
1295
|
-
}
|
|
1296
|
-
|
|
1297
|
-
if (PFElement.trackPerformance()) {
|
|
1298
|
-
try {
|
|
1299
|
-
performance.mark(`${this._markId}-defined`);
|
|
1300
|
-
} catch (err) {
|
|
1301
|
-
this.log(`Performance marks are not supported by this browser.`);
|
|
1302
|
-
}
|
|
1303
|
-
}
|
|
1304
|
-
}
|
|
1305
|
-
|
|
1306
|
-
static _createCache() {
|
|
1307
|
-
this._cache = {
|
|
1308
|
-
properties: {},
|
|
1309
|
-
globalProperties: {},
|
|
1310
|
-
componentProperties: {},
|
|
1311
|
-
cascadingProperties: {},
|
|
1312
|
-
attr2prop: {},
|
|
1313
|
-
prop2attr: {}
|
|
1314
|
-
};
|
|
1315
|
-
}
|
|
1316
|
-
/**
|
|
1317
|
-
* Cache an object in a given cache namespace. This overwrites anything
|
|
1318
|
-
* already in that namespace.
|
|
1319
|
-
*/
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
static _setCache(namespace, object) {
|
|
1323
|
-
this._cache[namespace] = object;
|
|
1324
|
-
}
|
|
1325
|
-
/**
|
|
1326
|
-
* Get a cached object by namespace, or get all cached objects.
|
|
1327
|
-
*/
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
static _getCache(namespace) {
|
|
1331
|
-
return namespace ? this._cache[namespace] : this._cache;
|
|
1332
|
-
}
|
|
1333
|
-
/**
|
|
1334
|
-
* Populate initial values for properties cache.
|
|
1335
|
-
*/
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
static _populateCache(pfe) {
|
|
1339
|
-
// @TODO add a warning when a component property conflicts with a global property.
|
|
1340
|
-
const mergedProperties = _extends({}, pfe.properties, PFElement.properties);
|
|
1341
|
-
|
|
1342
|
-
pfe._setCache("componentProperties", pfe.properties);
|
|
1343
|
-
|
|
1344
|
-
pfe._setCache("globalProperties", PFElement.properties);
|
|
1345
|
-
|
|
1346
|
-
pfe._setCache("properties", mergedProperties); // create mapping objects to go from prop name to attrname and back
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
const prop2attr = {};
|
|
1350
|
-
const attr2prop = {};
|
|
1351
|
-
|
|
1352
|
-
for (let propName in mergedProperties) {
|
|
1353
|
-
const attrName = this._convertPropNameToAttrName(propName);
|
|
1354
|
-
|
|
1355
|
-
prop2attr[propName] = attrName;
|
|
1356
|
-
attr2prop[attrName] = propName;
|
|
1357
|
-
}
|
|
1358
|
-
|
|
1359
|
-
pfe._setCache("attr2prop", attr2prop);
|
|
1360
|
-
|
|
1361
|
-
pfe._setCache("prop2attr", prop2attr);
|
|
1362
|
-
|
|
1363
|
-
const cascadingProperties = this._parsePropertiesForCascade(mergedProperties);
|
|
1364
|
-
|
|
1365
|
-
if (Object.keys(cascadingProperties)) pfe._setCache("cascadingProperties", cascadingProperties);
|
|
1366
|
-
}
|
|
1367
|
-
/**
|
|
1368
|
-
* allProperties returns an object containing PFElement's global properties
|
|
1369
|
-
* and the descendents' (such as PfeCard, etc) component properties. The two
|
|
1370
|
-
* objects are merged together and in the case of a property name conflict,
|
|
1371
|
-
* PFElement's properties override the component's properties.
|
|
1372
|
-
*/
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
static get allProperties() {
|
|
1376
|
-
return this._getCache("properties");
|
|
1377
|
-
}
|
|
1378
|
-
/**
|
|
1379
|
-
* cascadingProperties returns an object containing PFElement's global properties
|
|
1380
|
-
* and the descendents' (such as PfeCard, etc) component properties. The two
|
|
1381
|
-
* objects are merged together and in the case of a property name conflict,
|
|
1382
|
-
* PFElement's properties override the component's properties.
|
|
1383
|
-
*/
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
static get cascadingProperties() {
|
|
1387
|
-
return this._getCache("cascadingProperties");
|
|
1388
|
-
}
|
|
1389
|
-
/**
|
|
1390
|
-
* Breakpoint object mapping human-readable size names to viewport sizes
|
|
1391
|
-
* To overwrite this at the component-level, include `static get breakpoint` in your component's class definition
|
|
1392
|
-
* @returns {Object} keys are t-shirt sizes and values map to screen-sizes (sourced from PF4)
|
|
1393
|
-
*/
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
static get breakpoint() {
|
|
1397
|
-
return {
|
|
1398
|
-
xs: "0px",
|
|
1399
|
-
// $pf-global--breakpoint--xs: 0 !default;
|
|
1400
|
-
sm: "576px",
|
|
1401
|
-
// $pf-global--breakpoint--sm: 576px !default;
|
|
1402
|
-
md: "768px",
|
|
1403
|
-
// $pf-global--breakpoint--md: 768px !default;
|
|
1404
|
-
lg: "992px",
|
|
1405
|
-
// $pf-global--breakpoint--lg: 992px !default;
|
|
1406
|
-
xl: "1200px",
|
|
1407
|
-
// $pf-global--breakpoint--xl: 1200px !default;
|
|
1408
|
-
"2xl": "1450px" // $pf-global--breakpoint--2xl: 1450px !default;
|
|
1409
|
-
|
|
1410
|
-
};
|
|
1411
|
-
}
|
|
1412
|
-
|
|
1413
|
-
} // Initialize the global instances
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
PFElement.allInstances = [];
|
|
1417
|
-
autoReveal(PFElement.log);
|
|
1418
|
-
|
|
1419
|
-
// https://tc39.github.io/ecma262/#sec-array.prototype.findIndex
|
|
1420
|
-
|
|
1421
|
-
if (!Array.prototype.findIndex) {
|
|
1422
|
-
Object.defineProperty(Array.prototype, "findIndex", {
|
|
1423
|
-
value: function (predicate) {
|
|
1424
|
-
// 1. Let O be ? ToObject(this value).
|
|
1425
|
-
if (this == null) {
|
|
1426
|
-
throw new TypeError('"this" is null or not defined');
|
|
1427
|
-
}
|
|
1428
|
-
|
|
1429
|
-
var o = Object(this); // 2. Let len be ? ToLength(? Get(O, "length")).
|
|
1430
|
-
|
|
1431
|
-
var len = o.length >>> 0; // 3. If IsCallable(predicate) is false, throw a TypeError exception.
|
|
1432
|
-
|
|
1433
|
-
if (typeof predicate !== "function") {
|
|
1434
|
-
throw new TypeError("predicate must be a function");
|
|
1435
|
-
} // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
var thisArg = arguments[1]; // 5. Let k be 0.
|
|
1439
|
-
|
|
1440
|
-
var k = 0; // 6. Repeat, while k < len
|
|
1441
|
-
|
|
1442
|
-
while (k < len) {
|
|
1443
|
-
// a. Let Pk be ! ToString(k).
|
|
1444
|
-
// b. Let kValue be ? Get(O, Pk).
|
|
1445
|
-
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
|
|
1446
|
-
// d. If testResult is true, return k.
|
|
1447
|
-
var kValue = o[k];
|
|
1448
|
-
|
|
1449
|
-
if (predicate.call(thisArg, kValue, k, o)) {
|
|
1450
|
-
return k;
|
|
1451
|
-
} // e. Increase k by 1.
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
k++;
|
|
1455
|
-
} // 7. Return -1.
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
return -1;
|
|
1459
|
-
},
|
|
1460
|
-
configurable: true,
|
|
1461
|
-
writable: true
|
|
1462
|
-
});
|
|
1463
|
-
}
|
|
1464
|
-
/*!
|
|
1465
|
-
* PatternFly Elements: PfeTabs 1.12.3
|
|
1466
|
-
* @license
|
|
1467
|
-
* Copyright 2021 Red Hat, Inc.
|
|
1468
|
-
*
|
|
1469
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1470
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
1471
|
-
* in the Software without restriction, including without limitation the rights
|
|
1472
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1473
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
1474
|
-
* furnished to do so, subject to the following conditions:
|
|
1475
|
-
*
|
|
1476
|
-
* The above copyright notice and this permission notice shall be included in
|
|
1477
|
-
* all copies or substantial portions of the Software.
|
|
1478
|
-
*
|
|
1479
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1480
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1481
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1482
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1483
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1484
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1485
|
-
* SOFTWARE.
|
|
1486
|
-
*
|
|
1487
|
-
*/
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
const TAB_CONTENT_MUTATION_CONFIG = {
|
|
1491
|
-
characterData: true,
|
|
1492
|
-
childList: true,
|
|
1493
|
-
subtree: true
|
|
1494
|
-
};
|
|
1495
|
-
|
|
1496
|
-
class PfeTab extends PFElement {
|
|
1497
|
-
// Injected at build-time
|
|
1498
|
-
static get version() {
|
|
1499
|
-
return "1.12.3";
|
|
1500
|
-
} // Injected at build-time
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
get html() {
|
|
1504
|
-
return `
|
|
1505
|
-
<style>:host{text-align:left;position:relative;display:block;cursor:pointer;margin:0 0 calc(1px * -1);margin:var(--pfe-tabs__tab--Margin,0 0 calc(var(--pfe-theme--ui--border-width,1px) * -1));padding:1rem calc(1rem * 2) 1rem calc(1rem * 2);padding:var(--pfe-tabs__tab--PaddingTop,var(--pfe-theme--container-padding,1rem)) var(--pfe-tabs__tab--PaddingRight,calc(var(--pfe-theme--container-padding,1rem) * 2)) var(--pfe-tabs__tab--PaddingBottom,var(--pfe-theme--container-padding,1rem)) var(--pfe-tabs__tab--PaddingLeft,calc(var(--pfe-theme--container-padding,1rem) * 2));border-style:solid;border-style:var(--pfe-theme--ui--border-style,solid);border-width:1px;border-width:var(--pfe-theme--ui--border-width,1px);border-color:transparent;border-bottom-width:3px;border-bottom-width:var(--pfe-tabs--BorderWidth,var(--pfe-theme--ui--border-width--active,3px));background-color:none;background-color:var(--pfe-tabs--BackgroundColor--inactive,none);text-align:center;text-align:var(--pfe-tabs__tab--TextAlign,center);text-transform:none;text-transform:var(--pfe-tabs__tab--TextTransform,none);color:#6a6e73;color:var(--pfe-tabs--Color,var(--pfe-theme--color--text--muted,#6a6e73));font-size:1rem;font-size:var(--pfe-tabs__tab--FontSize,var(--pf-global--FontSize--md,1rem));font-family:"Red Hat Text",RedHatText,Overpass,Overpass,Arial,sans-serif;font-family:var(--pfe-tabs__tab--LineHeight, var(--pfe-theme--font-family, "Red Hat Text", "RedHatText", "Overpass", Overpass, Arial, sans-serif));line-height:1.5;line-height:var(--pfe-tabs__tab--LineHeight,var(--pfe-theme--line-height,1.5));font-weight:400;font-weight:var(--pfe-tabs__tab--FontWeight,var(--pfe-theme--font-weight--normal,400));--pf-c--FontSize:var(--pfe-tabs--FontSize)}:host #tab{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:100%}:host #tab *{font-size:inherit;font-weight:inherit;color:inherit;margin:0}:host([aria-selected=true]){background-color:transparent;background-color:var(--pfe-tabs--BackgroundColor,transparent);border-bottom-color:#06c;border-bottom-color:var(--pfe-tabs--BorderColor,var(--pfe-tabs--highlight,var(--pfe-theme--color--ui-accent,#06c)))}:host([aria-selected=true]) #tab *{color:#151515;color:var(--pfe-tabs--Color--focus,var(--pfe-tabs--focus,var(--pfe-theme--color--text,#151515)))}:host(:active),:host(:hover){background-color:transparent;background-color:var(--pfe-tabs--BackgroundColor,transparent);border-bottom-color:#b8bbbe;border-bottom-color:var(--pfe-tabs--BorderColor--hover,#b8bbbe)}:host(:active) #tab *,:host(:hover) #tab *{color:#151515;color:var(--pfe-tabs--Color--focus,var(--pfe-tabs--focus,var(--pfe-theme--color--text,#151515)))}@media screen and (min-width:768px){:host([vertical]){border-bottom-color:transparent;border-bottom-width:0;border-left-color:#d2d2d2;border-left-color:var(--pfe-theme--color--surface--border,#d2d2d2);border-left-width:1px;border-left-width:var(--pfe-theme--ui--border-width,1px);padding:1rem;padding:var(--pfe-theme--container-padding,1rem);--pfe-tabs--Margin:0 calc(var(--pfe-theme--ui--border-width, 1px) * -1) 0 0}:host([vertical][aria-selected=true]){border-left-color:#06c;border-left-color:var(--pfe-tabs--BorderColor,var(--pfe-tabs--highlight,var(--pfe-theme--color--ui-accent,#06c)));border-left-width:3px}:host([vertical]:not([variant=earth])){border-left:1px solid #d2d2d2;border-left:var(--pfe-theme--ui--border-width,1px) var(--pfe-theme--ui--border-style,solid) var(--pfe-theme--color--surface--border,#d2d2d2);text-align:left!important}:host([vertical]:not([variant=earth])[aria-selected=true]){border-right:3px solid transparent;border-right:var(--pfe-tabs--BorderWidth,var(--pfe-theme--ui--border-width--active,3px)) var(--pfe-theme--ui--border-style,solid) transparent;border-left:3px solid #06c;border-left:var(--pfe-tabs--BorderWidth,var(--pfe-theme--ui--border-width--active,3px)) var(--pfe-theme--ui--border-style,solid) var(--pfe-tabs--BorderColor,var(--pfe-tabs--highlight,var(--pfe-theme--color--ui-accent,#06c)));padding-left:calc(1rem - 2px);padding-left:calc(var(--pfe-theme--container-padding,1rem) - 2px)}:host([vertical]:not([variant=earth])[aria-selected=false]){border-right:3px solid transparent;border-right:var(--pfe-tabs--BorderWidth,var(--pfe-theme--ui--border-width--active,3px)) var(--pfe-theme--ui--border-style,solid) transparent}:host([vertical]:not([variant=earth])[aria-selected=false]:hover){border-right:3px solid transparent;border-right:var(--pfe-tabs--BorderWidth,var(--pfe-theme--ui--border-width--active,3px)) var(--pfe-theme--ui--border-style,solid) transparent;border-bottom:0;border-left:3px solid #b8bbbe;border-left:var(--pfe-tabs--BorderWidth,var(--pfe-theme--ui--border-width--active,3px)) var(--pfe-theme--ui--border-style,solid) var(--pfe-tabs--BorderColor--hover,#b8bbbe);padding-left:calc(1rem - 2px);padding-left:calc(var(--pfe-theme--container-padding,1rem) - 2px)}}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([variant=earth]){background-color:#f0f0f0;color:#6a6e73}}:host(:not([vertical])[variant=earth]:not([aria-selected=true]):first-of-type){border-left-color:transparent}:host(:not([vertical])[variant=earth]:not([aria-selected=true]):last-of-type){border-right-color:transparent}:host([variant=earth][aria-selected=false]){background-color:#f0f0f0;background-color:var(--pfe-tabs--BackgroundColor--inactive,var(--pfe-theme--color--surface--lighter,#f0f0f0));border-color:#d2d2d2;border-color:var(--pfe-theme--color--surface--border,#d2d2d2);border-top-width:3px;border-top-width:var(--pfe-tabs--BorderWidth,var(--pfe-theme--ui--border-width--active,3px));border-top-color:transparent;border-bottom-color:#b8bbbe;border-bottom-color:var(--pfe-tabs--BorderColor--hover,#b8bbbe);border-bottom-width:1px;border-bottom-width:var(--pfe-theme--ui--border-width,1px)}:host([variant=earth][aria-selected=false]:hover){border-top-color:#b8bbbe;border-top-color:var(--pfe-tabs--BorderColor--hover,#b8bbbe)}:host([variant=earth][aria-selected=true]){background-color:#fff;background-color:var(--pfe-tabs--BackgroundColor,var(--pfe-theme--color--surface--lightest,#fff));border-bottom:0;border-left-color:#d2d2d2;border-left-color:var(--pfe-theme--color--surface--border,#d2d2d2);border-right-color:#d2d2d2;border-right-color:var(--pfe-theme--color--surface--border,#d2d2d2);border-top:solid #06c 3px;border-top:solid var(--pfe-tabs--BorderColor,var(--pfe-tabs--highlight,var(--pfe-theme--color--ui-accent,#06c))) var(--pfe-tabs--BorderWidth,var(--pfe-theme--ui--border-width--active,3px))}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([variant=earth][aria-selected=true]){color:#6a6e73;background-color:#fff;border-left:1px solid #d2d2d2;border-top:3px solid #06c;border-top:var(--pfe-tabs--BorderWidth,var(--pfe-theme--ui--border-width--active,3px)) solid var(--pfe-tabs--BorderColor,var(--pfe-tabs--highlight,var(--pfe-theme--color--ui-accent,#06c)));border-bottom:0}}:host([variant=earth][aria-selected=true]:last-of-type){border-right:1px solid #d2d2d2;border-right:var(--pfe-theme--ui--border-width,1px) var(--pfe-theme--ui--border-style,solid) var(--pfe-theme--color--surface--border,#d2d2d2)}@media screen and (min-width:768px){:host([vertical][variant=earth]){border-top:1px solid #d2d2d2;border-top:var(--pfe-theme--ui--border-width,1px) var(--pfe-theme--ui--border-style,solid) var(--pfe-theme--color--surface--border,#d2d2d2);border-bottom:1px solid #d2d2d2;border-bottom:var(--pfe-theme--ui--border-width,1px) var(--pfe-theme--ui--border-style,solid) var(--pfe-theme--color--surface--border,#d2d2d2);border-left-width:3px;border-left-width:var(--pfe-theme--ui--border-width--active,3px);text-align:left}:host([vertical][variant=earth][aria-selected=false]:first-of-type){border-top-color:transparent;border-left:3px solid transparent;border-left:var(--pfe-tabs--BorderWidth,var(--pfe-theme--ui--border-width--active,3px)) var(--pfe-theme--ui--border-style,solid) transparent}:host([vertical][variant=earth][aria-selected=false]:last-of-type){border-bottom-color:transparent}:host([vertical][variant=earth][aria-selected=false]){border-right:0;border-bottom-color:transparent;border-left-color:transparent}:host([vertical][variant=earth][aria-selected=false]:hover){border-left-color:#b8bbbe;border-left-color:var(--pfe-tabs--BorderColor--hover,#b8bbbe);border-top-color:#d2d2d2;border-top-color:var(--pfe-theme--color--surface--border,#d2d2d2)}:host([vertical][variant=earth][aria-selected=false]:first-of-type:hover){border-left-color:#d2d2d2;border-left-color:var(--pfe-theme--color--surface--border,#d2d2d2);border-top-color:transparent}:host([vertical][variant=earth][aria-selected=true]){border-top-color:#d2d2d2;border-top-color:var(--pfe-theme--color--surface--border,#d2d2d2);border-left-color:#06c;border-left-color:var(--pfe-tabs--BorderColor,var(--pfe-tabs--highlight,var(--pfe-theme--color--ui-accent,#06c)));border-right-color:transparent;margin-right:-1px}}:host([on=dark][variant=earth]){--pfe-tabs--Color:var(--pfe-theme--color--text--on-dark, #fff);--pfe-tabs--Color--focus:var(--pfe-theme--color--text--on-dark, #fff);border-right-color:#6a6e73;border-right-color:var(--pfe-theme--color--surface--border--darker,#6a6e73);border-left-color:#6a6e73;border-left-color:var(--pfe-theme--color--surface--border--darker,#6a6e73)}:host([on=dark][variant=earth][aria-selected=false]){--pfe-tabs--Color:var(--pfe-theme--color--text--muted--on-dark, #d2d2d2);--pfe-tabs--BackgroundColor--inactive:var(--pfe-theme--color--surface--darker, #3c3f42)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([on=dark][variant=earth][aria-selected=false]){background-color:#fff!important;background-color:var(--pfe-theme--color--surface--lightest,#fff)!important}:host([on=dark][variant=earth][aria-selected=false]) #tab *{color:#151515!important}}:host([on=dark][variant=earth][aria-selected=true]){--pfe-tabs--Color--focus:var(--pfe-theme--color--text--on-dark, #fff);--pfe-tabs--BackgroundColor:var(--pfe-theme--color--surface--darkest, #151515)}:host([variant=earth][on=saturated][aria-selected=false]){--pfe-tabs--BackgroundColor:var(--pfe-theme--color--surface--lighter, #f0f0f0)}:host([variant=earth][on=saturated][aria-selected=true]){--pfe-tabs--BackgroundColor:var(--pfe-theme--color--surface--lightest, #fff)}:host([on=saturated]:not([variant=earth])){--pfe-tabs--Color:var(--pfe-theme--color--text--on-saturated, #fff);--pfe-tabs--Color--focus:var(--pfe-theme--color--text--on-saturated, #fff)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([on=saturated]:not([variant=earth])){background-color:transparent}:host([on=saturated]:not([variant=earth])) #tab *{color:#151515!important}}:host([on=saturated]:not([variant=earth])[aria-selected=true]){--pfe-tabs--Color--focus:var(--pfe-theme--color--text--on-saturated, #fff);--pfe-tabs--BorderColor:var(--pfe-theme--color--ui-base--on-saturated, #fff)}:host([on=saturated]:not([variant=earth])[aria-selected=false]){--pfe-tabs--Color:var(--pfe-theme--color--text--muted--on-saturated, #d2d2d2)}:host([on=saturated]:not([variant=earth])[aria-selected=false]:hover){--pfe-tabs--BorderColor:var(--pfe-theme--color--surface--border, #d2d2d2)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([on=saturated]:not([variant=earth])[aria-selected=true]:last-of-type){border-left:0!important}}:host([on=dark]:not([variant=earth])){--pfe-tabs--Color:var(--pfe-theme--color--text--on-dark, #fff);--pfe-tabs--Color--focus:var(--pfe-theme--color--text--on-dark, #fff)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([on=dark]:not([variant=earth])) #tab *{color:#151515!important}}:host([on=dark]:not([variant=earth])[aria-selected=false]){--pfe-tabs--Color:var(--pfe-theme--color--text--muted--on-saturated, #d2d2d2)}:host([on=dark]:not([variant=earth])[aria-selected=false]:hover){--pfe-tabs--BorderColor:var(--pfe-theme--color--surface--lightest, #fff);border-bottom-color:#f0f0f0;border-bottom-color:var(--pfe-theme--color--surface--base,#f0f0f0);--pfe-tabs__tab--BorderBottom:var(--pfe-tabs--BorderWidth, var(--pfe-theme--ui--border-width--active, 3px)) var(--pfe-theme--ui--border-style, solid) var(--pfe-theme--color--surface--border, #d2d2d2)}:host([on=dark]:not([variant=earth])[vertical][aria-selected=false]:hover){border-bottom-color:transparent} /*# sourceMappingURL=pfe-tab.min.css.map */</style>
|
|
1506
|
-
<span id="tab"></span>`;
|
|
1507
|
-
}
|
|
1508
|
-
|
|
1509
|
-
static get tag() {
|
|
1510
|
-
return "pfe-tab";
|
|
1511
|
-
}
|
|
1512
|
-
|
|
1513
|
-
get styleUrl() {
|
|
1514
|
-
return "pfe-tab.scss";
|
|
1515
|
-
}
|
|
1516
|
-
|
|
1517
|
-
get templateUrl() {
|
|
1518
|
-
return "pfe-tab.html";
|
|
1519
|
-
}
|
|
1520
|
-
|
|
1521
|
-
static get properties() {
|
|
1522
|
-
return {
|
|
1523
|
-
selected: {
|
|
1524
|
-
title: "Selected tab",
|
|
1525
|
-
type: String,
|
|
1526
|
-
default: "false",
|
|
1527
|
-
attr: "aria-selected",
|
|
1528
|
-
values: ["true", "false"],
|
|
1529
|
-
observer: "_selectedHandler"
|
|
1530
|
-
},
|
|
1531
|
-
controls: {
|
|
1532
|
-
title: "Connected panel ID",
|
|
1533
|
-
type: String,
|
|
1534
|
-
attr: "aria-controls"
|
|
1535
|
-
},
|
|
1536
|
-
role: {
|
|
1537
|
-
type: String,
|
|
1538
|
-
default: "tab"
|
|
1539
|
-
},
|
|
1540
|
-
tabindex: {
|
|
1541
|
-
type: Number,
|
|
1542
|
-
default: -1
|
|
1543
|
-
},
|
|
1544
|
-
variant: {
|
|
1545
|
-
title: "Variant",
|
|
1546
|
-
type: String,
|
|
1547
|
-
enum: ["wind", "earth"]
|
|
1548
|
-
},
|
|
1549
|
-
// @TODO: Deprecated in 1.0
|
|
1550
|
-
oldPfeId: {
|
|
1551
|
-
type: String,
|
|
1552
|
-
attr: "pfe-id",
|
|
1553
|
-
observer: "_oldPfeIdChanged"
|
|
1554
|
-
}
|
|
1555
|
-
};
|
|
1556
|
-
} // Declare the type of this component
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
static get PfeType() {
|
|
1560
|
-
return PFElement.PfeTypes.Content;
|
|
1561
|
-
}
|
|
1562
|
-
|
|
1563
|
-
constructor() {
|
|
1564
|
-
super(PfeTab, {
|
|
1565
|
-
type: PfeTab.PfeType
|
|
1566
|
-
});
|
|
1567
|
-
this._init = this._init.bind(this);
|
|
1568
|
-
this._setTabContent = this._setTabContent.bind(this);
|
|
1569
|
-
this._getTabElement = this._getTabElement.bind(this);
|
|
1570
|
-
this._observer = new MutationObserver(this._init);
|
|
1571
|
-
}
|
|
1572
|
-
|
|
1573
|
-
connectedCallback() {
|
|
1574
|
-
super.connectedCallback();
|
|
1575
|
-
this._tabItem = this.shadowRoot.querySelector(`#tab`);
|
|
1576
|
-
if (this.hasLightDOM()) this._init();
|
|
1577
|
-
|
|
1578
|
-
this._observer.observe(this, TAB_CONTENT_MUTATION_CONFIG);
|
|
1579
|
-
}
|
|
1580
|
-
|
|
1581
|
-
disconnectedCallback() {
|
|
1582
|
-
super.disconnectedCallback();
|
|
1583
|
-
|
|
1584
|
-
this._observer.disconnect();
|
|
1585
|
-
}
|
|
1586
|
-
|
|
1587
|
-
_selectedHandler() {
|
|
1588
|
-
if (this.selected === "true") this.tabindex = 0;else this.tabindex = -1;
|
|
1589
|
-
}
|
|
1590
|
-
|
|
1591
|
-
_oldPfeIdChanged(oldVal, newVal) {
|
|
1592
|
-
if (!this.id) this.id = newVal;
|
|
1593
|
-
}
|
|
1594
|
-
|
|
1595
|
-
_init() {
|
|
1596
|
-
if (window.ShadyCSS) this._observer.disconnect(); // Force role to be set to tab
|
|
1597
|
-
|
|
1598
|
-
this.role = "tab"; // Copy the tab content into the template
|
|
1599
|
-
|
|
1600
|
-
this._setTabContent(); // If an ID is not defined, generate a random one
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
if (!this.id) this.id = this.randomId;
|
|
1604
|
-
if (window.ShadyCSS) this._observer.observe(this, TAB_CONTENT_MUTATION_CONFIG);
|
|
1605
|
-
}
|
|
1606
|
-
|
|
1607
|
-
_getTabElement() {
|
|
1608
|
-
// Check if there is no nested element or nested textNodes
|
|
1609
|
-
if (!this.firstElementChild && !this.firstChild) {
|
|
1610
|
-
this.warn(`No tab content provided`);
|
|
1611
|
-
return;
|
|
1612
|
-
}
|
|
1613
|
-
|
|
1614
|
-
if (this.firstElementChild && this.firstElementChild.tagName) {
|
|
1615
|
-
// If the first element is a slot, query for it's content
|
|
1616
|
-
if (this.firstElementChild.tagName === "SLOT") {
|
|
1617
|
-
const slotted = this.firstElementChild.assignedNodes(); // If there is no content inside the slot, return empty with a warning
|
|
1618
|
-
|
|
1619
|
-
if (slotted.length === 0) {
|
|
1620
|
-
this.warn(`No heading information exists within this slot.`);
|
|
1621
|
-
return;
|
|
1622
|
-
} // If there is more than 1 element in the slot, capture the first h-tag
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
if (slotted.length > 1) this.warn(`Tab heading currently only supports 1 heading tag.`);
|
|
1626
|
-
const htags = slotted.filter(slot => slot.tagName.match(/^H[1-6]/) || slot.tagName === "P");
|
|
1627
|
-
if (htags.length > 0) return htags[0];else return;
|
|
1628
|
-
} else if (this.firstElementChild.tagName.match(/^H[1-6]/) || this.firstElementChild.tagName === "P") {
|
|
1629
|
-
return this.firstElementChild;
|
|
1630
|
-
} else {
|
|
1631
|
-
this.warn(`Tab heading should contain at least 1 heading tag for correct semantics.`);
|
|
1632
|
-
}
|
|
1633
|
-
}
|
|
1634
|
-
|
|
1635
|
-
return;
|
|
1636
|
-
}
|
|
1637
|
-
|
|
1638
|
-
_setTabContent() {
|
|
1639
|
-
let label = "";
|
|
1640
|
-
let isTag = false;
|
|
1641
|
-
|
|
1642
|
-
let tabElement = this._getTabElement();
|
|
1643
|
-
|
|
1644
|
-
if (tabElement) {
|
|
1645
|
-
// Copy the tab content into the template
|
|
1646
|
-
label = tabElement.textContent.trim().replace(/\s+/g, " ");
|
|
1647
|
-
isTag = true;
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
|
-
if (!tabElement) {
|
|
1651
|
-
// If no element is found, try for a text node
|
|
1652
|
-
if (this.textContent.trim().replace(/\s+/g, " ")) {
|
|
1653
|
-
label = this.textContent.trim().replace(/\s+/g, " ");
|
|
1654
|
-
}
|
|
1655
|
-
}
|
|
1656
|
-
|
|
1657
|
-
if (!label) {
|
|
1658
|
-
this.warn(`There does not appear to be any content in the tab region.`);
|
|
1659
|
-
return;
|
|
1660
|
-
}
|
|
1661
|
-
|
|
1662
|
-
let semantics = "h3";
|
|
1663
|
-
|
|
1664
|
-
if (isTag) {
|
|
1665
|
-
semantics = tabElement.tagName.toLowerCase();
|
|
1666
|
-
} // Create an h-level tag for the shadow tab, default h3
|
|
1667
|
-
// or use the provided semantics from light DOM
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
let heading = document.createElement(semantics); // Assign the label content to the new heading
|
|
1671
|
-
|
|
1672
|
-
heading.textContent = label; // Attach the heading to the tabItem
|
|
1673
|
-
|
|
1674
|
-
if (this._tabItem) {
|
|
1675
|
-
this._tabItem.innerHTML = "";
|
|
1676
|
-
|
|
1677
|
-
this._tabItem.appendChild(heading);
|
|
1678
|
-
}
|
|
1679
|
-
}
|
|
1680
|
-
|
|
1681
|
-
}
|
|
1682
|
-
/*!
|
|
1683
|
-
* PatternFly Elements: PfeTabs 1.12.3
|
|
1684
|
-
* @license
|
|
1685
|
-
* Copyright 2021 Red Hat, Inc.
|
|
1686
|
-
*
|
|
1687
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1688
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
1689
|
-
* in the Software without restriction, including without limitation the rights
|
|
1690
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1691
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
1692
|
-
* furnished to do so, subject to the following conditions:
|
|
1693
|
-
*
|
|
1694
|
-
* The above copyright notice and this permission notice shall be included in
|
|
1695
|
-
* all copies or substantial portions of the Software.
|
|
1696
|
-
*
|
|
1697
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1698
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1699
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1700
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1701
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1702
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1703
|
-
* SOFTWARE.
|
|
1704
|
-
*
|
|
1705
|
-
*/
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
const TAB_PANEL_MUTATION_CONFIG = {
|
|
1709
|
-
childList: true,
|
|
1710
|
-
subtree: true
|
|
1711
|
-
};
|
|
1712
|
-
|
|
1713
|
-
class PfeTabPanel extends PFElement {
|
|
1714
|
-
// Injected at build-time
|
|
1715
|
-
static get version() {
|
|
1716
|
-
return "1.12.3";
|
|
1717
|
-
} // Injected at build-time
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
get html() {
|
|
1721
|
-
return `
|
|
1722
|
-
<style>:host{display:block;color:#3c3f42;color:var(--pfe-broadcasted--text,#3c3f42)}:host(:focus){outline:0}:host [tabindex]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;height:100%}:host .container{margin:0;width:100%;background-color:transparent;background-color:var(--pfe-tabs__panel--BackgroundColor,transparent);border-top:0;border-top:var(--pfe-tabs__panel--BorderTop,0);border-right:0;border-right:var(--pfe-tabs__panel--BorderRight,0);border-bottom:0;border-bottom:var(--pfe-tabs__panel--BorderBottom,0);border-left:0;border-left:var(--pfe-tabs__panel--BorderLeft,0);padding-top:calc(1rem * 3);padding-top:var(--pfe-tabs__panel--PaddingTop,calc(var(--pfe-theme--container-padding,1rem) * 3))}@media screen and (min-width:1200px){:host .container{padding-top:calc(1rem * 3);padding-top:var(--pfe-tabs__panel--PaddingTop,calc(var(--pfe-theme--container-padding,1rem) * 3));padding-right:0;padding-right:var(--pfe-tabs__panel--PaddingRight,0);padding-bottom:0;padding-bottom:var(--pfe-tabs__panel--PaddingBottom,0);padding-left:0;padding-left:var(--pfe-tabs__panel--PaddingLeft,0)}}:host .container::after{clear:both;content:"";display:table}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host .container{padding:1em;background-color:#fff!important;color:#151515!important}}:host([hidden]){display:none}:host([variant=earth]){background-color:#fff;background-color:var(--pfe-tabs__panel--BackgroundColor,var(--pfe-theme--color--surface--lightest,#fff))}:host([variant=earth]) .container{padding-top:calc(1rem * 3);padding-top:var(--pfe-tabs__panel--PaddingTop,calc(var(--pfe-theme--container-padding,1rem) * 3));padding-right:calc(1rem * 3);padding-right:var(--pfe-tabs__panel--PaddingRight,calc(var(--pfe-theme--container-padding,1rem) * 3));padding-bottom:calc(1rem * 3);padding-bottom:var(--pfe-tabs__panel--PaddingBottom,calc(var(--pfe-theme--container-padding,1rem) * 3));padding-left:calc(1rem * 3);padding-left:var(--pfe-tabs__panel--PaddingLeft,calc(var(--pfe-theme--container-padding,1rem) * 3))}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([variant=earth]) .container{background-color:#fff;padding:1em;border-right:1px solid #d2d2d2;border-bottom:1px solid #d2d2d2;border-left:1px solid #d2d2d2}}@media screen and (min-width:768px){:host([variant=wind][vertical]) .container{padding-top:0;padding-top:var(--pfe-tabs__panel--PaddingTop,0);padding-bottom:0;padding-bottom:var(--pfe-tabs__panel--PaddingBottom,0);padding-right:0;padding-right:var(--pfe-tabs__panel--PaddingRight,0);margin:0 calc(1rem - 2px);margin:0 calc(var(--pfe-theme--container-spacer,1rem) - 2px)}}@media screen and (min-width:768px) and (-ms-high-contrast:active),screen and (min-width:768px) and (-ms-high-contrast:none){:host([variant=wind][vertical]) .container{padding:1em 0 1em 2em}}@media screen and (min-width:768px){:host([variant=earth][vertical]){border-top:0;border-top:var(--pfe-tabs--BorderTop,0);border-left:1px solid #d2d2d2;border-left:var(--pfe-tabs--BorderLeft,var(--pfe-theme--ui--border-width,1px) var(--pfe-theme--ui--border-style,solid) var(--pfe-theme--color--surface--border,#d2d2d2));height:100%;background-color:#fff;background-color:var(--pfe-tabs__panel--BackgroundColor,var(--pfe-theme--color--surface--lightest,#fff))}:host([variant=earth][vertical]) .container{padding-left:calc(1rem * 3);padding-left:var(--pfe-tabs__panel--PaddingLeft,calc(var(--pfe-theme--container-padding,1rem) * 3))}}@media screen and (min-width:768px) and (-ms-high-contrast:active),screen and (min-width:768px) and (-ms-high-contrast:none){:host([variant=earth][vertical]) .container{border-top:1px solid #d2d2d2}}:host([variant=earth]) .container{padding-top:calc(1rem * 3);padding-top:var(--pfe-tabs__panel--PaddingTop,calc(var(--pfe-theme--container-padding,1rem) * 3));padding-right:calc(1rem * 3);padding-right:var(--pfe-tabs__panel--PaddingRight,calc(var(--pfe-theme--container-padding,1rem) * 3));padding-bottom:calc(1rem * 3);padding-bottom:var(--pfe-tabs__panel--PaddingBottom,calc(var(--pfe-theme--container-padding,1rem) * 3));padding-left:calc(1rem * 3);padding-left:var(--pfe-tabs__panel--PaddingLeft,calc(var(--pfe-theme--container-padding,1rem) * 3))}:host([on=dark][variant=earth]){background-color:#151515;background-color:var(--pfe-tabs__panel--BackgroundColor,var(--pfe-theme--color--surface--darkest,#151515));--pfe-broadcasted--text:var(--pfe-theme--color--text--on-dark, #fff);--pfe-broadcasted--text--muted:var(--pfe-theme--color--text--muted--on-dark, #d2d2d2);--pfe-broadcasted--link:var(--pfe-theme--color--link--on-dark, #73bcf7);--pfe-broadcasted--link--hover:var(--pfe-theme--color--link--hover--on-dark, #bee1f4);--pfe-broadcasted--link--focus:var(--pfe-theme--color--link--focus--on-dark, #bee1f4);--pfe-broadcasted--link--visited:var(--pfe-theme--color--link--visited--on-dark, #bee1f4);--pfe-broadcasted--link-decoration:var(--pfe-theme--link-decoration--on-dark, none);--pfe-broadcasted--link-decoration--hover:var(--pfe-theme--link-decoration--hover--on-dark, underline);--pfe-broadcasted--link-decoration--focus:var(--pfe-theme--link-decoration--focus--on-dark, underline);--pfe-broadcasted--link-decoration--visited:var(--pfe-theme--link-decoration--visited--on-dark, none)}:host([on=saturated][variant=earth]){background-color:#fff;background-color:var(--pfe-tabs__panel--BackgroundColor,var(--pfe-theme--color--surface--lightest,#fff));--pfe-broadcasted--text:var(--pfe-theme--color--text, #151515);--pfe-broadcasted--text--muted:var(--pfe-theme--color--text--muted, #6a6e73);--pfe-broadcasted--link:var(--pfe-theme--color--link, #06c);--pfe-broadcasted--link--hover:var(--pfe-theme--color--link--hover, #004080);--pfe-broadcasted--link--focus:var(--pfe-theme--color--link--focus, #004080);--pfe-broadcasted--link--visited:var(--pfe-theme--color--link--visited, #6753ac);--pfe-broadcasted--link-decoration:var(--pfe-theme--link-decoration, none);--pfe-broadcasted--link-decoration--hover:var(--pfe-theme--link-decoration--hover, underline);--pfe-broadcasted--link-decoration--focus:var(--pfe-theme--link-decoration--focus, underline);--pfe-broadcasted--link-decoration--visited:var(--pfe-theme--link-decoration--visited, none)}:host([on=saturated]:not([variant=earth])){--pfe-broadcasted--text:var(--pfe-theme--color--text--on-saturated, #fff);--pfe-broadcasted--text--muted:var(--pfe-theme--color--text--muted--on-saturated, #d2d2d2);--pfe-broadcasted--link:var(--pfe-theme--color--link--on-saturated, #fff);--pfe-broadcasted--link--hover:var(--pfe-theme--color--link--hover--on-saturated, #fafafa);--pfe-broadcasted--link--focus:var(--pfe-theme--color--link--focus--on-saturated, #fafafa);--pfe-broadcasted--link--visited:var(--pfe-theme--color--link--visited--on-saturated, #d2d2d2);--pfe-broadcasted--link-decoration:var(--pfe-theme--link-decoration--on-saturated, underline);--pfe-broadcasted--link-decoration--hover:var(--pfe-theme--link-decoration--hover--on-saturated, underline);--pfe-broadcasted--link-decoration--focus:var(--pfe-theme--link-decoration--focus--on-saturated, underline);--pfe-broadcasted--link-decoration--visited:var(--pfe-theme--link-decoration--visited--on-saturated, underline)}:host([on=dark]:not([variant=earth])){--pfe-broadcasted--text:var(--pfe-theme--color--text--on-dark, #fff);--pfe-broadcasted--text--muted:var(--pfe-theme--color--text--muted--on-dark, #d2d2d2);--pfe-broadcasted--link:var(--pfe-theme--color--link--on-dark, #73bcf7);--pfe-broadcasted--link--hover:var(--pfe-theme--color--link--hover--on-dark, #bee1f4);--pfe-broadcasted--link--focus:var(--pfe-theme--color--link--focus--on-dark, #bee1f4);--pfe-broadcasted--link--visited:var(--pfe-theme--color--link--visited--on-dark, #bee1f4);--pfe-broadcasted--link-decoration:var(--pfe-theme--link-decoration--on-dark, none);--pfe-broadcasted--link-decoration--hover:var(--pfe-theme--link-decoration--hover--on-dark, underline);--pfe-broadcasted--link-decoration--focus:var(--pfe-theme--link-decoration--focus--on-dark, underline);--pfe-broadcasted--link-decoration--visited:var(--pfe-theme--link-decoration--visited--on-dark, none)} /*# sourceMappingURL=pfe-tab-panel.min.css.map */</style>
|
|
1723
|
-
<div tabindex="-1" role="tabpanel">
|
|
1724
|
-
<div class="container">
|
|
1725
|
-
<slot></slot>
|
|
1726
|
-
</div>
|
|
1727
|
-
</div>`;
|
|
1728
|
-
}
|
|
1729
|
-
|
|
1730
|
-
static get tag() {
|
|
1731
|
-
return "pfe-tab-panel";
|
|
1732
|
-
}
|
|
1733
|
-
|
|
1734
|
-
get styleUrl() {
|
|
1735
|
-
return "pfe-tab-panel.scss";
|
|
1736
|
-
}
|
|
1737
|
-
|
|
1738
|
-
get templateUrl() {
|
|
1739
|
-
return "pfe-tab-panel.html";
|
|
1740
|
-
}
|
|
1741
|
-
|
|
1742
|
-
static get properties() {
|
|
1743
|
-
return {
|
|
1744
|
-
selected: {
|
|
1745
|
-
title: "Selected tab",
|
|
1746
|
-
type: Boolean,
|
|
1747
|
-
default: false,
|
|
1748
|
-
attr: "aria-selected",
|
|
1749
|
-
observer: "_selectedHandler"
|
|
1750
|
-
},
|
|
1751
|
-
hidden: {
|
|
1752
|
-
title: "Visibility",
|
|
1753
|
-
type: Boolean,
|
|
1754
|
-
default: false
|
|
1755
|
-
},
|
|
1756
|
-
role: {
|
|
1757
|
-
type: String,
|
|
1758
|
-
default: "tabpanel"
|
|
1759
|
-
},
|
|
1760
|
-
tabindex: {
|
|
1761
|
-
type: Number,
|
|
1762
|
-
default: 0
|
|
1763
|
-
},
|
|
1764
|
-
labelledby: {
|
|
1765
|
-
type: String,
|
|
1766
|
-
attr: "aria-labelledby"
|
|
1767
|
-
},
|
|
1768
|
-
variant: {
|
|
1769
|
-
title: "Variant",
|
|
1770
|
-
type: String,
|
|
1771
|
-
enum: ["wind", "earth"]
|
|
1772
|
-
},
|
|
1773
|
-
// @TODO: Deprecated in 1.0
|
|
1774
|
-
oldPfeId: {
|
|
1775
|
-
type: String,
|
|
1776
|
-
attr: "pfe-id",
|
|
1777
|
-
observer: "_oldPfeIdChanged"
|
|
1778
|
-
}
|
|
1779
|
-
};
|
|
1780
|
-
} // Declare the type of this component
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
static get PfeType() {
|
|
1784
|
-
return PFElement.PfeTypes.Container;
|
|
1785
|
-
}
|
|
1786
|
-
|
|
1787
|
-
constructor() {
|
|
1788
|
-
super(PfeTabPanel, {
|
|
1789
|
-
type: PfeTabPanel.PfeType
|
|
1790
|
-
});
|
|
1791
|
-
this._init = this._init.bind(this);
|
|
1792
|
-
this._observer = new MutationObserver(this._init);
|
|
1793
|
-
}
|
|
1794
|
-
|
|
1795
|
-
connectedCallback() {
|
|
1796
|
-
super.connectedCallback();
|
|
1797
|
-
if (this.hasLightDOM()) this._init();
|
|
1798
|
-
|
|
1799
|
-
this._observer.observe(this, TAB_PANEL_MUTATION_CONFIG);
|
|
1800
|
-
}
|
|
1801
|
-
|
|
1802
|
-
disconnectedCallback() {
|
|
1803
|
-
super.disconnectedCallback();
|
|
1804
|
-
|
|
1805
|
-
this._observer.disconnect();
|
|
1806
|
-
}
|
|
1807
|
-
|
|
1808
|
-
_init() {
|
|
1809
|
-
if (window.ShadyCSS) this._observer.disconnect(); // If an ID is not defined, generate a random one
|
|
1810
|
-
|
|
1811
|
-
if (!this.id) this.id = this.randomId; // Force role to be set to tab
|
|
1812
|
-
|
|
1813
|
-
this.role = "tabpanel";
|
|
1814
|
-
|
|
1815
|
-
if (this.previousElementSibling && this.previousElementSibling.selected !== "true") {
|
|
1816
|
-
this.hidden = true;
|
|
1817
|
-
}
|
|
1818
|
-
|
|
1819
|
-
if (window.ShadyCSS) this._observer.observe(this, TAB_PANEL_MUTATION_CONFIG);
|
|
1820
|
-
}
|
|
1821
|
-
|
|
1822
|
-
_oldPfeIdChanged(oldVal, newVal) {
|
|
1823
|
-
if (!this.id) this.id = newVal;
|
|
1824
|
-
}
|
|
1825
|
-
|
|
1826
|
-
}
|
|
1827
|
-
/*!
|
|
1828
|
-
* PatternFly Elements: PfeTabs 1.12.3
|
|
1829
|
-
* @license
|
|
1830
|
-
* Copyright 2021 Red Hat, Inc.
|
|
1831
|
-
*
|
|
1832
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1833
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
1834
|
-
* in the Software without restriction, including without limitation the rights
|
|
1835
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1836
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
1837
|
-
* furnished to do so, subject to the following conditions:
|
|
1838
|
-
*
|
|
1839
|
-
* The above copyright notice and this permission notice shall be included in
|
|
1840
|
-
* all copies or substantial portions of the Software.
|
|
1841
|
-
*
|
|
1842
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1843
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1844
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1845
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1846
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1847
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1848
|
-
* SOFTWARE.
|
|
1849
|
-
*
|
|
1850
|
-
*/
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
const KEYCODE = {
|
|
1854
|
-
DOWN: 40,
|
|
1855
|
-
LEFT: 37,
|
|
1856
|
-
RIGHT: 39,
|
|
1857
|
-
UP: 38,
|
|
1858
|
-
HOME: 36,
|
|
1859
|
-
END: 35
|
|
1860
|
-
}; // @IE11 doesn't support URLSearchParams
|
|
1861
|
-
// https://caniuse.com/#search=urlsearchparams
|
|
1862
|
-
|
|
1863
|
-
const CAN_USE_URLSEARCHPARAMS = window.URLSearchParams ? true : false;
|
|
1864
|
-
const TABS_MUTATION_CONFIG = {
|
|
1865
|
-
childList: true,
|
|
1866
|
-
subtree: true
|
|
1867
|
-
};
|
|
1868
|
-
|
|
1869
|
-
class PfeTabs extends PFElement {
|
|
1870
|
-
// Injected at build-time
|
|
1871
|
-
static get version() {
|
|
1872
|
-
return "1.12.3";
|
|
1873
|
-
} // Injected at build-time
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
get html() {
|
|
1877
|
-
return `
|
|
1878
|
-
<style>@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host{color:#151515!important}}:host{display:block;display:var(--pfe-tabs--Display,block);padding:0;padding:var(--pfe-tabs--Padding,0)}:host .tabs{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;flex-direction:var(--pfe-tabs__tabs--FlexDirection,row);width:auto;width:var(--pfe-tabs__tabs--Width,auto);border-top:0;border-top:var(--pfe-tabs__tabs--BorderTop,0);border-right:0;border-right:var(--pfe-tabs__tabs--BorderRight,0);border-bottom:1px solid #d2d2d2;border-bottom:var(--pfe-tabs__tabs--BorderBottom,var(--pfe-theme--ui--border-width,1px) var(--pfe-theme--ui--border-style,solid) var(--pfe-tabs__tabs--BorderColor,var(--pfe-theme--color--surface--border,#d2d2d2)));border-left:0;border-left:var(--pfe-tabs__tabs--BorderLeft,0);padding:0;padding:var(--pfe-tabs__tabs--Padding,0)}:host .panels{width:auto;width:var(--pfe-tabs__panels--Width,auto)}:host(:not([vertical])[tab-align=center]) .tabs{-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}@media screen and (min-width:768px){:host([vertical]){--pfe-tabs--Display:flex;--pfe-tabs__tabs--FlexDirection:column;--pfe-tabs__tabs--Width:20%;--pfe-tabs__tabs--BorderRight:var(--pfe-theme--ui--border-width, 1px) var(--pfe-theme--ui--border-style, solid) var(--pfe-tabs--BorderColor);--pfe-tabs__tabs--BorderBottom:0;--pfe-tabs__panels--Width:80%;--pfe-tabs__panels--PaddingRight:var(--pfe-theme--container-padding, 1rem)}}@media screen and (min-width:768px) and (-ms-high-contrast:active),screen and (min-width:768px) and (-ms-high-contrast:none){:host([vertical]){display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}:host([vertical]) .tabs{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;width:22.22%;border-right:1px solid #d2d2d2;border-right:1px solid var(--pfe-theme--color--surface--border,#d2d2d2);border-bottom:0}:host([vertical]) .panels{width:77.8%;padding-right:1em}}@media screen and (min-width:768px) and (-ms-high-contrast:active),screen and (min-width:768px) and (-ms-high-contrast:none){:host([vertical][variant=earth]) .tabs{padding:1em 0 0 0}}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host(:not([variant=earth])){background-color:#fff;background-color:var(--pfe-theme--color--surface--lightest,#fff);color:#151515;color:var(--pfe-theme--color--text,#151515)}}:host([variant=earth]){--pfe-tabs__tabs--PaddingLeft:var(--pfe-theme--container-padding, 1rem)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([variant=earth]) .tabs{padding-left:1em}}:host([on=dark]){--pfe-broadcasted--text:var(--pfe-theme--color--text--on-dark, #fff);--pfe-broadcasted--text--muted:var(--pfe-theme--color--text--muted--on-dark, #d2d2d2);--pfe-broadcasted--link:var(--pfe-theme--color--link--on-dark, #73bcf7);--pfe-broadcasted--link--hover:var(--pfe-theme--color--link--hover--on-dark, #bee1f4);--pfe-broadcasted--link--focus:var(--pfe-theme--color--link--focus--on-dark, #bee1f4);--pfe-broadcasted--link--visited:var(--pfe-theme--color--link--visited--on-dark, #bee1f4);--pfe-broadcasted--link-decoration:var(--pfe-theme--link-decoration--on-dark, none);--pfe-broadcasted--link-decoration--hover:var(--pfe-theme--link-decoration--hover--on-dark, underline);--pfe-broadcasted--link-decoration--focus:var(--pfe-theme--link-decoration--focus--on-dark, underline);--pfe-broadcasted--link-decoration--visited:var(--pfe-theme--link-decoration--visited--on-dark, none)}:host([on=saturated]){--pfe-broadcasted--text:var(--pfe-theme--color--text--on-saturated, #fff);--pfe-broadcasted--text--muted:var(--pfe-theme--color--text--muted--on-saturated, #d2d2d2);--pfe-broadcasted--link:var(--pfe-theme--color--link--on-saturated, #fff);--pfe-broadcasted--link--hover:var(--pfe-theme--color--link--hover--on-saturated, #fafafa);--pfe-broadcasted--link--focus:var(--pfe-theme--color--link--focus--on-saturated, #fafafa);--pfe-broadcasted--link--visited:var(--pfe-theme--color--link--visited--on-saturated, #d2d2d2);--pfe-broadcasted--link-decoration:var(--pfe-theme--link-decoration--on-saturated, underline);--pfe-broadcasted--link-decoration--hover:var(--pfe-theme--link-decoration--hover--on-saturated, underline);--pfe-broadcasted--link-decoration--focus:var(--pfe-theme--link-decoration--focus--on-saturated, underline);--pfe-broadcasted--link-decoration--visited:var(--pfe-theme--link-decoration--visited--on-saturated, underline)}:host([on=light]){--pfe-broadcasted--text:var(--pfe-theme--color--text, #151515);--pfe-broadcasted--text--muted:var(--pfe-theme--color--text--muted, #6a6e73);--pfe-broadcasted--link:var(--pfe-theme--color--link, #06c);--pfe-broadcasted--link--hover:var(--pfe-theme--color--link--hover, #004080);--pfe-broadcasted--link--focus:var(--pfe-theme--color--link--focus, #004080);--pfe-broadcasted--link--visited:var(--pfe-theme--color--link--visited, #6753ac);--pfe-broadcasted--link-decoration:var(--pfe-theme--link-decoration, none);--pfe-broadcasted--link-decoration--hover:var(--pfe-theme--link-decoration--hover, underline);--pfe-broadcasted--link-decoration--focus:var(--pfe-theme--link-decoration--focus, underline);--pfe-broadcasted--link-decoration--visited:var(--pfe-theme--link-decoration--visited, none)}:host([vertical]) .tabs-prefix,:host([vertical]) .tabs-suffix{left:0;top:0;content:" ";height:calc(1rem * 2);height:calc(var(--pfe-theme--container-padding,1rem) * 2);width:1px;position:relative}@media screen and (min-width:768px){:host([vertical]:not([variant=earth])) .tabs-prefix,:host([vertical]:not([variant=earth])) .tabs-suffix{background-color:#d2d2d2;background-color:var(--pfe-tabs__tabs--BorderColor,var(--pfe-theme--color--surface--border,#d2d2d2))}}:host(:not([vertical])[variant=earth]) .tabs-prefix{left:0;top:0;content:" ";height:1px;width:1rem;width:var(--pfe-theme--container-padding,1rem);position:relative}@media screen and (min-width:768px){:host(:not([vertical])[variant=earth]) .tabs-prefix{width:calc(1rem * 2);width:calc(var(--pfe-theme--container-padding,1rem) * 2)}}:host([hidden]){display:none} /*# sourceMappingURL=pfe-tabs.min.css.map */</style>
|
|
1879
|
-
<div class="tabs">
|
|
1880
|
-
<div class="tabs-prefix"></div>
|
|
1881
|
-
<slot name="tab"></slot>
|
|
1882
|
-
<div class="tabs-suffix"></div>
|
|
1883
|
-
</div>
|
|
1884
|
-
<div class="panels">
|
|
1885
|
-
<slot name="panel"></slot>
|
|
1886
|
-
</div>`;
|
|
1887
|
-
}
|
|
1888
|
-
|
|
1889
|
-
static get tag() {
|
|
1890
|
-
return "pfe-tabs";
|
|
1891
|
-
}
|
|
1892
|
-
|
|
1893
|
-
get styleUrl() {
|
|
1894
|
-
return "pfe-tabs.scss";
|
|
1895
|
-
}
|
|
1896
|
-
|
|
1897
|
-
static get meta() {
|
|
1898
|
-
return {
|
|
1899
|
-
title: "Tabs",
|
|
1900
|
-
description: "This element creates a tabbed interface."
|
|
1901
|
-
};
|
|
1902
|
-
}
|
|
1903
|
-
|
|
1904
|
-
get templateUrl() {
|
|
1905
|
-
return "pfe-tabs.html";
|
|
1906
|
-
} // Each set contains a header and a panel
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
static get contentTemplate() {
|
|
1910
|
-
return `
|
|
1911
|
-
<pfe-tab content-type="header" slot="tab"></pfe-tab>
|
|
1912
|
-
<pfe-tab-panel content-type="panel" slot="panel"></pfe-tab-panel>
|
|
1913
|
-
`;
|
|
1914
|
-
}
|
|
1915
|
-
|
|
1916
|
-
static get properties() {
|
|
1917
|
-
return {
|
|
1918
|
-
vertical: {
|
|
1919
|
-
title: "Vertical orientation",
|
|
1920
|
-
type: Boolean,
|
|
1921
|
-
default: false,
|
|
1922
|
-
cascade: "pfe-tab,pfe-tab-panel",
|
|
1923
|
-
observer: "_verticalHandler"
|
|
1924
|
-
},
|
|
1925
|
-
orientation: {
|
|
1926
|
-
title: "Orientation",
|
|
1927
|
-
type: String,
|
|
1928
|
-
attr: "aria-orientation",
|
|
1929
|
-
default: "horizontal",
|
|
1930
|
-
values: ["horizontal", "vertical"]
|
|
1931
|
-
},
|
|
1932
|
-
// Do not set a default of 0, it causes a the URL history to
|
|
1933
|
-
// be updated on load for every tab; infinite looping goodness
|
|
1934
|
-
// Seriously, don't set a default here unless you do a rewrite
|
|
1935
|
-
selectedIndex: {
|
|
1936
|
-
title: "Index of the selected tab",
|
|
1937
|
-
type: Number,
|
|
1938
|
-
observer: "_selectedIndexHandler"
|
|
1939
|
-
},
|
|
1940
|
-
tabAlign: {
|
|
1941
|
-
title: "Tab alignment",
|
|
1942
|
-
type: String,
|
|
1943
|
-
enum: ["center"]
|
|
1944
|
-
},
|
|
1945
|
-
controls: {
|
|
1946
|
-
type: String,
|
|
1947
|
-
attr: "aria-controls"
|
|
1948
|
-
},
|
|
1949
|
-
variant: {
|
|
1950
|
-
title: "Variant",
|
|
1951
|
-
type: String,
|
|
1952
|
-
enum: ["wind", "earth"],
|
|
1953
|
-
default: "wind",
|
|
1954
|
-
cascade: "pfe-tab,pfe-tab-panel"
|
|
1955
|
-
},
|
|
1956
|
-
tabHistory: {
|
|
1957
|
-
title: "Tab History",
|
|
1958
|
-
type: Boolean,
|
|
1959
|
-
default: false,
|
|
1960
|
-
observer: "_tabHistoryHandler"
|
|
1961
|
-
},
|
|
1962
|
-
role: {
|
|
1963
|
-
type: String,
|
|
1964
|
-
default: "tablist"
|
|
1965
|
-
},
|
|
1966
|
-
// @TODO: Deprecated for 1.0
|
|
1967
|
-
oldVariant: {
|
|
1968
|
-
type: String,
|
|
1969
|
-
attr: "pfe-variant",
|
|
1970
|
-
alias: "variant"
|
|
1971
|
-
},
|
|
1972
|
-
// @TODO: Deprecated for 1.0
|
|
1973
|
-
oldTabHistory: {
|
|
1974
|
-
type: Boolean,
|
|
1975
|
-
alias: "tabHistory",
|
|
1976
|
-
attr: "pfe-tab-history"
|
|
1977
|
-
},
|
|
1978
|
-
// @TODO: Deprecated for 1.0
|
|
1979
|
-
oldPfeId: {
|
|
1980
|
-
type: String,
|
|
1981
|
-
attr: "pfe-id",
|
|
1982
|
-
observer: "_oldPfeIdChanged"
|
|
1983
|
-
}
|
|
1984
|
-
};
|
|
1985
|
-
}
|
|
1986
|
-
|
|
1987
|
-
static get slots() {
|
|
1988
|
-
return {
|
|
1989
|
-
tab: {
|
|
1990
|
-
title: "Tab",
|
|
1991
|
-
type: "array",
|
|
1992
|
-
namedSlot: true,
|
|
1993
|
-
items: {
|
|
1994
|
-
$ref: "pfe-tab"
|
|
1995
|
-
}
|
|
1996
|
-
},
|
|
1997
|
-
panel: {
|
|
1998
|
-
title: "Panel",
|
|
1999
|
-
type: "array",
|
|
2000
|
-
namedSlot: true,
|
|
2001
|
-
items: {
|
|
2002
|
-
$ref: "pfe-tab-panel"
|
|
2003
|
-
}
|
|
2004
|
-
}
|
|
2005
|
-
};
|
|
2006
|
-
}
|
|
2007
|
-
|
|
2008
|
-
static get events() {
|
|
2009
|
-
return {
|
|
2010
|
-
hiddenTab: `${this.tag}:hidden-tab`,
|
|
2011
|
-
shownTab: `${this.tag}:shown-tab`
|
|
2012
|
-
};
|
|
2013
|
-
} // Declare the type of this component
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
static get PfeType() {
|
|
2017
|
-
return PFElement.PfeTypes.Combo;
|
|
2018
|
-
}
|
|
2019
|
-
|
|
2020
|
-
constructor() {
|
|
2021
|
-
super(PfeTabs, {
|
|
2022
|
-
type: PfeTabs.PfeType
|
|
2023
|
-
});
|
|
2024
|
-
this._linked = false;
|
|
2025
|
-
this._init = this._init.bind(this);
|
|
2026
|
-
this._onClick = this._onClick.bind(this);
|
|
2027
|
-
this._linkPanels = this._linkPanels.bind(this);
|
|
2028
|
-
this._popstateEventHandler = this._popstateEventHandler.bind(this);
|
|
2029
|
-
this._observer = new MutationObserver(this._init);
|
|
2030
|
-
this._updateHistory = true;
|
|
2031
|
-
}
|
|
2032
|
-
|
|
2033
|
-
connectedCallback() {
|
|
2034
|
-
Promise.all([customElements.whenDefined(PfeTab.tag), customElements.whenDefined(PfeTabPanel.tag)]).then(() => {
|
|
2035
|
-
super.connectedCallback();
|
|
2036
|
-
if (this.hasLightDOM()) this._init();
|
|
2037
|
-
|
|
2038
|
-
this._observer.observe(this, TABS_MUTATION_CONFIG);
|
|
2039
|
-
|
|
2040
|
-
this.addEventListener("keydown", this._onKeyDown);
|
|
2041
|
-
this.addEventListener("click", this._onClick);
|
|
2042
|
-
});
|
|
2043
|
-
}
|
|
2044
|
-
|
|
2045
|
-
disconnectedCallback() {
|
|
2046
|
-
super.disconnectedCallback();
|
|
2047
|
-
this.removeEventListener("keydown", this._onKeyDown);
|
|
2048
|
-
|
|
2049
|
-
this._allTabs().forEach(tab => tab.removeEventListener("click", this._onClick));
|
|
2050
|
-
|
|
2051
|
-
this._observer.disconnect();
|
|
2052
|
-
|
|
2053
|
-
if (this.tabHistory) window.removeEventListener("popstate", this._popstateEventHandler);
|
|
2054
|
-
}
|
|
2055
|
-
|
|
2056
|
-
_verticalHandler() {
|
|
2057
|
-
if (this.vertical) this.orientation = "vertical";else this.orientation = "horizontal";
|
|
2058
|
-
}
|
|
2059
|
-
|
|
2060
|
-
_selectedIndexHandler(oldVal, newVal) {
|
|
2061
|
-
// Wait until the tab and panels are loaded
|
|
2062
|
-
Promise.all([customElements.whenDefined(PfeTab.tag), customElements.whenDefined(PfeTabPanel.tag)]).then(() => {
|
|
2063
|
-
this._linkPanels();
|
|
2064
|
-
|
|
2065
|
-
this.selectIndex(newVal);
|
|
2066
|
-
this._updateHistory = true;
|
|
2067
|
-
});
|
|
2068
|
-
}
|
|
2069
|
-
|
|
2070
|
-
_tabHistoryHandler() {
|
|
2071
|
-
if (!this.tabHistory) window.removeEventListener("popstate", this._popstateEventHandler);else window.addEventListener("popstate", this._popstateEventHandler);
|
|
2072
|
-
}
|
|
2073
|
-
|
|
2074
|
-
_oldPfeIdChanged(oldVal, newVal) {
|
|
2075
|
-
if (!this.id && newVal) this.id = newVal;
|
|
2076
|
-
}
|
|
2077
|
-
|
|
2078
|
-
select(newTab) {
|
|
2079
|
-
if (!newTab) return;
|
|
2080
|
-
|
|
2081
|
-
if (newTab.tagName.toLowerCase() !== PfeTab.tag) {
|
|
2082
|
-
this.warn(`the tab must be a ${PfeTab.tag} element`);
|
|
2083
|
-
return;
|
|
2084
|
-
}
|
|
2085
|
-
|
|
2086
|
-
this.selectedIndex = this._getTabIndex(newTab);
|
|
2087
|
-
}
|
|
2088
|
-
|
|
2089
|
-
selectIndex(_index) {
|
|
2090
|
-
if (_index === undefined || _index === null) return;
|
|
2091
|
-
const index = parseInt(_index, 10);
|
|
2092
|
-
|
|
2093
|
-
const tabs = this._allTabs();
|
|
2094
|
-
|
|
2095
|
-
const tab = tabs[index];
|
|
2096
|
-
|
|
2097
|
-
if (tabs.length > 0 && !tab) {
|
|
2098
|
-
this.warn(`tab ${_index} does not exist`);
|
|
2099
|
-
return;
|
|
2100
|
-
} else if (!tabs && !tab) {
|
|
2101
|
-
// Wait for upgrade?
|
|
2102
|
-
return;
|
|
2103
|
-
}
|
|
2104
|
-
|
|
2105
|
-
if (this.selected && this.tabHistory && this._updateHistory && CAN_USE_URLSEARCHPARAMS) {
|
|
2106
|
-
// @IE11 doesn't support URLSearchParams
|
|
2107
|
-
// https://caniuse.com/#search=urlsearchparams
|
|
2108
|
-
// rebuild the url
|
|
2109
|
-
const pathname = window.location.pathname;
|
|
2110
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
2111
|
-
const hash = window.location.hash;
|
|
2112
|
-
urlParams.set(this.id, tab.id);
|
|
2113
|
-
history.pushState({}, "", `${pathname}?${urlParams.toString()}${hash}`);
|
|
2114
|
-
}
|
|
2115
|
-
|
|
2116
|
-
this._selectTab(tab);
|
|
2117
|
-
|
|
2118
|
-
return tab;
|
|
2119
|
-
}
|
|
2120
|
-
|
|
2121
|
-
_init() {
|
|
2122
|
-
const tabIndexFromURL = this._getTabIndexFromURL();
|
|
2123
|
-
|
|
2124
|
-
this._linked = false;
|
|
2125
|
-
|
|
2126
|
-
this._linkPanels(); // Force role to be set to tablist
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
if (window.ShadyCSS) this._observer.disconnect();
|
|
2130
|
-
this.role = "tablist";
|
|
2131
|
-
|
|
2132
|
-
if (tabIndexFromURL > -1) {
|
|
2133
|
-
this._setFocus = true;
|
|
2134
|
-
this.selectedIndex = tabIndexFromURL;
|
|
2135
|
-
}
|
|
2136
|
-
|
|
2137
|
-
if (this.selectedIndex === null) this.selectedIndex = 0;
|
|
2138
|
-
if (window.ShadyCSS) this._observer.observe(this, TABS_MUTATION_CONFIG);
|
|
2139
|
-
}
|
|
2140
|
-
|
|
2141
|
-
_linkPanels() {
|
|
2142
|
-
if (this._linked) return;
|
|
2143
|
-
if (window.ShadyCSS) this._observer.disconnect();
|
|
2144
|
-
|
|
2145
|
-
this._allTabs().forEach(tab => {
|
|
2146
|
-
const panel = tab.nextElementSibling;
|
|
2147
|
-
|
|
2148
|
-
if (panel.tagName.toLowerCase() !== PfeTabPanel.tag) {
|
|
2149
|
-
this.warn(`not a sibling of a <${PfeTabPanel.tag}>`);
|
|
2150
|
-
return;
|
|
2151
|
-
} // Connect the 2 items via appropriate aria attributes
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
tab.controls = panel.id;
|
|
2155
|
-
panel.labelledby = tab.id;
|
|
2156
|
-
tab.addEventListener("click", this._onClick);
|
|
2157
|
-
});
|
|
2158
|
-
|
|
2159
|
-
this._linked = true;
|
|
2160
|
-
if (window.ShadyCSS) this._observer.observe(this, TABS_MUTATION_CONFIG);
|
|
2161
|
-
}
|
|
2162
|
-
|
|
2163
|
-
_allPanels() {
|
|
2164
|
-
return [...this.children].filter(child => child.matches(PfeTabPanel.tag));
|
|
2165
|
-
}
|
|
2166
|
-
|
|
2167
|
-
_allTabs() {
|
|
2168
|
-
return [...this.children].filter(child => child.matches(PfeTab.tag));
|
|
2169
|
-
}
|
|
2170
|
-
|
|
2171
|
-
_panelForTab(tab) {
|
|
2172
|
-
if (!tab || !tab.controls) return;
|
|
2173
|
-
return this.querySelector(`#${tab.controls}`);
|
|
2174
|
-
}
|
|
2175
|
-
|
|
2176
|
-
_prevTab() {
|
|
2177
|
-
const tabs = this._allTabs();
|
|
2178
|
-
|
|
2179
|
-
let newIdx = tabs.findIndex(tab => tab.selected === "true") - 1;
|
|
2180
|
-
return tabs[(newIdx + tabs.length) % tabs.length];
|
|
2181
|
-
}
|
|
2182
|
-
|
|
2183
|
-
_firstTab() {
|
|
2184
|
-
const tabs = this._allTabs();
|
|
2185
|
-
|
|
2186
|
-
return tabs[0];
|
|
2187
|
-
}
|
|
2188
|
-
|
|
2189
|
-
_lastTab() {
|
|
2190
|
-
const tabs = this._allTabs();
|
|
2191
|
-
|
|
2192
|
-
return tabs[tabs.length - 1];
|
|
2193
|
-
}
|
|
2194
|
-
|
|
2195
|
-
_nextTab() {
|
|
2196
|
-
const tabs = this._allTabs();
|
|
2197
|
-
|
|
2198
|
-
let newIdx = tabs.findIndex(tab => tab.selected === "true") + 1;
|
|
2199
|
-
return tabs[newIdx % tabs.length];
|
|
2200
|
-
}
|
|
2201
|
-
|
|
2202
|
-
_getTabIndex(_tab) {
|
|
2203
|
-
if (_tab) {
|
|
2204
|
-
const tabs = this._allTabs();
|
|
2205
|
-
|
|
2206
|
-
return tabs.findIndex(tab => tab.id === _tab.id);
|
|
2207
|
-
} else {
|
|
2208
|
-
this.warn(`No tab was provided to _getTabIndex; required to return the index value.`);
|
|
2209
|
-
return 0;
|
|
2210
|
-
}
|
|
2211
|
-
}
|
|
2212
|
-
|
|
2213
|
-
reset() {
|
|
2214
|
-
const tabs = this._allTabs();
|
|
2215
|
-
|
|
2216
|
-
const panels = this._allPanels();
|
|
2217
|
-
|
|
2218
|
-
tabs.forEach(tab => tab.selected = "false");
|
|
2219
|
-
panels.forEach(panel => panel.hidden = true);
|
|
2220
|
-
}
|
|
2221
|
-
|
|
2222
|
-
_selectTab(newTab) {
|
|
2223
|
-
if (!newTab) return;
|
|
2224
|
-
this.reset();
|
|
2225
|
-
|
|
2226
|
-
const newPanel = this._panelForTab(newTab);
|
|
2227
|
-
|
|
2228
|
-
let newTabSelected = false;
|
|
2229
|
-
if (!newPanel) this.warn(`No panel was found for the selected tab${newTab.id ? `: pfe-tab#${newTab.id}` : ""}`); // this.selected on tabs contains a pointer to the selected tab element
|
|
2230
|
-
|
|
2231
|
-
if (this.selected && this.selected !== newTab) {
|
|
2232
|
-
newTabSelected = true;
|
|
2233
|
-
this.emitEvent(PfeTabs.events.hiddenTab, {
|
|
2234
|
-
detail: {
|
|
2235
|
-
tab: this.selected
|
|
2236
|
-
}
|
|
2237
|
-
});
|
|
2238
|
-
}
|
|
2239
|
-
|
|
2240
|
-
newTab.selected = "true";
|
|
2241
|
-
newPanel.hidden = false; // Update the value of the selected pointer to the new tab
|
|
2242
|
-
|
|
2243
|
-
this.selected = newTab;
|
|
2244
|
-
|
|
2245
|
-
if (newTabSelected) {
|
|
2246
|
-
if (this._setFocus) newTab.focus();
|
|
2247
|
-
this.emitEvent(PfeTabs.events.shownTab, {
|
|
2248
|
-
detail: {
|
|
2249
|
-
tab: this.selected
|
|
2250
|
-
}
|
|
2251
|
-
});
|
|
2252
|
-
}
|
|
2253
|
-
|
|
2254
|
-
this._setFocus = false;
|
|
2255
|
-
}
|
|
2256
|
-
|
|
2257
|
-
_onKeyDown(event) {
|
|
2258
|
-
const tabs = this._allTabs();
|
|
2259
|
-
|
|
2260
|
-
const foundTab = tabs.find(tab => tab === event.target);
|
|
2261
|
-
|
|
2262
|
-
if (!foundTab) {
|
|
2263
|
-
return;
|
|
2264
|
-
}
|
|
2265
|
-
|
|
2266
|
-
if (event.altKey) {
|
|
2267
|
-
return;
|
|
2268
|
-
}
|
|
2269
|
-
|
|
2270
|
-
let newTab;
|
|
2271
|
-
|
|
2272
|
-
switch (event.keyCode) {
|
|
2273
|
-
case KEYCODE.LEFT:
|
|
2274
|
-
case KEYCODE.UP:
|
|
2275
|
-
newTab = this._prevTab();
|
|
2276
|
-
break;
|
|
2277
|
-
|
|
2278
|
-
case KEYCODE.RIGHT:
|
|
2279
|
-
case KEYCODE.DOWN:
|
|
2280
|
-
newTab = this._nextTab();
|
|
2281
|
-
break;
|
|
2282
|
-
|
|
2283
|
-
case KEYCODE.HOME:
|
|
2284
|
-
newTab = this._firstTab();
|
|
2285
|
-
break;
|
|
2286
|
-
|
|
2287
|
-
case KEYCODE.END:
|
|
2288
|
-
newTab = this._lastTab();
|
|
2289
|
-
break;
|
|
2290
|
-
|
|
2291
|
-
default:
|
|
2292
|
-
return;
|
|
2293
|
-
}
|
|
2294
|
-
|
|
2295
|
-
event.preventDefault();
|
|
2296
|
-
|
|
2297
|
-
if (newTab) {
|
|
2298
|
-
this.selectedIndex = this._getTabIndex(newTab);
|
|
2299
|
-
this._setFocus = true;
|
|
2300
|
-
} else {
|
|
2301
|
-
this.warn(`No new tab could be found.`);
|
|
2302
|
-
}
|
|
2303
|
-
}
|
|
2304
|
-
|
|
2305
|
-
_onClick(event) {
|
|
2306
|
-
// Find the clicked tab
|
|
2307
|
-
const foundTab = this._allTabs().find(tab => tab === event.currentTarget); // If the tab wasn't found in the markup, exit the handler
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
if (!foundTab) return; // Update the selected index to the clicked tab
|
|
2311
|
-
|
|
2312
|
-
this.selectedIndex = this._getTabIndex(event.currentTarget);
|
|
2313
|
-
}
|
|
2314
|
-
|
|
2315
|
-
_getTabIndexFromURL() {
|
|
2316
|
-
let urlParams; // @IE11 doesn't support URLSearchParams
|
|
2317
|
-
// https://caniuse.com/#search=urlsearchparams
|
|
2318
|
-
// @Deprecated in 1.0
|
|
2319
|
-
// the "pfe-" prefix has been deprecated but we'll continue to support it
|
|
2320
|
-
// we'll give priority to the urlParams.has(`${this.id}`) attribute first
|
|
2321
|
-
// and fallback to urlParams.has(`pfe-${this.id}`) if it exists. We should
|
|
2322
|
-
// be able to remove the || part of the if statement in the future
|
|
2323
|
-
|
|
2324
|
-
if (CAN_USE_URLSEARCHPARAMS) {
|
|
2325
|
-
urlParams = new URLSearchParams(window.location.search);
|
|
2326
|
-
const tabsetInUrl = urlParams.has(`${this.id}`) || urlParams.has(`pfe-${this.id}`); // remove this condition when it's no longer used in production
|
|
2327
|
-
|
|
2328
|
-
if (urlParams && tabsetInUrl) {
|
|
2329
|
-
let id = urlParams.get(`${this.id}`) || urlParams.get(`pfe-${this.id}`); // remove this condition when it's no longer used in production
|
|
2330
|
-
|
|
2331
|
-
return this._allTabs().findIndex(tab => tab.id === id);
|
|
2332
|
-
}
|
|
2333
|
-
}
|
|
2334
|
-
|
|
2335
|
-
return -1;
|
|
2336
|
-
}
|
|
2337
|
-
|
|
2338
|
-
_popstateEventHandler() {
|
|
2339
|
-
const tabIndexFromURL = this._getTabIndexFromURL();
|
|
2340
|
-
|
|
2341
|
-
this._updateHistory = false;
|
|
2342
|
-
if (tabIndexFromURL > -1) this.selectedIndex = tabIndexFromURL;
|
|
2343
|
-
}
|
|
2344
|
-
|
|
2345
|
-
}
|
|
2346
|
-
|
|
2347
|
-
PFElement.create(PfeTab);
|
|
2348
|
-
PFElement.create(PfeTabPanel);
|
|
2349
|
-
PFElement.create(PfeTabs);
|
|
2350
|
-
|
|
2351
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
|
|
2352
|
-
|
|
2353
|
-
(function () {
|
|
2354
|
-
if (typeof window.CustomEvent === "function") return false;
|
|
2355
|
-
|
|
2356
|
-
function CustomEvent(event, params) {
|
|
2357
|
-
params = params || {
|
|
2358
|
-
bubbles: false,
|
|
2359
|
-
cancelable: false,
|
|
2360
|
-
detail: null
|
|
2361
|
-
};
|
|
2362
|
-
var evt = document.createEvent("CustomEvent");
|
|
2363
|
-
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
|
|
2364
|
-
return evt;
|
|
2365
|
-
}
|
|
2366
|
-
|
|
2367
|
-
window.CustomEvent = CustomEvent;
|
|
2368
|
-
})();
|
|
2369
|
-
|
|
2370
|
-
class PfeIconSet {
|
|
2371
|
-
/**
|
|
2372
|
-
* Run the icon set's name resolver to turn an icon name into an icon path, id, etc.
|
|
2373
|
-
*/
|
|
2374
|
-
resolveIconName(iconName) {
|
|
2375
|
-
return this._resolveIconName(iconName, this.name, this.path);
|
|
2376
|
-
}
|
|
2377
|
-
/**
|
|
2378
|
-
* Create a new icon set. Icon sets have a name (ie, a namespace). For
|
|
2379
|
-
* example, an icon with a name of "rh-logo" represents a "logo" icon from the
|
|
2380
|
-
* "rh" set. Icon set names are always separated from the rest of the icon
|
|
2381
|
-
* name with a hyphen `-`. This means that set names cannot contain a hyphen.
|
|
2382
|
-
*
|
|
2383
|
-
* @param {String} name the namespace of the icon set
|
|
2384
|
-
* @param {String} path the web-accessible path to the icon set (for instance, a CDN)
|
|
2385
|
-
* @param {Function} resolveIconName an optional function to combine the path and an icon name into a final path. The function will be passed the namespaced icon name (for example, "rh-api" where rh is the namespace and api is the individual icon's name)
|
|
2386
|
-
* @returns {Object} an object with the status of the icon set installation, such as `{ result: true, text: 'icon set installed' }` or `{ result: false, text: 'icon set is already installed' }`
|
|
2387
|
-
*/
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
constructor(name, path, resolveIconName) {
|
|
2391
|
-
this.name = name;
|
|
2392
|
-
this.path = path;
|
|
2393
|
-
this._resolveIconName = resolveIconName;
|
|
2394
|
-
}
|
|
2395
|
-
|
|
2396
|
-
}
|
|
2397
|
-
/**
|
|
2398
|
-
* An 'init' function to add the PFE built-in icon sets to the current page.
|
|
2399
|
-
*/
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
function addBuiltIns({
|
|
2403
|
-
PfeIcon,
|
|
2404
|
-
config
|
|
2405
|
-
}) {
|
|
2406
|
-
// If the user wants to completely opt out of default icon sets,
|
|
2407
|
-
// allow them to.
|
|
2408
|
-
if (config.IconSets && config.IconSets.length === 0) {
|
|
2409
|
-
return;
|
|
2410
|
-
} // If the user provides their own icon sets, use them. If not, use our defaults.
|
|
2411
|
-
// @TODO: Switch from access.redhat.com to another icon set.
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
const iconSets = config.IconSets || [{
|
|
2415
|
-
name: "web",
|
|
2416
|
-
path: "https://access.redhat.com/webassets/avalon/j/lib/rh-iconfont-svgs"
|
|
2417
|
-
}, {
|
|
2418
|
-
name: "rh",
|
|
2419
|
-
path: "https://access.redhat.com/webassets/avalon/j/lib/rh-iconfont-svgs"
|
|
2420
|
-
}];
|
|
2421
|
-
|
|
2422
|
-
let resolveDefaultIconName = (name, iconSetName, iconSetPath) => {
|
|
2423
|
-
const regex = new RegExp(`^${iconSetName}(-icon)?-(.*)`);
|
|
2424
|
-
const [,, iconName] = regex.exec(name);
|
|
2425
|
-
const iconId = `${iconSetName}-icon-${iconName}`;
|
|
2426
|
-
const iconPath = `${iconSetPath}/${iconId}.svg`;
|
|
2427
|
-
return iconPath;
|
|
2428
|
-
}; // Register the icon sets.
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
iconSets.forEach(set => {
|
|
2432
|
-
// If there's a `resolveIconName` function provided, use it. If not, fall back
|
|
2433
|
-
// to the `resolveDefaultIconName` function.
|
|
2434
|
-
if (set.resolveIconName && typeof set.resolveIconName === "function") {
|
|
2435
|
-
resolveDefaultIconName = set.resolveIconName;
|
|
2436
|
-
}
|
|
2437
|
-
|
|
2438
|
-
PfeIcon.addIconSet(set.name, set.path, resolveDefaultIconName);
|
|
2439
|
-
});
|
|
2440
|
-
}
|
|
2441
|
-
/*!
|
|
2442
|
-
* PatternFly Elements: PfeIcon 1.12.3
|
|
2443
|
-
* @license
|
|
2444
|
-
* Copyright 2021 Red Hat, Inc.
|
|
2445
|
-
*
|
|
2446
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
2447
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
2448
|
-
* in the Software without restriction, including without limitation the rights
|
|
2449
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
2450
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
2451
|
-
* furnished to do so, subject to the following conditions:
|
|
2452
|
-
*
|
|
2453
|
-
* The above copyright notice and this permission notice shall be included in
|
|
2454
|
-
* all copies or substantial portions of the Software.
|
|
2455
|
-
*
|
|
2456
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
2457
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
2458
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
2459
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
2460
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
2461
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
2462
|
-
* SOFTWARE.
|
|
2463
|
-
*
|
|
2464
|
-
*/
|
|
2465
|
-
|
|
2466
|
-
/**
|
|
2467
|
-
* Sets the id attribute on the <filter> element and points the CSS `filter` at that id.
|
|
2468
|
-
*/
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
function _setRandomFilterId(el) {
|
|
2472
|
-
const randomId = "filter-" + Math.random().toString().slice(2, 10); // set the CSS filter property to point at the given id
|
|
2473
|
-
|
|
2474
|
-
el.shadowRoot.querySelector("svg image").style.filter = `url(#${randomId})`; // set the id attribute on the SVG filter element to match
|
|
2475
|
-
|
|
2476
|
-
el.shadowRoot.querySelector("svg filter").setAttribute("id", randomId);
|
|
2477
|
-
}
|
|
2478
|
-
|
|
2479
|
-
class PfeIcon extends PFElement {
|
|
2480
|
-
// Injected at build-time
|
|
2481
|
-
static get version() {
|
|
2482
|
-
return "1.12.3";
|
|
2483
|
-
} // Injected at build-time
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
get html() {
|
|
2487
|
-
return `
|
|
2488
|
-
<style>@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host{color:#151515!important}}:host([on=dark]){--pfe-broadcasted--text:var(--pfe-theme--color--text--on-dark, #fff);--pfe-broadcasted--text--muted:var(--pfe-theme--color--text--muted--on-dark, #d2d2d2);--pfe-broadcasted--link:var(--pfe-theme--color--link--on-dark, #73bcf7);--pfe-broadcasted--link--hover:var(--pfe-theme--color--link--hover--on-dark, #bee1f4);--pfe-broadcasted--link--focus:var(--pfe-theme--color--link--focus--on-dark, #bee1f4);--pfe-broadcasted--link--visited:var(--pfe-theme--color--link--visited--on-dark, #bee1f4);--pfe-broadcasted--link-decoration:var(--pfe-theme--link-decoration--on-dark, none);--pfe-broadcasted--link-decoration--hover:var(--pfe-theme--link-decoration--hover--on-dark, underline);--pfe-broadcasted--link-decoration--focus:var(--pfe-theme--link-decoration--focus--on-dark, underline);--pfe-broadcasted--link-decoration--visited:var(--pfe-theme--link-decoration--visited--on-dark, none)}:host([on=saturated]){--pfe-broadcasted--text:var(--pfe-theme--color--text--on-saturated, #fff);--pfe-broadcasted--text--muted:var(--pfe-theme--color--text--muted--on-saturated, #d2d2d2);--pfe-broadcasted--link:var(--pfe-theme--color--link--on-saturated, #fff);--pfe-broadcasted--link--hover:var(--pfe-theme--color--link--hover--on-saturated, #fafafa);--pfe-broadcasted--link--focus:var(--pfe-theme--color--link--focus--on-saturated, #fafafa);--pfe-broadcasted--link--visited:var(--pfe-theme--color--link--visited--on-saturated, #d2d2d2);--pfe-broadcasted--link-decoration:var(--pfe-theme--link-decoration--on-saturated, underline);--pfe-broadcasted--link-decoration--hover:var(--pfe-theme--link-decoration--hover--on-saturated, underline);--pfe-broadcasted--link-decoration--focus:var(--pfe-theme--link-decoration--focus--on-saturated, underline);--pfe-broadcasted--link-decoration--visited:var(--pfe-theme--link-decoration--visited--on-saturated, underline)}:host([on=light]){--pfe-broadcasted--text:var(--pfe-theme--color--text, #151515);--pfe-broadcasted--text--muted:var(--pfe-theme--color--text--muted, #6a6e73);--pfe-broadcasted--link:var(--pfe-theme--color--link, #06c);--pfe-broadcasted--link--hover:var(--pfe-theme--color--link--hover, #004080);--pfe-broadcasted--link--focus:var(--pfe-theme--color--link--focus, #004080);--pfe-broadcasted--link--visited:var(--pfe-theme--color--link--visited, #6753ac);--pfe-broadcasted--link-decoration:var(--pfe-theme--link-decoration, none);--pfe-broadcasted--link-decoration--hover:var(--pfe-theme--link-decoration--hover, underline);--pfe-broadcasted--link-decoration--focus:var(--pfe-theme--link-decoration--focus, underline);--pfe-broadcasted--link-decoration--visited:var(--pfe-theme--link-decoration--visited, none)}:host{--context:var(--pfe-icon--context, light);position:relative;display:inline-block;-webkit-box-sizing:content-box!important;box-sizing:content-box!important;width:-webkit-fit-content!important;width:-moz-fit-content!important;width:fit-content!important;height:-webkit-fit-content!important;height:-moz-fit-content!important;height:fit-content!important;line-height:0;max-width:1em;max-width:var(--pfe-icon--size,var(--pfe-theme--icon-size,1em));max-height:1em;max-height:var(--pfe-icon--size,var(--pfe-theme--icon-size,1em))}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host{width:1em!important;width:var(--pfe-theme--icon-size,1em)!important;height:1em!important;height:var(--pfe-theme--icon-size,1em)!important}}:host svg{width:1em;width:var(--pfe-icon--size,var(--pfe-theme--icon-size,1em));height:1em;height:var(--pfe-icon--size,var(--pfe-theme--icon-size,1em))}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host svg{width:1em!important;width:var(--pfe-theme--icon-size,1em)!important;height:1em!important;height:var(--pfe-theme--icon-size,1em)!important}}:host([block]){display:block;margin-bottom:1rem;margin-bottom:var(--pfe-icon--spacing,var(--pfe-theme--container-spacer,1rem));margin-top:1rem;margin-top:var(--pfe-icon--spacing,var(--pfe-theme--container-spacer,1rem))}:host([block]):first-child{margin-top:0}:host(:not(.load-failed)){vertical-align:middle;border-radius:50%;background-color:transparent;background-color:var(--pfe-icon--BackgroundColor,transparent);border:1px solid transparent;border:var(--pfe-icon--BorderWidth,var(--pfe-theme--ui--border-width,1px)) var(--pfe-theme--ui--border-style,solid) var(--pfe-icon--BorderColor,var(--pfe-icon--BackgroundColor,transparent));padding:0;padding:var(--pfe-icon--Padding,0)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host(:not(.load-failed)){background-color:#fff!important}:host(:not(.load-failed)) svg filter feFlood{flood-color:#000!important}}@supports (-ms-accelerator:true){:host(:not(.load-failed)){background-color:#fff!important}:host(:not(.load-failed)) svg filter feFlood{flood-color:#000!important}}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host(:not(.load-failed)) svg image{-webkit-filter:none;filter:none}}:host(:not(.load-failed)) filter feFlood{flood-color:#3c3f42;flood-color:var(--pfe-icon--color,var(--pfe-icon--Color,var(--pfe-broadcasted--text,#3c3f42)))}:host(:not(.load-failed)) .pfe-icon--fallback{display:none}:host([size="2x"]){max-width:2em;max-width:var(--pfe-icon--size,2em);max-height:2em;max-height:var(--pfe-icon--size,2em)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([size="2x"]){width:2em!important;height:2em!important}}:host([size="2x"]) svg{width:2em;width:var(--pfe-icon--size,2em);height:2em;height:var(--pfe-icon--size,2em)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([size="2x"]) svg{width:2em!important;height:2em!important}}:host([size="3x"]){max-width:3em;max-width:var(--pfe-icon--size,3em);max-height:3em;max-height:var(--pfe-icon--size,3em)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([size="3x"]){width:3em!important;height:3em!important}}:host([size="3x"]) svg{width:3em;width:var(--pfe-icon--size,3em);height:3em;height:var(--pfe-icon--size,3em)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([size="3x"]) svg{width:3em!important;height:3em!important}}:host([size="4x"]){max-width:4em;max-width:var(--pfe-icon--size,4em);max-height:4em;max-height:var(--pfe-icon--size,4em)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([size="4x"]){width:4em!important;height:4em!important}}:host([size="4x"]) svg{width:4em;width:var(--pfe-icon--size,4em);height:4em;height:var(--pfe-icon--size,4em)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([size="4x"]) svg{width:4em!important;height:4em!important}}:host([size=xl]){max-width:100px;max-width:var(--pfe-icon--size,100px);max-height:100px;max-height:var(--pfe-icon--size,100px)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([size=xl]){width:100px!important;height:100px!important}}:host([size=xl]) svg{width:100px;width:var(--pfe-icon--size,100px);height:100px;height:var(--pfe-icon--size,100px)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([size=xl]) svg{width:100px!important;height:100px!important}}:host([size=lg]){max-width:64px;max-width:var(--pfe-icon--size,64px);max-height:64px;max-height:var(--pfe-icon--size,64px)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([size=lg]){width:64px!important;height:64px!important}}:host([size=lg]) svg{width:64px;width:var(--pfe-icon--size,64px);height:64px;height:var(--pfe-icon--size,64px)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([size=lg]) svg{width:64px!important;height:64px!important}}:host([size=md]){max-width:32px;max-width:var(--pfe-icon--size,32px);max-height:32px;max-height:var(--pfe-icon--size,32px)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([size=md]){width:32px!important;height:32px!important}}:host([size=md]) svg{width:32px;width:var(--pfe-icon--size,32px);height:32px;height:var(--pfe-icon--size,32px)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([size=md]) svg{width:32px!important;height:32px!important}}:host([size=sm]){max-width:14px;max-width:var(--pfe-icon--size,14px);max-height:14px;max-height:var(--pfe-icon--size,14px)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([size=sm]){width:14px!important;height:14px!important}}:host([size=sm]) svg{width:14px;width:var(--pfe-icon--size,14px);height:14px;height:var(--pfe-icon--size,14px)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host([size=sm]) svg{width:14px!important;height:14px!important}}:host([circled]:not([circled=false])){padding:.5em;padding:var(--pfe-icon--Padding,.5em);background-color:#fff;background-color:var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--surface--lightest,#fff));border-color:#d2d2d2;border-color:var(--pfe-icon--BorderColor,var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--surface--border,#d2d2d2)))}:host([color=critical]:not([circled])) filter feFlood,:host([color=critical][circled=false]) filter feFlood{flood-color:#a30000;flood-color:var(--pfe-icon--color,var(--pfe-icon--Color,var(--pfe-theme--color--feedback--critical,#a30000)))}:host([color=critical][circled]:not([circled=false])){background-color:#a30000;background-color:var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--feedback--critical,#a30000));border-color:#a30000;border-color:var(--pfe-icon--BorderColor,var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--feedback--critical,#a30000)));--pfe-icon--context:dark}:host([color=important]:not([circled])) filter feFlood,:host([color=important][circled=false]) filter feFlood{flood-color:#c9190b;flood-color:var(--pfe-icon--color,var(--pfe-icon--Color,var(--pfe-theme--color--feedback--important,#c9190b)))}:host([color=important][circled]:not([circled=false])){background-color:#c9190b;background-color:var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--feedback--important,#c9190b));border-color:#c9190b;border-color:var(--pfe-icon--BorderColor,var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--feedback--important,#c9190b)));--pfe-icon--context:dark}:host([color=moderate]:not([circled])) filter feFlood,:host([color=moderate][circled=false]) filter feFlood{flood-color:#f0ab00;flood-color:var(--pfe-icon--color,var(--pfe-icon--Color,var(--pfe-theme--color--feedback--moderate,#f0ab00)))}:host([color=moderate][circled]:not([circled=false])){background-color:#f0ab00;background-color:var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--feedback--moderate,#f0ab00));border-color:#f0ab00;border-color:var(--pfe-icon--BorderColor,var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--feedback--moderate,#f0ab00)))}:host([color=success]:not([circled])) filter feFlood,:host([color=success][circled=false]) filter feFlood{flood-color:#3e8635;flood-color:var(--pfe-icon--color,var(--pfe-icon--Color,var(--pfe-theme--color--feedback--success,#3e8635)))}:host([color=success][circled]:not([circled=false])){background-color:#3e8635;background-color:var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--feedback--success,#3e8635));border-color:#3e8635;border-color:var(--pfe-icon--BorderColor,var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--feedback--success,#3e8635)));--pfe-icon--context:dark}:host([color=info]:not([circled])) filter feFlood,:host([color=info][circled=false]) filter feFlood{flood-color:#06c;flood-color:var(--pfe-icon--color,var(--pfe-icon--Color,var(--pfe-theme--color--feedback--info,#06c)))}:host([color=info][circled]:not([circled=false])){background-color:#06c;background-color:var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--feedback--info,#06c));border-color:#06c;border-color:var(--pfe-icon--BorderColor,var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--feedback--info,#06c)));--pfe-icon--context:dark}:host([color=default]:not([circled])) filter feFlood,:host([color=default][circled=false]) filter feFlood{flood-color:#4f5255;flood-color:var(--pfe-icon--color,var(--pfe-icon--Color,var(--pfe-theme--color--feedback--default,#4f5255)))}:host([color=default][circled]:not([circled=false])){background-color:#4f5255;background-color:var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--feedback--default,#4f5255));border-color:#4f5255;border-color:var(--pfe-icon--BorderColor,var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--feedback--default,#4f5255)));--pfe-icon--context:dark}:host([color=lightest]:not([circled])) filter feFlood,:host([color=lightest][circled=false]) filter feFlood{flood-color:#fff;flood-color:var(--pfe-icon--color,var(--pfe-icon--Color,var(--pfe-theme--color--surface--lightest,#fff)))}:host([color=lightest][circled]:not([circled=false])){--pfe-icon--context:var(--pfe-theme--color--surface--lightest--context, light);background-color:#fff;background-color:var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--surface--lightest,#fff));border-color:#fff;border-color:var(--pfe-icon--BorderColor,var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--surface--lightest,#fff)))}:host([color=base]:not([circled])) filter feFlood,:host([color=base][circled=false]) filter feFlood{flood-color:#f0f0f0;flood-color:var(--pfe-icon--color,var(--pfe-icon--Color,var(--pfe-theme--color--surface--base,#f0f0f0)))}:host([color=base][circled]:not([circled=false])){--pfe-icon--context:var(--pfe-theme--color--surface--base--context, light);background-color:#f0f0f0;background-color:var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--surface--base,#f0f0f0));border-color:#f0f0f0;border-color:var(--pfe-icon--BorderColor,var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--surface--base,#f0f0f0)))}:host([color=darker]:not([circled])) filter feFlood,:host([color=darker][circled=false]) filter feFlood{flood-color:#3c3f42;flood-color:var(--pfe-icon--color,var(--pfe-icon--Color,var(--pfe-theme--color--surface--darker,#3c3f42)))}:host([color=darker][circled]:not([circled=false])){--pfe-icon--context:var(--pfe-theme--color--surface--darker--context, dark);background-color:#3c3f42;background-color:var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--surface--darker,#3c3f42));border-color:#3c3f42;border-color:var(--pfe-icon--BorderColor,var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--surface--darker,#3c3f42)))}:host([color=darkest]:not([circled])) filter feFlood,:host([color=darkest][circled=false]) filter feFlood{flood-color:#151515;flood-color:var(--pfe-icon--color,var(--pfe-icon--Color,var(--pfe-theme--color--surface--darkest,#151515)))}:host([color=darkest][circled]:not([circled=false])){--pfe-icon--context:var(--pfe-theme--color--surface--darkest--context, dark);background-color:#151515;background-color:var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--surface--darkest,#151515));border-color:#151515;border-color:var(--pfe-icon--BorderColor,var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--surface--darkest,#151515)))}:host([color=complement]:not([circled])) filter feFlood,:host([color=complement][circled=false]) filter feFlood{flood-color:#002952;flood-color:var(--pfe-icon--color,var(--pfe-icon--Color,var(--pfe-theme--color--surface--complement,#002952)))}:host([color=complement][circled]:not([circled=false])){--pfe-icon--context:var(--pfe-theme--color--surface--complement--context, saturated);background-color:#002952;background-color:var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--surface--complement,#002952));border-color:#002952;border-color:var(--pfe-icon--BorderColor,var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--surface--complement,#002952)))}:host([color=accent]:not([circled])) filter feFlood,:host([color=accent][circled=false]) filter feFlood{flood-color:#004080;flood-color:var(--pfe-icon--color,var(--pfe-icon--Color,var(--pfe-theme--color--surface--accent,#004080)))}:host([color=accent][circled]:not([circled=false])){--pfe-icon--context:var(--pfe-theme--color--surface--accent--context, saturated);background-color:#004080;background-color:var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--surface--accent,#004080));border-color:#004080;border-color:var(--pfe-icon--BorderColor,var(--pfe-icon--BackgroundColor,var(--pfe-theme--color--surface--accent,#004080)))}:host(.load-failed) svg image,:host(.load-failed.has-fallback) svg,:host(.load-failed[on-fail=collapse]) svg{display:none}:host(.load-failed[on-fail=collapse]){max-width:0;max-width:var(--pfe-icon--size,0);max-height:0;max-height:var(--pfe-icon--size,0)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host(.load-failed[on-fail=collapse]){width:0!important;height:0!important}}:host(.load-failed[on-fail=collapse]) svg{width:0;width:var(--pfe-icon--size,0);height:0;height:var(--pfe-icon--size,0)}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){:host(.load-failed[on-fail=collapse]) svg{width:0!important;height:0!important}} /*# sourceMappingURL=pfe-icon.min.css.map */</style>
|
|
2489
|
-
<div class="pfe-icon--fallback">
|
|
2490
|
-
<slot></slot>
|
|
2491
|
-
</div>
|
|
2492
|
-
<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20">
|
|
2493
|
-
<filter color-interpolation-filters="sRGB" x="0" y="0" height="100%" width="100%">
|
|
2494
|
-
<feFlood result="COLOR" />
|
|
2495
|
-
<feComposite operator="in" in="COLOR" in2="SourceAlpha" />
|
|
2496
|
-
</filter>
|
|
2497
|
-
<image xlink:href="" width="100%" height="100%"></image>
|
|
2498
|
-
</svg>`;
|
|
2499
|
-
}
|
|
2500
|
-
|
|
2501
|
-
static get tag() {
|
|
2502
|
-
return "pfe-icon";
|
|
2503
|
-
}
|
|
2504
|
-
|
|
2505
|
-
get templateUrl() {
|
|
2506
|
-
return "pfe-icon.html";
|
|
2507
|
-
}
|
|
2508
|
-
|
|
2509
|
-
get styleUrl() {
|
|
2510
|
-
return "pfe-icon.scss";
|
|
2511
|
-
}
|
|
2512
|
-
|
|
2513
|
-
get schemaUrl() {
|
|
2514
|
-
return "pfe-icon.json";
|
|
2515
|
-
} // Declare the type of this component
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
static get PfeType() {
|
|
2519
|
-
return PFElement.PfeTypes.Content;
|
|
2520
|
-
}
|
|
2521
|
-
|
|
2522
|
-
static get properties() {
|
|
2523
|
-
return {
|
|
2524
|
-
icon: {
|
|
2525
|
-
type: String,
|
|
2526
|
-
observer: "updateIcon",
|
|
2527
|
-
prefix: false
|
|
2528
|
-
},
|
|
2529
|
-
size: {
|
|
2530
|
-
type: String,
|
|
2531
|
-
values: ["xl", "lg", "md", "sm", "1x", "2x", "3x", "4x"],
|
|
2532
|
-
default: "1x"
|
|
2533
|
-
},
|
|
2534
|
-
color: {
|
|
2535
|
-
type: String,
|
|
2536
|
-
values: ["complement", "accent", "lightest", "base", "darker", "darkest", "critical", "important", "moderate", "success", "info"],
|
|
2537
|
-
observer: "_colorChanged"
|
|
2538
|
-
},
|
|
2539
|
-
onFail: {
|
|
2540
|
-
type: String,
|
|
2541
|
-
values: ["collapse"]
|
|
2542
|
-
},
|
|
2543
|
-
circled: {
|
|
2544
|
-
type: Boolean
|
|
2545
|
-
},
|
|
2546
|
-
block: {
|
|
2547
|
-
type: Boolean
|
|
2548
|
-
},
|
|
2549
|
-
// TODO: Deprecated for 1.0
|
|
2550
|
-
oldColor: {
|
|
2551
|
-
type: String,
|
|
2552
|
-
alias: "color",
|
|
2553
|
-
attr: "pfe-color"
|
|
2554
|
-
},
|
|
2555
|
-
// TODO: Deprecated for 1.0
|
|
2556
|
-
oldSize: {
|
|
2557
|
-
type: String,
|
|
2558
|
-
alias: "size",
|
|
2559
|
-
attr: "pfe-size"
|
|
2560
|
-
},
|
|
2561
|
-
// TODO: Deprecated for 1.0
|
|
2562
|
-
oldCircled: {
|
|
2563
|
-
type: Boolean,
|
|
2564
|
-
alias: "circled",
|
|
2565
|
-
attr: "pfe-circled"
|
|
2566
|
-
},
|
|
2567
|
-
// TODO: Deprecated for 1.0
|
|
2568
|
-
oldBlock: {
|
|
2569
|
-
type: Boolean,
|
|
2570
|
-
alias: "block",
|
|
2571
|
-
attr: "data-block"
|
|
2572
|
-
}
|
|
2573
|
-
};
|
|
2574
|
-
}
|
|
2575
|
-
|
|
2576
|
-
static get EVENTS() {
|
|
2577
|
-
return {
|
|
2578
|
-
ADD_ICON_SET: `${this.tag}:add-icon-set`
|
|
2579
|
-
};
|
|
2580
|
-
}
|
|
2581
|
-
|
|
2582
|
-
get upgraded() {
|
|
2583
|
-
return this.image.hasAttribute("xlink:href");
|
|
2584
|
-
}
|
|
2585
|
-
|
|
2586
|
-
_iconLoad() {
|
|
2587
|
-
this.classList.remove("load-failed");
|
|
2588
|
-
}
|
|
2589
|
-
|
|
2590
|
-
_iconLoadError(e) {
|
|
2591
|
-
this.classList.add("load-failed");
|
|
2592
|
-
if (this.hasLightDOM()) this.classList.add("has-fallback");
|
|
2593
|
-
}
|
|
2594
|
-
|
|
2595
|
-
_colorChanged() {
|
|
2596
|
-
// Update the context
|
|
2597
|
-
this.resetContext();
|
|
2598
|
-
}
|
|
2599
|
-
|
|
2600
|
-
constructor() {
|
|
2601
|
-
super(PfeIcon, {
|
|
2602
|
-
type: PfeIcon.PfeType
|
|
2603
|
-
});
|
|
2604
|
-
this._iconLoad = this._iconLoad.bind(this);
|
|
2605
|
-
this._iconLoadError = this._iconLoadError.bind(this);
|
|
2606
|
-
this.image = this.shadowRoot.querySelector("svg image");
|
|
2607
|
-
|
|
2608
|
-
if (this.image) {
|
|
2609
|
-
this.image.addEventListener("load", this._iconLoad);
|
|
2610
|
-
this.image.addEventListener("error", this._iconLoadError);
|
|
2611
|
-
} // Attach a listener for the registration of an icon set
|
|
2612
|
-
// Leaving this attached allows for the registered set to be updated
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
document.body.addEventListener(PfeIcon.EVENTS.ADD_ICON_SET, () => this.updateIcon());
|
|
2616
|
-
}
|
|
2617
|
-
|
|
2618
|
-
disconnectedCallback() {
|
|
2619
|
-
super.disconnectedCallback();
|
|
2620
|
-
|
|
2621
|
-
if (this.image) {
|
|
2622
|
-
this.image.removeEventListener("load", this._iconLoad);
|
|
2623
|
-
this.image.removeEventListener("error", this._iconLoadError);
|
|
2624
|
-
}
|
|
2625
|
-
}
|
|
2626
|
-
|
|
2627
|
-
updateIcon() {
|
|
2628
|
-
const {
|
|
2629
|
-
set
|
|
2630
|
-
} = PfeIcon.getIconSet(this.icon);
|
|
2631
|
-
|
|
2632
|
-
if (set) {
|
|
2633
|
-
const iconPath = set.resolveIconName(this.icon);
|
|
2634
|
-
this.image.setAttribute("xlink:href", iconPath);
|
|
2635
|
-
|
|
2636
|
-
_setRandomFilterId(this);
|
|
2637
|
-
}
|
|
2638
|
-
}
|
|
2639
|
-
/**
|
|
2640
|
-
* Get an icon set by providing the set's name, _or_ the name of an icon from that set.
|
|
2641
|
-
*
|
|
2642
|
-
* @param {String} iconName the name of the set, or the name of an icon from that set.
|
|
2643
|
-
* @return {PfeIconSet} the icon set
|
|
2644
|
-
*/
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
static getIconSet(iconName) {
|
|
2648
|
-
let set;
|
|
2649
|
-
|
|
2650
|
-
if (iconName) {
|
|
2651
|
-
const [setName] = iconName.split("-");
|
|
2652
|
-
set = this._iconSets[setName];
|
|
2653
|
-
}
|
|
2654
|
-
|
|
2655
|
-
return {
|
|
2656
|
-
set
|
|
2657
|
-
};
|
|
2658
|
-
}
|
|
2659
|
-
|
|
2660
|
-
static addIconSet(name, path, resolveIconName) {
|
|
2661
|
-
let resolveFunction;
|
|
2662
|
-
|
|
2663
|
-
if (typeof resolveIconName === "function") {
|
|
2664
|
-
resolveFunction = resolveIconName;
|
|
2665
|
-
} else if (typeof resolveIconName === "undefined" && this._iconSets[name] && typeof this._iconSets[name]._resolveIconName === "function") {
|
|
2666
|
-
resolveFunction = this._iconSets[name]._resolveIconName;
|
|
2667
|
-
} else if (typeof resolveIconName !== "function" && typeof resolveIconName !== "undefined") {
|
|
2668
|
-
PfeIcon.warn(`[${this.tag}]: The third input to addIconSet should be a function that parses and returns the icon's filename.`);
|
|
2669
|
-
} else {
|
|
2670
|
-
PfeIcon.warn(`[${this.tag}]: The set ${name} needs a resolve function for the icon names.`);
|
|
2671
|
-
} // Register the icon set and set up the event indicating the change
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
this._iconSets[name] = new PfeIconSet(name, path, resolveFunction);
|
|
2675
|
-
document.body.dispatchEvent(new CustomEvent(this.EVENTS.ADD_ICON_SET, {
|
|
2676
|
-
bubbles: false,
|
|
2677
|
-
detail: {
|
|
2678
|
-
set: this._iconSets[name]
|
|
2679
|
-
}
|
|
2680
|
-
}));
|
|
2681
|
-
}
|
|
2682
|
-
|
|
2683
|
-
}
|
|
2684
|
-
|
|
2685
|
-
PfeIcon._iconSets = {}; // Allow the user to supply their own icon sets via config.
|
|
2686
|
-
// See more in the pfe-icon README.md.
|
|
2687
|
-
|
|
2688
|
-
const config = PFElement.config;
|
|
2689
|
-
addBuiltIns({
|
|
2690
|
-
PfeIcon,
|
|
2691
|
-
config
|
|
2692
|
-
});
|
|
2693
|
-
PFElement.create(PfeIcon);
|
|
15
|
+
var css_248z = ".vulnerabilities-table .impact-icon {\n font-size: 1.5rem;\n padding-right: 0.5rem; }\n .vulnerabilities-table .impact-icon.color-critical {\n color: #a30000; }\n .vulnerabilities-table .impact-icon.color-important {\n color: #ec7a08; }\n .vulnerabilities-table .impact-icon.color-moderate {\n color: #f5c12e; }\n .vulnerabilities-table .impact-icon.color-low {\n color: #777; }\n\n.vulnerabilities-table__affected-packages-cell {\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap; }\n\n.vulnerabilities-table__impact-cell {\n display: flex;\n align-items: center;\n flex-wrap: nowrap; }\n\n.filterable-table {\n padding-bottom: var(--pf-global--spacer--lg); }\n .filterable-table__bottom-pagination[class] {\n margin-top: 1rem; }\n .filterable-table .pf-c-toolbar {\n padding-top: 0; }\n .filterable-table .pf-c-toolbar__content {\n --pf-c-toolbar__content--PaddingRight: 0;\n --pf-c-toolbar__content--PaddingLeft: 0; }\n .filterable-table .pf-c-input-group__text {\n --pf-c-input-group__text--PaddingRight: 0; }\n .filterable-table .pf-c-pagination.pf-m-bottom {\n --pf-c-pagination--m-bottom--md--PaddingRight: 0; }\n\n.packages-table .pf-c-tabs__item > button {\n padding: 1rem 1.5rem; }\n\n.packages-table__excluded-packages-disclaimer {\n margin: 1rem 0 0 0.5rem; }\n\n.filter-input {\n width: 18rem;\n margin: 1rem 0 1rem 0; }\n";
|
|
2694
16
|
|
|
2695
17
|
/*! *****************************************************************************
|
|
2696
18
|
Copyright (c) Microsoft Corporation.
|
|
@@ -3903,7 +1225,17 @@ const SearchIconConfig = {
|
|
|
3903
1225
|
|
|
3904
1226
|
const SearchIcon = createIcon(SearchIconConfig);
|
|
3905
1227
|
|
|
3906
|
-
|
|
1228
|
+
const SecurityIconConfig = {
|
|
1229
|
+
name: 'SecurityIcon',
|
|
1230
|
+
height: 1024,
|
|
1231
|
+
width: 896,
|
|
1232
|
+
svgPath: 'M861.5,0 L34.5,0 C15.4,0 0,14.3 0,32 L0,452.1 C0,768 387.7,1024 448.5,1024 C509.3,1024 896,768 896,452.2 L896,32 C896,14.3 880.6,0 861.5,0 Z M490.7,768 L405.3,768 C393.5,767.8 384.2,757.5 384,744.7 L384,663.3 C384.2,650.5 393.6,640.3 405.3,640 L490.7,640 C502.5,640.2 511.8,650.5 512,663.3 L512,744.7 L512.1,744.7 C511.8,757.5 502.4,767.8 490.7,768 Z M543.9,162.7 L517.2,514.4 C515.8,530.9 502,544 485.3,544 L410.6,544 C394,544 380.1,531.2 378.7,514.7 L352.1,163 C350.5,144.3 365.3,128.3 384,128.3 L512,128 C530.7,128 545.4,144 543.9,162.7 Z',
|
|
1233
|
+
yOffset: 0,
|
|
1234
|
+
xOffset: 0,
|
|
1235
|
+
};
|
|
1236
|
+
|
|
1237
|
+
const SecurityIcon = createIcon(SecurityIconConfig);
|
|
1238
|
+
|
|
3907
1239
|
const DEFAULT_PAGE = 1;
|
|
3908
1240
|
const DEFAULT_PERPAGE = 10;
|
|
3909
1241
|
function FilterableTable({
|
|
@@ -4030,10 +1362,15 @@ function FilterableTable({
|
|
|
4030
1362
|
}, renderPagination('top'))));
|
|
4031
1363
|
return React__default.createElement("div", {
|
|
4032
1364
|
className: 'filterable-table'
|
|
4033
|
-
}, isLoading ? React__default.createElement(Bullseye,
|
|
4034
|
-
|
|
1365
|
+
}, isLoading ? React__default.createElement(Bullseye, {
|
|
1366
|
+
style: {
|
|
1367
|
+
minHeight: '15rem'
|
|
1368
|
+
}
|
|
1369
|
+
}, React__default.createElement("div", null, React__default.createElement(Title, {
|
|
1370
|
+
headingLevel: 'h3'
|
|
1371
|
+
}, React__default.createElement(Spinner, {
|
|
4035
1372
|
size: 'lg'
|
|
4036
|
-
}))) : React__default.createElement(React__default.Fragment, null, header, React__default.createElement(TableComposable, {
|
|
1373
|
+
})))) : React__default.createElement(React__default.Fragment, null, header, React__default.createElement(TableComposable, {
|
|
4037
1374
|
"aria-label": 'Packages Table'
|
|
4038
1375
|
}, React__default.createElement(Thead, null, React__default.createElement(Tr, null, columns.map((col, colIdx) => React__default.createElement(Th, Object.assign({
|
|
4039
1376
|
key: `pkg-table-head-${colIdx}`
|
|
@@ -4051,14 +1388,14 @@ function FilterableTable({
|
|
|
4051
1388
|
return React__default.createElement(Td, {
|
|
4052
1389
|
key: `pkg-table-row-${rowIdx}-col-${colIdx}`
|
|
4053
1390
|
}, (_renderRow = renderRow(row)) == null ? void 0 : _renderRow[colIdx]);
|
|
4054
|
-
}))) : React__default.createElement(Td, {
|
|
1391
|
+
}))) : React__default.createElement(Tr, null, React__default.createElement(Td, {
|
|
4055
1392
|
colSpan: columns.length
|
|
4056
1393
|
}, React__default.createElement(EmptyState, null, React__default.createElement(EmptyStateIcon, {
|
|
4057
1394
|
icon: SearchIcon
|
|
4058
1395
|
}), React__default.createElement(Title, {
|
|
4059
1396
|
headingLevel: 'h5',
|
|
4060
1397
|
size: 'lg'
|
|
4061
|
-
}, "No results found")))))), renderPagination('bottom'));
|
|
1398
|
+
}, "No results found"))))))), renderPagination('bottom'));
|
|
4062
1399
|
}
|
|
4063
1400
|
|
|
4064
1401
|
const FilterInput = ({
|
|
@@ -4078,9 +1415,8 @@ const FilterInput = ({
|
|
|
4078
1415
|
|
|
4079
1416
|
return React__default.createElement("div", {
|
|
4080
1417
|
className: 'filter-input'
|
|
4081
|
-
}, React__default.createElement(
|
|
1418
|
+
}, React__default.createElement(SearchInput, {
|
|
4082
1419
|
value: searchStr,
|
|
4083
|
-
type: 'text',
|
|
4084
1420
|
placeholder: placeholder,
|
|
4085
1421
|
onChange: onChange,
|
|
4086
1422
|
"aria-label": 'Text input filter',
|
|
@@ -4091,14 +1427,8 @@ const FilterInput = ({
|
|
|
4091
1427
|
onClick: event => {
|
|
4092
1428
|
event.stopPropagation();
|
|
4093
1429
|
event.preventDefault();
|
|
4094
|
-
}
|
|
4095
|
-
|
|
4096
|
-
class: 'clear-icon action-icon',
|
|
4097
|
-
icon: 'fas-times',
|
|
4098
|
-
onClick: event => onChange('', event)
|
|
4099
|
-
}), React__default.createElement("pfe-icon", {
|
|
4100
|
-
class: 'search-icon action-icon',
|
|
4101
|
-
icon: 'fas-search-solid'
|
|
1430
|
+
},
|
|
1431
|
+
onClear: event => onChange("", event)
|
|
4102
1432
|
}));
|
|
4103
1433
|
};
|
|
4104
1434
|
|
|
@@ -4171,10 +1501,8 @@ function EcoSelect({
|
|
|
4171
1501
|
|
|
4172
1502
|
const onSelect = (event, selection) => {
|
|
4173
1503
|
const result = selected.includes(selection) ? selected.filter(item => item !== selection) : [selection, ...selected];
|
|
4174
|
-
setSelected(
|
|
4175
|
-
|
|
4176
|
-
return result;
|
|
4177
|
-
});
|
|
1504
|
+
setSelected(result);
|
|
1505
|
+
onChange && onChange(result, event);
|
|
4178
1506
|
};
|
|
4179
1507
|
|
|
4180
1508
|
const id = uniqueId('select-');
|
|
@@ -4227,10 +1555,8 @@ const VulnerabilitiesTable = ({
|
|
|
4227
1555
|
}) => {
|
|
4228
1556
|
return React__default.createElement(React__default.Fragment, null, React__default.createElement("div", {
|
|
4229
1557
|
className: 'vulnerabilities-table__impact-cell'
|
|
4230
|
-
}, React__default.createElement(
|
|
4231
|
-
|
|
4232
|
-
className: `color-${severity.toLowerCase()}`,
|
|
4233
|
-
icon: 'fas-shield-fill-exclamation'
|
|
1558
|
+
}, React__default.createElement(SecurityIcon, {
|
|
1559
|
+
className: `impact-icon color-${severity.toLowerCase()}`
|
|
4234
1560
|
}), React__default.createElement("span", null, severity)));
|
|
4235
1561
|
};
|
|
4236
1562
|
|
|
@@ -4299,7 +1625,7 @@ const VulnerabilitiesTable = ({
|
|
|
4299
1625
|
};
|
|
4300
1626
|
|
|
4301
1627
|
const onStatusFilterChange = (selected, vulnerability) => {
|
|
4302
|
-
return selected === 'fixed' ? vulnerability
|
|
1628
|
+
return selected === 'fixed' ? !!(vulnerability != null && vulnerability.advisory_id) : selected === 'unfixed' ? !(vulnerability != null && vulnerability.advisory_id) : true;
|
|
4303
1629
|
};
|
|
4304
1630
|
|
|
4305
1631
|
const onImpactFilterChange = (selected, vulnerability) => {
|
|
@@ -4376,10 +1702,6 @@ const severitySortOrder = {
|
|
|
4376
1702
|
Moderate: 3,
|
|
4377
1703
|
Low: 4
|
|
4378
1704
|
};
|
|
4379
|
-
PfeIcon.addIconSet('fas', './img', (iconName, _, path) => {
|
|
4380
|
-
const name = iconName.replace('fas-', '');
|
|
4381
|
-
return `${path}/${name}.svg`;
|
|
4382
|
-
});
|
|
4383
1705
|
|
|
4384
1706
|
const InsertCss = () => {
|
|
4385
1707
|
const styleId = 'example-component-styles';
|
|
@@ -4399,6 +1721,7 @@ const PackagesTable = ({
|
|
|
4399
1721
|
}) => {
|
|
4400
1722
|
const [excludedPackages, setExcludedPackages] = React.useState([]);
|
|
4401
1723
|
const [uniqueVulnerabilities, setUniqueVulnerabilities] = React.useState([]);
|
|
1724
|
+
const [activeKey, setActiveKey] = React.useState(0);
|
|
4402
1725
|
React.useEffect(() => {
|
|
4403
1726
|
const VALID_REDHAT_GPG_KEYS = ['199e2f91fd431d51', '5326810137017186', '45689c882fa658e0', '219180cddb42a60e', '7514f77d8366b0d9', 'fd372689897da07a', '938a80caf21541eb', '08b871e6a5787476'];
|
|
4404
1727
|
|
|
@@ -4431,30 +1754,27 @@ const PackagesTable = ({
|
|
|
4431
1754
|
InsertCss();
|
|
4432
1755
|
return React.createElement(React.Fragment, null, (uniqueVulnerabilities.length > 0 || excludedPackages.length > 0) && React.createElement("div", {
|
|
4433
1756
|
className: 'packages-table'
|
|
4434
|
-
}, React.createElement(
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
},
|
|
4441
|
-
|
|
4442
|
-
|
|
1757
|
+
}, React.createElement(Tabs, {
|
|
1758
|
+
activeKey: activeKey,
|
|
1759
|
+
onSelect: (_evt, tabKey) => setActiveKey(tabKey),
|
|
1760
|
+
variant: 'default',
|
|
1761
|
+
isBox: true,
|
|
1762
|
+
"aria-label": 'vulnerability tab'
|
|
1763
|
+
}, uniqueVulnerabilities.length > 0 && React.createElement(Tab, {
|
|
1764
|
+
eventKey: 0,
|
|
1765
|
+
title: `Vulnerabilities (${uniqueVulnerabilities.length})`
|
|
4443
1766
|
}, React.createElement(VulnerabilitiesTable, {
|
|
4444
1767
|
vulnerabilities: uniqueVulnerabilities,
|
|
4445
1768
|
isLoading: _isLoading
|
|
4446
|
-
}))
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
}, "Excluded Packages ", `(${excludedPackages.length})`), React.createElement("pfe-tab-panel", {
|
|
4450
|
-
slot: 'panel',
|
|
4451
|
-
role: 'region'
|
|
1769
|
+
})), excludedPackages.length > 0 && React.createElement(Tab, {
|
|
1770
|
+
eventKey: 1,
|
|
1771
|
+
title: `Excluded Packages (${excludedPackages.length})`
|
|
4452
1772
|
}, React.createElement("p", {
|
|
4453
1773
|
className: 'packages-table__excluded-packages-disclaimer'
|
|
4454
1774
|
}, "The following packages were found in this image and cannot be scanned or compared to public vulnerability information. This image may include additional packages or content not found or listed below."), React.createElement(ExcludedPackagesTable, {
|
|
4455
1775
|
excludedPackages: excludedPackages,
|
|
4456
1776
|
isLoading: _isLoading
|
|
4457
|
-
})))))
|
|
1777
|
+
})))));
|
|
4458
1778
|
};
|
|
4459
1779
|
|
|
4460
1780
|
export { PackagesTable, severitySortOrder };
|