@lion/ui 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/calendar/src/LionCalendar.js +6 -0
- package/components/core/src/DisabledWithTabIndexMixin.js +7 -0
- package/components/core/src/ScopedElementsMixin.js +58 -37
- package/components/core/test/ScopedElementsMixin.test.js +131 -0
- package/components/core/test/ssr-definitions/ScopedElementsHost.define.js +1 -0
- package/components/form-core/src/FormControlMixin.js +6 -0
- package/components/form-core/src/utils/SyncUpdatableMixin.js +7 -0
- package/components/form-core/src/validate/LionValidationFeedback.js +4 -2
- package/components/form-core/test/validate/lion-validation-feedback.test.js +12 -0
- package/components/icon/src/LionIcon.js +6 -0
- package/components/localize/src/LocalizeManager.js +258 -178
- package/components/overlays/src/OverlayMixin.js +7 -0
- package/components/progress-indicator/src/LionProgressIndicator.js +6 -0
- package/components/steps/src/LionStep.js +6 -0
- package/components/steps/src/LionSteps.js +6 -0
- package/components/tabs/src/LionTabs.js +6 -0
- package/components/tooltip/src/LionTooltip.js +6 -0
- package/custom-elements.json +685 -159
- package/dist-types/components/calendar/src/LionCalendar.d.ts +5 -0
- package/dist-types/components/calendar/src/LionCalendar.d.ts.map +1 -1
- package/dist-types/components/core/src/DisabledWithTabIndexMixin.d.ts.map +1 -1
- package/dist-types/components/core/src/ScopedElementsMixin.d.ts +43 -6
- package/dist-types/components/core/src/ScopedElementsMixin.d.ts.map +1 -1
- package/dist-types/components/core/test/ScopedElementsMixin.test.d.ts +2 -0
- package/dist-types/components/core/test/ScopedElementsMixin.test.d.ts.map +1 -0
- package/dist-types/components/core/test/ssr-definitions/ScopedElementsHost.define.d.ts +2 -0
- package/dist-types/components/core/test/ssr-definitions/ScopedElementsHost.define.d.ts.map +1 -0
- package/dist-types/components/form-core/src/FormControlMixin.d.ts.map +1 -1
- package/dist-types/components/form-core/src/utils/SyncUpdatableMixin.d.ts.map +1 -1
- package/dist-types/components/form-core/src/validate/LionValidationFeedback.d.ts.map +1 -1
- package/dist-types/components/icon/src/LionIcon.d.ts +5 -0
- package/dist-types/components/icon/src/LionIcon.d.ts.map +1 -1
- package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts +1 -1
- package/dist-types/components/input-file/src/LionInputFile.d.ts +1 -1
- package/dist-types/components/input-file/src/LionSelectedFileList.d.ts +1 -1
- package/dist-types/components/localize/src/LocalizeManager.d.ts +108 -93
- package/dist-types/components/localize/src/LocalizeManager.d.ts.map +1 -1
- package/dist-types/components/overlays/src/OverlayMixin.d.ts.map +1 -1
- package/dist-types/components/progress-indicator/src/LionProgressIndicator.d.ts +5 -0
- package/dist-types/components/progress-indicator/src/LionProgressIndicator.d.ts.map +1 -1
- package/dist-types/components/select-rich/src/LionSelectRich.d.ts +1 -1
- package/dist-types/components/steps/src/LionStep.d.ts +5 -0
- package/dist-types/components/steps/src/LionStep.d.ts.map +1 -1
- package/dist-types/components/steps/src/LionSteps.d.ts +5 -0
- package/dist-types/components/steps/src/LionSteps.d.ts.map +1 -1
- package/dist-types/components/switch/src/LionSwitch.d.ts +1 -1
- package/dist-types/components/tabs/src/LionTabs.d.ts +5 -0
- package/dist-types/components/tabs/src/LionTabs.d.ts.map +1 -1
- package/dist-types/components/tooltip/src/LionTooltip.d.ts +5 -0
- package/dist-types/components/tooltip/src/LionTooltip.d.ts.map +1 -1
- package/dist-types/tsconfig.tsbuildinfo +1 -1
- package/docs/components/checkbox-group/overview.md +2 -2
- package/docs/components/collapsible/overview.md +1 -1
- package/docs/components/combobox/overview.md +1 -1
- package/docs/components/combobox/use-cases.md +1 -1
- package/docs/components/dialog/overview.md +1 -1
- package/docs/components/fieldset/overview.md +5 -5
- package/docs/components/form/overview.md +3 -3
- package/docs/components/icon/use-cases.md +1 -1
- package/docs/components/input/api-table.md +1 -1
- package/docs/components/input/overview.md +1 -1
- package/docs/components/input-amount/api-table.md +1 -1
- package/docs/components/input-amount/overview.md +3 -3
- package/docs/components/input-date/api-table.md +1 -1
- package/docs/components/input-date/overview.md +3 -3
- package/docs/components/input-datepicker/api-table.md +1 -1
- package/docs/components/input-datepicker/overview.md +5 -5
- package/docs/components/input-email/api-table.md +1 -1
- package/docs/components/input-email/overview.md +2 -2
- package/docs/components/input-file/api-table.md +1 -1
- package/docs/components/input-file/overview.md +1 -1
- package/docs/components/input-iban/api-table.md +1 -1
- package/docs/components/input-iban/overview.md +2 -2
- package/docs/components/input-range/api-table.md +1 -1
- package/docs/components/input-range/overview.md +2 -2
- package/docs/components/input-stepper/api-table.md +1 -1
- package/docs/components/input-stepper/overview.md +1 -1
- package/docs/components/input-tel/api-table.md +1 -1
- package/docs/components/input-tel/overview.md +1 -1
- package/docs/components/input-tel/use-cases.md +6 -6
- package/docs/components/input-tel-dropdown/api-table.md +1 -1
- package/docs/components/input-tel-dropdown/overview.md +1 -1
- package/docs/components/listbox/use-cases.md +1 -1
- package/docs/components/radio-group/api-table.md +1 -1
- package/docs/components/radio-group/overview.md +3 -3
- package/docs/components/select/api-table.md +1 -1
- package/docs/components/select/use-cases.md +1 -1
- package/docs/components/select-rich/api-table.md +1 -1
- package/docs/components/select-rich/use-cases.md +1 -1
- package/docs/components/switch/api-table.md +1 -1
- package/docs/components/tabs/examples.md +1 -1
- package/docs/components/textarea/api-table.md +1 -1
- package/docs/fundamentals/index.md +4 -4
- package/docs/fundamentals/node-tools/providence-analytics/LocalConfiguration.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/QueryResult.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/analyzer.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/dashboard.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/overview.md +3 -3
- package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
- package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
- package/docs/fundamentals/rationales/accessibility.md +1 -1
- package/docs/fundamentals/systems/core/SlotMixin.md +1 -1
- package/docs/fundamentals/systems/core/overview.md +1 -1
- package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
- package/docs/fundamentals/systems/form/model-value.md +1 -1
- package/docs/fundamentals/systems/form/overview.md +28 -28
- package/docs/fundamentals/systems/form/validate.md +2 -2
- package/docs/fundamentals/systems/localize/api-table.md +38 -37
- package/docs/fundamentals/systems/localize/overview.md +4 -4
- package/docs/fundamentals/systems/overlays/configuration.md +2 -2
- package/docs/fundamentals/systems/overlays/overview.md +5 -5
- package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
- package/docs/fundamentals/tools/helpers/overview.md +1 -1
- package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
- package/docs/guides/how-to/create-a-custom-field.md +5 -5
- package/docs/guides/how-to/create-a-form.md +4 -4
- package/docs/guides/how-to/extend-a-native-input.md +2 -2
- package/docs/guides/index.md +8 -8
- package/docs/guides/principles/index.md +5 -5
- package/docs/guides/principles/styling.md +1 -1
- package/package.json +1 -1
|
@@ -369,6 +369,12 @@ export class LionCalendar extends LocalizeMixin(LitElement) {
|
|
|
369
369
|
}
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
+
/**
|
|
373
|
+
* // TODO: check if this is a false positive or if we can improve
|
|
374
|
+
* @configure ReactiveElement
|
|
375
|
+
*/
|
|
376
|
+
static enabledWarnings = super.enabledWarnings?.filter(w => w !== 'change-in-update') || [];
|
|
377
|
+
|
|
372
378
|
/**
|
|
373
379
|
* @private
|
|
374
380
|
*/
|
|
@@ -49,6 +49,13 @@ const DisabledWithTabIndexMixinImplementation = superclass =>
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* // TODO: check if this is a false positive or if we can improve
|
|
54
|
+
* @configure ReactiveElement
|
|
55
|
+
*/
|
|
56
|
+
// @ts-expect-error
|
|
57
|
+
static enabledWarnings = super.enabledWarnings?.filter(w => w !== 'change-in-update') || [];
|
|
58
|
+
|
|
52
59
|
/**
|
|
53
60
|
* @param {number} value
|
|
54
61
|
* @private
|
|
@@ -1,6 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
import { dedupeMixin } from '@open-wc/dedupe-mixin';
|
|
2
|
+
import { adoptStyles, isServer } from 'lit';
|
|
3
|
+
import { ScopedElementsMixin as OpenWcLitScopedElementsMixin } from '@open-wc/scoped-elements/lit-element.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {import('../../form-core/types/validate/ValidateMixinTypes.js').ScopedElementsMap} ScopedElementsMap
|
|
7
|
+
* @typedef {import('@open-wc/dedupe-mixin').Constructor<ScopedElementsHost>} ScopedElementsHostConstructor
|
|
8
|
+
* @typedef {import('@open-wc/scoped-elements/lit-element.js').ScopedElementsHost} ScopedElementsHost
|
|
9
|
+
* @typedef {import('./types.js').ScopedElementsHostV2Constructor} ScopedElementsHostV2Constructor
|
|
10
|
+
* @typedef {import('@open-wc/dedupe-mixin').Constructor<LitElement>} LitElementConstructor
|
|
11
|
+
* @typedef {import('lit').CSSResultOrNative} CSSResultOrNative
|
|
12
|
+
* @typedef {typeof import('lit').LitElement} TypeofLitElement
|
|
13
|
+
* @typedef {import('lit').LitElement} LitElement
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export function supportsScopedRegistry() {
|
|
17
|
+
return Boolean(
|
|
18
|
+
// @ts-expect-error
|
|
19
|
+
globalThis.ShadowRoot?.prototype.createElement && globalThis.ShadowRoot?.prototype.importNode,
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
2
24
|
* This file is combination of '@open-wc/scoped-elements@v3/lit-element.js' and '@open-wc/scoped-elements@v3/html-element.js'.
|
|
3
25
|
* Then on top of those, some code from '@open-wc/scoped-elements@v2' is brought to to make polyfill not mandatory.
|
|
26
|
+
* This can be a great help for ssr scenarios, allowing elements to be consumed without needing knowledge about internall
|
|
27
|
+
* consumption.
|
|
28
|
+
* (N.B. at this point in time, this is limited to the scenario where there's one version of lion on the page).
|
|
4
29
|
*
|
|
5
30
|
* ## Considerations
|
|
6
31
|
* In its current state, the [scoped-custom-element-registry](https://github.com/webcomponents/polyfills/tree/master/packages/scoped-custom-element-registry) draft spec has uncertainties:
|
|
@@ -21,29 +46,7 @@
|
|
|
21
46
|
* This can be beneficial for performance, bundle size, ease of use and SSR capabilities.
|
|
22
47
|
*
|
|
23
48
|
* We will keep a close eye on developments in spec and polyfill, and will re-evaluate the scoped-elements approach when the time is right.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
import { dedupeMixin } from '@open-wc/dedupe-mixin';
|
|
27
|
-
import { adoptStyles } from 'lit';
|
|
28
|
-
import { ScopedElementsMixin as OpenWcLitScopedElementsMixin } from '@open-wc/scoped-elements/lit-element.js';
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @typedef {import('@open-wc/scoped-elements/lit-element.js').ScopedElementsHost} ScopedElementsHost
|
|
32
|
-
* @typedef {import('../../form-core/types/validate/ValidateMixinTypes.js').ScopedElementsMap} ScopedElementsMap
|
|
33
|
-
* @typedef {import('lit').CSSResultOrNative} CSSResultOrNative
|
|
34
|
-
* @typedef {import('lit').LitElement} LitElement
|
|
35
|
-
* @typedef {typeof import('lit').LitElement} TypeofLitElement
|
|
36
|
-
* @typedef {import('@open-wc/dedupe-mixin').Constructor<LitElement>} LitElementConstructor
|
|
37
|
-
* @typedef {import('@open-wc/dedupe-mixin').Constructor<ScopedElementsHost>} ScopedElementsHostConstructor
|
|
38
|
-
* @typedef {import('./types.js').ScopedElementsHostV2Constructor} ScopedElementsHostV2Constructor
|
|
39
|
-
*/
|
|
40
|
-
|
|
41
|
-
const supportsScopedRegistry = Boolean(
|
|
42
|
-
// @ts-expect-error
|
|
43
|
-
ShadowRoot.prototype.createElement && ShadowRoot.prototype.importNode,
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
/**
|
|
49
|
+
*
|
|
47
50
|
* @template {LitElementConstructor} T
|
|
48
51
|
* @param {T} superclass
|
|
49
52
|
* @return {T & ScopedElementsHostConstructor & ScopedElementsHostV2Constructor}
|
|
@@ -51,8 +54,29 @@ const supportsScopedRegistry = Boolean(
|
|
|
51
54
|
const ScopedElementsMixinImplementation = superclass =>
|
|
52
55
|
/** @type {ScopedElementsHost} */
|
|
53
56
|
class ScopedElementsHost extends OpenWcLitScopedElementsMixin(superclass) {
|
|
57
|
+
constructor() {
|
|
58
|
+
super();
|
|
59
|
+
|
|
60
|
+
if (isServer) {
|
|
61
|
+
// We are on the server: this means we can't support scoped registries...
|
|
62
|
+
// So we must treat it like the "no-polyfill scenario", that registers scoped
|
|
63
|
+
// elements used for internal composition on the global registry.
|
|
64
|
+
// On the client that would happen in connectedCallback, so we do it here...
|
|
65
|
+
// N.B. keep in mind that this does not work when we have multiple element (versions)
|
|
66
|
+
// with the same name. (like multiple versions of lion extension layers).
|
|
67
|
+
// If we want to support this, we must re-introduce the shim-behavior of ScopedElementsMixin v1
|
|
68
|
+
// to make this work with ssr as well.
|
|
69
|
+
// @ts-expect-error
|
|
70
|
+
this.registry = customElements;
|
|
71
|
+
// @ts-expect-error
|
|
72
|
+
for (const [name, klass] of Object.entries(this.constructor.scopedElements || {})) {
|
|
73
|
+
this.defineScopedElement(name, klass);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
54
78
|
createScopedElement(/** @type {string} */ tagName) {
|
|
55
|
-
const root = supportsScopedRegistry ? this.shadowRoot : document;
|
|
79
|
+
const root = supportsScopedRegistry() ? this.shadowRoot : document;
|
|
56
80
|
// @ts-expect-error polyfill to support createElement on shadowRoot is loaded
|
|
57
81
|
return root.createElement(tagName);
|
|
58
82
|
}
|
|
@@ -61,12 +85,12 @@ const ScopedElementsMixinImplementation = superclass =>
|
|
|
61
85
|
* Defines a scoped element.
|
|
62
86
|
*
|
|
63
87
|
* @param {string} tagName
|
|
64
|
-
* @param {typeof HTMLElement}
|
|
88
|
+
* @param {typeof HTMLElement} classToBeRegistered
|
|
65
89
|
*/
|
|
66
|
-
defineScopedElement(tagName,
|
|
67
|
-
// @ts-ignore
|
|
90
|
+
defineScopedElement(tagName, classToBeRegistered) {
|
|
68
91
|
const registeredClass = this.registry.get(tagName);
|
|
69
|
-
|
|
92
|
+
const isAlreadyRegistered = registeredClass && registeredClass === classToBeRegistered;
|
|
93
|
+
if (isAlreadyRegistered && !supportsScopedRegistry()) {
|
|
70
94
|
// eslint-disable-next-line no-console
|
|
71
95
|
console.error(
|
|
72
96
|
[
|
|
@@ -80,10 +104,8 @@ const ScopedElementsMixinImplementation = superclass =>
|
|
|
80
104
|
);
|
|
81
105
|
}
|
|
82
106
|
if (!registeredClass) {
|
|
83
|
-
|
|
84
|
-
return this.registry.define(tagName, klass);
|
|
107
|
+
return this.registry.define(tagName, classToBeRegistered);
|
|
85
108
|
}
|
|
86
|
-
// @ts-ignore
|
|
87
109
|
return this.registry.get(tagName);
|
|
88
110
|
}
|
|
89
111
|
|
|
@@ -92,12 +114,12 @@ const ScopedElementsMixinImplementation = superclass =>
|
|
|
92
114
|
* @returns {ShadowRoot}
|
|
93
115
|
*/
|
|
94
116
|
attachShadow(options) {
|
|
95
|
-
// @ts-
|
|
117
|
+
// @ts-expect-error
|
|
96
118
|
const { scopedElements } = /** @type {typeof ScopedElementsHost} */ (this.constructor);
|
|
97
119
|
|
|
98
120
|
const shouldCreateRegistry =
|
|
99
121
|
!this.registry ||
|
|
100
|
-
// @ts-
|
|
122
|
+
// @ts-expect-error
|
|
101
123
|
(this.registry === this.constructor.__registry &&
|
|
102
124
|
!Object.prototype.hasOwnProperty.call(this.constructor, '__registry'));
|
|
103
125
|
|
|
@@ -108,8 +130,7 @@ const ScopedElementsMixinImplementation = superclass =>
|
|
|
108
130
|
* This is important specifically for superclasses/inheritance
|
|
109
131
|
*/
|
|
110
132
|
if (shouldCreateRegistry) {
|
|
111
|
-
|
|
112
|
-
this.registry = supportsScopedRegistry ? new CustomElementRegistry() : customElements;
|
|
133
|
+
this.registry = supportsScopedRegistry() ? new CustomElementRegistry() : customElements;
|
|
113
134
|
for (const [tagName, klass] of Object.entries(scopedElements ?? {})) {
|
|
114
135
|
this.defineScopedElement(tagName, klass);
|
|
115
136
|
}
|
|
@@ -131,7 +152,7 @@ const ScopedElementsMixinImplementation = superclass =>
|
|
|
131
152
|
);
|
|
132
153
|
|
|
133
154
|
const createdRoot = this.attachShadow(shadowRootOptions);
|
|
134
|
-
if (supportsScopedRegistry) {
|
|
155
|
+
if (supportsScopedRegistry()) {
|
|
135
156
|
// @ts-expect-error
|
|
136
157
|
this.renderOptions.creationScope = createdRoot;
|
|
137
158
|
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { expect, fixture } from '@open-wc/testing';
|
|
2
|
+
import {
|
|
3
|
+
ssrNonHydratedFixture,
|
|
4
|
+
ssrHydratedFixture,
|
|
5
|
+
csrFixture,
|
|
6
|
+
} from '@lit-labs/testing/fixtures.js';
|
|
7
|
+
import { LitElement, html } from 'lit';
|
|
8
|
+
import sinon from 'sinon';
|
|
9
|
+
import { browserDetection } from '../src/browserDetection.js';
|
|
10
|
+
|
|
11
|
+
import { ScopedElementsMixin, supportsScopedRegistry } from '../src/ScopedElementsMixin.js';
|
|
12
|
+
|
|
13
|
+
const hasRealScopedRegistrySupport = supportsScopedRegistry();
|
|
14
|
+
const originalShadowRootProps = {
|
|
15
|
+
// @ts-expect-error
|
|
16
|
+
createElement: globalThis.ShadowRoot?.prototype.createElement,
|
|
17
|
+
// @ts-expect-error
|
|
18
|
+
importNode: globalThis.ShadowRoot?.prototype.importNode,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// Even though the polyfill might be loaded in this test or we run it in a browser supporting these features,
|
|
22
|
+
// we mock "no support", so that `supportsScopedRegistry()` returns false inside ScopedElementsMixin..
|
|
23
|
+
function mockNoRegistrySupport() {
|
|
24
|
+
// Are we on a server or do we have no polyfill? Nothing to be done here...
|
|
25
|
+
if (!hasRealScopedRegistrySupport) return;
|
|
26
|
+
|
|
27
|
+
// This will be enough to make the `supportsScopedRegistry()` check fail inside ScopedElementsMixin and bypass scoped registries
|
|
28
|
+
globalThis.ShadowRoot = globalThis.ShadowRoot || { prototype: {} };
|
|
29
|
+
// @ts-expect-error
|
|
30
|
+
globalThis.ShadowRoot.prototype.createElement = null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
mockNoRegistrySupport.restore = () => {
|
|
34
|
+
// Are we on a server or do we have no polyfill? Nothing to be done here...
|
|
35
|
+
if (!hasRealScopedRegistrySupport) return;
|
|
36
|
+
|
|
37
|
+
// @ts-expect-error
|
|
38
|
+
globalThis.ShadowRoot.prototype.createElement = originalShadowRootProps.createElement;
|
|
39
|
+
// @ts-expect-error
|
|
40
|
+
globalThis.ShadowRoot.prototype.importNode = originalShadowRootProps.importNode;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
class ScopedElementsChild extends LitElement {
|
|
44
|
+
render() {
|
|
45
|
+
return html`<span>I'm a child</span>`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
class ScopedElementsHost extends ScopedElementsMixin(LitElement) {
|
|
50
|
+
static scopedElements = { 'scoped-elements-child': ScopedElementsChild };
|
|
51
|
+
|
|
52
|
+
render() {
|
|
53
|
+
return html`<scoped-elements-child></scoped-elements-child>`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
customElements.define('scoped-elements-host', ScopedElementsHost);
|
|
57
|
+
|
|
58
|
+
describe('ScopedElementsMixin', () => {
|
|
59
|
+
it('renders child elements correctly (that were not registered yet on global registry)', async () => {
|
|
60
|
+
// customElements.define('scoped-elements-child', ScopedElementsChild);
|
|
61
|
+
for (const _fixture of [csrFixture, ssrNonHydratedFixture, ssrHydratedFixture]) {
|
|
62
|
+
const el = await _fixture(html`<scoped-elements-host></scoped-elements-host>`, {
|
|
63
|
+
// we must provide modules atm
|
|
64
|
+
modules: ['./ssr-definitions/ScopedElementsHost.define.js'],
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Wait for FF support
|
|
68
|
+
if (!browserDetection.isFirefox) {
|
|
69
|
+
expect(
|
|
70
|
+
el.shadowRoot?.querySelector('scoped-elements-child')?.shadowRoot?.innerHTML,
|
|
71
|
+
).to.contain("<span>I'm a child</span>");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// @ts-expect-error
|
|
75
|
+
expect(el.registry.get('scoped-elements-child')).to.not.be.undefined;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('When scoped registries are supported', () => {
|
|
80
|
+
it('registers elements on local registry', async () => {
|
|
81
|
+
const ceDefineSpy = sinon.spy(customElements, 'define');
|
|
82
|
+
|
|
83
|
+
const el = /** @type {ScopedElementsHost} */ (
|
|
84
|
+
await fixture(html`<scoped-elements-host></scoped-elements-host>`)
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
// @ts-expect-error
|
|
88
|
+
expect(el.registry.get('scoped-elements-child')).to.equal(ScopedElementsChild);
|
|
89
|
+
expect(el.registry).to.not.equal(customElements);
|
|
90
|
+
expect(ceDefineSpy.calledWith('scoped-elements-child')).to.be.false;
|
|
91
|
+
|
|
92
|
+
ceDefineSpy.restore();
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe('When scoped registries are not supported', () => {
|
|
97
|
+
class ScopedElementsChildNoReg extends LitElement {
|
|
98
|
+
render() {
|
|
99
|
+
return html`<span>I'm a child</span>`;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
class ScopedElementsHostNoReg extends ScopedElementsMixin(LitElement) {
|
|
104
|
+
static scopedElements = { 'scoped-elements-child-no-reg': ScopedElementsChildNoReg };
|
|
105
|
+
|
|
106
|
+
render() {
|
|
107
|
+
return html`<scoped-elements-child-no-reg></scoped-elements-child-no-reg>`;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
before(() => {
|
|
111
|
+
mockNoRegistrySupport();
|
|
112
|
+
customElements.define('scoped-elements-host-no-reg', ScopedElementsHostNoReg);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
after(() => {
|
|
116
|
+
mockNoRegistrySupport.restore();
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('registers elements', async () => {
|
|
120
|
+
const ceDefineSpy = sinon.spy(customElements, 'define');
|
|
121
|
+
|
|
122
|
+
const el = /** @type {ScopedElementsHostNoReg} */ (
|
|
123
|
+
await fixture(html`<scoped-elements-host-no-reg></scoped-elements-host-no-reg>`)
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
expect(el.registry).to.equal(customElements);
|
|
127
|
+
expect(ceDefineSpy.calledWith('scoped-elements-child-no-reg')).to.be.true;
|
|
128
|
+
ceDefineSpy.restore();
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// ... empty file needed for '@lit-labs/testing/fixtures.js'
|
|
@@ -152,6 +152,12 @@ const FormControlMixinImplementation = superclass =>
|
|
|
152
152
|
return /** @type {LionValidationFeedback} */ (this.__getDirectSlotChild('feedback'));
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
+
/**
|
|
156
|
+
* TODO: check if this is a false positive or if we can improve
|
|
157
|
+
* @configure ReactiveElement
|
|
158
|
+
*/
|
|
159
|
+
static enabledWarnings = super.enabledWarnings?.filter(w => w !== 'change-in-update') || [];
|
|
160
|
+
|
|
155
161
|
constructor() {
|
|
156
162
|
super();
|
|
157
163
|
|
|
@@ -56,6 +56,13 @@ const SyncUpdatableMixinImplementation = superclass =>
|
|
|
56
56
|
this.__SyncUpdatableNamespace.connected = false;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
/**
|
|
60
|
+
* // TODO: check if this is a false positive or if we can improve
|
|
61
|
+
* @configure ReactiveElement
|
|
62
|
+
*/
|
|
63
|
+
// @ts-expect-error
|
|
64
|
+
static enabledWarnings = super.enabledWarnings?.filter(w => w !== 'change-in-update') || [];
|
|
65
|
+
|
|
59
66
|
/**
|
|
60
67
|
* Makes the propertyAccessor.`hasChanged` compatible in synchronous updates
|
|
61
68
|
* @param {string} name
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { css, html, LitElement } from 'lit';
|
|
1
|
+
import { css, html, LitElement, nothing } from 'lit';
|
|
2
2
|
import { LocalizeMixin } from '@lion/ui/localize-no-side-effects.js';
|
|
3
3
|
import { localizeNamespaceLoader } from '../localizeNamespaceLoader.js';
|
|
4
4
|
|
|
@@ -90,7 +90,9 @@ export class LionValidationFeedback extends LocalizeMixin(LitElement) {
|
|
|
90
90
|
this.feedbackData.map(
|
|
91
91
|
({ message, type, validator }) => html`
|
|
92
92
|
<div class="validation-feedback__type">
|
|
93
|
-
${
|
|
93
|
+
${message && type
|
|
94
|
+
? this._localizeManager.msg(`lion-form-core:validation${capitalize(type)}`)
|
|
95
|
+
: nothing}
|
|
94
96
|
</div>
|
|
95
97
|
${this._messageTemplate({ message, type, validator })}
|
|
96
98
|
`,
|
|
@@ -91,6 +91,18 @@ describe('lion-validation-feedback', () => {
|
|
|
91
91
|
expect(validationFeedbackType?.textContent?.trim()).to.equal('Info');
|
|
92
92
|
});
|
|
93
93
|
|
|
94
|
+
it('it does not share the type if there is no message', async () => {
|
|
95
|
+
const el = /** @type {LionValidationFeedback} */ (
|
|
96
|
+
await fixture(html`<lion-validation-feedback></lion-validation-feedback>`)
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
el.feedbackData = [{ message: '', type: 'error', validator: new AlwaysInvalid() }];
|
|
100
|
+
await el.updateComplete;
|
|
101
|
+
|
|
102
|
+
const validationFeedbackType = el.shadowRoot?.querySelector('.validation-feedback__type');
|
|
103
|
+
expect(validationFeedbackType?.textContent?.trim()).to.not.equal('Error');
|
|
104
|
+
});
|
|
105
|
+
|
|
94
106
|
describe('accessibility', () => {
|
|
95
107
|
it('passes a11y audit when with a message', async () => {
|
|
96
108
|
const el = /** @type {LionValidationFeedback} */ (
|
|
@@ -102,6 +102,12 @@ export class LionIcon extends LitElement {
|
|
|
102
102
|
this.__svg = nothing;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
/**
|
|
106
|
+
* TODO: check if this is a false positive or if we can improve
|
|
107
|
+
* @configure ReactiveElement
|
|
108
|
+
*/
|
|
109
|
+
static enabledWarnings = super.enabledWarnings?.filter(w => w !== 'change-in-update') || [];
|
|
110
|
+
|
|
105
111
|
/** @param {import('lit').PropertyValues} changedProperties */
|
|
106
112
|
update(changedProperties) {
|
|
107
113
|
super.update(changedProperties);
|