@epa-wg/custom-element-dist 0.0.33 → 0.0.34
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/.claude/settings.local.json +18 -0
- package/.github/workflows/deploy.yml +59 -0
- package/.idea/copilot.data.migration.agent.xml +6 -0
- package/.idea/copilot.data.migration.ask.xml +6 -0
- package/.idea/copilot.data.migration.edit.xml +6 -0
- package/.idea/custom-element-dist.iml +2 -0
- package/.storybook/main.ts +20 -17
- package/.storybook/preview.ts +23 -23
- package/README.md +6 -4
- package/coverage/block-navigation.js +1 -1
- package/coverage/coverage-final.json +4 -3
- package/coverage/index.html +34 -19
- package/coverage/sorter.js +21 -7
- package/coverage/src/custom-element/coverage.svg +1 -1
- package/coverage/src/custom-element/custom-element.js/coverage.svg +1 -1
- package/coverage/src/custom-element/custom-element.js.html +435 -378
- package/coverage/src/custom-element/http-request.js/coverage.svg +1 -1
- package/coverage/src/custom-element/http-request.js.html +38 -17
- package/coverage/src/custom-element/index.html +26 -26
- package/coverage/src/custom-element/local-storage.js.html +1 -1
- package/coverage/src/custom-element/location-element.js.html +1 -1
- package/coverage/src/custom-element/module-url.js.html +1 -1
- package/coverage/src/index.html +1 -1
- package/coverage/src/material/theme/colors.js/coverage.svg +10 -0
- package/coverage/src/material/theme/colors.js.html +217 -0
- package/coverage/src/material/theme/coverage.svg +10 -0
- package/coverage/src/material/theme/index.html +116 -0
- package/coverage/src/mocks/handlers.ts.html +1 -1
- package/coverage/src/mocks/index.html +1 -1
- package/coverage/src/stories/frame.canvas.ts.html +1 -1
- package/coverage/src/stories/http-request.stories.ts.html +1 -1
- package/coverage/src/stories/index.html +1 -1
- package/coverage/src/stories/testStoryBook.ts.html +12 -12
- package/coverage/src/sum.ts.html +1 -1
- package/dist/{custom-element-WnOqmEOe.js → custom-element-BoYMoUtP.js} +193 -183
- package/dist/custom-element-BqtjrCRF.cjs +97 -0
- package/dist/custom-element-bundle.cjs +1 -1
- package/dist/custom-element-bundle.js +3 -3
- package/dist/demo/a.html +10 -3
- package/dist/demo/a.svg +26 -26
- package/dist/demo/html-template.html +4 -3
- package/dist/demo/s.xml +3856 -67
- package/dist/demo/s.xslt +13 -72
- package/dist/demo/s1.xml +3706 -0
- package/dist/http-request-DSaowcG1.cjs +1 -0
- package/dist/{http-request-BOvP4KTl.js → http-request-DTCzZ1gc.js} +15 -9
- package/package.json +2 -2
- package/public/demo/a.html +10 -3
- package/public/demo/a.svg +26 -26
- package/public/demo/html-template.html +4 -3
- package/public/demo/s.xml +3856 -67
- package/public/demo/s.xslt +13 -72
- package/public/demo/s1.xml +3706 -0
- package/src/custom-element/custom-element.js +28 -9
- package/src/custom-element/demo/a.html +10 -3
- package/src/custom-element/demo/a.svg +26 -26
- package/src/custom-element/demo/html-template.html +4 -3
- package/src/custom-element/demo/s.xml +3856 -67
- package/src/custom-element/demo/s.xslt +13 -72
- package/src/custom-element/demo/s1.xml +3706 -0
- package/src/custom-element/http-request.js +7 -0
- package/src/custom-element/ide/web-types-dce.json +1 -1
- package/src/custom-element/ide/web-types-xsl.json +1 -1
- package/src/material/angular.css +987 -987
- package/src/material/components/action.html +262 -0
- package/src/material/components/autocomplete.html +167 -239
- package/src/material/components/badge.html +238 -239
- package/src/material/components/dropdown.html +0 -1
- package/src/material/components/icon-link.html +160 -161
- package/src/material/components/icon.html +251 -252
- package/src/material/components/input.html +569 -570
- package/src/material/components/menu.html +235 -236
- package/src/material/components.html +157 -158
- package/src/material/demo.css +36 -36
- package/src/material/index.html +109 -110
- package/src/material/material.css +356 -356
- package/src/material/theme/Base-Principles.md +339 -0
- package/src/material/theme/README.md +298 -18
- package/src/material/theme/UI Domain Model in web applications.svg +1 -0
- package/src/material/theme/User Semantic Theme tokens.svg +1 -0
- package/src/material/theme/action-pending-poc.html +62 -0
- package/src/material/theme/actions-color.html +141 -0
- package/src/material/theme/colors-light.html +631 -0
- package/src/material/theme/colors-native.html +51 -0
- package/src/material/theme/colors-poc.html +66 -0
- package/src/material/theme/colors.html +297 -0
- package/src/material/theme/colors.js +44 -0
- package/src/material/theme/consumer-theme.css +745 -0
- package/src/material/theme/semantic.css +132 -132
- package/src/material/theme/style-bug.html +123 -0
- package/src/material/theme/theme-data.css +43 -0
- package/src/material/theme/theme-data.xhtml +2926 -0
- package/src/material/theme/todo.md +274 -0
- package/src/material/theme/tokens/action-colors.png +0 -0
- package/src/material/theme/tokens/cem-article-illustration-4x1-letterbox-2000x500.png +0 -0
- package/src/material/theme/tokens/cem-breakpoints.md +519 -0
- package/src/material/theme/tokens/cem-colors.md +715 -0
- package/src/material/theme/tokens/cem-consumerflow-typography-matrix.svg +198 -0
- package/src/material/theme/tokens/cem-coupling.md +372 -0
- package/src/material/theme/tokens/cem-data-vs-reading-numerals.svg +164 -0
- package/src/material/theme/tokens/cem-dimension.md +625 -0
- package/src/material/theme/tokens/cem-layering.md +562 -0
- package/src/material/theme/tokens/cem-m3-parity.md +343 -0
- package/src/material/theme/tokens/cem-responsive.md +238 -0
- package/src/material/theme/tokens/cem-shape.md +691 -0
- package/src/material/theme/tokens/cem-stroke-density-illustration-4to1-v3.svg +102 -0
- package/src/material/theme/tokens/cem-stroke.md +480 -0
- package/src/material/theme/tokens/cem-timing.md +198 -0
- package/src/material/theme/tokens/cem-typography-model-stack.svg +64 -0
- package/src/material/theme/tokens/cem-voice-fonts-typography.md +718 -0
- package/src/material/theme/tokens/cem-voice-ladder.svg +91 -0
- package/src/material/theme/tokens/chips.png +0 -0
- package/src/material/theme/tokens/columns-page.png +0 -0
- package/src/material/theme/tokens/initials.png +0 -0
- package/src/material/theme/tokens/nav-buttons.png +0 -0
- package/src/material/theme/tokens/script.png +0 -0
- package/src/material/theme/tokens/sufler.png +0 -0
- package/src/material/theme/tokens/typography-icons.png +0 -0
- package/src/mocks/versions.mock.ts +1 -1
- package/src/stories/__screenshots__/dom-merge.test.stories.ts/dom-merge-dom-merge-OrderPreservingOn2ndTransform-1.png +0 -0
- package/src/stories/__screenshots__/xslt-conditionals.test.stories.ts/xslt-conditionals-xslt-conditionals-MultipleIfOrderingWorkaround-1.png +0 -0
- package/src/stories/dom-merge.test.stories.ts +25 -1
- package/src/stories/xslt-conditionals.test.stories.ts +492 -0
- package/src/stories/xslt-if.test.stories.ts +89 -0
- package/storybook-static/assets/{Color-F6OSRLHC-Cbp293x2.js → Color-F6OSRLHC-CzTOSlqB.js} +1 -1
- package/storybook-static/assets/{Configure-BrFr4SLE.js → Configure-7GqRsAoJ.js} +1 -1
- package/storybook-static/assets/{DocsRenderer-CFRXHY34-DhHzJiIO.js → DocsRenderer-CFRXHY34-Duc5rSIm.js} +2 -2
- package/storybook-static/assets/{attributes.test.stories-Gg9LQTEK.js → attributes.test.stories-DYuxF8h1.js} +1 -1
- package/storybook-static/assets/{css.test.stories-B_3ltOrx.js → css.test.stories-LOmvINyb.js} +1 -1
- package/storybook-static/assets/{custom-element-CPnvJnn8.js → custom-element-Bwx7otrT.js} +6 -6
- package/storybook-static/assets/{dom-merge.test.stories-nQxcgLoM.js → dom-merge.test.stories-CEKhWjaS.js} +47 -6
- package/storybook-static/assets/entry-preview-BNCt9WBs.js +26 -0
- package/storybook-static/assets/{entry-preview-docs-Dwczwtsc.js → entry-preview-docs-CbF8-81D.js} +2 -2
- package/storybook-static/assets/{external-template.test.stories-DZ-rjnfd.js → external-template.test.stories-jHu0wsJ-.js} +1 -1
- package/storybook-static/assets/{form.test.stories-DQhPYtMj.js → form.test.stories-CUyUnmwP.js} +1 -1
- package/storybook-static/assets/{frame.canvas-ClTqYyMN.js → frame.canvas-E5n9h6j1.js} +1 -1
- package/storybook-static/assets/{handlers-CLkps6Nz.js → handlers-F7GUfMqr.js} +1 -1
- package/storybook-static/assets/http-request-BWeEEBkP.js +1 -0
- package/storybook-static/assets/{http-request.stories-jo0f73nw.js → http-request.stories-wyX5-QOv.js} +1 -1
- package/storybook-static/assets/{iframe-CZwRpnn9.js → iframe-BS_DPWl0.js} +11 -11
- package/storybook-static/assets/{index-Dr4PwNfd.js → index-CGuyH0k-.js} +87 -87
- package/storybook-static/assets/{index-CJQtnF9V.js → index-DB7LLObI.js} +1 -1
- package/storybook-static/assets/index-DO1nmyvI.js +11 -0
- package/storybook-static/assets/{index-B68YUdzy.js → index-V1EGs-wm.js} +3 -3
- package/storybook-static/assets/{local-storage.test.stories-uA5EKRPf.js → local-storage.test.stories-BxOhsf1k.js} +1 -1
- package/storybook-static/assets/{location-element.test.stories-Cu-6Elcg.js → location-element.test.stories-DqhvvUoa.js} +1 -1
- package/storybook-static/assets/{module-url.test.stories-CD_wusXQ.js → module-url.test.stories-C1gG9G7Y.js} +1 -1
- package/storybook-static/assets/{preview-BFlNN3Wj.js → preview-Bn8igYMp.js} +1 -1
- package/storybook-static/assets/{preview-CuCH40jj.js → preview-Cwy1XFu2.js} +2 -2
- package/storybook-static/assets/{preview-Cm4PPhHS.js → preview-D6sehqkw.js} +1 -1
- package/storybook-static/assets/{set-url.test.stories-CY7B9BVZ.js → set-url.test.stories-BKQNdknJ.js} +1 -1
- package/storybook-static/assets/{slice-events.test.stories-BVnPXm6e.js → slice-events.test.stories-ChqULCeA.js} +1 -1
- package/storybook-static/assets/{slots.test.stories-Dxsa9KdA.js → slots.test.stories-BlyLoCRe.js} +1 -1
- package/storybook-static/assets/{version-select.test.stories-Buga1PAa.js → version-select.test.stories-CPGSh1tR.js} +1 -1
- package/storybook-static/assets/xslt-conditionals.test.stories-YC6QPqWZ.js +633 -0
- package/storybook-static/assets/xslt-if.test.stories-BRSWy2-x.js +71 -0
- package/storybook-static/demo/a.html +10 -3
- package/storybook-static/demo/a.svg +26 -26
- package/storybook-static/demo/html-template.html +4 -3
- package/storybook-static/demo/s.xml +3856 -67
- package/storybook-static/demo/s.xslt +13 -72
- package/storybook-static/demo/s1.xml +3706 -0
- package/storybook-static/iframe.html +2 -2
- package/storybook-static/index.json +1 -1
- package/storybook-static/project.json +1 -1
- package/storybook-static/sb-addons/essentials-controls-1/manager-bundle.js +69 -66
- package/storybook-static/sb-addons/essentials-docs-3/manager-bundle.js +62 -59
- package/dist/custom-element-6slVaFEs.cjs +0 -97
- package/dist/http-request-DPrY7mGh.cjs +0 -1
- package/storybook-static/assets/attributes.test.stories-CzWkKw0e.js +0 -1
- package/storybook-static/assets/entry-preview-DHVXbf3x.js +0 -26
- package/storybook-static/assets/external-template.test.stories-BivZqBTp.js +0 -1
- package/storybook-static/assets/http-request-DNq59pnj.js +0 -1
- package/storybook-static/assets/index-BwkS7JH_.js +0 -8
- package/storybook-static/assets/module-url.test.stories-CTjUAk3J.js +0 -1
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="860" viewBox="0 0 1200 860" role="img" aria-label="Voice ladder: seven levels with ink thickness and speech prosody mappings">
|
|
3
|
+
<defs>
|
|
4
|
+
<style>
|
|
5
|
+
:root {
|
|
6
|
+
--cem-ink: #111;
|
|
7
|
+
--cem-surface: #fff;
|
|
8
|
+
--cem-outline: #c7c7c7;
|
|
9
|
+
--cem-muted: #666;
|
|
10
|
+
--cem-accent: #005a9c;
|
|
11
|
+
--cem-soft: #f6f7f9;
|
|
12
|
+
}
|
|
13
|
+
.frame { fill: var(--cem-surface); stroke: var(--cem-outline); stroke-width: 2; rx: 18; }
|
|
14
|
+
.step { fill: var(--cem-surface); stroke: var(--cem-outline); stroke-width: 1.8; rx: 18; }
|
|
15
|
+
.step-accent { fill: var(--cem-surface); stroke: var(--cem-accent); stroke-width: 2.4; rx: 18; }
|
|
16
|
+
.title { font: 700 32px system-ui, -apple-system, "Segoe UI", Arial, sans-serif; fill: var(--cem-ink); }
|
|
17
|
+
.muted { font: 400 16px system-ui, -apple-system, "Segoe UI", Arial, sans-serif; fill: var(--cem-muted); }
|
|
18
|
+
.h { font: 650 20px system-ui, -apple-system, "Segoe UI", Arial, sans-serif; fill: var(--cem-ink); }
|
|
19
|
+
.t { font: 400 16px system-ui, -apple-system, "Segoe UI", Arial, sans-serif; fill: var(--cem-ink); }
|
|
20
|
+
.mono { font: 550 15px ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; fill: var(--cem-muted); }
|
|
21
|
+
.pill { fill: var(--cem-soft); stroke: var(--cem-outline); stroke-width: 1.2; rx: 999; }
|
|
22
|
+
.pilltext { font: 650 13px ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; fill: var(--cem-accent); }
|
|
23
|
+
.colh { font: 650 16px system-ui, -apple-system, "Segoe UI", Arial, sans-serif; fill: var(--cem-muted); }
|
|
24
|
+
</style>
|
|
25
|
+
</defs>
|
|
26
|
+
|
|
27
|
+
<rect x="30" y="30" width="1140" height="800" class="frame"/>
|
|
28
|
+
|
|
29
|
+
<text x="70" y="92" class="title">Voice ladder (7 levels) with ink and speech projections</text>
|
|
30
|
+
<text x="70" y="125" class="muted">Use the same voice semantics across modalities. Map voice → ink thickness and voice → read‑aloud prosody.</text>
|
|
31
|
+
|
|
32
|
+
<text x="90" y="170" class="colh">Voice level</text>
|
|
33
|
+
<text x="340" y="170" class="colh">Ink projection</text>
|
|
34
|
+
<text x="690" y="170" class="colh">Speech projection (TTS)</text>
|
|
35
|
+
|
|
36
|
+
<rect x="70" y="195" width="1060" height="78" class="step"/>
|
|
37
|
+
<text x="90" y="225" class="h">whisper</text>
|
|
38
|
+
<rect x="90" y="238" width="150" height="24" class="pill"/><text x="102" y="255" class="pilltext">de-emphasize</text>
|
|
39
|
+
<text x="340" y="225" class="t">ink thickness:</text>
|
|
40
|
+
<text x="455" y="225" class="mono">var(--cem-thickness-x-light)</text>
|
|
41
|
+
<text x="690" y="225" class="t">rate / pitch / volume:</text>
|
|
42
|
+
<text x="865" y="225" class="mono">1.00 / 0.95 / 0.65</text>
|
|
43
|
+
|
|
44
|
+
<rect x="70" y="285" width="1060" height="78" class="step"/>
|
|
45
|
+
<text x="90" y="315" class="h">soft</text>
|
|
46
|
+
<rect x="90" y="328" width="120" height="24" class="pill"/><text x="102" y="345" class="pilltext">secondary</text>
|
|
47
|
+
<text x="340" y="315" class="t">ink thickness:</text>
|
|
48
|
+
<text x="455" y="315" class="mono">var(--cem-thickness-light)</text>
|
|
49
|
+
<text x="690" y="315" class="t">rate / pitch / volume:</text>
|
|
50
|
+
<text x="865" y="315" class="mono">1.00 / 0.98 / 0.75</text>
|
|
51
|
+
|
|
52
|
+
<rect x="70" y="375" width="1060" height="78" class="step"/>
|
|
53
|
+
<text x="90" y="405" class="h">gentle</text>
|
|
54
|
+
<rect x="90" y="418" width="130" height="24" class="pill"/><text x="102" y="435" class="pilltext">navigation</text>
|
|
55
|
+
<text x="340" y="405" class="t">ink thickness:</text>
|
|
56
|
+
<text x="455" y="405" class="mono">var(--cem-thickness-normal)</text>
|
|
57
|
+
<text x="690" y="405" class="t">rate / pitch / volume:</text>
|
|
58
|
+
<text x="865" y="405" class="mono">1.00 / 1.00 / 0.85</text>
|
|
59
|
+
|
|
60
|
+
<rect x="70" y="465" width="1060" height="78" class="step-accent"/>
|
|
61
|
+
<text x="90" y="495" class="h">regular</text>
|
|
62
|
+
<rect x="90" y="508" width="140" height="24" class="pill"/><text x="102" y="525" class="pilltext">default</text>
|
|
63
|
+
<text x="340" y="495" class="t">ink thickness:</text>
|
|
64
|
+
<text x="455" y="495" class="mono">var(--cem-thickness-normal)</text>
|
|
65
|
+
<text x="690" y="495" class="t">rate / pitch / volume:</text>
|
|
66
|
+
<text x="865" y="495" class="mono">1.00 / 1.00 / 1.00</text>
|
|
67
|
+
|
|
68
|
+
<rect x="70" y="555" width="1060" height="78" class="step"/>
|
|
69
|
+
<text x="90" y="585" class="h">firm</text>
|
|
70
|
+
<rect x="90" y="598" width="140" height="24" class="pill"/><text x="102" y="615" class="pilltext">actions</text>
|
|
71
|
+
<text x="340" y="585" class="t">ink thickness:</text>
|
|
72
|
+
<text x="455" y="585" class="mono">var(--cem-thickness-bold)</text>
|
|
73
|
+
<text x="690" y="585" class="t">rate / pitch / volume:</text>
|
|
74
|
+
<text x="865" y="585" class="mono">0.98 / 1.03 / 1.00</text>
|
|
75
|
+
|
|
76
|
+
<rect x="70" y="645" width="1060" height="78" class="step"/>
|
|
77
|
+
<text x="90" y="675" class="h">strong</text>
|
|
78
|
+
<rect x="90" y="688" width="160" height="24" class="pill"/><text x="102" y="705" class="pilltext">section focus</text>
|
|
79
|
+
<text x="340" y="675" class="t">ink thickness:</text>
|
|
80
|
+
<text x="455" y="675" class="mono">var(--cem-thickness-x-bold)</text>
|
|
81
|
+
<text x="690" y="675" class="t">rate / pitch / volume:</text>
|
|
82
|
+
<text x="865" y="675" class="mono">0.96 / 1.06 / 1.00</text>
|
|
83
|
+
|
|
84
|
+
<rect x="70" y="735" width="1060" height="78" class="step"/>
|
|
85
|
+
<text x="90" y="765" class="h">loud</text>
|
|
86
|
+
<rect x="90" y="778" width="180" height="24" class="pill"/><text x="102" y="795" class="pilltext">use sparingly</text>
|
|
87
|
+
<text x="340" y="765" class="t">ink thickness:</text>
|
|
88
|
+
<text x="455" y="765" class="mono">var(--cem-thickness-xx-bold)</text>
|
|
89
|
+
<text x="690" y="765" class="t">rate / pitch / volume:</text>
|
|
90
|
+
<text x="865" y="765" class="mono">0.94 / 1.10 / 1.00</text>
|
|
91
|
+
</svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -154,7 +154,7 @@ export const OrderPreservingOn2ndTransform:Story =
|
|
|
154
154
|
|
|
155
155
|
await fireEvent.click(canvas.getByTestId('cb2'));
|
|
156
156
|
await expect(await canvas.findByText('#2')).toBeInTheDocument();
|
|
157
|
-
await expect(canvas.getByTestId("beforeC1").nextElementSibling).toEqual(
|
|
157
|
+
await expect(canvas.getByTestId("beforeC1").nextElementSibling.textContent).toEqual('#1')
|
|
158
158
|
},
|
|
159
159
|
};
|
|
160
160
|
export const ReadSystemValidityMessage:Story =
|
|
@@ -194,6 +194,30 @@ export const ReadSystemValidityMessage:Story =
|
|
|
194
194
|
},
|
|
195
195
|
};
|
|
196
196
|
|
|
197
|
+
export const EmbedDCE:Story =
|
|
198
|
+
{ args : {title: 'Render inner components', body:`
|
|
199
|
+
<template id="test-icon">
|
|
200
|
+
<attribute name="img"></attribute>
|
|
201
|
+
<i>{img}</i>
|
|
202
|
+
</template>
|
|
203
|
+
<template id="test-button">
|
|
204
|
+
<attribute name="text"></attribute>
|
|
205
|
+
<button>
|
|
206
|
+
<slot>{text}</slot>
|
|
207
|
+
</button>
|
|
208
|
+
</template>
|
|
209
|
+
|
|
210
|
+
<custom-element src="#test-icon" tag="test-icon"></custom-element>
|
|
211
|
+
<custom-element src="#test-button" tag="test-button"></custom-element>
|
|
212
|
+
<test-button>icon:<test-icon img="👍"></test-icon></test-button>
|
|
213
|
+
`}
|
|
214
|
+
, play: async ({canvasElement}) =>
|
|
215
|
+
{
|
|
216
|
+
const canvas = within(canvasElement);
|
|
217
|
+
await expect(await canvas.findByText('👍')).toBeInTheDocument();
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
|
|
197
221
|
//#region unit tests
|
|
198
222
|
/* istanbul ignore else -- @preserve */
|
|
199
223
|
if( 'test' === import.meta.env.MODE &&
|
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
// noinspection DuplicatedCode
|
|
2
|
+
|
|
3
|
+
import type { StoryObj } from '@storybook/web-components';
|
|
4
|
+
import { expect, userEvent, within } from '@storybook/test';
|
|
5
|
+
|
|
6
|
+
import '../custom-element/custom-element.js';
|
|
7
|
+
|
|
8
|
+
type TProps = { title: string; tag: string; template: string; payload: string };
|
|
9
|
+
|
|
10
|
+
type Story = StoryObj<TProps>;
|
|
11
|
+
|
|
12
|
+
function sleep(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms)); }
|
|
13
|
+
|
|
14
|
+
function render(args: TProps) {
|
|
15
|
+
const { title, tag, template, payload } = args;
|
|
16
|
+
return `
|
|
17
|
+
<fieldset>
|
|
18
|
+
<legend>${title}</legend>
|
|
19
|
+
<custom-element tag="${tag}" hidden>
|
|
20
|
+
<template>
|
|
21
|
+
${template}
|
|
22
|
+
</template>
|
|
23
|
+
</custom-element>
|
|
24
|
+
${payload}
|
|
25
|
+
</fieldset>
|
|
26
|
+
`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const meta = {
|
|
30
|
+
title: 'xslt-conditionals',
|
|
31
|
+
render
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default meta;
|
|
35
|
+
|
|
36
|
+
export const IfTrue: Story = {
|
|
37
|
+
args: {
|
|
38
|
+
title: 'xsl:if - condition is true',
|
|
39
|
+
tag: 'if-true-test',
|
|
40
|
+
template: `
|
|
41
|
+
<attribute name="show-message"></attribute>
|
|
42
|
+
<if test="//@show-message">
|
|
43
|
+
<span data-testid="result">Message is visible</span>
|
|
44
|
+
</if>
|
|
45
|
+
`,
|
|
46
|
+
payload: `<if-true-test show-message="yes"></if-true-test>`
|
|
47
|
+
},
|
|
48
|
+
play: async ({ canvasElement }) => {
|
|
49
|
+
const canvas = within(canvasElement);
|
|
50
|
+
await sleep(50);
|
|
51
|
+
const result = await canvas.findByTestId('result');
|
|
52
|
+
expect(result).toBeInTheDocument();
|
|
53
|
+
expect(result).toHaveTextContent('Message is visible');
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const IfFalse: Story = {
|
|
58
|
+
args: {
|
|
59
|
+
title: 'xsl:if - condition is false',
|
|
60
|
+
tag: 'if-false-test',
|
|
61
|
+
template: `
|
|
62
|
+
<attribute name="show-message"></attribute>
|
|
63
|
+
<if test="//@show-message = 'yes'">
|
|
64
|
+
<span data-testid="hidden-result">Should not appear</span>
|
|
65
|
+
</if>
|
|
66
|
+
<span data-testid="fallback">Fallback content</span>
|
|
67
|
+
`,
|
|
68
|
+
payload: `<if-false-test show-message="no"></if-false-test>`
|
|
69
|
+
},
|
|
70
|
+
play: async ({ canvasElement }) => {
|
|
71
|
+
const canvas = within(canvasElement);
|
|
72
|
+
await sleep(50);
|
|
73
|
+
const fallback = await canvas.findByTestId('fallback');
|
|
74
|
+
expect(fallback).toBeInTheDocument();
|
|
75
|
+
expect(canvasElement.querySelector('[data-testid="hidden-result"]')).toBeNull();
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const IfNotExists: Story = {
|
|
80
|
+
args: {
|
|
81
|
+
title: 'xsl:if - attribute not exists',
|
|
82
|
+
tag: 'if-not-exists-test',
|
|
83
|
+
template: `
|
|
84
|
+
<attribute name="optional"></attribute>
|
|
85
|
+
<if test="not(//attributes/@optional)">
|
|
86
|
+
<span data-testid="result">No attribute provided</span>
|
|
87
|
+
</if>
|
|
88
|
+
<if test="//attributes/@optional">
|
|
89
|
+
<span data-testid="has-attr">Attribute exists</span>
|
|
90
|
+
</if>
|
|
91
|
+
`,
|
|
92
|
+
payload: `<if-not-exists-test></if-not-exists-test>`
|
|
93
|
+
},
|
|
94
|
+
play: async ({ canvasElement }) => {
|
|
95
|
+
const canvas = within(canvasElement);
|
|
96
|
+
await sleep(50);
|
|
97
|
+
const result = await canvas.findByTestId('result');
|
|
98
|
+
expect(result).toBeInTheDocument();
|
|
99
|
+
expect(result).toHaveTextContent('No attribute provided');
|
|
100
|
+
expect(canvasElement.querySelector('[data-testid="has-attr"]')).toBeNull();
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export const ChooseWhenOtherwise: Story = {
|
|
105
|
+
args: {
|
|
106
|
+
title: 'xsl:choose/when/otherwise - basic switch',
|
|
107
|
+
tag: 'choose-basic-test',
|
|
108
|
+
template: `
|
|
109
|
+
<attribute name="status"></attribute>
|
|
110
|
+
<choose>
|
|
111
|
+
<when test="//attributes/@status = 'success'">
|
|
112
|
+
<span data-testid="result" class="success">Operation succeeded</span>
|
|
113
|
+
</when>
|
|
114
|
+
<when test="//attributes/@status = 'error'">
|
|
115
|
+
<span data-testid="result" class="error">Operation failed</span>
|
|
116
|
+
</when>
|
|
117
|
+
<otherwise>
|
|
118
|
+
<span data-testid="result" class="unknown">Unknown status</span>
|
|
119
|
+
</otherwise>
|
|
120
|
+
</choose>
|
|
121
|
+
`,
|
|
122
|
+
payload: `<choose-basic-test status="success"></choose-basic-test>`
|
|
123
|
+
},
|
|
124
|
+
play: async ({ canvasElement }) => {
|
|
125
|
+
const canvas = within(canvasElement);
|
|
126
|
+
await sleep(50);
|
|
127
|
+
const result = await canvas.findByTestId('result');
|
|
128
|
+
expect(result).toBeInTheDocument();
|
|
129
|
+
expect(result).toHaveTextContent('Operation succeeded');
|
|
130
|
+
expect(result).toHaveClass('success');
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export const ChooseSecondWhen: Story = {
|
|
135
|
+
args: {
|
|
136
|
+
title: 'xsl:choose - second when branch',
|
|
137
|
+
tag: 'choose-second-test',
|
|
138
|
+
template: `
|
|
139
|
+
<attribute name="status"></attribute>
|
|
140
|
+
<choose>
|
|
141
|
+
<when test="//attributes/@status = 'success'">
|
|
142
|
+
<span data-testid="result" class="success">Operation succeeded</span>
|
|
143
|
+
</when>
|
|
144
|
+
<when test="//attributes/@status = 'error'">
|
|
145
|
+
<span data-testid="result" class="error">Operation failed</span>
|
|
146
|
+
</when>
|
|
147
|
+
<otherwise>
|
|
148
|
+
<span data-testid="result" class="unknown">Unknown status</span>
|
|
149
|
+
</otherwise>
|
|
150
|
+
</choose>
|
|
151
|
+
`,
|
|
152
|
+
payload: `<choose-second-test status="error"></choose-second-test>`
|
|
153
|
+
},
|
|
154
|
+
play: async ({ canvasElement }) => {
|
|
155
|
+
const canvas = within(canvasElement);
|
|
156
|
+
await sleep(50);
|
|
157
|
+
const result = await canvas.findByTestId('result');
|
|
158
|
+
expect(result).toBeInTheDocument();
|
|
159
|
+
expect(result).toHaveTextContent('Operation failed');
|
|
160
|
+
expect(result).toHaveClass('error');
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
export const ChooseOtherwise: Story = {
|
|
165
|
+
args: {
|
|
166
|
+
title: 'xsl:choose - otherwise fallback',
|
|
167
|
+
tag: 'choose-otherwise-test',
|
|
168
|
+
template: `
|
|
169
|
+
<attribute name="status"></attribute>
|
|
170
|
+
<choose>
|
|
171
|
+
<when test="//attributes/@status = 'success'">
|
|
172
|
+
<span data-testid="result" class="success">Operation succeeded</span>
|
|
173
|
+
</when>
|
|
174
|
+
<when test="//attributes/@status = 'error'">
|
|
175
|
+
<span data-testid="result" class="error">Operation failed</span>
|
|
176
|
+
</when>
|
|
177
|
+
<otherwise>
|
|
178
|
+
<span data-testid="result" class="unknown">Unknown status</span>
|
|
179
|
+
</otherwise>
|
|
180
|
+
</choose>
|
|
181
|
+
`,
|
|
182
|
+
payload: `<choose-otherwise-test status="pending"></choose-otherwise-test>`
|
|
183
|
+
},
|
|
184
|
+
play: async ({ canvasElement }) => {
|
|
185
|
+
const canvas = within(canvasElement);
|
|
186
|
+
await sleep(50);
|
|
187
|
+
const result = await canvas.findByTestId('result');
|
|
188
|
+
expect(result).toBeInTheDocument();
|
|
189
|
+
expect(result).toHaveTextContent('Unknown status');
|
|
190
|
+
expect(result).toHaveClass('unknown');
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
export const ChooseNoAttribute: Story = {
|
|
195
|
+
args: {
|
|
196
|
+
title: 'xsl:choose - no attribute provided',
|
|
197
|
+
tag: 'choose-no-attr-test',
|
|
198
|
+
template: `
|
|
199
|
+
<attribute name="level"></attribute>
|
|
200
|
+
<choose>
|
|
201
|
+
<when test="//attributes/@level = 'high'">
|
|
202
|
+
<span data-testid="result">High priority</span>
|
|
203
|
+
</when>
|
|
204
|
+
<when test="//attributes/@level = 'low'">
|
|
205
|
+
<span data-testid="result">Low priority</span>
|
|
206
|
+
</when>
|
|
207
|
+
<otherwise>
|
|
208
|
+
<span data-testid="result">Default priority</span>
|
|
209
|
+
</otherwise>
|
|
210
|
+
</choose>
|
|
211
|
+
`,
|
|
212
|
+
payload: `<choose-no-attr-test></choose-no-attr-test>`
|
|
213
|
+
},
|
|
214
|
+
play: async ({ canvasElement }) => {
|
|
215
|
+
const canvas = within(canvasElement);
|
|
216
|
+
await sleep(50);
|
|
217
|
+
const result = await canvas.findByTestId('result');
|
|
218
|
+
expect(result).toBeInTheDocument();
|
|
219
|
+
expect(result).toHaveTextContent('Default priority');
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
export const NestedConditions: Story = {
|
|
224
|
+
args: {
|
|
225
|
+
title: 'Nested conditionals',
|
|
226
|
+
tag: 'nested-cond-test',
|
|
227
|
+
template: `
|
|
228
|
+
<attribute name="type"></attribute>
|
|
229
|
+
<attribute name="active"></attribute>
|
|
230
|
+
<choose>
|
|
231
|
+
<when test="//attributes/@type = 'user'">
|
|
232
|
+
<if test="//attributes/@active = 'true'">
|
|
233
|
+
<span data-testid="result">Active user</span>
|
|
234
|
+
</if>
|
|
235
|
+
<if test="//attributes/@active != 'true'">
|
|
236
|
+
<span data-testid="result">Inactive user</span>
|
|
237
|
+
</if>
|
|
238
|
+
</when>
|
|
239
|
+
<otherwise>
|
|
240
|
+
<span data-testid="result">Not a user</span>
|
|
241
|
+
</otherwise>
|
|
242
|
+
</choose>
|
|
243
|
+
`,
|
|
244
|
+
payload: `<nested-cond-test type="user" active="true"></nested-cond-test>`
|
|
245
|
+
},
|
|
246
|
+
play: async ({ canvasElement }) => {
|
|
247
|
+
const canvas = within(canvasElement);
|
|
248
|
+
await sleep(50);
|
|
249
|
+
const result = await canvas.findByTestId('result');
|
|
250
|
+
expect(result).toBeInTheDocument();
|
|
251
|
+
expect(result).toHaveTextContent('Active user');
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
export const NestedConditionsInactive: Story = {
|
|
256
|
+
args: {
|
|
257
|
+
title: 'Nested conditionals - inactive user',
|
|
258
|
+
tag: 'nested-cond-inactive-test',
|
|
259
|
+
template: `
|
|
260
|
+
<attribute name="type"></attribute>
|
|
261
|
+
<attribute name="active"></attribute>
|
|
262
|
+
<choose>
|
|
263
|
+
<when test="//attributes/@type = 'user'">
|
|
264
|
+
<if test="//attributes/@active = 'true'">
|
|
265
|
+
<span data-testid="result">Active user</span>
|
|
266
|
+
</if>
|
|
267
|
+
<if test="//attributes/@active != 'true'">
|
|
268
|
+
<span data-testid="result">Inactive user</span>
|
|
269
|
+
</if>
|
|
270
|
+
</when>
|
|
271
|
+
<otherwise>
|
|
272
|
+
<span data-testid="result">Not a user</span>
|
|
273
|
+
</otherwise>
|
|
274
|
+
</choose>
|
|
275
|
+
`,
|
|
276
|
+
payload: `<nested-cond-inactive-test type="user" active="false"></nested-cond-inactive-test>`
|
|
277
|
+
},
|
|
278
|
+
play: async ({ canvasElement }) => {
|
|
279
|
+
const canvas = within(canvasElement);
|
|
280
|
+
await sleep(50);
|
|
281
|
+
const result = await canvas.findByTestId('result');
|
|
282
|
+
expect(result).toBeInTheDocument();
|
|
283
|
+
expect(result).toHaveTextContent('Inactive user');
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
export const NumericComparison: Story = {
|
|
288
|
+
args: {
|
|
289
|
+
title: 'Numeric comparison in conditions',
|
|
290
|
+
tag: 'numeric-cond-test',
|
|
291
|
+
template: `
|
|
292
|
+
<attribute name="count"></attribute>
|
|
293
|
+
<choose>
|
|
294
|
+
<when test="//attributes/@count > 10">
|
|
295
|
+
<span data-testid="result">Many items</span>
|
|
296
|
+
</when>
|
|
297
|
+
<when test="//attributes/@count > 0">
|
|
298
|
+
<span data-testid="result">Some items</span>
|
|
299
|
+
</when>
|
|
300
|
+
<otherwise>
|
|
301
|
+
<span data-testid="result">No items</span>
|
|
302
|
+
</otherwise>
|
|
303
|
+
</choose>
|
|
304
|
+
`,
|
|
305
|
+
payload: `<numeric-cond-test count="15"></numeric-cond-test>`
|
|
306
|
+
},
|
|
307
|
+
play: async ({ canvasElement }) => {
|
|
308
|
+
const canvas = within(canvasElement);
|
|
309
|
+
await sleep(50);
|
|
310
|
+
const result = await canvas.findByTestId('result');
|
|
311
|
+
expect(result).toBeInTheDocument();
|
|
312
|
+
expect(result).toHaveTextContent('Many items');
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
export const NumericComparisonLow: Story = {
|
|
317
|
+
args: {
|
|
318
|
+
title: 'Numeric comparison - low value',
|
|
319
|
+
tag: 'numeric-cond-low-test',
|
|
320
|
+
template: `
|
|
321
|
+
<attribute name="count"></attribute>
|
|
322
|
+
<choose>
|
|
323
|
+
<when test="//attributes/@count > 10">
|
|
324
|
+
<span data-testid="result">Many items</span>
|
|
325
|
+
</when>
|
|
326
|
+
<when test="//attributes/@count > 0">
|
|
327
|
+
<span data-testid="result">Some items</span>
|
|
328
|
+
</when>
|
|
329
|
+
<otherwise>
|
|
330
|
+
<span data-testid="result">No items</span>
|
|
331
|
+
</otherwise>
|
|
332
|
+
</choose>
|
|
333
|
+
`,
|
|
334
|
+
payload: `<numeric-cond-low-test count="5"></numeric-cond-low-test>`
|
|
335
|
+
},
|
|
336
|
+
play: async ({ canvasElement }) => {
|
|
337
|
+
const canvas = within(canvasElement);
|
|
338
|
+
await sleep(50);
|
|
339
|
+
const result = await canvas.findByTestId('result');
|
|
340
|
+
expect(result).toBeInTheDocument();
|
|
341
|
+
expect(result).toHaveTextContent('Some items');
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
export const BooleanAndCondition: Story = {
|
|
346
|
+
args: {
|
|
347
|
+
title: 'Boolean AND condition',
|
|
348
|
+
tag: 'and-cond-test',
|
|
349
|
+
template: `
|
|
350
|
+
<attribute name="logged-in"></attribute>
|
|
351
|
+
<attribute name="admin"></attribute>
|
|
352
|
+
<if test="//attributes/@logged-in = 'true' and //attributes/@admin = 'true'">
|
|
353
|
+
<span data-testid="result">Admin panel access granted</span>
|
|
354
|
+
</if>
|
|
355
|
+
<if test="not(//attributes/@logged-in = 'true' and //attributes/@admin = 'true')">
|
|
356
|
+
<span data-testid="result">Access denied</span>
|
|
357
|
+
</if>
|
|
358
|
+
`,
|
|
359
|
+
payload: `<and-cond-test logged-in="true" admin="true"></and-cond-test>`
|
|
360
|
+
},
|
|
361
|
+
play: async ({ canvasElement }) => {
|
|
362
|
+
const canvas = within(canvasElement);
|
|
363
|
+
await sleep(50);
|
|
364
|
+
const result = await canvas.findByTestId('result');
|
|
365
|
+
expect(result).toBeInTheDocument();
|
|
366
|
+
expect(result).toHaveTextContent('Admin panel access granted');
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
export const BooleanOrCondition: Story = {
|
|
371
|
+
args: {
|
|
372
|
+
title: 'Boolean OR condition',
|
|
373
|
+
tag: 'or-cond-test',
|
|
374
|
+
template: `
|
|
375
|
+
<attribute name="role"></attribute>
|
|
376
|
+
<if test="//attributes/@role = 'admin' or //attributes/@role = 'moderator'">
|
|
377
|
+
<span data-testid="result">Elevated privileges</span>
|
|
378
|
+
</if>
|
|
379
|
+
<if test="not(//attributes/@role = 'admin' or //attributes/@role = 'moderator')">
|
|
380
|
+
<span data-testid="result">Standard user</span>
|
|
381
|
+
</if>
|
|
382
|
+
`,
|
|
383
|
+
payload: `<or-cond-test role="moderator"></or-cond-test>`
|
|
384
|
+
},
|
|
385
|
+
play: async ({ canvasElement }) => {
|
|
386
|
+
const canvas = within(canvasElement);
|
|
387
|
+
await sleep(50);
|
|
388
|
+
const result = await canvas.findByTestId('result');
|
|
389
|
+
expect(result).toBeInTheDocument();
|
|
390
|
+
expect(result).toHaveTextContent('Elevated privileges');
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
export const MultipleInstances: Story = {
|
|
395
|
+
args: {
|
|
396
|
+
title: 'Multiple instances with different conditions',
|
|
397
|
+
tag: 'multi-instance-test',
|
|
398
|
+
template: `
|
|
399
|
+
<attribute name="data-testid"></attribute>
|
|
400
|
+
<attribute name="variant"></attribute>
|
|
401
|
+
<choose>
|
|
402
|
+
<when test="//attributes/@variant = 'primary'">
|
|
403
|
+
<button data-testid="{$data-testid}-primary" class="primary">Primary Button</button>
|
|
404
|
+
</when>
|
|
405
|
+
<when test="//attributes/@variant = 'secondary'">
|
|
406
|
+
<button data-testid="{$data-testid}-secondary" class="secondary">Secondary Button</button>
|
|
407
|
+
</when>
|
|
408
|
+
<otherwise>
|
|
409
|
+
<button data-testid="{$data-testid}-otherwise" class="default">Default Button</button>
|
|
410
|
+
</otherwise>
|
|
411
|
+
</choose>
|
|
412
|
+
`,
|
|
413
|
+
payload: `
|
|
414
|
+
<multi-instance-test data-testid="btn1" variant="primary"></multi-instance-test>
|
|
415
|
+
<multi-instance-test data-testid="btn2" variant="secondary"></multi-instance-test>
|
|
416
|
+
<multi-instance-test data-testid="btn3" variant="unknown"></multi-instance-test>
|
|
417
|
+
`
|
|
418
|
+
},
|
|
419
|
+
play: async ({ canvasElement }) => {
|
|
420
|
+
const canvas = within(canvasElement);
|
|
421
|
+
await sleep(50);
|
|
422
|
+
|
|
423
|
+
const btn1 = await canvas.findByTestId('btn1-primary');
|
|
424
|
+
expect(btn1).toHaveTextContent('Primary Button');
|
|
425
|
+
expect(btn1).toHaveClass('primary');
|
|
426
|
+
|
|
427
|
+
const btn2 = await canvas.findByTestId('btn2-secondary');
|
|
428
|
+
expect(btn2).toHaveTextContent('Secondary Button');
|
|
429
|
+
expect(btn2).toHaveClass('secondary');
|
|
430
|
+
|
|
431
|
+
const btn3 = await canvas.findByTestId('btn3-otherwise');
|
|
432
|
+
expect(btn3).toHaveTextContent('Default Button');
|
|
433
|
+
expect(btn3).toHaveClass('default');
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
export const MultipleIfOrderingIssue: Story = {
|
|
439
|
+
args: {
|
|
440
|
+
title: 'KNOWN ISSUE: Multiple IF blocks - out of order',
|
|
441
|
+
tag: 'multi-if-order-issue',
|
|
442
|
+
template: `
|
|
443
|
+
<div data-testid="whole-text">
|
|
444
|
+
<label><input type="checkbox" data-testid="toggle-a" slice="show-a" value="AA" /> A</label>
|
|
445
|
+
|
|
446
|
+
<hr/>
|
|
447
|
+
▶
|
|
448
|
+
<if test="//show-a = 'AA'">
|
|
449
|
+
!A
|
|
450
|
+
</if>
|
|
451
|
+
◀
|
|
452
|
+
</div>
|
|
453
|
+
<if test="//show-a = 'AA'">
|
|
454
|
+
<div data-testid="t-1">T1</div>
|
|
455
|
+
</if>
|
|
456
|
+
`,
|
|
457
|
+
payload: `
|
|
458
|
+
<multi-if-order-issue></multi-if-order-issue>
|
|
459
|
+
`
|
|
460
|
+
},
|
|
461
|
+
play: async ({ canvasElement }) => {
|
|
462
|
+
const canvas = within(canvasElement);
|
|
463
|
+
|
|
464
|
+
// Initially ▶\s+◀ should be visible, !A should not
|
|
465
|
+
const container = await canvas.findByTestId('whole-text');
|
|
466
|
+
expect(container.textContent).to.toMatch(/▶\s+◀/);
|
|
467
|
+
|
|
468
|
+
// check A - show !A
|
|
469
|
+
const toggleA = await canvas.findByTestId('toggle-a');
|
|
470
|
+
debugger;
|
|
471
|
+
await userEvent.click(toggleA);
|
|
472
|
+
|
|
473
|
+
expect( await await canvas.findByTestId('t-1')).toBeInTheDocument();
|
|
474
|
+
// !A is rendered
|
|
475
|
+
expect(container.textContent).to.toMatch(/\!A/);
|
|
476
|
+
// !A afer ▶
|
|
477
|
+
expect(container.textContent).to.toMatch(/▶\s+\!A/);
|
|
478
|
+
// !A before ◀
|
|
479
|
+
expect(container.textContent).to.toMatch(/\!A\s+◀/);
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
//#region unit tests
|
|
484
|
+
/* istanbul ignore else -- @preserve */
|
|
485
|
+
if ('test' === import.meta.env.MODE &&
|
|
486
|
+
!import.meta.url.includes('skiptest')) {
|
|
487
|
+
const mod = await import('./xslt-conditionals.test.stories.ts?skiptest');
|
|
488
|
+
const { testStoryBook } = await import('./testStoryBook');
|
|
489
|
+
const { describe } = await import('vitest');
|
|
490
|
+
describe(meta.title, () => testStoryBook(mod, meta));
|
|
491
|
+
}
|
|
492
|
+
//#endregion
|