@simple-reporting/base 1.0.6 → 1.0.8

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/dev/package.json CHANGED
@@ -19,7 +19,7 @@
19
19
  "postinstall": "srl prepare"
20
20
  },
21
21
  "dependencies": {
22
- "@simple-reporting/base": "^1.0.6",
22
+ "@simple-reporting/base": "^1.0.8",
23
23
  "axios": "^1.9.0",
24
24
  "chalk": "^5.4.1",
25
25
  "exceljs": "^4.4.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simple-reporting/base",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Manage srl templates, build and publish",
5
5
  "bin": {
6
6
  "srl": "cli.js"
@@ -339,6 +339,13 @@ async function writeComponent(group, name) {
339
339
  return false;
340
340
  }
341
341
 
342
+ const componentNameArray = name.split('.');
343
+ let componentName = name;
344
+ if (componentNameArray[1]) {
345
+ componentNameArray.shift()
346
+ componentName = componentNameArray.join(('.'));
347
+ }
348
+
342
349
  try {
343
350
  const stat = await statSync(join(folders.ld, group, name));
344
351
  console.error(`Component ${group}/${name} already exist!`);
@@ -353,9 +360,9 @@ async function writeComponent(group, name) {
353
360
  await mkdirSync(join(folders.ld, group, name));
354
361
  await mkdirSync(join(folders.ld, group, name, 'scss'));
355
362
  await writeFileSync(
356
- join(folders.ld, group, name, `${name}.html`),
357
- `<p class="srl-grid srl-${name} srl-linkable">
358
- <span class="srl-grid__inner srl-${name}__text" doc-editable="paragraph">
363
+ join(folders.ld, group, name, `${componentName}.html`),
364
+ `<p class="srl-grid srl-${componentName} srl-linkable">
365
+ <span class="srl-grid__inner srl-${componentName}__text" doc-editable="paragraph">
359
366
  Editable Text
360
367
  </span>
361
368
  </p>
@@ -364,8 +371,8 @@ async function writeComponent(group, name) {
364
371
  await writeFileSync(
365
372
  join(folders.ld, group, name, `ld-conf.json`),
366
373
  `{
367
- "name": "${name}",
368
- "label": "${name.charAt(0).toUpperCase()}${name.slice(1)}"
374
+ "name": "${componentName}",
375
+ "label": "${componentName.charAt(0).toUpperCase()}${componentName.slice(1)}"
369
376
  }`,
370
377
  );
371
378
  await writeFileSync(
@@ -379,9 +386,9 @@ async function writeComponent(group, name) {
379
386
  await writeFileSync(
380
387
  join(folders.ld, group, name, 'scss', `general.scss`),
381
388
  `@use "srl";
382
- .srl-${name} {
383
-
384
- }`,
389
+ .srl-${componentName} {
390
+
391
+ }`,
385
392
  );
386
393
  await writeFileSync(
387
394
  join(folders.ld, group, name, 'scss', `pdf.scss`),
@@ -167,10 +167,11 @@ async function mapComponents(lddJson) {
167
167
  const vueFiles = globSync(join(groupPath, component, '*.vue'));
168
168
  if (vueFiles.length) {
169
169
  vueFiles.forEach( c => {
170
- const vueName = c.split('/').pop().substring(0, -4);
170
+ const vueFile = c.split('/').pop();
171
+ const vueName = toUpperCamelCase(vueFile.substring(0, vueFile.length - 4));
171
172
  vueComponents.push({
172
- name: `SrlLd${toUpperCamelCase(vueName)}`,
173
- path: join('#ld', group, component, `${vueName}.vue`),
173
+ name: `SrlLd${vueName}`,
174
+ path: join('#ld', group, component, vueFile),
174
175
  });
175
176
  })
176
177
  }
@@ -0,0 +1,11 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ item: NsWowNavigationItem
4
+ }>();
5
+
6
+ const prefix = props.item.iconPrefix ?? 'srl-icon'
7
+ </script>
8
+
9
+ <template>
10
+ <i :class="`${prefix} ${prefix}-${props.item.icon}`" aria-hidden="true"></i>
11
+ </template>
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ item: NsWowNavigationItem;
4
+ }>();
5
+
6
+ const prefix = props.item.iconPrefix ?? 'srl-icon'
7
+ </script>
8
+
9
+ <template>
10
+ <span>{{ props.item.label }}</span>
11
+ <i :class="`${prefix} ${prefix}-${props.item.iconAfter}`" aria-hidden="true"></i>
12
+ </template>
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ item: NsWowNavigationItem;
4
+ }>();
5
+
6
+ const prefix = props.item.iconPrefix ?? 'srl-icon'
7
+ </script>
8
+
9
+ <template>
10
+ <i :class="`${prefix} ${prefix}-${props.item.iconAfter}`" aria-hidden="true"></i>
11
+ <span>{{ props.item.label }}</span>
12
+ </template>
@@ -5,5 +5,5 @@ const pops = defineProps<{
5
5
  </script>
6
6
 
7
7
  <template>
8
- {{ pops.item.label }}
8
+ <span>{{ pops.item.label }}</span>
9
9
  </template>
@@ -3,6 +3,9 @@ import MenuItemContentText from './Content/Text.vue';
3
3
  import MenuItemContentImage from './Content/Image.vue';
4
4
  import MenuItemContentImageBefore from './Content/ImageBefore.vue';
5
5
  import MenuItemContentImageAfter from './Content/ImageAfter.vue';
6
+ import MenuItemContentIcon from './Content/Icon.vue';
7
+ import MenuItemContentIconBefore from './Content/IconBefore.vue';
8
+ import MenuItemContentIconAfter from './Content/IconAfter.vue';
6
9
 
7
10
  const props = defineProps<{
8
11
  item: NsWowNavigationItem;
@@ -10,7 +13,22 @@ const props = defineProps<{
10
13
  </script>
11
14
 
12
15
  <template>
13
- <MenuItemContentImage v-if="props.item.img" :item="props.item" />
16
+ <MenuItemContentIcon
17
+ v-if="props.item.icon"
18
+ :item="props.item"
19
+ />
20
+ <MenuItemContentIconBefore
21
+ v-else-if="props.item.iconBefore"
22
+ :item="props.item"
23
+ />
24
+ <MenuItemContentIconAfter
25
+ v-else-if="props.item.iconAfter"
26
+ :item="props.item"
27
+ />
28
+ <MenuItemContentImage
29
+ v-else-if="props.item.img"
30
+ :item="props.item"
31
+ />
14
32
  <MenuItemContentImageBefore
15
33
  v-else-if="props.item.imgBefore"
16
34
  :item="props.item"
@@ -5,6 +5,25 @@ import MenuList from './List.vue';
5
5
  import type { RouterLink } from 'vue-router';
6
6
  import { isExternalPath } from '#utils/uri';
7
7
 
8
+ type BackButtonItem = {
9
+ title?: string;
10
+ img?: {
11
+ src: string;
12
+ alt?: string;
13
+ };
14
+ imgBefore?: {
15
+ src: string;
16
+ alt?: string;
17
+ };
18
+ imgAfter?: {
19
+ src: string;
20
+ alt?: string;
21
+ };
22
+ attributes?: {
23
+ [key: string]: string;
24
+ };
25
+ };
26
+
8
27
  const props = defineProps<{
9
28
  name: string;
10
29
  item: NsWowNavigationItem;
@@ -13,6 +32,9 @@ const props = defineProps<{
13
32
  disableTabIndex: boolean;
14
33
  initOpen: number;
15
34
  depth: number;
35
+ backButonEnabled?: boolean;
36
+ backButtonLabel?: string;
37
+ backButtonItem: BackButtonItem
16
38
  }>();
17
39
 
18
40
  const emit = defineEmits([
@@ -44,6 +66,8 @@ function toggle() {
44
66
  const item = menu.value?.items[0].$el;
45
67
  item.$el ? item.$el.focus() : item.focus();
46
68
  });
69
+ } else {
70
+ menu.value.closeAll();
47
71
  }
48
72
  }
49
73
 
@@ -102,6 +126,16 @@ defineExpose({
102
126
  menu,
103
127
  });
104
128
 
129
+ function internalLinkClick(event: Event) {
130
+ !props.item.callback || props.item.callback(event);
131
+ routerChange()
132
+ }
133
+
134
+ function externalLinkClick(event: Event) {
135
+ !props.item.callback || props.item.callback(event);
136
+ link()
137
+ }
138
+
105
139
  const dynamicAttributes = computed(() => {
106
140
  return props.item.attributes ?? {};
107
141
  });
@@ -117,7 +151,7 @@ const dynamicAttributes = computed(() => {
117
151
  :class="{ active: item.active }"
118
152
  :title="props.item.title ?? props.item.label"
119
153
  v-bind="dynamicAttributes"
120
- @click="routerChange"
154
+ @click="internalLinkClick"
121
155
  @keydown.left.stop.prevent="prev"
122
156
  @keydown.up.stop.prevent="prev"
123
157
  @keydown.down.stop.prevent="next"
@@ -125,7 +159,6 @@ const dynamicAttributes = computed(() => {
125
159
  @keydown.tab.exact="tab"
126
160
  @keydown.shift.tab.exact="back"
127
161
  @keydown.esc.stop.prevent="close"
128
- @keydown.enter="link"
129
162
  >
130
163
  <MenuItemContent :item="props.item" />
131
164
  </router-link>
@@ -135,9 +168,10 @@ const dynamicAttributes = computed(() => {
135
168
  ref="$el"
136
169
  :href="props.item.href"
137
170
  :title="props.item.title ?? props.item.label"
171
+ :aria-label="props.item.icon ? props.item.title ?? props.item.label : undefined"
138
172
  :target="props.item.href?.startsWith('http') ? '_blank' : undefined"
139
173
  v-bind="dynamicAttributes"
140
- @click="link"
174
+ @click="externalLinkClick"
141
175
  @keydown.left.stop.prevent="prev"
142
176
  @keydown.up.stop.prevent="prev"
143
177
  @keydown.down.stop.prevent="next"
@@ -155,6 +189,7 @@ const dynamicAttributes = computed(() => {
155
189
  ref="$el"
156
190
  :tabindex="props.index === 0 && !props.disableTabIndex ? 0 : -1"
157
191
  :title="props.item.title ?? props.item.label"
192
+ :aria-label="props.item.icon ? props.item.title ?? props.item.label : undefined"
158
193
  v-bind="dynamicAttributes"
159
194
  @click="props.item.callback"
160
195
  @keydown.left.stop.prevent="prev"
@@ -177,8 +212,9 @@ const dynamicAttributes = computed(() => {
177
212
  :aria-expanded="opened"
178
213
  :aria-controls="`${props.name}-${id}`"
179
214
  :title="props.item.title ?? props.item.label"
215
+ :aria-label="props.item.icon ? props.item.title ?? props.item.label : undefined"
180
216
  v-bind="dynamicAttributes"
181
- @click="toggle"
217
+ @click.stop="toggle"
182
218
  @keydown.left.stop.prevent="prev"
183
219
  @keydown.up.stop.prevent="prev"
184
220
  @keydown.down.stop.prevent="next"
@@ -198,6 +234,9 @@ const dynamicAttributes = computed(() => {
198
234
  :disableTab="props.disableTab"
199
235
  :initOpen="props.initOpen"
200
236
  :depth="props.depth + 1"
237
+ :backButonEnabled="props.backButonEnabled"
238
+ :backButtonLabel="props.backButonEnabled ? props.item.label : undefined"
239
+ :backButtonItem="props.backButtonItem"
201
240
  v-model:opened="opened"
202
241
  @link="link"
203
242
  @routerChange="emit('routerChange')"
@@ -50,18 +50,41 @@
50
50
  * @link="handleNavigation"
51
51
  * />
52
52
  */
53
- import { ref } from 'vue';
53
+ import { computed, ref } from 'vue'
54
54
  import MenuItem from './Item.vue';
55
55
 
56
+ type BackButtonItem = {
57
+ title?: string;
58
+ img?: {
59
+ src: string;
60
+ alt?: string;
61
+ };
62
+ imgBefore?: {
63
+ src: string;
64
+ alt?: string;
65
+ };
66
+ imgAfter?: {
67
+ src: string;
68
+ alt?: string;
69
+ };
70
+ attributes?: {
71
+ [key: string]: string;
72
+ };
73
+ };
74
+
56
75
  const props = withDefaults(
57
76
  defineProps<{
58
77
  name: string;
59
78
  menu: NsWowNavigationItem[];
79
+ id?: string;
60
80
  disableTab?: boolean;
61
81
  disableTabIndex?: boolean;
62
82
  initOpen?: number;
63
83
  singleOpen?: boolean;
64
84
  depth?: number;
85
+ backButonEnabled?: boolean;
86
+ backButtonItem?: BackButtonItem;
87
+ backButtonLabel?: string;
65
88
  }>(),
66
89
  {
67
90
  disableTab: false,
@@ -69,6 +92,7 @@ const props = withDefaults(
69
92
  initOpen: 0,
70
93
  singleOpen: true,
71
94
  depth: 0,
95
+ backButtonItem: {}
72
96
  },
73
97
  );
74
98
 
@@ -149,6 +173,31 @@ function closeAll(keep?: number | string) {
149
173
 
150
174
  const $el = ref<HTMLUListElement>();
151
175
 
176
+ const menuItems = computed<NsWowNavigationItem[]>(() => {
177
+ return props.backButonEnabled && props.depth ? [
178
+ {
179
+ label: props.backButtonLabel,
180
+ title: props.backButtonItem.title,
181
+ img: props.backButtonItem.img,
182
+ imgBefore: props.backButtonItem.imgBefore,
183
+ imgAfter: props.backButtonItem.imgAfter,
184
+ attributes: props.backButtonItem.attributes ?
185
+ Object.assign(props.backButtonItem.attributes,
186
+ {
187
+ 'aria-controls': props.id,
188
+ 'aria-expanded': opened.value
189
+ }
190
+ ):
191
+ {
192
+ 'aria-controls': props.id,
193
+ 'aria-expanded': opened.value
194
+ },
195
+ callback: close,
196
+ },
197
+ ...props.menu,
198
+ ] : props.menu
199
+ });
200
+
152
201
  defineExpose({
153
202
  closeAll,
154
203
  $el,
@@ -157,8 +206,8 @@ defineExpose({
157
206
  </script>
158
207
 
159
208
  <template>
160
- <ul ref="$el" :hidden="!opened">
161
- <template v-for="(item, index) in props.menu" :key="index">
209
+ <ul ref="$el" :id="props.id" :hidden="!opened">
210
+ <template v-for="(item, index) in menuItems" :key="index">
162
211
  <MenuItem
163
212
  ref="items"
164
213
  :item="item"
@@ -168,6 +217,9 @@ defineExpose({
168
217
  :disableTabIndex="props.disableTabIndex"
169
218
  :initOpen="props.initOpen"
170
219
  :depth="props.depth"
220
+ :backButonEnabled="props.backButonEnabled"
221
+ :backButtonLabel="props.backButtonLabel"
222
+ :backButtonItem="props.backButtonItem"
171
223
  @open="open"
172
224
  @close="close"
173
225
  @next="next"
@@ -7,6 +7,7 @@ import _useMenu from './menu';
7
7
  import _useSearch from './search';
8
8
  import _useSettings from './settings';
9
9
  import _useViewPort from './viewPort';
10
+ import _useLanguageSwitch from './languageSwitch';
10
11
  import * as cssStyles from './cssStyles.ts'
11
12
 
12
13
  export const useArticle = _useArticle;
@@ -18,6 +19,7 @@ export const useMenu = _useMenu;
18
19
  export const useSearch = _useSearch;
19
20
  export const useSettings = _useSettings;
20
21
  export const useViewPort = _useViewPort;
22
+ export const useLanguageSwitch = _useLanguageSwitch;
21
23
  export const addCssStyles = cssStyles.addCssStyles;
22
24
  export const useCssStyles = cssStyles.useCssStyles;
23
25
 
@@ -31,6 +33,7 @@ export default {
31
33
  useSearch,
32
34
  useSettings,
33
35
  useViewPort,
36
+ useLanguageSwitch,
34
37
  addCssStyles,
35
38
  useCssStyles,
36
39
  };
@@ -0,0 +1,53 @@
1
+ import { computed } from 'vue'
2
+ import Tr from '@/i18n/translation.ts'
3
+ import { useArticle, useConfig } from '#composables'
4
+
5
+
6
+
7
+ type NsWowLanguageSwitch = {
8
+ current: { label: string; href: string },
9
+ items: NsWowNavigationItem[]
10
+ }
11
+
12
+ const languageSwitch = computed<NsWowLanguageSwitch>(() => {
13
+
14
+ const config = useConfig()
15
+ const article = useArticle()
16
+
17
+ const res: NsWowLanguageSwitch = {
18
+ current: { label: config.value.locale, href: `/${config.value.locale}` },
19
+ items: []
20
+ }
21
+ for (const locale of config.value.settings.languages) {
22
+ if (locale !== config.value.locale) {
23
+ res.items.push({
24
+ label: locale,
25
+ href: `/${locale}`,
26
+ callback: () => {
27
+ Tr.switchLanguage(locale)
28
+ }
29
+ })
30
+ }
31
+ }
32
+
33
+ if (article.value) {
34
+ const uuid = article.value.uuid
35
+ if (uuid) {
36
+ for (const locale of config.value.settings.languages) {
37
+ const slug = config.value.articles[locale].find((a) => a.uuid === uuid)?.slug || ''
38
+ if (locale === config.value.locale) {
39
+ res.current.href = `/${locale}/${slug}`
40
+ } else {
41
+ const item = res.items.find((i) => i.label === locale)
42
+ item ? item.href = `/${locale}/${slug}` : null
43
+ }
44
+ }
45
+ }
46
+ }
47
+
48
+ return res
49
+ })
50
+
51
+ export default function useLanguageSwitch() {
52
+ return languageSwitch
53
+ }