@simple-reporting/base 1.0.15 → 1.0.17

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.
Files changed (101) hide show
  1. package/dev/eslint.config.js +5 -0
  2. package/dev/package.json +1 -1
  3. package/dev/src/App.vue +2 -7
  4. package/dev/src/assets/scss/components/icons.scss +287 -0
  5. package/dev/src/assets/scss/components/note/accordion.scss +57 -24
  6. package/dev/src/assets/scss/components/round-button.scss +75 -0
  7. package/dev/src/assets/scss/general.scss +2 -0
  8. package/dev/src/assets/scss/placeholders.scss +315 -1
  9. package/dev/src/assets/scss/web.scss +1 -0
  10. package/dev/src/components/{PageHeader.vue → Page/Header.vue} +1 -2
  11. package/dev/src/views/ArticleView.vue +2 -3
  12. package/dev/srl.config.json +23 -8
  13. package/livingdocs/010.Titles/020.title-h2/title-h2.html +5 -6
  14. package/livingdocs/010.Titles/030.title-h3/title-h3.html +4 -5
  15. package/livingdocs/010.Titles/040.title-h4/title-h4.html +4 -5
  16. package/livingdocs/020.Text/060.quote-with-portrait/scss/general.scss +1 -0
  17. package/livingdocs/040.Media/010.table/ld-conf.json +1 -6
  18. package/livingdocs/040.Media/010.table/scss/general.scss +53 -1
  19. package/livingdocs/040.Media/010.table/table.html +11 -9
  20. package/livingdocs/040.Media/010.table/table.vue +0 -1
  21. package/livingdocs/040.Media/030.video/ld-conf.json +3 -0
  22. package/livingdocs/040.Media/030.video/scss/general.scss +4 -0
  23. package/livingdocs/040.Media/030.video/scss/web.scss +23 -32
  24. package/livingdocs/040.Media/030.video/video.html +13 -12
  25. package/livingdocs/040.Media/030.video/video.vue +53 -0
  26. package/livingdocs/060.Buttons/010.button-container/button-container.html +5 -0
  27. package/livingdocs/060.Buttons/010.button-container/ld-conf.json +19 -0
  28. package/livingdocs/060.Buttons/010.button-container/properties.json +1 -0
  29. package/livingdocs/060.Buttons/010.button-container/scss/app.scss +1 -0
  30. package/livingdocs/060.Buttons/010.button-container/scss/editor.scss +1 -0
  31. package/livingdocs/060.Buttons/010.button-container/scss/general.scss +6 -0
  32. package/livingdocs/060.Buttons/010.button-container/scss/pdf.scss +1 -0
  33. package/livingdocs/060.Buttons/010.button-container/scss/web.scss +1 -0
  34. package/livingdocs/060.Buttons/010.button-container/scss/word.scss +1 -0
  35. package/livingdocs/060.Buttons/010.button-container/scss/xbrl.scss +2 -0
  36. package/livingdocs/060.Buttons/020.button/button.html +4 -0
  37. package/livingdocs/060.Buttons/020.button/ld-conf.json +15 -0
  38. package/livingdocs/060.Buttons/020.button/scss/app.scss +1 -0
  39. package/livingdocs/060.Buttons/020.button/scss/editor.scss +1 -0
  40. package/livingdocs/060.Buttons/020.button/scss/general.scss +89 -0
  41. package/livingdocs/060.Buttons/020.button/scss/pdf.scss +1 -0
  42. package/livingdocs/060.Buttons/020.button/scss/web.scss +1 -0
  43. package/livingdocs/060.Buttons/020.button/scss/word.scss +1 -0
  44. package/livingdocs/060.Buttons/020.button/scss/xbrl.scss +3 -0
  45. package/livingdocs/090.Signatures/010.signature-container/scss/web.scss +1 -0
  46. package/livingdocs/110.PDF/040.pdf-chapter-title/scss/editor.scss +0 -6
  47. package/livingdocs/999.Properties/hide-quote-characters/properties.json +1 -1
  48. package/livingdocs/999.Properties/icon/properties.json +19 -0
  49. package/livingdocs/999.Properties/reverse/properties.json +7 -0
  50. package/package.json +1 -1
  51. package/plugins/viteSrlPlugin.d.ts +5 -1
  52. package/plugins/viteSrlPlugin.js +7 -3
  53. package/scripts/build.js +118 -17
  54. package/scripts/ldd/mapLdd.js +2 -2
  55. package/scripts/vue/components.js +14 -15
  56. package/srl/components/Srl/{Note → Category}/Accordion/Content.vue +7 -1
  57. package/srl/components/Srl/{Note → Category}/Accordion.vue +2 -1
  58. package/srl/components/Srl/Menu/Item.vue +7 -3
  59. package/srl/components/Srl/Menu.vue +2 -1
  60. package/srl/composables/config.ts +13 -14
  61. package/srl/composables/cssStyles.ts +1 -1
  62. package/srl/composables/menu.ts +5 -1
  63. package/srl/composables/viewPort.ts +4 -3
  64. package/srl/plugins/initProject.ts +1 -1
  65. package/srl/utils/html.ts +3 -3
  66. package/dev/src/components/SrlPage/KFCApplication/KFCApplication.vue +0 -715
  67. package/dev/src/components/SrlPage/KFCApplication/KFCDropdownCharts.vue +0 -112
  68. package/dev/src/components/SrlPage/KFCApplication/KFCDropdownPeriod.vue +0 -85
  69. package/dev/src/components/SrlPage/KFCApplication/KFCTable.vue +0 -63
  70. package/dev/src/components/SrlPage/KFCApplication/hooks/kfcData.ts +0 -9
  71. package/dev/src/components/SrlPage/KFCApplication/models/KFCApplication.ts +0 -183
  72. package/dev/src/components/SrlPage/KFCApplication/scss/_highcharts-basic.scss +0 -1136
  73. package/dev/src/components/SrlPage/KFCApplication/scss/_highcharts-custom.scss +0 -71
  74. package/dev/src/components/SrlPage/KFCApplication/scss/_highcharts-general.scss +0 -113
  75. package/dev/src/components/SrlPage/KFCApplication/scss/_iz-keyfigure-comparison-dropdown.scss +0 -189
  76. package/dev/src/components/SrlPage/KFCApplication/scss/_iz-keyfigure-comparison.scss +0 -151
  77. package/dev/src/components/SrlPage/KFCApplication/scss/_kfc-loading.scss +0 -40
  78. package/dev/src/components/SrlPage/KFCApplication/scss/_kfc-print.scss +0 -20
  79. package/dev/src/components/SrlPage/KFCApplication/scss/_srl-button-kfc.scss +0 -21
  80. package/dev/src/components/SrlPage/KFCApplication/scss/_variables.scss +0 -10
  81. package/dev/src/components/SrlPage/KFCApplication/services/xlsxParser.ts +0 -194
  82. package/dev/src/components/SrlPage/KFCApplication/theme/SvgColumnView.vue +0 -28
  83. package/dev/src/components/SrlPage/KFCApplication/theme/SvgDownloadChart.vue +0 -26
  84. package/dev/src/components/SrlPage/KFCApplication/theme/SvgDropdown.vue +0 -18
  85. package/dev/src/components/SrlPage/KFCApplication/theme/SvgIndexedValues.vue +0 -18
  86. package/dev/src/components/SrlPage/KFCApplication/theme/SvgLegendSwap.vue +0 -18
  87. package/dev/src/components/SrlPage/KFCApplication/theme/SvgLineView.vue +0 -28
  88. package/dev/src/components/SrlPage/KFCApplication/theme/SvgPDFChart.vue +0 -26
  89. package/dev/src/components/SrlPage/KFCApplication/theme/SvgPrintChart.vue +0 -33
  90. package/dev/src/components/SrlPage/KFCApplication/theme/SvgTableView.vue +0 -67
  91. package/dev/src/components/SrlPage/KFCApplication/utils/XDownloader.js +0 -455
  92. package/dev/src/components/SrlPage/KFCApplication/utils/XDownloaderStyle.js +0 -44
  93. package/dev/src/components/SrlPage/KFCApplication/utils/XTableNamer.js +0 -68
  94. /package/dev/src/components/{BypassLinks.vue → Page/BypassLinks.vue} +0 -0
  95. /package/dev/src/components/{PageFooter.vue → Page/Footer.vue} +0 -0
  96. /package/dev/src/components/{PageMain.vue → Page/Main.vue} +0 -0
  97. /package/dev/src/components/{MainNavigation.vue → Page/MainNavigation.vue} +0 -0
  98. /package/dev/src/components/{NavLanguages.vue → Page/NavLanguages.vue} +0 -0
  99. /package/dev/src/components/{PrevNext.vue → Page/PrevNext.vue} +0 -0
  100. /package/srl/{components/App.vue → App.vue} +0 -0
  101. /package/srl/components/Srl/{Note → Category}/Accordion/Toggle.vue +0 -0
@@ -0,0 +1,89 @@
1
+ @use "srl";
2
+ @use "assets/scss/placeholders";
3
+
4
+ .srl-button {
5
+ display: flex;
6
+ gap: srl.spacer-get(100);
7
+ align-items: center;
8
+ padding: srl.spacer-get(200);
9
+ background-color: srl.colors-white-1000();
10
+ border: 1px solid srl.colors-primary-1000();
11
+ text-decoration: none;
12
+ transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease;
13
+ border-radius: srl.system-size-unit(24);
14
+ cursor: pointer;
15
+ @include srl.typography-button-text();
16
+
17
+ @media (prefers-reduced-motion: reduce) {
18
+ transition-duration: 0s;
19
+ }
20
+
21
+ &.srl-has-icon,
22
+ [class*="-after"] &,
23
+ .srl-header__meta-navigation &,
24
+ &[class*="-before"],
25
+ &[class*="-after"] {
26
+ padding: srl.system-size-unit(11) srl.spacer-get(200);
27
+ }
28
+
29
+ [class*="-after"] &,
30
+ &[class*="-after"] {
31
+ flex-direction: row-reverse;
32
+ }
33
+
34
+ &[aria-expanded="true"] {
35
+ border-bottom: none;
36
+ border-bottom-left-radius: 0;
37
+ border-bottom-right-radius: 0;
38
+ }
39
+
40
+ &:hover {
41
+ background-color: srl.colors-primary-1000();
42
+ //border-color: srl.colors-white-1000();
43
+ color: srl.colors-white-1000();
44
+
45
+ &[aria-expanded="true"] {
46
+ border-color: srl.colors-primary-1000();
47
+ }
48
+
49
+ .srl-bg-primary-1000 & {
50
+ border-color: srl.colors-secondary-1000();
51
+ background-color: srl.colors-secondary-1000();
52
+ }
53
+ }
54
+
55
+ &:focus {
56
+ background-color: srl.colors-primary-1000();
57
+ border-color: srl.colors-primary-1000();
58
+ color: srl.colors-white-1000();
59
+
60
+ .srl-bg-primary-1000 & {
61
+ background-color: srl.colors-primary-1000();
62
+ border-color: srl.colors-primary-1000();
63
+ color: srl.colors-white-1000();
64
+ }
65
+ }
66
+ }
67
+
68
+ .srl-button__icon {
69
+ display: none;
70
+
71
+ [class*="srl-icon-"][class*="-before"] &,
72
+ [class*="srl-icon-"][class*="-after"] & {
73
+ display: block;
74
+ @extend %srl-icon;
75
+ @extend %srl-icon-mask;
76
+ }
77
+
78
+ .srl-icon-arrow-left-before & {
79
+ @extend %srl-icon-arrow-left;
80
+ }
81
+
82
+ .srl-icon-arrow-right-after & {
83
+ @extend %srl-icon-arrow-right;
84
+ }
85
+
86
+ .srl-icon-download-after & {
87
+ @extend %srl-icon-download;
88
+ }
89
+ }
@@ -0,0 +1 @@
1
+ @use "srl";
@@ -0,0 +1 @@
1
+ @use "srl";
@@ -0,0 +1 @@
1
+ @use "pdf";
@@ -0,0 +1,3 @@
1
+ @use "srl";
2
+ @use "general";
3
+
@@ -3,4 +3,5 @@
3
3
  .srl-signature__content {
4
4
  display: grid;
5
5
  grid-template-columns: subgrid;
6
+ row-gap: srl.spacer-get(300);
6
7
  }
@@ -2,12 +2,6 @@
2
2
  @use "web";
3
3
  @use 'assets/scss/placeholders';
4
4
 
5
- .srl-pdf-chapter-title {
6
- border-bottom: 1px solid #{srl.colors-primary-1000()};
7
- @include srl.spacer-padding-block(200);
8
- @extend %srl-grid-base;
9
- }
10
-
11
5
  .srl-pdf-chapter-title__text {
12
6
  @extend %srl-regular-width;
13
7
  }
@@ -2,6 +2,6 @@
2
2
  "hide-quote-characters": {
3
3
  "label": "Hide quote characters before and after",
4
4
  "type": "option",
5
- "value": "hide-quote-characters"
5
+ "value": "srl-hide-quote-characters"
6
6
  }
7
7
  }
@@ -0,0 +1,19 @@
1
+ {
2
+ "icon": {
3
+ "label": "Icon",
4
+ "type": "select",
5
+ "options": [
6
+ {
7
+ "caption": "None"
8
+ },
9
+ {
10
+ "caption": "Arrow right",
11
+ "value": "srl-icon-arrow-right-after"
12
+ },
13
+ {
14
+ "caption": "Download",
15
+ "value": "srl-icon-download-after"
16
+ }
17
+ ]
18
+ }
19
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "reverse": {
3
+ "label": "Reverse",
4
+ "type": "option",
5
+ "value": "srl-reverse"
6
+ }
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simple-reporting/base",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "Manage srl templates, build and publish",
5
5
  "bin": {
6
6
  "srl": "cli.js"
@@ -1,2 +1,6 @@
1
1
  import type { Plugin } from 'vite';
2
- declare function viteSrlPlugin(): Plugin;
2
+
3
+ declare function viteSrlPlugin(): Plugin;
4
+
5
+ export default viteSrlPlugin;
6
+ export { viteSrlPlugin };
@@ -125,7 +125,7 @@ function triggerAction(callback) {
125
125
  }, 200);
126
126
  }
127
127
 
128
- export default function viteSrlPlugin() {
128
+ function viteSrlPlugin() {
129
129
  return {
130
130
  name: 'vite-srl-plugin',
131
131
  config(config) {
@@ -137,6 +137,7 @@ export default function viteSrlPlugin() {
137
137
  config.resolve.alias = config.resolve.alias || {};
138
138
  config.resolve.alias['~'] = folders.root;
139
139
  config.resolve.alias['@'] = folders.srlSrc;
140
+ config.resolve.alias['#srl'] = folders.srlRoot;
140
141
  config.resolve.alias['#components'] = folders.srlComponents;
141
142
  config.resolve.alias['#composables'] = folders.srlComposables;
142
143
  config.resolve.alias['#plugins'] = folders.srlPlugins;
@@ -199,7 +200,7 @@ export default function viteSrlPlugin() {
199
200
  }
200
201
 
201
202
  if (
202
- path.includes('src/components/Srl') &&
203
+ path.includes('src/components/') &&
203
204
  path.endsWith('.vue')
204
205
  ) {
205
206
  triggerAction(vueComponents);
@@ -241,7 +242,7 @@ export default function viteSrlPlugin() {
241
242
  }
242
243
 
243
244
  if (
244
- path.includes('src/components/Srl') &&
245
+ path.includes('src/components/') &&
245
246
  path.endsWith('.vue')
246
247
  ) {
247
248
  triggerAction(vueComponents);
@@ -250,3 +251,6 @@ export default function viteSrlPlugin() {
250
251
  },
251
252
  };
252
253
  }
254
+
255
+ export default viteSrlPlugin;
256
+ export { viteSrlPlugin };
package/scripts/build.js CHANGED
@@ -1,4 +1,4 @@
1
- import { join } from 'node:path/posix';
1
+ import { join, relative } from 'node:path/posix';
2
2
  import {
3
3
  statSync,
4
4
  writeFileSync,
@@ -243,6 +243,7 @@ async function zipApp() {
243
243
  async function zipLdd() {
244
244
  console.log("\n\nCreate zip file for LDD");
245
245
  await checkFolders();
246
+
246
247
  const archiver = require('archiver');
247
248
  const output = createWriteStream(join(outputPath, 'design.zip'));
248
249
  const archive = archiver('zip', {
@@ -455,21 +456,6 @@ async function buildLdd(version) {
455
456
  }
456
457
  }
457
458
  },
458
- resolve: {
459
- alias: {
460
- '~': folders.root,
461
- '@': folders.srlSrc,
462
- '#components': folders.srlComponents,
463
- '#composables': folders.srlComposables,
464
- '#plugins': folders.srlPlugins,
465
- '#types': folders.srlTypes,
466
- '#utils': folders.srlUtils,
467
- '#imports': folders.srlImports,
468
- '#ldd': folders.packageLd,
469
- 'assets': folders.srlAssets,
470
- 'srl': folders.srlSystem,
471
- },
472
- },
473
459
  publicDir: false,
474
460
  })
475
461
  }
@@ -484,6 +470,7 @@ async function buildLdd(version) {
484
470
  join(folders.root, 'livingdocs.config.json'),
485
471
  join(folders.srlOutput, 'ldd', 'design.json'),
486
472
  );
473
+ buildPdfCustomer()
487
474
  });
488
475
  } catch (e) {
489
476
  console.error(e);
@@ -491,6 +478,121 @@ async function buildLdd(version) {
491
478
  }
492
479
  }
493
480
 
481
+ async function buildPdfCustomer() {
482
+ const lddPdfDir = join(folders.srlOutput, 'ldd', 'pdf');
483
+ const lddJson = await readLivingDocsJson();
484
+
485
+ try {
486
+ const pdfDir = join(folders.srlOutput, 'pdf');
487
+ statSync(pdfDir);
488
+ await cpSync(pdfDir, lddPdfDir, { recursive: true });
489
+ console.log('PDF folder has been copied to ' + lddPdfDir);
490
+ } catch (e) {
491
+ console.error(e)
492
+ }
493
+
494
+ try {
495
+ const customerDir = join(folders.root, 'pdf', 'customers');
496
+ statSync(customerDir);
497
+ const customerFolders = readdirSync(customerDir, { withFileTypes: true })
498
+ .filter(dirent => dirent.isDirectory())
499
+ .map(dirent => dirent.name);
500
+
501
+ try {
502
+ for (let i = 0; i < customerFolders.length; i++) {
503
+ const customer = customerFolders[i];
504
+ const customerFolder = join(customerDir, customer);
505
+ const customerTarget = join(lddPdfDir, customer);
506
+
507
+ const jsReferences = [
508
+ 'pdf.js'
509
+ ];
510
+ const cssReferences = [
511
+ 'pdf.css'
512
+ ];
513
+
514
+ try {
515
+ const scssPath = join(customerFolder, 'custom.ts');
516
+ statSync(scssPath);
517
+ const config = {
518
+ css: {
519
+ preprocessorOptions: {
520
+ scss: {
521
+ api: 'modern-compiler',
522
+ },
523
+ },
524
+ },
525
+ base: './',
526
+ build: {
527
+ outDir: customerTarget,
528
+ lib: {
529
+ fileName: 'custom',
530
+ entry: scssPath,
531
+ formats: ['es'],
532
+ },
533
+ },
534
+ publicDir: false,
535
+ };
536
+ await viteBuild(config)
537
+
538
+ try {
539
+ statSync(join(customerTarget, 'custom.js'));
540
+ jsReferences.push(`${customer}/custom.js`);
541
+ } catch (e) {}
542
+
543
+ try {
544
+ statSync(join(customerTarget, 'custom.css'));
545
+ cssReferences.push(`${customer}/custom.css`);
546
+ } catch (e) {}
547
+
548
+
549
+ } catch (e) {}
550
+
551
+ const files = await glob(join(customerFolder, '**', '*'), { withFileTypes: true });
552
+ for (const file of files) {
553
+ if (file.isFile()) {
554
+ if (!file.name.endsWith('.scss') && !file.name.endsWith('.ts') && !file.name.endsWith('.tsx')) {
555
+ const from = file.fullpath();
556
+ const to = join(customerTarget, relative(customerFolder, file.fullpath()));
557
+ await cpSync(from, to);
558
+ console.log(`Copy /${relative(folders.root, from)} to /${relative(folders.root, to)}`);
559
+ }
560
+ if (file.name.endsWith('.css')) {
561
+ cssReferences.push(`${relative(customerDir, file.fullpath())}`);
562
+ }
563
+ if (file.name.endsWith('.js')) {
564
+ jsReferences.push(`${relative(customerDir, file.fullpath())}`);
565
+ }
566
+ }
567
+ }
568
+
569
+ const ns = `${nsWowInternalLddUrl}/${lddJson.name}/${lddJson.version}/pdf`;
570
+
571
+ const pdfConfig = [
572
+ '<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">'
573
+ ];
574
+ cssReferences.forEach( p => {
575
+ pdfConfig.push(` <userStyleSheets><uri>${ns}/${p}</uri></userStyleSheets>`);
576
+ })
577
+
578
+ jsReferences.forEach( p => {
579
+ pdfConfig.push(` <userScripts><uri>${ns}/${p}</uri></userScripts>`);
580
+ })
581
+
582
+ pdfConfig.push(`</configuration>`);
583
+
584
+ const pdfConfigPath = join(customerTarget, 'pdf-configuration.xml');
585
+ await writeFileSync(pdfConfigPath, pdfConfig.join('\n'));
586
+ console.log(`Create PDF configuration file /${relative(folders.root, pdfConfigPath)}`);
587
+ }
588
+ } catch (e) {
589
+ console.error(e)
590
+ }
591
+ } catch (e) {}
592
+
593
+ return true;
594
+ }
595
+
494
596
  /**
495
597
  * Builds the word document by compiling the HTML file using Vite and
496
598
  * returns the result.
@@ -501,7 +603,6 @@ async function buildLdd(version) {
501
603
  async function buildWord() {
502
604
  console.log("\n\nBuild Word");
503
605
  await checkFolders();
504
- let configFile = false;
505
606
 
506
607
  const config = {
507
608
  css: {
@@ -184,8 +184,8 @@ async function mapComponents(lddJson) {
184
184
 
185
185
  // write async components
186
186
  const asyncComponents = [
187
- `import { defineAsyncComponent } from 'vue'`,
188
- `export default function asyncLdComponent(app) {`,
187
+ `import { defineAsyncComponent, type App } from 'vue'`,
188
+ `export default function asyncLdComponent(app: App): void {`,
189
189
  ];
190
190
 
191
191
  for (let i = 0; i < vueComponents.length; i++) {
@@ -7,7 +7,6 @@ function toPascalAfterSlash(str) {
7
7
  }
8
8
  function readVueDir(entryPath, prefix = '') {
9
9
  const componentsPath = join(entryPath, 'components');
10
- const baseDir = join(componentsPath, 'Srl');
11
10
  const result = {};
12
11
 
13
12
  function search(dir) {
@@ -29,47 +28,47 @@ function readVueDir(entryPath, prefix = '') {
29
28
  }
30
29
  }
31
30
 
32
- if (existsSync(baseDir) && statSync(baseDir).isDirectory()) {
33
- search(baseDir);
31
+ if (existsSync(componentsPath) && statSync(componentsPath).isDirectory()) {
32
+ search(componentsPath);
34
33
  }
35
34
 
36
35
  return result;
37
36
  }
38
37
 
39
38
  export async function vueComponents() {
40
- const srlComponents = readVueDir(folders.srlRoot, '#');
41
39
  const appComponents = readVueDir(folders.srlSrc, '@/');
40
+ const srlComponents = readVueDir(folders.srlRoot, '#');
42
41
 
43
42
  const components = []
44
43
  const types = []
45
44
 
46
- for (const [name, info] of Object.entries(srlComponents)) {
47
- const componentPath = appComponents[name] ? appComponents[name].component : info.component
48
- const typePath = appComponents[name] ? appComponents[name].type : info.type
45
+ for (const [name, info] of Object.entries(appComponents)) {
49
46
  components.push(
50
- `app.component('${name}', defineAsyncComponent(() => import('${componentPath}')));`,
47
+ `app.component('${name}', defineAsyncComponent(() => import('${info.component}')));`,
51
48
  )
52
49
  types.push({
53
50
  name: name,
54
- type: ` type ${name} = typeof import('${typePath}')['default'];`,
51
+ type: ` type ${name} = typeof import('${info.type}')['default'];`,
55
52
  })
56
53
  }
57
54
 
58
- for (const [name, info] of Object.entries(appComponents)) {
59
- if (!srlComponents[name]) {
55
+ for (const [name, info] of Object.entries(srlComponents)) {
56
+ const componentPath = appComponents[name] ? appComponents[name].component : info.component
57
+ const typePath = appComponents[name] ? appComponents[name].type : info.type
58
+ if (!appComponents[name]) {
60
59
  components.push(
61
- `app.component('${name}', defineAsyncComponent(() => import('${info.component}')));`,
60
+ `app.component('${name}', defineAsyncComponent(() => import('${componentPath}')));`,
62
61
  )
63
62
  types.push({
64
63
  name: name,
65
- type: ` type ${name} = typeof import('${info.type}')['default'];`,
64
+ type: ` type ${name} = typeof import('${typePath}')['default'];`,
66
65
  })
67
66
  }
68
67
  }
69
68
 
70
69
  writeFileSync(join(folders.srlPlugins, 'asyncSrlComponents.ts'),
71
- `import { defineAsyncComponent } from 'vue';
72
- export default function asyncSrlComponents(app) {
70
+ `import { defineAsyncComponent, type App } from 'vue';
71
+ export default function asyncSrlComponents(app: App): void {
73
72
  ${components.join('\n ')}
74
73
  }
75
74
  `, 'utf8');
@@ -57,7 +57,13 @@ onMounted(() => {
57
57
  </script>
58
58
 
59
59
  <template>
60
- <div ref="rootEl" :id="props.accordion.id" :hidden="!props.accordion.state">
60
+ <div
61
+ ref="rootEl"
62
+ :id="props.accordion.id"
63
+ :hidden="!props.accordion.state"
64
+ tabindex="-1"
65
+ @keydown.esc.stop.prevent="accordion.close()"
66
+ >
61
67
  <slot/>
62
68
  </div>
63
69
  </template>
@@ -12,11 +12,12 @@ function toggle() {
12
12
 
13
13
  function open() {
14
14
  state.value = true
15
- rootEl.value.querySelector<HTMLDivElement>(`#${id.value}`)?.focus()
15
+ rootEl.value?.querySelector<HTMLDivElement>(`#${id.value}`)?.focus()
16
16
  }
17
17
 
18
18
  function close() {
19
19
  state.value = false
20
+ rootEl.value?.querySelector<HTMLDivElement>(`[aria-controls="${id.value}"]`)?.focus()
20
21
  }
21
22
 
22
23
  const accordion = computed(() => {
@@ -167,11 +167,12 @@ const classListItem = computed(() => {
167
167
  </script>
168
168
 
169
169
  <template>
170
- <li v-if="!item.children && props.item.href" :class="classListLi">
170
+ <li v-if="!item.children && props.item.href" role="none" :class="classListLi">
171
171
  <router-link
172
172
  v-if="!external"
173
173
  ref="$el"
174
174
  tabindex="-1"
175
+ role="menuitem"
175
176
  :to="props.item.href"
176
177
  :class="classListItem"
177
178
  :title="props.item.title ?? props.item.label"
@@ -195,6 +196,7 @@ const classListItem = computed(() => {
195
196
  v-else
196
197
  tabindex="-1"
197
198
  ref="$el"
199
+ role="menuitem"
198
200
  :href="props.item.href"
199
201
  :title="props.item.title ?? props.item.label"
200
202
  :class="classListItem"
@@ -217,11 +219,12 @@ const classListItem = computed(() => {
217
219
  />
218
220
  </a>
219
221
  </li>
220
- <li v-else-if="props.item.callback" :class="classListLi">
222
+ <li v-else-if="props.item.callback" role="none" :class="classListLi">
221
223
  <button
222
224
  type="button"
223
225
  ref="$el"
224
226
  tabindex="-1"
227
+ role="menuitem"
225
228
  :class="classListItem"
226
229
  :title="props.item.title ?? props.item.label"
227
230
  :aria-label="props.item.icon ? props.item.title ?? props.item.label : undefined"
@@ -242,11 +245,12 @@ const classListItem = computed(() => {
242
245
  />
243
246
  </button>
244
247
  </li>
245
- <li v-else :class="classListLi">
248
+ <li v-else :class="classListLi" role="none">
246
249
  <button
247
250
  type="button"
248
251
  ref="$el"
249
252
  tabindex="-1"
253
+ role="menuitem"
250
254
  :aria-haspopup="props.item.children ? 'true' : 'false'"
251
255
  :aria-expanded="opened"
252
256
  :aria-controls="`${props.name}-${id}`"
@@ -167,7 +167,7 @@ function routerChange() {
167
167
  }
168
168
 
169
169
  function closeAll(keep?: number | string) {
170
- items.value.forEach((item: typeof MenuItem, index: number) => {
170
+ items.value.forEach((item: SrlMenuItem, index: number) => {
171
171
  if (keep !== index) item.closeItem()
172
172
  })
173
173
  }
@@ -236,6 +236,7 @@ defineExpose({
236
236
  <ul
237
237
  ref="$el"
238
238
  tabindex="0"
239
+ :role="props.depth === 0 ? 'menubar' : 'menu'"
239
240
  :id="props.id"
240
241
  :class="classList"
241
242
  :hidden="!opened"
@@ -61,11 +61,6 @@ async function setConfig(): Promise<Ref<NsWowConfig>> {
61
61
  await loadSettings();
62
62
  await loadTranslations();
63
63
 
64
- const defaultMessages = import.meta.glob('@/locales/*.json', {
65
- eager: true,
66
- import: 'default',
67
- });
68
-
69
64
  for (const locale of config.value.settings.languages) {
70
65
  await loadRouting(locale);
71
66
  await loadDownloads(locale);
@@ -97,7 +92,8 @@ async function loadSettings() {
97
92
  config.value.locale = data.defaultLanguage;
98
93
  document.documentElement.lang = data.defaultLanguage;
99
94
  } catch (e) {
100
- errorLog(`"${file}" could not be loaded.`, e);
95
+ const o = e as Error;
96
+ errorLog(`"${file}" could not be loaded.`, o);
101
97
  }
102
98
  }
103
99
 
@@ -105,10 +101,10 @@ async function loadTranslations() {
105
101
  const file = `./json/translations_hosting.json`;
106
102
  try {
107
103
  const response: Response = await fetch(file);
108
- const data: NsWowTranslations = await response.json();
109
- config.value.translations = data;
104
+ config.value.translations = await response.json() as NsWowTranslations;
110
105
  } catch (e) {
111
- errorLog(`"${file}" could not be loaded.`, e);
106
+ const o = e as Error;
107
+ errorLog(`"${file}" could not be loaded.`, o);
112
108
  }
113
109
  }
114
110
 
@@ -120,19 +116,22 @@ async function loadRouting(locale: string) {
120
116
  config.value.articles[locale] = routing.pages;
121
117
  config.value.menus[locale] = routing.menu;
122
118
  } catch (e) {
123
- errorLog(`"${file}" could not be loaded.`, e);
119
+ const o = e as Error;
120
+ errorLog(`"${file}" could not be loaded.`, o);
124
121
  }
125
122
  }
126
123
 
127
124
  async function loadDownloads(locale: string) {
128
- config.value.downloads[locale] = {};
125
+ config.value.downloads[locale] = {
126
+ structure: [],
127
+ };
129
128
  const file: string = `./downloads/downloads_${locale}.json`;
130
129
  try {
131
130
  const response: Response = await fetch(file);
132
- const data = await response.json();
133
- config.value.downloads[locale] = data;
131
+ config.value.downloads[locale] = await response.json();
134
132
  } catch (e) {
135
- errorLog(`"${file}" could not be loaded.`, e);
133
+ const o = e as Error;
134
+ errorLog(`"${file}" could not be loaded.`, o);
136
135
  }
137
136
  }
138
137
 
@@ -6,7 +6,7 @@ export function addCssStyles(cssString: string): void {
6
6
  cssStyles.value.includes(cssString) || cssStyles.value.push(cssString);
7
7
  }
8
8
 
9
- export function useCssStyles(): string[] {
9
+ export function useCssStyles(): typeof cssStyles {
10
10
  return cssStyles;
11
11
  }
12
12
 
@@ -35,8 +35,12 @@ import {
35
35
  import { isRouterPath } from '#utils/uri';
36
36
  import useConfig from './config';
37
37
 
38
+ type Menus = {
39
+ [key: string]: ComputedRef<NsWowNavigationItem[]>;
40
+ }
41
+
38
42
  const config = useConfig();
39
- const menus = {};
43
+ const menus: Menus = {};
40
44
 
41
45
  function buildNav(
42
46
  item: NsWowMenu,