Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 0 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ git subtree pull --prefix assets/vue https://github.com/valantic/vue-template.gi
. |- setup Configuration and setup of the application
. |- stores Pinia stores
. |- styleguide Assets, components, mock data and routes for the stylguide
. |- translations Translations for the application
|- blueprints File blueprints
|- (dist) Build folder
|- (node_modules) Node modules used by this project
Expand Down Expand Up @@ -602,48 +601,6 @@ In cases where HTML is pre-rendered by twig, slots can be used to give the HTML
</html>
```

## Translations

All text which is defined in frontend MUST be placed trough translations. There should NOT be any hard coded inline text in the component templates or JavaScript.

### Plugin

We use the [vue-i18n](https://github.com/kazupon/vue-i18n) plugin to handle translations. This tool also allows us to handle localizations (e.g. number or date formats). The documentation can be found [here](https://kazupon.github.io/vue-i18n/guide/started.html).

We discovered that the provided directive `v-t` accelerates the memory leak issue in IE11 since it creates copies of the translation JSON for each use (as of v8.15.3). For this reason, please use the `{{$t()}}` method.

### Keys

Translations should be marked with a specific translation key. Don't use English text as ab identifier key, since it might interfere with other uses in the application or can simply have different meanings in other languages, that need to be distinguished.

The key should always be namespaced with the components name. E.g. `c-component.specificKey`

```js
// Bad
this.$t('Some translateable text.');

// Good
this.$t('e-button.defaultLabel');
```

### Placeholders

vue-i18n allows the usage of [placeholders](https://kazupon.github.io/vue-i18n/guide/formatting.html#named-formatting). This means you should add dynamic parts with a placeholder to the translation and not concatenate them in the component template or JavaScript.

### Pluralization

Be aware that [vue-i18n](https://github.com/kazupon/vue-i18n) also supports a [pluralization](https://kazupon.github.io/vue-i18n/guide/pluralization.html) syntax. So you should not define multiple translations and then switch them in templates.

### Use outside of component or Vue instance

If you need to use translations outside of a component or Vue instance, where the utilities are injected, you can use the vue-i18n instance which is exported from `setup/i18n.js`.

```javascript
import { i18n } from '@/setup/i18n';

const translation = i18n.global.t('c-add-to-cart.notLoggedInTitle');
```

## Blueprints

In the `/blueprints` folder you'll find templates for several tasks like a new component, test or styleguide entry. Please always base new files on this blueprints and not on an empty or copied existing file.
Expand Down
64 changes: 2 additions & 62 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@
"body-scroll-lock": "~4.0.0-beta.0",
"the-new-css-reset": "~1.11.3",
"vite": "~6.2.0",
"vue": "~3.5.13",
"vue-i18n": "~11.1.1"
"vue": "~3.5.13"
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "~4.3.0",
Expand Down
2 changes: 0 additions & 2 deletions package.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ This will test the current state of TS, JS and CSS code. Tests **MUST** be execu
> core, css
- [vue](https://www.npmjs.com/package/vue) - Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
> core, cue
- [vue-i18n](https://www.npmjs.com/package/vue-i18n) - Internationalization plugin for Vue.js
> core, vue

## Dev-Dependencies

Expand Down
58 changes: 34 additions & 24 deletions src/components/c-vas-language.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,18 @@
<e-vas-select
v-model="language"
:class="b()"
:options="options"
:options="availableLanguages"
/>
</label>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import i18n, { I18N_LOCALES } from '../setup/i18n';
import { defineComponent, PropType } from 'vue';
import eVasSelect, { Options } from '../elements/e-vas-select.vue';

// type Setup = {};

type Data = {
i18nLocales: string[];
};
// type Data = {};

export default defineComponent({
name: 'c-vas-language',
Expand All @@ -27,43 +24,56 @@
eVasSelect
},

// props: {},
props: {
/**
* Array of available languages.
*/
availableLanguages: {
type: Array as PropType<Options[]>,
default: () => [],
},

/**
* The currently selected language.
*/
selectedLanguage: {
type: String,
default: '',
},
},

emits: {
'updateLanguage': (language: string) => typeof language === 'string',
},

// setup(): Setup {
// return {
// };
// },
data(): Data {
return {
i18nLocales: I18N_LOCALES,
};
},
// data(): Data {
// return {};
// },

// components: {},
computed: {
options(): Options[] {
return this.i18nLocales.map(locale => ({
value: locale,
label: this.$t(`s-language.${locale}`)
}));
},

/**
* The current language.
*/
language: {
get() {
// @ts-ignore -- 'locale' is a reactive, not a string. @see https://github.com/intlify/vue-i18n-next/issues/785
return i18n.global.locale?.value;
return this.selectedLanguage
},
set(value: string) {
// TODO: we need to set the locale.
console.log('set: ', value);
this.$emit('updateLanguage', value);
},
},
},
// methods: {},
// watch: {},
watch: {
language(newLanguage: string) {
this.$emit('updateLanguage', newLanguage);
},
},

// beforeCreate() {},
// created() {},
Expand Down
28 changes: 26 additions & 2 deletions src/components/c-vas-sidebar-config.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<template>
<ul :class="b()">
<li :class="b('item')">
<c-vas-language />
<c-vas-language :selected-language="selectedLanguage"
:available-languages="availableLanguages"
@update-language="onUpdateLanguage" />
</li>
<li :class="b('item')">
<c-vas-theme-selector
Expand Down Expand Up @@ -39,6 +41,7 @@
import cVasThemeSelector from './c-vas-theme-selector.vue';
import eVasToggle from '../elements/e-vas-toggle.vue';
import cVasHtmlValidation from './c-vas-html-validation.vue';
import type { Options } from '../elements/e-vas-select.vue';

// type Setup = {};
type Data = {
Expand Down Expand Up @@ -71,10 +74,27 @@
type: Array as PropType<ThemeConfig[]>,
default: () => [],
},

/**
* Array of available languages.
*/
availableLanguages: {
type: Array as PropType<Options[]>,
default: () => [],
},

/**
* The currently selected language.
*/
selectedLanguage: {
type: String,
default: '',
},
},

emits: {
'updateTheme': (theme: string) => typeof theme === 'string',
'updateLanguage': (language: string) => typeof language === 'string',
},
// setup(): Setup {
// return {
Expand All @@ -90,7 +110,11 @@
methods: {
onUpdateTheme(theme: string) {
this.$emit('updateTheme', theme);
}
},

onUpdateLanguage(language: string) {
this.$emit('updateLanguage', language);
},
},
});
</script>
Expand Down
8 changes: 8 additions & 0 deletions src/components/c-vas-sidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@
<c-vas-sidebar-config
:theme-path="settings.themePath"
:available-themes="settings.availableThemes"
:available-languages="settings.availableLanguages"
:selected-language="settings.selectedLanguage"
@update-theme="onUpdateTheme"
@update-language="onUpdateLanguage"
/>
</section>
</div>
Expand Down Expand Up @@ -107,6 +110,7 @@

emits: {
'updateTheme': (theme: string) => typeof theme === 'string',
'updateLanguage': (language: string) => typeof language === 'string',
},
setup(): Setup {
return {
Expand Down Expand Up @@ -163,6 +167,10 @@
this.$emit('updateTheme', theme);
},

onUpdateLanguage(language: string) {
this.$emit('updateLanguage', language);
},

/**
* Hides the overlay if the user clicks somewhere else than inside the container.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/components/c-vas-theme-selector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
},
set(value: string) {
// TODO: we need to set the theme.
console.log('set: ', value);
console.log('set: ', value); /* eslint-disable-line no-console */
},
},

Expand Down
4 changes: 1 addition & 3 deletions src/elements/e-vas-multiselect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
v-if="isOpen && hasSearch"
v-model="searchTerm"
ref="searchField"
:placeholder="$t('e-multiselect.searchFieldPlaceholder')"
:class="b('search-field')"
type="text"
@mouseenter="hover = true"
Expand Down Expand Up @@ -59,7 +58,6 @@

<script lang="ts">
import { defineComponent, PropType, Ref, ref, toRefs } from 'vue';
import i18n from '../setup/i18n';
import useFormStates, { FormStates, withProps } from '../compositions/form-states';
import useUuid, { Uuid } from '../compositions/uuid';
import eVasCheckbox from './e-vas-checkbox.vue';
Expand Down Expand Up @@ -122,7 +120,7 @@
*/
placeholder: {
type: [String, Boolean],
default: i18n.global.t('e-multiselect.defaultPlaceholder'),
default: 'placeholder',
validator: (value: string | boolean) => typeof value === 'string' || !value,
},

Expand Down
Loading