@lmvz-ds/components 0.12.5 → 0.13.1
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/cjs/assets-CJzJZPzV.js +26 -0
- package/dist/{esm/Effect-BhQLGXPs.js → cjs/icons-FIfJEo6G.js} +1708 -5205
- package/dist/cjs/{index-CVw4GUo6.js → index-Bp6Dd2i1.js} +4 -2
- package/dist/cjs/{index-9ZJx0550.js → index-D3BMpL5w.js} +0 -3
- package/dist/cjs/index.cjs.js +4 -6
- package/dist/cjs/lmvz-action.cjs.entry.js +1 -1
- package/dist/cjs/lmvz-button.cjs.entry.js +7 -10
- package/dist/cjs/lmvz-card.cjs.entry.js +4 -5
- package/dist/cjs/lmvz-chip.cjs.entry.js +1 -1
- package/dist/cjs/lmvz-components.cjs.js +1 -1
- package/dist/cjs/lmvz-header.cjs.entry.js +13 -12
- package/dist/cjs/lmvz-icon.cjs.entry.js +8 -10
- package/dist/cjs/lmvz-input.cjs.entry.js +8 -11
- package/dist/cjs/lmvz-menuitem.cjs.entry.js +5 -7
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/reactive-controller-host-BMDEj1kX.js +168 -0
- package/dist/collection/components/lmvz-button/lmvz-button.js +3 -3
- package/dist/collection/components/lmvz-card/lmvz-card.js +3 -4
- package/dist/collection/components/lmvz-header/lmvz-header.js +11 -8
- package/dist/collection/components/lmvz-icon/icons.js +2 -2
- package/dist/collection/components/lmvz-icon/lmvz-icon.js +2 -2
- package/dist/collection/components/lmvz-icon/test/icons.unit.js +21 -12
- package/dist/collection/components/lmvz-input/lmvz-input.css +5 -2
- package/dist/collection/components/lmvz-input/lmvz-input.js +3 -3
- package/dist/collection/components/lmvz-menuitem/lmvz-menuitem.js +3 -3
- package/dist/collection/integration/header-integration.js +3 -1
- package/dist/collection/utils/{validation → aria}/aria-validation-controller.js +15 -34
- package/dist/collection/utils/{list-keyboard-controller.js → aria/list-keyboard-controller.js} +1 -1
- package/dist/collection/utils/assets.js +9 -6
- package/dist/collection/utils/http.js +2 -2
- package/dist/collection/utils/{http.test.js → http.unit.js} +8 -7
- package/dist/collection/utils/validation/svg.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/lmvz-action.js +1 -1
- package/dist/components/lmvz-button.js +1 -1
- package/dist/components/lmvz-card.js +1 -1
- package/dist/components/lmvz-chip.js +1 -1
- package/dist/components/lmvz-header.js +1 -1
- package/dist/components/lmvz-icon.js +1 -1
- package/dist/components/lmvz-input.js +1 -1
- package/dist/components/lmvz-menuitem.js +1 -1
- package/dist/components/{p-DMLRPGid.js → p-BfTCfPZ1.js} +1 -1
- package/dist/components/p-BsS3QvWn.js +1 -0
- package/dist/components/p-CMteT-Yo.js +1 -0
- package/dist/components/p-CdYWDK7m.js +1 -0
- package/dist/components/p-vi4YzJmv.js +1 -0
- package/dist/esm/assets-BelZNJ1W.js +23 -0
- package/dist/{cjs/Effect-CNhHt4Xb.js → esm/icons-CM7lsnuO.js} +1751 -5457
- package/dist/esm/{index-Bt32KzDW.js → index-BfTCfPZ1.js} +3 -1
- package/dist/esm/{index-smGPjoDX.js → index-T5ljELGS.js} +1 -3
- package/dist/esm/index.js +4 -5
- package/dist/esm/lmvz-action.entry.js +1 -1
- package/dist/esm/lmvz-button.entry.js +5 -8
- package/dist/esm/lmvz-card.entry.js +4 -5
- package/dist/esm/lmvz-chip.entry.js +1 -1
- package/dist/esm/lmvz-components.js +2 -2
- package/dist/esm/lmvz-header.entry.js +11 -10
- package/dist/esm/lmvz-icon.entry.js +5 -7
- package/dist/esm/lmvz-input.entry.js +6 -9
- package/dist/esm/lmvz-menuitem.entry.js +3 -5
- package/dist/esm/loader.js +2 -2
- package/dist/esm/reactive-controller-host-CZ3dGAjR.js +165 -0
- package/dist/lmvz-components/index.esm.js +1 -1
- package/dist/lmvz-components/lmvz-components.esm.js +1 -1
- package/dist/lmvz-components/p-16878d4c.entry.js +1 -0
- package/dist/lmvz-components/p-6e3314ab.entry.js +1 -0
- package/dist/lmvz-components/p-8ea1a349.entry.js +1 -0
- package/dist/lmvz-components/{p-d4b68381.entry.js → p-980688a0.entry.js} +1 -1
- package/dist/lmvz-components/{p-DMLRPGid.js → p-BfTCfPZ1.js} +1 -1
- package/dist/lmvz-components/p-BoR31cjC.js +1 -0
- package/dist/lmvz-components/p-CVf2C8dL.js +1 -0
- package/dist/lmvz-components/p-CZ3dGAjR.js +1 -0
- package/dist/lmvz-components/p-T5ljELGS.js +2 -0
- package/dist/lmvz-components/p-a34542fa.entry.js +1 -0
- package/dist/lmvz-components/p-d2bf6a3f.entry.js +1 -0
- package/dist/lmvz-components/p-d9dc29a1.entry.js +1 -0
- package/dist/lmvz-components/{p-9faac8f3.entry.js → p-feda2ec5.entry.js} +1 -1
- package/dist/manifest.json +1 -1
- package/dist/types/components/lmvz-button/lmvz-button.d.ts +2 -2
- package/dist/types/components/lmvz-header/lmvz-header.d.ts +5 -4
- package/dist/types/components/lmvz-icon/lmvz-icon.d.ts +1 -1
- package/dist/types/components/lmvz-input/lmvz-input.d.ts +1 -1
- package/dist/types/components/lmvz-menuitem/lmvz-menuitem.d.ts +2 -2
- package/dist/types/utils/{validation → aria}/aria-validation-controller.d.ts +1 -5
- package/dist/types/utils/{element-activation-controller.d.ts → aria/element-activation-controller.d.ts} +2 -2
- package/dist/types/utils/{list-keyboard-controller.d.ts → aria/list-keyboard-controller.d.ts} +1 -1
- package/dist/types/utils/assets.d.ts +1 -8
- package/dist/types/utils/http.d.ts +3 -3
- package/dist/types/utils/validation/svg.d.ts +2 -2
- package/hydrate/index.js +3608 -54447
- package/hydrate/index.mjs +3608 -54447
- package/package.json +17 -18
- package/readme.md +18 -0
- package/dist/cjs/MutableQueue-Bk9tBfaK.js +0 -462
- package/dist/cjs/_commonjsHelpers-CFO10eej.js +0 -7
- package/dist/cjs/aria-validation-controller-B3hMkau3.js +0 -2930
- package/dist/cjs/assets-BguFB3wV.js +0 -71
- package/dist/cjs/axe-BNqwbBGU.js +0 -32834
- package/dist/cjs/icons-7wUEcWEo.js +0 -607
- package/dist/components/p-3I3wZmp8.js +0 -1
- package/dist/components/p-B85MJLTf.js +0 -1
- package/dist/components/p-BaPwpeMs.js +0 -1
- package/dist/components/p-CAi33KTt.js +0 -1
- package/dist/components/p-CdofjRtQ.js +0 -1
- package/dist/components/p-D1HbKFuh.js +0 -12
- package/dist/components/p-UwhTS2ue.js +0 -1
- package/dist/esm/MutableQueue-CNlEFklh.js +0 -431
- package/dist/esm/_commonjsHelpers-B85MJLTf.js +0 -5
- package/dist/esm/aria-validation-controller-iA4YWFG-.js +0 -2927
- package/dist/esm/assets-Iu8neKuE.js +0 -67
- package/dist/esm/axe-cRQ9Ux1I.js +0 -32832
- package/dist/esm/icons-Bx1wWPM2.js +0 -603
- package/dist/lmvz-components/p-1a10fcbd.entry.js +0 -1
- package/dist/lmvz-components/p-274c36df.entry.js +0 -1
- package/dist/lmvz-components/p-2ba68483.entry.js +0 -1
- package/dist/lmvz-components/p-4XIjw3k8.js +0 -1
- package/dist/lmvz-components/p-51Fb_qqD.js +0 -1
- package/dist/lmvz-components/p-77e26e71.entry.js +0 -1
- package/dist/lmvz-components/p-B85MJLTf.js +0 -1
- package/dist/lmvz-components/p-BhQLGXPs.js +0 -1
- package/dist/lmvz-components/p-CXWyvf0D.js +0 -1
- package/dist/lmvz-components/p-D1HbKFuh.js +0 -12
- package/dist/lmvz-components/p-D7I-Bc5i.js +0 -1
- package/dist/lmvz-components/p-a5fe62b6.entry.js +0 -1
- package/dist/lmvz-components/p-c8b78793.entry.js +0 -1
- package/dist/lmvz-components/p-smGPjoDX.js +0 -2
- /package/dist/collection/utils/{element-activation-controller.js → aria/element-activation-controller.js} +0 -0
- /package/dist/types/utils/{http.test.d.ts → http.unit.d.ts} +0 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { h, Host } from "@stencil/core";
|
|
2
|
-
import {
|
|
3
|
-
import { syncCreateAssetUrlSafely } from "../../utils/assets";
|
|
2
|
+
import { createAssetUrlSafely } from "../../utils/assets";
|
|
4
3
|
export class LmvzCard {
|
|
5
4
|
cardTitle;
|
|
6
5
|
imageUrl;
|
|
@@ -8,7 +7,7 @@ export class LmvzCard {
|
|
|
8
7
|
primaryActionLabel = '';
|
|
9
8
|
primaryAction;
|
|
10
9
|
get fallbackImage() {
|
|
11
|
-
return
|
|
10
|
+
return createAssetUrlSafely('card-placeholder.svg');
|
|
12
11
|
}
|
|
13
12
|
_onPrimaryClick() {
|
|
14
13
|
this.primaryAction.emit();
|
|
@@ -20,7 +19,7 @@ export class LmvzCard {
|
|
|
20
19
|
const imgStyle = {
|
|
21
20
|
backgroundImage: `url(${this.imageUrl ?? this.fallbackImage})`,
|
|
22
21
|
};
|
|
23
|
-
return (h(Host, { key: '
|
|
22
|
+
return (h(Host, { key: 'ba2e8d9e25428c744da2470cbd677306c56b09ae', role: "article" }, h("div", { key: '54ff7545559a4b6fb00c94909717234f4dfedd7c', class: "top" }, h("div", { key: '7bff35f247b6e8aca9b6346103139daa65ca16a3', class: "image-wrapper", style: imgStyle }, h("div", { key: 'c2c3d21227175b9dc0a55c75294f6c21bc713a26', class: "chip-slot" }, h("slot", { key: '1a7002aab5fc3f9f698c3d1678f8819ea36f91d3', name: "chip" })))), h("div", { key: 'a313321abe4da83db4b2ba64fdefa28edde93d41', class: "bottom" }, h("header", { key: 'f5ba333fcaa59d5b4f61dee94aba4628f49db9d7' }, h("h2", { key: 'b7d9ad6944b136476703cde89f885b189583eef1', class: "title" }, this.cardTitle)), h("p", { key: '6594626904a4f9fbc53d5956b71bbdefe00add8c', class: "description" }, this.description), h("div", { key: 'd8bbfebeb572fcf6990160a0dba7c5ae8a5a7fc7', class: "actions" }, h("button", { key: '6311a97a18412f8fbf8eb33e8a0f7a17700e71c6', class: "primary", onClick: this._onPrimaryClick.bind(this), "data-testid": "primary" }, this.primaryActionLabel), h("button", { key: '12033ad5018d100f84f0149d83dc965d8e5b2c66', class: "tertiary", "aria-label": "More actions", onClick: this._onOverflowClick }, h("span", { key: 'e11f8008542b4f7f70d1273bb31200c50d02aabb', class: "icon-placeholder" }, "..."))))));
|
|
24
23
|
}
|
|
25
24
|
static get is() { return "lmvz-card"; }
|
|
26
25
|
static get encapsulation() { return "scoped"; }
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { h, Host } from "@stencil/core";
|
|
2
|
-
import {
|
|
2
|
+
import { AriaValidationController } from "../../utils/aria/aria-validation-controller";
|
|
3
|
+
import { ListKeyboardNavigationController } from "../../utils/aria/list-keyboard-controller";
|
|
3
4
|
import { ReactiveControllerHost } from "../../utils/reactive-controller-host";
|
|
4
|
-
import { AriaValidationController } from "../../utils/validation/aria-validation-controller";
|
|
5
5
|
export class LmvzHeader extends ReactiveControllerHost {
|
|
6
6
|
el;
|
|
7
7
|
primarySlot;
|
|
@@ -30,11 +30,11 @@ export class LmvzHeader extends ReactiveControllerHost {
|
|
|
30
30
|
this.updateElementsActive();
|
|
31
31
|
}
|
|
32
32
|
componentDidLoad() {
|
|
33
|
-
this.primarySlot.addEventListener('slotchange', this.
|
|
34
|
-
this.
|
|
35
|
-
this.secondarySlot.addEventListener('slotchange', this.
|
|
33
|
+
this.primarySlot.addEventListener('slotchange', this.handlePrimaryNavItemsChange.bind(this));
|
|
34
|
+
this.handlePrimaryNavItemsChange();
|
|
35
|
+
this.secondarySlot.addEventListener('slotchange', this.handleSecondaryNavItemsChange.bind(this));
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
handlePrimaryNavItemsChange() {
|
|
38
38
|
const items = this.primaryMenuitems;
|
|
39
39
|
if (!items.length) {
|
|
40
40
|
console.warn('Primary slot has no assigned elements. Please add navigation items to the primary slot.');
|
|
@@ -46,11 +46,14 @@ export class LmvzHeader extends ReactiveControllerHost {
|
|
|
46
46
|
});
|
|
47
47
|
this.updateElementsActive();
|
|
48
48
|
}
|
|
49
|
-
|
|
49
|
+
handleSecondaryNavItemsChange() {
|
|
50
50
|
const items = this.secondaryMenuitems;
|
|
51
51
|
if (!items.length) {
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
|
+
this.updateKeyboardNavSubjects();
|
|
55
|
+
}
|
|
56
|
+
updateKeyboardNavSubjects() {
|
|
54
57
|
this.keyboardNavigationController.updateElements([...this.primaryMenuitems, ...this.secondaryMenuitems]);
|
|
55
58
|
}
|
|
56
59
|
updateElementsActive() {
|
|
@@ -71,7 +74,7 @@ export class LmvzHeader extends ReactiveControllerHost {
|
|
|
71
74
|
}
|
|
72
75
|
}
|
|
73
76
|
render() {
|
|
74
|
-
return (h(Host, { key: '
|
|
77
|
+
return (h(Host, { key: '783c855e49e1a2447107d6205a1b2c50285ccfff', onFocus: this.delegateFocus.bind(this) }, h("div", { key: '84a78b0ed3e170c49a711fa4091f80dbc7003b2f', class: "brand" }, h("slot", { key: '76cc54f17a7bc5f825433fc56351666a93891fd2', name: "brand" }, h("lmvz-icon", { key: 'e196e43720cb4b4c3f79b3071d534b50480f6206', id: "fallback-logo-lmvz", icon: "Logo", size: "inherit", "aria-label": "Lehrmittelverlag Z\u00FCrich" }))), h("nav", { key: 'd25a719752bd4085da5ad18af94afc66e9cabd5e', "aria-label": "Hauptnavigation" }, h("div", { key: '8a12c2c53bd061b3559ce9693780e592b3d7aa32', role: "menubar", class: "primary-menubar" }, h("slot", { key: '4461632675dc657f675883e8ef618e371ace0ad7', name: "nav-primary", ref: el => (this.primarySlot = el) }), h("div", { key: 'c1dabc588ac376db667df32d3edbdd6dce60aaad', role: "menu", id: "nav-secondary", class: "secondary-menubar", hidden: !this.lmvzActiveNav, ref: el => (this.secondaryNav = el) }, h("slot", { key: '74ca44ee2f755ffe9ea3ebc19cc2b227ae22df8b', name: this.secondarySlotName, ref: el => (this.secondarySlot = el) })))), h("div", { key: 'a4d250a5fcd10390aed1f5369c28ddec9aa9ee8d', class: "actions" }, h("slot", { key: '77a499ce12d269e79221ca971cc1b203d179f459', name: "actions" }))));
|
|
75
78
|
}
|
|
76
79
|
static get is() { return "lmvz-header"; }
|
|
77
80
|
static get encapsulation() { return "shadow"; }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Cache, Duration, Effect } from "effect";
|
|
2
|
-
import {
|
|
2
|
+
import { createAssetUrlSafely } from "../../utils/assets";
|
|
3
3
|
import { httpClient, responseAsText } from "../../utils/http";
|
|
4
4
|
import { createValidSVGString, SVGString } from "../../utils/validation/svg";
|
|
5
5
|
export const emptyDefaultSvg = () => SVGString(`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"></svg>`);
|
|
@@ -8,7 +8,7 @@ const createIconCache = () => Cache.make({
|
|
|
8
8
|
timeToLive: Duration.infinity,
|
|
9
9
|
lookup: (key) => Effect.gen(function* () {
|
|
10
10
|
const name = key;
|
|
11
|
-
const assetPath =
|
|
11
|
+
const assetPath = createAssetUrlSafely(`${name}.svg`, 'icons');
|
|
12
12
|
const res = yield* httpClient(assetPath);
|
|
13
13
|
const responseString = yield* responseAsText(res);
|
|
14
14
|
return yield* createValidSVGString(responseString);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Build, h, Host } from "@stencil/core";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
|
+
import { AriaValidationController } from "../../utils/aria/aria-validation-controller";
|
|
3
4
|
import { ReactiveControllerHost } from "../../utils/reactive-controller-host";
|
|
4
|
-
import { AriaValidationController } from "../../utils/validation/aria-validation-controller";
|
|
5
5
|
import { emptyDefaultSvg, fetchIconSvg } from "./icons";
|
|
6
6
|
export class LmvzIcon extends ReactiveControllerHost {
|
|
7
7
|
intersectionObserver;
|
|
@@ -39,7 +39,7 @@ export class LmvzIcon extends ReactiveControllerHost {
|
|
|
39
39
|
this.iconData = await Effect.runPromise(fetchIconSvg(this.icon).pipe(Effect.tapError(error => Effect.logError(`Error loading icon "${icon}":`, error.message, error.cause, error.stack)), Effect.catchAll(() => Effect.succeed(emptyDefaultSvg()))));
|
|
40
40
|
}
|
|
41
41
|
render() {
|
|
42
|
-
return h(Host, { key: '
|
|
42
|
+
return h(Host, { key: 'd4c1cbfbaf39ebf6aa26415d46100763b9f89b5b', role: "img", "aria-hidden": `${this.ariaHidden}`, innerHTML: this.iconData });
|
|
43
43
|
}
|
|
44
44
|
waitUntilVisible(callback, rootMargin = 50) {
|
|
45
45
|
if (!Build.isBrowser || typeof window === 'undefined' || !window.IntersectionObserver) {
|
|
@@ -1,34 +1,40 @@
|
|
|
1
|
+
import { beforeAll, beforeEach, describe, expect, test, vi } from "@stencil/vitest";
|
|
1
2
|
import { Effect } from "effect";
|
|
2
3
|
import { FetchError, ResponseTextError } from "../../../utils/http";
|
|
3
4
|
import { BrandValidationError, SVGString } from "../../../utils/validation/svg";
|
|
4
5
|
import { clearIconCache, emptyDefaultSvg, fetchIconSvg } from "../icons";
|
|
6
|
+
const fetchMock = vi.fn();
|
|
7
|
+
const mockResponse = (textResult) => ({
|
|
8
|
+
status: 200,
|
|
9
|
+
url: 'https://example.com/icons/actions.svg',
|
|
10
|
+
text: vi.fn().mockResolvedValue(textResult),
|
|
11
|
+
});
|
|
5
12
|
describe('icon utils:', () => {
|
|
6
13
|
beforeAll(() => {
|
|
7
|
-
|
|
8
|
-
parseFromString(str,
|
|
14
|
+
vi.stubGlobal('DOMParser', class {
|
|
15
|
+
parseFromString(str, _type) {
|
|
9
16
|
return {
|
|
10
17
|
documentElement: {
|
|
11
|
-
nodeName: str.
|
|
18
|
+
nodeName: typeof str === 'string' && str.trimStart().startsWith('<svg') ? 'svg' : 'not-svg',
|
|
12
19
|
},
|
|
13
20
|
};
|
|
14
21
|
}
|
|
15
|
-
};
|
|
22
|
+
});
|
|
16
23
|
});
|
|
17
24
|
beforeEach(() => {
|
|
18
|
-
|
|
19
|
-
|
|
25
|
+
vi.clearAllMocks();
|
|
26
|
+
fetchMock.mockReset();
|
|
27
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
20
28
|
return Effect.runPromise(clearIconCache());
|
|
21
29
|
});
|
|
22
30
|
const validSvg = '<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg>';
|
|
23
31
|
const invalidSvg = '<div>not an svg</div>';
|
|
24
32
|
const iconName = 'actions';
|
|
25
33
|
function mockFetchSuccess(svg = validSvg) {
|
|
26
|
-
|
|
27
|
-
text: () => Promise.resolve(svg),
|
|
28
|
-
});
|
|
34
|
+
fetchMock.mockResolvedValueOnce(mockResponse(svg));
|
|
29
35
|
}
|
|
30
36
|
function mockFetchFailure() {
|
|
31
|
-
|
|
37
|
+
fetchMock.mockRejectedValueOnce(new Error('fail'));
|
|
32
38
|
}
|
|
33
39
|
test('fetchIcon returns valid SVGString when fetch succeeds with valid SVG', async () => {
|
|
34
40
|
mockFetchSuccess(validSvg);
|
|
@@ -48,7 +54,9 @@ describe('icon utils:', () => {
|
|
|
48
54
|
expect(result.message).toContain('SVGString');
|
|
49
55
|
});
|
|
50
56
|
test('fetchIcon throws specific NotFoundError when icon is missing', async () => {
|
|
51
|
-
|
|
57
|
+
fetchMock.mockResolvedValueOnce({
|
|
58
|
+
status: 200,
|
|
59
|
+
url: 'https://example.com/icons/missing.svg',
|
|
52
60
|
text: () => Promise.reject(new Error('not found')),
|
|
53
61
|
});
|
|
54
62
|
const result = await Effect.runPromise(fetchIconSvg('missing').pipe(Effect.flip));
|
|
@@ -60,7 +68,7 @@ describe('icon utils:', () => {
|
|
|
60
68
|
expect(result).toBeInstanceOf(BrandValidationError);
|
|
61
69
|
});
|
|
62
70
|
test('fetchIcon throws specific BrandValidationError for non-string SVG', async () => {
|
|
63
|
-
|
|
71
|
+
fetchMock.mockResolvedValueOnce(mockResponse(123));
|
|
64
72
|
const result = await Effect.runPromise(fetchIconSvg(iconName).pipe(Effect.flip));
|
|
65
73
|
expect(result).toBeInstanceOf(BrandValidationError);
|
|
66
74
|
});
|
|
@@ -85,5 +93,6 @@ describe('icon utils:', () => {
|
|
|
85
93
|
const result2 = await Effect.runPromise(fetchIconSvg(iconName));
|
|
86
94
|
expect(result1).toContain('<svg');
|
|
87
95
|
expect(result2).toBe(result1);
|
|
96
|
+
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
88
97
|
});
|
|
89
98
|
});
|
|
@@ -179,7 +179,10 @@ input {
|
|
|
179
179
|
input::placeholder {
|
|
180
180
|
color: var(--label-color);
|
|
181
181
|
}
|
|
182
|
-
|
|
182
|
+
div:empty {
|
|
183
|
+
display: none;
|
|
184
|
+
}
|
|
185
|
+
[role='status'] {
|
|
183
186
|
padding-top: 8px; /* space-gap-component-input-helper-text */
|
|
184
187
|
padding-left: 12px; /* input-md-padding-x for helper text indent */
|
|
185
188
|
font-size: 12px;
|
|
@@ -187,7 +190,7 @@ input::placeholder {
|
|
|
187
190
|
font-family: Router, sans-serif;
|
|
188
191
|
font-weight: 500; /* Medium weight */
|
|
189
192
|
}
|
|
190
|
-
|
|
193
|
+
[role='alert'] {
|
|
191
194
|
padding-top: 8px;
|
|
192
195
|
padding-left: 12px;
|
|
193
196
|
font-size: 12px;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { h } from "@stencil/core";
|
|
2
2
|
import classNames from "classnames";
|
|
3
|
+
import { AriaValidationController } from "../../utils/aria/aria-validation-controller";
|
|
3
4
|
import { componentOnReady } from "../../utils/component";
|
|
4
5
|
import { ReactiveControllerHost } from "../../utils/reactive-controller-host";
|
|
5
|
-
import { AriaValidationController } from "../../utils/validation/aria-validation-controller";
|
|
6
6
|
let inputIdCounter = 0;
|
|
7
7
|
export class LmvzInput extends ReactiveControllerHost {
|
|
8
8
|
el;
|
|
@@ -142,9 +142,9 @@ export class LmvzInput extends ReactiveControllerHost {
|
|
|
142
142
|
render() {
|
|
143
143
|
const hasValue = Boolean(this.value);
|
|
144
144
|
const shouldFloatLabel = hasValue || Boolean(this.placeholder);
|
|
145
|
-
return (h("div", { key: '
|
|
145
|
+
return (h("div", { key: '4dffa432df9b8ca5d89c02b59cfe25b9321ca162', class: classNames('input-container', {
|
|
146
146
|
'interaction-filled': hasValue,
|
|
147
|
-
}) }, h("div", { key: '
|
|
147
|
+
}) }, h("div", { key: 'ade1cd1137acce218d458c1b66b2eb29cf887b70', class: "input-wrapper" }, h("slot", { key: '013dff3540481724658ff754bf3db0585ec3b6f4', name: "before-input" }), h("div", { key: '6587bb63c79f97c31abff5be0a91eb16374971d5', class: "label-input-group" }, h("label", { key: '2ef0a35fbd38b255423d2793415568a661476db3', htmlFor: this.inputId, class: classNames({ floating: shouldFloatLabel }) }, this.label, this.required && (h("span", { key: '0785826710ee4ecea96037cc689c34a43113552e', class: "required-indicator", "aria-hidden": "true" }, ' ', "*"))), h("input", { key: '5ad0d4b2d1c11dd89824db87e331232ba703a05e', id: this.inputId, ref: el => (this.nativeInputElement = el), type: this.type, min: this.min, max: this.max, step: this.step, value: this.value, name: this.name, placeholder: this.placeholder, disabled: this.disabled, readOnly: this.readonly, required: this.required, form: this.form, autocomplete: this.autocomplete, inputmode: this.inputmode, autocorrect: this.autocorrect, autocapitalize: this.autocapitalize, spellcheck: this.spellcheck, autofocus: this.autofocus, minlength: this.minlength, maxlength: this.maxlength, pattern: this.pattern, "aria-invalid": this.error ? 'true' : 'false', "aria-required": this.required ? 'true' : 'false', "aria-describedby": this.describedBy, "aria-errormessage": this.errorId, onInput: this.handleInput, onChange: this.handleChange, onFocus: this.handleFocus, onBlur: this.handleBlur })), h("slot", { key: 'a23676cc830cac7fbf87fef81a8d05b50b831725', name: "after-input" })), h("div", { key: 'e0a05138954d70508f840b6d5c4f53e74c2f2979', id: this.helperId, role: "status" }, this.helperText || null), h("div", { key: 'fcba57be2d596b3b8aa0ac97b2fd31dc3e77e14b', id: this.errorId, role: "alert" }, (this.showErrorMessage && this.errorMessage) || null)));
|
|
148
148
|
}
|
|
149
149
|
static get is() { return "lmvz-input"; }
|
|
150
150
|
static get encapsulation() { return "scoped"; }
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Host, h } from "@stencil/core";
|
|
2
|
-
import {
|
|
2
|
+
import { AriaValidationController } from "../../utils/aria/aria-validation-controller";
|
|
3
|
+
import { ElementActivationController } from "../../utils/aria/element-activation-controller";
|
|
3
4
|
import { ReactiveControllerHost } from "../../utils/reactive-controller-host";
|
|
4
|
-
import { AriaValidationController } from "../../utils/validation/aria-validation-controller";
|
|
5
5
|
export class LmvzMenuItem extends ReactiveControllerHost {
|
|
6
6
|
el;
|
|
7
7
|
get role() {
|
|
@@ -17,7 +17,7 @@ export class LmvzMenuItem extends ReactiveControllerHost {
|
|
|
17
17
|
this.addController(new ElementActivationController(this));
|
|
18
18
|
}
|
|
19
19
|
render() {
|
|
20
|
-
return (h(Host, { key: '
|
|
20
|
+
return (h(Host, { key: 'c4a21e628aaf4e983d51ce7b1f38ff66c47ec3ac' }, h("slot", { key: '0040d27a11c4bdd5a49dd54f352ba7d17b53ff7b' })));
|
|
21
21
|
}
|
|
22
22
|
static get is() { return "lmvz-menuitem"; }
|
|
23
23
|
static get encapsulation() { return "scoped"; }
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { enableAriaValidation } from "@lmvz-ds/aria-validation";
|
|
1
2
|
import { h, Host } from "@stencil/core";
|
|
3
|
+
enableAriaValidation();
|
|
2
4
|
export class HeaderIntegration {
|
|
3
5
|
activeNav;
|
|
4
6
|
activate(event) {
|
|
@@ -15,7 +17,7 @@ export class HeaderIntegration {
|
|
|
15
17
|
this.activeNav = navId;
|
|
16
18
|
}
|
|
17
19
|
render() {
|
|
18
|
-
return (h(Host, { key: '
|
|
20
|
+
return (h(Host, { key: '2c1e17a546e2f02d3a0571c8ad25f04dc4ddc21c' }, h("lmvz-header", { key: '2072642f27497dba23b82766efb47bae66cf2ca4', lmvzActiveNav: this.activeNav }, h("lmvz-menuitem", { key: '2f3f76364aeccf1d0012403599df6089324a6407', slot: "nav-primary", id: "lehrmittel", onLmvzActivation: this.activate.bind(this) }, h("a", { key: '925a3cddc298fd33c08b2a911a7b668503dd6457', href: "#" }, "Lehrmittel")), h("lmvz-menuitem", { key: '3579a89fb31a3c4f34550553830b4f17c466a26c', slot: "nav-primary", id: "verwaltung", onLmvzActivation: this.activate.bind(this) }, h("a", { key: 'f33245d9ae6eada3eab9fd65f6994e3950785a49', href: "#" }, "Verwaltung")), h("lmvz-menuitem", { key: '53fb94f79851dd87bf235fe7008004cc6ac81ba5', slot: "connect-nav-lehrmittel" }, h("lmvz-icon", { key: '74a1a501f0b0207c041470e6133cf9811922ad90', icon: "book" }), "Deutsch 7"), h("lmvz-menuitem", { key: 'b5885aeabe690ea9b16e5e1779de50e231ee9e68', slot: "connect-nav-lehrmittel" }, h("lmvz-icon", { key: 'a5691f42169f9812cd46206baf3e71b91dbda01d', icon: "book" }), "Mathe 2"), h("lmvz-menuitem", { key: 'b171e9be2812c4743482a40cb10cad501d1e5826', slot: "connect-nav-verwaltung" }, h("lmvz-icon", { key: 'f89e3b94ea03de64a516df80bcc152dfa814b0fc', icon: "cog" }), "iwas mit Verwaltung"), h("lmvz-menuitem", { key: 'f32ca2a5aab550d65a7a9da9210944cb5c66f83c', slot: "connect-nav-verwaltung", "aria-label": "Einstellungen" }, h("lmvz-icon", { key: '6a8b0d2afd0c94e44567a74d46a55e526f53dbd5', icon: "cog" })), h("lmvz-button", { key: '9c31e29f041ed4ae515eef1b966e8fcb68c7acd8', slot: "actions", "aria-label": "Benutzerkonto" }, h("lmvz-icon", { key: '340aa71a47c0714850bbdcbfbf971931fb83060e', icon: "user" }))), h("main", { key: '16c5b3916cb4dd172423f41f33015d2348407659' }, h("h1", { key: 'f71be25ec19f727050709f092c8c28f7f8a1cfde' }, "Content"))));
|
|
19
21
|
}
|
|
20
22
|
static get is() { return "header-integration"; }
|
|
21
23
|
static get encapsulation() { return "shadow"; }
|
|
@@ -1,49 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Effect, Queue, Stream } from "effect";
|
|
1
|
+
import { ARIA_VALIDATION_RUNTIME_CHANGED_EVENT, isAriaValidationEnabled, queueValidation } from "@lmvz-ds/aria-validation";
|
|
3
2
|
export class AriaValidationController {
|
|
4
3
|
host;
|
|
5
4
|
config;
|
|
6
|
-
static get globalValidationEnabled() {
|
|
7
|
-
return Build.isDev;
|
|
8
|
-
}
|
|
9
|
-
static axe = this.globalValidationEnabled ? import('axe-core') : null;
|
|
10
|
-
static axeQueue = null;
|
|
11
|
-
static axeStreamFiber = null;
|
|
12
5
|
visibilityObserver;
|
|
13
6
|
elementQueued = false;
|
|
14
7
|
elementValidated = false;
|
|
15
8
|
knownValidationErrors = [];
|
|
16
9
|
get disabled() {
|
|
17
|
-
return !
|
|
10
|
+
return !isAriaValidationEnabled();
|
|
18
11
|
}
|
|
19
12
|
constructor(host, config) {
|
|
20
13
|
this.host = host;
|
|
21
14
|
this.config = config;
|
|
22
|
-
AriaValidationController.initializeAxeStream();
|
|
23
15
|
}
|
|
24
|
-
|
|
25
|
-
if (!
|
|
26
|
-
return;
|
|
27
|
-
if (this.axeStreamFiber)
|
|
16
|
+
onRuntimeConfigChange = () => {
|
|
17
|
+
if (!isAriaValidationEnabled())
|
|
28
18
|
return;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const axeLib = yield* Effect.promise(() => AriaValidationController.axe);
|
|
32
|
-
if (!axeLib) {
|
|
33
|
-
console.error('Axe library not available, ARIA validation will not run.');
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
const stream = Stream.fromQueue(queue).pipe(Stream.mapEffect(({ context, onComplete }) => Effect.async(resume => {
|
|
37
|
-
axeLib.run(context, {}, (error, results) => {
|
|
38
|
-
onComplete(error, results);
|
|
39
|
-
resume(Effect.void);
|
|
40
|
-
});
|
|
41
|
-
})));
|
|
42
|
-
yield* Stream.runDrain(stream);
|
|
43
|
-
});
|
|
44
|
-
this.axeStreamFiber = Effect.runFork(program);
|
|
45
|
-
}
|
|
19
|
+
this.checkLazyValidation();
|
|
20
|
+
};
|
|
46
21
|
hostDidLoad() {
|
|
22
|
+
if (typeof window !== 'undefined') {
|
|
23
|
+
window.addEventListener(ARIA_VALIDATION_RUNTIME_CHANGED_EVENT, this.onRuntimeConfigChange);
|
|
24
|
+
}
|
|
47
25
|
if (this.elementQueued || this.elementValidated)
|
|
48
26
|
return;
|
|
49
27
|
if (!this.host.el.checkVisibility()) {
|
|
@@ -57,6 +35,9 @@ export class AriaValidationController {
|
|
|
57
35
|
}
|
|
58
36
|
hostDisconnected() {
|
|
59
37
|
this.discardVisibilityObserver();
|
|
38
|
+
if (typeof window !== 'undefined') {
|
|
39
|
+
window.removeEventListener(ARIA_VALIDATION_RUNTIME_CHANGED_EVENT, this.onRuntimeConfigChange);
|
|
40
|
+
}
|
|
60
41
|
}
|
|
61
42
|
observeVisibilityOnce() {
|
|
62
43
|
this.visibilityObserver = new IntersectionObserver(entries => {
|
|
@@ -81,10 +62,10 @@ export class AriaValidationController {
|
|
|
81
62
|
this.enqueueValidation();
|
|
82
63
|
}
|
|
83
64
|
enqueueValidation() {
|
|
84
|
-
if (!
|
|
65
|
+
if (!isAriaValidationEnabled())
|
|
85
66
|
return;
|
|
86
67
|
this.elementQueued = true;
|
|
87
|
-
|
|
68
|
+
queueValidation({
|
|
88
69
|
context: { include: this.host.el, exclude: this.knownValidationErrors },
|
|
89
70
|
onComplete: (error, results) => {
|
|
90
71
|
this.elementValidated = true;
|
|
@@ -113,7 +94,7 @@ export class AriaValidationController {
|
|
|
113
94
|
console.groupEnd();
|
|
114
95
|
this.knownValidationErrors.push(...targets);
|
|
115
96
|
},
|
|
116
|
-
})
|
|
97
|
+
});
|
|
117
98
|
}
|
|
118
99
|
discardVisibilityObserver() {
|
|
119
100
|
if (!this.visibilityObserver)
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { getAssetPath } from "@stencil/core";
|
|
2
|
-
import { Data, Effect } from "effect";
|
|
3
2
|
import { getLocationBase } from "./environment";
|
|
4
|
-
export class URLCreationError extends Data.TaggedError('URLCreationError') {
|
|
5
|
-
}
|
|
6
3
|
const relativeAssetsPath = '../../assets';
|
|
7
|
-
export const
|
|
4
|
+
export const createAssetUrlSafely = (file, pathFromAssetRoot) => {
|
|
8
5
|
const relativeAssetPath = joinPath(relativeAssetsPath, pathFromAssetRoot, file);
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
try {
|
|
7
|
+
return getAssetPath(relativeAssetPath);
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
console.warn(`Failed to create URL for asset "${file}" in path "${pathFromAssetRoot}".
|
|
11
|
+
Please provide an absolute URL in your app's 'setAssetPath(...)' configuration! Falling back to a relative URL, which may work in some environments but is not guaranteed to be correct.`);
|
|
12
|
+
return new URL(relativeAssetPath, getLocationBase());
|
|
13
|
+
}
|
|
11
14
|
};
|
|
12
15
|
function joinPath(...parts) {
|
|
13
16
|
return parts.filter(Boolean).join('/').replace('//', '/').replace('/./', '/');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Data, Effect } from "effect";
|
|
1
|
+
import { Data, Micro as Effect } from "effect";
|
|
2
2
|
export class FetchError extends Data.TaggedError('FetchError') {
|
|
3
3
|
}
|
|
4
4
|
export class NotFoundError extends Data.TaggedError('NotFoundError') {
|
|
@@ -9,7 +9,7 @@ export const httpClient = (input, init) => Effect.gen(function* () {
|
|
|
9
9
|
catch: error => new FetchError({ cause: error }),
|
|
10
10
|
});
|
|
11
11
|
if (response.status === 404) {
|
|
12
|
-
return yield* new NotFoundError({ url: response.url });
|
|
12
|
+
return yield* Effect.fail(new NotFoundError({ url: response.url }));
|
|
13
13
|
}
|
|
14
14
|
return response;
|
|
15
15
|
});
|
|
@@ -1,29 +1,30 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { describe, expect, it, vi } from "@stencil/vitest";
|
|
2
|
+
import { Micro as Effect } from "effect";
|
|
2
3
|
import { FetchError, NotFoundError, ResponseTextError, httpClient, responseAsText } from "./http";
|
|
3
4
|
describe('Http Utils', () => {
|
|
4
5
|
describe('httpClient', () => {
|
|
5
6
|
it('should return response on successful fetch', async () => {
|
|
6
7
|
const mockResponse = { status: 200, url: 'https://example.com' };
|
|
7
|
-
global.fetch =
|
|
8
|
+
global.fetch = vi.fn().mockResolvedValueOnce(mockResponse);
|
|
8
9
|
const result = await Effect.runPromise(httpClient('https://example.com'));
|
|
9
10
|
expect(result).toEqual(mockResponse);
|
|
10
11
|
});
|
|
11
12
|
it('should handle fetch errors', async () => {
|
|
12
13
|
const error = new Error('Network error');
|
|
13
|
-
global.fetch =
|
|
14
|
+
global.fetch = vi.fn().mockRejectedValueOnce(error);
|
|
14
15
|
const result = await Effect.runPromise(Effect.flip(httpClient('https://example.com')));
|
|
15
16
|
expect(result).toBeInstanceOf(FetchError);
|
|
16
17
|
expect(result.cause).toBe(error);
|
|
17
18
|
});
|
|
18
19
|
it('should return NotFoundError on 404 status', async () => {
|
|
19
20
|
const mockResponse = { status: 404, url: 'https://example.com/notfound' };
|
|
20
|
-
global.fetch =
|
|
21
|
+
global.fetch = vi.fn().mockResolvedValueOnce(mockResponse);
|
|
21
22
|
const result = await Effect.runPromise(Effect.flip(httpClient('https://example.com/notfound')));
|
|
22
23
|
expect(result).toBeInstanceOf(NotFoundError);
|
|
23
24
|
});
|
|
24
25
|
it('should pass RequestInit options to fetch', async () => {
|
|
25
26
|
const mockResponse = { status: 200, url: 'https://example.com' };
|
|
26
|
-
global.fetch =
|
|
27
|
+
global.fetch = vi.fn().mockResolvedValueOnce(mockResponse);
|
|
27
28
|
const init = { method: 'POST', headers: { 'Content-Type': 'application/json' } };
|
|
28
29
|
await Effect.runPromise(httpClient('https://example.com', init));
|
|
29
30
|
expect(global.fetch).toHaveBeenCalledWith('https://example.com', init);
|
|
@@ -31,13 +32,13 @@ describe('Http Utils', () => {
|
|
|
31
32
|
});
|
|
32
33
|
describe('responseAsText', () => {
|
|
33
34
|
it('should return text from response', async () => {
|
|
34
|
-
const mockResponse = { text:
|
|
35
|
+
const mockResponse = { text: vi.fn().mockResolvedValueOnce('Hello World') };
|
|
35
36
|
const result = await Effect.runPromise(responseAsText(mockResponse));
|
|
36
37
|
expect(result).toBe('Hello World');
|
|
37
38
|
});
|
|
38
39
|
it('should handle text reading errors', async () => {
|
|
39
40
|
const error = new Error('Read error');
|
|
40
|
-
const mockResponse = { text:
|
|
41
|
+
const mockResponse = { text: vi.fn().mockRejectedValueOnce(error) };
|
|
41
42
|
const result = await Effect.runPromise(Effect.flip(responseAsText(mockResponse)));
|
|
42
43
|
expect(result).toBeInstanceOf(ResponseTextError);
|
|
43
44
|
expect(result.message).toContain('Failed to read response text');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Brand, Data, Effect } from "effect";
|
|
1
|
+
import { Brand, Data, Micro as Effect } from "effect";
|
|
2
2
|
export const SVGString = Brand.refined(isValidSVG, () => Brand.error('SVG data is malformed'));
|
|
3
3
|
export class BrandValidationError extends Data.TaggedError('BrandValidationError') {
|
|
4
4
|
constructor(error, type) {
|
package/dist/components/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{g as getAssetPath,r as render,s as setAssetPath,a as setNonce,b as setPlatformOptions}from"./p-
|
|
1
|
+
export{g as getAssetPath,r as render,s as setAssetPath,a as setNonce,b as setPlatformOptions}from"./p-vi4YzJmv.js";import{r as e}from"./p-BsS3QvWn.js";export{c as clearIconCache}from"./p-BsS3QvWn.js";export{LmvzAction,defineCustomElement as defineCustomElementLmvzAction}from"./lmvz-action.js";export{LmvzButton,defineCustomElement as defineCustomElementLmvzButton}from"./lmvz-button.js";export{LmvzCard,defineCustomElement as defineCustomElementLmvzCard}from"./lmvz-card.js";export{LmvzChip,defineCustomElement as defineCustomElementLmvzChip}from"./lmvz-chip.js";export{LmvzHeader,defineCustomElement as defineCustomElementLmvzHeader}from"./lmvz-header.js";export{LmvzIcon,defineCustomElement as defineCustomElementLmvzIcon}from"./lmvz-icon.js";export{LmvzInput,defineCustomElement as defineCustomElementLmvzInput}from"./lmvz-input.js";export{LmvzMenuitem,defineCustomElement as defineCustomElementLmvzMenuitem}from"./lmvz-menuitem.js";const t=["primary","secondary","tertiary"],o=["small","default","large"],n=["xs","sm","md","lg"],m=[...n,"xl"],l=["text","email","password","tel","url","search","number"],i=[...n,"inherit"],d=["thin","medium","bold","filled"],u=["Logo","actions","adduser","alert","apple","arrow-down","arrow-left","arrow-right","arrow-up","book","bookmark","checkmark","chevron-down","chevron-left","chevron-right","chevron-up","close-l","close-sm","cog","computer","dashboard","delete","download","edit","external","facebook","favorite","filter","group","hide","home","info","instagram","letter","linkedin","logout","map","minus","navigation","plus","qr-scan","question","reader","reset","school","search","send","settings","share","shopping-cart","show","snapchat","sort","speech-bubble","star","student","upload","user","warn-circle","warn-triangle","whatsapp","world","x","youtube"];function f(t){return e(t).catch((e=>{console.error("Unhandled error in Effect:",e)}))}export{u as iconNames,i as iconSizes,d as iconWeights,l as inputTypes,f as run,o as scaleValues,n as sizes,m as textSizes,t as variants}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{p as t,H as e,c as s,h as c,d as i,t as o}from"./p-
|
|
1
|
+
import{p as t,H as e,c as s,h as c,d as i,t as o}from"./p-vi4YzJmv.js";const n=t(class extends e{constructor(t){super(),!1!==t&&this.__registerHost(),this.__attachShadow(),this.actionClick=s(this,"actionClick")}actionClick;_onClick(t){this.actionClick.emit(t)}render(){return c(i,{key:"71303bfe6ac64a96edd21800ae5e8c43a3a38c23",onClick:this._onClick.bind(this)},c("slot",{key:"94922fdfd355e7e4d1b78bedb80ae814c186b199"}))}static get style(){return":host{display:block}"}},[257,"lmvz-action"]),a=n,l=function(){"undefined"!=typeof customElements&&["lmvz-action"].forEach((t=>{"lmvz-action"===t&&(customElements.get(o(t))||customElements.define(o(t),n))}))};export{a as LmvzAction,l as defineCustomElement}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{p as t,c as o,h as e,d as r,t as n}from"./p-
|
|
1
|
+
import{p as t,c as o,h as e,d as r,t as n}from"./p-vi4YzJmv.js";import{c as a}from"./p-BfTCfPZ1.js";import{R as l,A as m}from"./p-CMteT-Yo.js";import{E as i}from"./p-CN0JX9-m.js";import{i as s,f as d}from"./p-B3JVFwO1.js";const c=t(class extends l{get el(){return this}inheritedAttributes={};formEl=null;formButtonEl=null;lmvzActivation;get ti(){return 0}scale="default";variant="secondary";disabled=!1;type="button";form;constructor(t){super(!1),!1!==t&&this.__registerHost(),this.__attachShadow(),this.lmvzActivation=o(this,"lmvzActivation"),this.addController(new m(this)),this.addController(new i(this,{localHandler:this.handleClick.bind(this),keys:["Enter"]}))}connectedCallback(){this.inheritedAttributes=s(this.el)}renderHiddenButton(){const t=this.formEl=d(this.form,this.el);if(!t)return;const{formButtonEl:o}=this;if(null!==o&&t.contains(o))return;const e=this.formButtonEl=document.createElement("button");e.type="submit",e.style.display="none",e.disabled=this.disabled,t.appendChild(e)}submitForm(t){this.formEl&&this.formButtonEl&&(t.preventDefault(),this.formButtonEl.click())}handleClick=t=>{"submit"===this.type&&this.submitForm(t)};render(){return this.renderHiddenButton(),e(r,{key:"cd4a63b866c801ad7f96f59d15e561a54bfe9ec2","aria-disabled":this.disabled?"true":null},e("button",{key:"a1e3ecb88fb84d724df4939519bb22d4b6725c1d",disabled:this.disabled,class:a(this.variant,{[this.scale??""]:!!this.scale,disabled:this.disabled}),...this.inheritedAttributes},e("slot",{key:"f1fd32c993b1ef9f6d62d6f3affa169c9368df78"})))}static get delegatesFocus(){return!0}static get style(){return" @layer lmvz-ds.reset, lmvz-ds.theme, lmvz-ds.components, lmvz-ds.overrides; @layer lmvz-ds.theme { @font-face { font-family: Router; src: local('Router-Book'), url('/assets/fonts/Router-Book.woff') format('woff'), local('Router'); font-weight: 400 normal; } @font-face { font-family: Router; src: local('Router-Medium'), url('/assets/fonts/Router-Medium.woff') format('woff'), local('Router'); font-weight: 500; } @font-face { font-family: Router; src: local('Router-Bold'), url('/assets/fonts/Router-Bold.woff') format('woff'), local('Router'); font-weight: 700 bold; } } @layer lmvz-ds.reset { h1, h2, h3, h4, h5, h6 { margin: 0; } } :host { button { --lmvz-button-color: var(--lmvz-component-color, var(--lmvz-semantic-color-int-on-primary, #ffffff)); --lmvz-button-padding-inline: var(--lmvz-button-padding, var(--lmvz-component-input-md-padding-x, clamp(0.75rem, 0.69rem + 0.26vw, 1rem))); --lmvz-button-padding-block: var(--lmvz-button-padding, var(--lmvz-component-input-md-padding-y, clamp(0.75rem, 0.69rem + 0.26vw, 1rem))); --lmvz-button-gap: var(--lmvz-component-input-md-gap-x, clamp(0.25rem, 0.16rem + 0.39vw, 0.63rem)); --lmvz-button-font: var(--lmvz-typography-body-lg, 400 clamp(1rem, 0.97rem + 0.13vw, 1.13rem) / 1.4 Router); --lmvz-button-radius: var(--lmvz-component-input-radius-default, 999px); --lmvz-button-border-width: 0; --lmvz-button-border-color: transparent; --lmvz-button-background: var(--lmvz-semantic-color-int-primary, #000000); display: inline-flex; align-items: center; justify-content: center; gap: var(--lmvz-button-gap); padding-block: var(--lmvz-button-padding-block); padding-inline: var(--lmvz-button-padding-inline); border-radius: var(--lmvz-button-radius); border: var(--lmvz-button-border-width) solid var(--lmvz-button-border-color); background-color: var(--lmvz-button-background); color: var(--lmvz-button-color); cursor: pointer; font: var(--lmvz-button-font); text-align: center; text-decoration: none; white-space: nowrap; transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease; } button > * { font: inherit; color: inherit; } button:focus-visible { outline: var(--lmvz-semantic-border-width-default, 1px) solid var(--lmvz-semantic-color-status-selected, #f1f9fe); outline-offset: var(--lmvz-component-input-sm-padding-x, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem)); } button:is([disabled], .disabled) { cursor: not-allowed; pointer-events: none; opacity: var(--lmvz-component-input-disabled-opacity, 40%); } button:not([disabled]):hover { --lmvz-button-background: var(--lmvz-semantic-color-int-primary-hover, #2e2e2e); } button:not([disabled]):active { --lmvz-button-background: var(--lmvz-semantic-color-int-primary-active, #545454); } button.secondary { --lmvz-button-background: var(--lmvz-semantic-color-int-secondary, #f0f0f0); --lmvz-button-color: var(--lmvz-semantic-color-int-on-secondary, #000000); --lmvz-button-border-width: var(--lmvz-semantic-border-width-default, 1px); --lmvz-button-border-color: var(--lmvz-semantic-color-border-default, #e0e0e0); } button.secondary:not([disabled], .disabled):hover { --lmvz-button-background: var(--lmvz-semantic-color-int-secondary-hover, #e0e0e0); --lmvz-button-border-color: var(--lmvz-semantic-color-border-hover, #c7c7c7); } button.secondary:not([disabled], .disabled):active { --lmvz-button-background: var(--lmvz-semantic-color-int-secondary-active, #d4d4d4); --lmvz-button-border-color: var(--lmvz-semantic-color-border-active, #d4d4d4); } button.tertiary { --lmvz-button-background: var(--lmvz-semantic-color-int-tertiary, #ffffff); --lmvz-button-color: var(--lmvz-semantic-color-int-on-tertiary, #545454); } button.tertiary:not([disabled], .disabled):hover { --lmvz-button-background: var(--lmvz-semantic-color-int-tertiary-hover, #f0f0f0); } button.tertiary:not([disabled], .disabled):active { --lmvz-button-background: var(--lmvz-semantic-color-int-tertiary-active, #e0e0e0); } button.small { --lmvz-button-padding-inline: var(--lmvz-component-input-sm-padding-x, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem)); --lmvz-button-padding-block: var(--lmvz-component-input-sm-padding-y, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem)); --lmvz-button-gap: var(--lmvz-component-input-sm-gap-x, clamp(0.25rem, 0.16rem + 0.39vw, 0.63rem)); --lmvz-button-font: var(--lmvz-typography-body-md, 400 clamp(0.88rem, 0.84rem + 0.13vw, 1rem) / 1.4 Router); } button.large { --lmvz-button-padding-inline: var(--lmvz-component-input-lg-padding-x, clamp(0.88rem, 0.78rem + 0.39vw, 1.25rem)); --lmvz-button-padding-block: var(--lmvz-component-input-lg-padding-y, clamp(0.88rem, 0.78rem + 0.39vw, 1.25rem)); --lmvz-button-gap: var(--lmvz-component-input-lg-gap-x, clamp(0.25rem, 0.16rem + 0.39vw, 0.63rem)); --lmvz-button-font: var(--lmvz-typography-body-lg, 400 clamp(1rem, 0.97rem + 0.13vw, 1.13rem) / 1.4 Router); } display: contents; } ::slotted(*) { --lmvz-component-color: var(--lmvz-button-color); } "}},[785,"lmvz-button",{ti:[2562,"tabindex"],scale:[513],variant:[513],disabled:[516],type:[1],form:[1]}]),v=c,u=function(){"undefined"!=typeof customElements&&["lmvz-button"].forEach((t=>{"lmvz-button"===t&&(customElements.get(n(t))||customElements.define(n(t),c))}))};export{v as LmvzButton,u as defineCustomElement}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{p as e,H as r,c as t,h as a,d as o,t as m}from"./p-
|
|
1
|
+
import{p as e,H as r,c as t,h as a,d as o,t as m}from"./p-vi4YzJmv.js";import{c as n}from"./p-CdYWDK7m.js";const l=e(class extends r{constructor(e){super(),!1!==e&&this.__registerHost(),this.primaryAction=t(this,"primaryAction")}cardTitle;imageUrl;description;primaryActionLabel="";primaryAction;get fallbackImage(){return n("card-placeholder.svg")}_onPrimaryClick(){this.primaryAction.emit()}_onOverflowClick(e){console.log(e)}render(){return a(o,{key:"ba2e8d9e25428c744da2470cbd677306c56b09ae",role:"article"},a("div",{key:"54ff7545559a4b6fb00c94909717234f4dfedd7c",class:"top"},a("div",{key:"7bff35f247b6e8aca9b6346103139daa65ca16a3",class:"image-wrapper",style:{backgroundImage:`url(${this.imageUrl??this.fallbackImage})`}},a("div",{key:"c2c3d21227175b9dc0a55c75294f6c21bc713a26",class:"chip-slot"},a("slot",{key:"1a7002aab5fc3f9f698c3d1678f8819ea36f91d3",name:"chip"})))),a("div",{key:"a313321abe4da83db4b2ba64fdefa28edde93d41",class:"bottom"},a("header",{key:"f5ba333fcaa59d5b4f61dee94aba4628f49db9d7"},a("h2",{key:"b7d9ad6944b136476703cde89f885b189583eef1",class:"title"},this.cardTitle)),a("p",{key:"6594626904a4f9fbc53d5956b71bbdefe00add8c",class:"description"},this.description),a("div",{key:"d8bbfebeb572fcf6990160a0dba7c5ae8a5a7fc7",class:"actions"},a("button",{key:"6311a97a18412f8fbf8eb33e8a0f7a17700e71c6",class:"primary",onClick:this._onPrimaryClick.bind(this),"data-testid":"primary"},this.primaryActionLabel),a("button",{key:"12033ad5018d100f84f0149d83dc965d8e5b2c66",class:"tertiary","aria-label":"More actions",onClick:this._onOverflowClick},a("span",{key:"e11f8008542b4f7f70d1273bb31200c50d02aabb",class:"icon-placeholder"},"...")))))}static get assetsDirs(){return["../../assets"]}static get style(){return"@layer lmvz-ds.reset, lmvz-ds.theme, lmvz-ds.components, lmvz-ds.overrides; @layer lmvz-ds.theme { @font-face { font-family: Router; src: local('Router-Book'), url('/assets/fonts/Router-Book.woff') format('woff'), local('Router'); font-weight: 400 normal; } @font-face { font-family: Router; src: local('Router-Medium'), url('/assets/fonts/Router-Medium.woff') format('woff'), local('Router'); font-weight: 500; } @font-face { font-family: Router; src: local('Router-Bold'), url('/assets/fonts/Router-Bold.woff') format('woff'), local('Router'); font-weight: 700 bold; } } @layer lmvz-ds.reset { h1, h2, h3, h4, h5, h6 { margin: 0; } } .sc-lmvz-card-h { button { --lmvz-button-color: var(--lmvz-component-color, var(--lmvz-semantic-color-int-on-primary, #ffffff)); --lmvz-button-padding-inline: var(--lmvz-button-padding, var(--lmvz-component-input-md-padding-x, clamp(0.75rem, 0.69rem + 0.26vw, 1rem))); --lmvz-button-padding-block: var(--lmvz-button-padding, var(--lmvz-component-input-md-padding-y, clamp(0.75rem, 0.69rem + 0.26vw, 1rem))); --lmvz-button-gap: var(--lmvz-component-input-md-gap-x, clamp(0.25rem, 0.16rem + 0.39vw, 0.63rem)); --lmvz-button-font: var(--lmvz-typography-body-lg, 400 clamp(1rem, 0.97rem + 0.13vw, 1.13rem) / 1.4 Router); --lmvz-button-radius: var(--lmvz-component-input-radius-default, 999px); --lmvz-button-border-width: 0; --lmvz-button-border-color: transparent; --lmvz-button-background: var(--lmvz-semantic-color-int-primary, #000000); display: inline-flex; align-items: center; justify-content: center; gap: var(--lmvz-button-gap); padding-block: var(--lmvz-button-padding-block); padding-inline: var(--lmvz-button-padding-inline); border-radius: var(--lmvz-button-radius); border: var(--lmvz-button-border-width) solid var(--lmvz-button-border-color); background-color: var(--lmvz-button-background); color: var(--lmvz-button-color); cursor: pointer; font: var(--lmvz-button-font); text-align: center; text-decoration: none; white-space: nowrap; transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease; } button > * { font: inherit; color: inherit; } button:focus-visible { outline: var(--lmvz-semantic-border-width-default, 1px) solid var(--lmvz-semantic-color-status-selected, #f1f9fe); outline-offset: var(--lmvz-component-input-sm-padding-x, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem)); } button:is([disabled], .disabled) { cursor: not-allowed; pointer-events: none; opacity: var(--lmvz-component-input-disabled-opacity, 40%); } button:not([disabled]):hover { --lmvz-button-background: var(--lmvz-semantic-color-int-primary-hover, #2e2e2e); } button:not([disabled]):active { --lmvz-button-background: var(--lmvz-semantic-color-int-primary-active, #545454); } button.secondary { --lmvz-button-background: var(--lmvz-semantic-color-int-secondary, #f0f0f0); --lmvz-button-color: var(--lmvz-semantic-color-int-on-secondary, #000000); --lmvz-button-border-width: var(--lmvz-semantic-border-width-default, 1px); --lmvz-button-border-color: var(--lmvz-semantic-color-border-default, #e0e0e0); } button.secondary:not([disabled], .disabled):hover { --lmvz-button-background: var(--lmvz-semantic-color-int-secondary-hover, #e0e0e0); --lmvz-button-border-color: var(--lmvz-semantic-color-border-hover, #c7c7c7); } button.secondary:not([disabled], .disabled):active { --lmvz-button-background: var(--lmvz-semantic-color-int-secondary-active, #d4d4d4); --lmvz-button-border-color: var(--lmvz-semantic-color-border-active, #d4d4d4); } button.tertiary { --lmvz-button-background: var(--lmvz-semantic-color-int-tertiary, #ffffff); --lmvz-button-color: var(--lmvz-semantic-color-int-on-tertiary, #545454); } button.tertiary:not([disabled], .disabled):hover { --lmvz-button-background: var(--lmvz-semantic-color-int-tertiary-hover, #f0f0f0); } button.tertiary:not([disabled], .disabled):active { --lmvz-button-background: var(--lmvz-semantic-color-int-tertiary-active, #e0e0e0); } button.small { --lmvz-button-padding-inline: var(--lmvz-component-input-sm-padding-x, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem)); --lmvz-button-padding-block: var(--lmvz-component-input-sm-padding-y, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem)); --lmvz-button-gap: var(--lmvz-component-input-sm-gap-x, clamp(0.25rem, 0.16rem + 0.39vw, 0.63rem)); --lmvz-button-font: var(--lmvz-typography-body-md, 400 clamp(0.88rem, 0.84rem + 0.13vw, 1rem) / 1.4 Router); } button.large { --lmvz-button-padding-inline: var(--lmvz-component-input-lg-padding-x, clamp(0.88rem, 0.78rem + 0.39vw, 1.25rem)); --lmvz-button-padding-block: var(--lmvz-component-input-lg-padding-y, clamp(0.88rem, 0.78rem + 0.39vw, 1.25rem)); --lmvz-button-gap: var(--lmvz-component-input-lg-gap-x, clamp(0.25rem, 0.16rem + 0.39vw, 0.63rem)); --lmvz-button-font: var(--lmvz-typography-body-lg, 400 clamp(1rem, 0.97rem + 0.13vw, 1.13rem) / 1.4 Router); } display: flex; min-width: var(--lmvz-other-component-card-minwidth, 20.4375rem); max-width: var(--lmvz-other-component-card-maxwidth, 21.6875rem); flex-direction: column; align-items: flex-start; border-radius: var(--lmvz-semantic-border-radius-lg, 14px); border: var(--lmvz-semantic-border-width-default, 1px) solid var(--lmvz-semantic-color-border-default, #e0e0e0); background: var(--lmvz-semantic-color-surface-primary, #ffffff); } *.sc-lmvz-card { color: var(--lmvz-semantic-color-on-surface-primary, #000000); font: var(--lmvz-typography-body-md, 400 clamp(0.88rem, 0.84rem + 0.13vw, 1rem) / 1.4 Router); } .top.sc-lmvz-card { display: flex; padding: var(--lmvz-dimension-8-12, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem)); flex-direction: column; justify-content: center; align-items: center; align-self: stretch; } .bottom.sc-lmvz-card { display: flex; min-width: 150px; padding: var(--lmvz-dimension-4-6, clamp(0.25rem, 0.22rem + 0.13vw, 0.38rem)) var(--lmvz-dimension-10-14, clamp(0.63rem, 0.56rem + 0.26vw, 0.88rem)) var(--lmvz-dimension-10-14, clamp(0.63rem, 0.56rem + 0.26vw, 0.88rem)) var(--lmvz-dimension-10-14, clamp(0.63rem, 0.56rem + 0.26vw, 0.88rem)); flex-direction: column; align-items: flex-start; align-self: stretch; } .title.sc-lmvz-card { margin: 0; display: flex; justify-content: center; align-items: center; align-self: stretch; padding-bottom: var(--lmvz-global-s4, 4px); overflow-wrap: break-word; font: var(--lmvz-typography-heading-2xl, 500 clamp(2rem, 1.94rem + 0.26vw, 2.25rem) / 1.2 Router); } .description.sc-lmvz-card { display: flex; margin: 0; padding-bottom: var(--lmvz-component-body-sm-padding-bottom, clamp(0.25rem, 0.16rem + 0.39vw, 0.63rem)); align-items: flex-start; align-self: stretch; white-space: pre-line; font: var(--lmvz-typography-body-md, 400 clamp(0.88rem, 0.84rem + 0.13vw, 1rem) / 1.4 Router); } .image-wrapper.sc-lmvz-card { aspect-ratio: 4 / 3; width: 100%; background-size: cover; background-position: center; flex: 1 0 0; align-self: stretch; border-radius: var(--lmvz-semantic-border-radius-md, 6px); } .actions.sc-lmvz-card { margin-top: var(--lmvz-component-form-wrapper-gap-y, clamp(1.13rem, 0.97rem + 0.65vw, 1.75rem)); display: flex; align-items: center; gap: var(--lmvz-component-input-md-gap-x, clamp(0.25rem, 0.16rem + 0.39vw, 0.63rem)); align-self: stretch; } button.primary.sc-lmvz-card, lmvz-button.primary.sc-lmvz-card { display: flex; justify-content: center; align-items: center; gap: var(--lmvz-component-input-md-gap-x, clamp(0.25rem, 0.16rem + 0.39vw, 0.63rem)); flex: 1 0 0; }"}},[774,"lmvz-card",{cardTitle:[1,"card-title"],imageUrl:[1,"image-url"],description:[1],primaryActionLabel:[1,"primary-action-label"]}]),i=l,c=function(){"undefined"!=typeof customElements&&["lmvz-card"].forEach((e=>{"lmvz-card"===e&&(customElements.get(m(e))||customElements.define(m(e),l))}))};export{i as LmvzCard,c as defineCustomElement}
|