Translation Group
<zn-translation-group> | ZnTranslationGroup
Puts several zn-translations fields behind one language select, so a whole form’s worth of copy is translated a language at a time.
The Translation Group component wraps multiple zn-translations components in a panel-styled
container with a shared language select. The fields sit in a
form group, so the caption, help text and the select share its label
column and the fields line up with every other form group around them. Closed, the select carries how many
languages are done as a 1/5 chip; open, each language is marked translated, partial or falling
back to English. Type to filter the list — by name or by language code, so de finds German.
Choosing a language switches every child at once.
<zn-translation-group label="Product Content" help-text="Every field is translated one language at a time" languages='{"en":"English","fr":"French","de":"German"}'> <zn-translations label="Name" name="name" values='{"en":"Wireless Headphones","fr":"Écouteurs sans fil","de":"Kabellose Kopfhörer"}' ></zn-translations> <zn-translations label="Description" name="description" values='{"en":"Premium noise-cancelling headphones","fr":"Écouteurs antibruit premium","de":"Premium-Kopfhörer mit Geräuschunterdrückung"}' ></zn-translations> </zn-translation-group>
Examples
Basic Usage
A translation group with two translation inputs sharing one language select.
<zn-translation-group languages='{"en":"English","fr":"French"}'> <zn-translations label="Title" name="title"></zn-translations> <zn-translations label="Subtitle" name="subtitle"></zn-translations> </zn-translation-group>
Label and Help Text
label names the section in the form group’s label column, and help-text sits under
it — the pair behave as they do on any other form group. The language select follows them, in the group’s
chip position. language-label sets the select’s accessible name — it is not shown, since the
caption names the section on screen.
<zn-translation-group label="Page Translations" help-text="Pick a language to edit every field in it" languages='{"en":"English","fr":"French","es":"Spanish"}'> <zn-translations label="Heading" name="heading"></zn-translations> <zn-translations label="Body" name="body"></zn-translations> </zn-translation-group>
Pre-filled Values
Set initial translations on each child. A language every child has a value for is marked
Translated; one only some children have is Partial; one no child has falls back to
English. English itself is marked Empty rather than falling back, having nothing to fall back
to, and counts towards the total like any other language.
<zn-translation-group label="Notification Templates" languages='{"en":"English","fr":"French","de":"German","es":"Spanish"}'> <zn-translations label="Subject" name="subject" values='{"en":"Welcome aboard!","fr":"Bienvenue !","de":"Willkommen!","es":"Bienvenido!"}' ></zn-translations> <zn-translations label="Preview Text" name="preview" values='{"en":"Get started with your account","fr":"Commencez avec votre compte","de":"Starten Sie mit Ihrem Konto","es":"Comience con su cuenta"}' ></zn-translations> </zn-translation-group>
Many Languages
Every configured language is offered whether or not it has been translated yet, so there is no separate step to add one — pick it and start typing. The chip on the closed select tracks how many are done.
<zn-translation-group label="Release Notes" languages='{"en":"English","ar":"Arabic","de":"German","es":"Spanish","fr":"French","it":"Italian","ja":"Japanese","ko":"Korean","pt":"Portuguese","ru":"Russian","tr":"Turkish","zh-hans":"Simplified Chinese"}'> <zn-translations label="Headline" name="headline" values='{"en":"Now shipping","ar":"متاح الآن","de":"Jetzt verfügbar","es":"Ya disponible","fr":"Disponible dès maintenant","it":"Disponibile ora","ja":"発売開始","ko":"출시됨","pt":"Disponível agora","ru":"Уже в продаже","tr":"Şimdi mevcut","zh-hans":"现已发布"}' ></zn-translations> <zn-translations label="Summary" name="summary" values='{"en":"Tap through the release highlights.","ar":"تصفح أبرز ميزات الإصدار.","de":"Highlights der Version ansehen.","es":"Consulta lo más destacado.","fr":"Découvrez les nouveautés.","it":"Scopri le novità.","ja":"リリースのハイライトをご覧ください。","ko":"업데이트 주요 내용 보기.","pt":"Veja os destaques.","ru":"Ознакомьтесь с обновлениями.","tr":"Sürüm önemli noktaları.","zh-hans":"浏览版本亮点。"}' ></zn-translations> </zn-translation-group>
Custom Accessible Name
language-label is read out by a screen reader in place of a visible label.
<zn-translation-group language-label="Language" languages='{"en":"English","fr":"French","de":"German"}'> <zn-translations label="Heading" name="heading" values='{"en":"Now shipping","de":"Jetzt verfügbar"}'></zn-translations> <zn-translations label="Body" name="body" values='{"en":"Tap through the highlights."}'></zn-translations> </zn-translation-group>
Inline (No Panel)
Nested inside another panel, the group’s own border and padding indent its fields out of line with
everything around them. inline drops the chrome so the group reads as a section of the form
instead.
<zn-panel caption="Product Details" icon="inventory_2"> <div style="display: flex; flex-direction: column; gap: 1rem;"> <zn-input label="Product SKU" value="PROD-12345" readonly></zn-input> <zn-translation-group inline label="Translatable Content" languages='{"en":"English","fr":"French","de":"German"}'> <zn-translations name="name" label="Product Name" values='{"en":"Premium Wireless Headphones","fr":"Écouteurs sans fil premium","de":"Premium kabellose Kopfhörer"}' ></zn-translations> <zn-translations name="short-description" label="Short Description" values='{"en":"High-quality wireless audio","fr":"Audio sans fil haute qualité","de":"Hochwertiges kabelloses Audio"}' ></zn-translations> </zn-translation-group> <zn-input label="Price" type="currency" value="299.99"></zn-input> </div> </zn-panel>
Actions
Buttons for the bottom of the group go in the actions slot. They sit on the white body rather
than the grey footer, and follow zinc’s form action rows in sitting on the right.
align="start" moves one to the left; any number can sit on either side. Write them in the order
they should be read — the sides are set by CSS ordering, so markup order is what a keyboard follows.
<zn-translation-group label="Product Content" languages='{"en":"English","fr":"French","de":"German"}'> <zn-translations label="Name" name="name" values='{"en":"Wireless Headphones","de":"Kabellose Kopfhörer"}'></zn-translations> <zn-translations label="Description" name="description" values='{"en":"Premium noise-cancelling headphones"}'></zn-translations> <zn-button slot="actions" align="start" color="transparent" icon="translate">Auto-translate</zn-button> <zn-button slot="actions" color="secondary">Cancel</zn-button> <zn-button slot="actions" color="success">Save</zn-button> </zn-translation-group>
Flush Layout
Remove body padding for a more compact appearance using the flush attribute.
<zn-translation-group flush label="Compact Translations" languages='{"en":"English","fr":"French"}'> <zn-translations label="Label" name="label"></zn-translations> <zn-translations label="Placeholder" name="placeholder"></zn-translations> </zn-translation-group>
Listening to Language Changes
The group emits a zn-language-change event when the active language changes.
<zn-translation-group id="group-events" label="Event Demo" languages='{"en":"English","fr":"French","de":"German"}'> <zn-translations label="Title" name="title"></zn-translations> <zn-translations label="Description" name="description"></zn-translations> </zn-translation-group> <div style="margin-top: 1rem; padding: 1rem; background: var(--zn-color-neutral-50); border-radius: 4px;"> <strong>Active Language:</strong> <span id="active-lang" style="font-family: monospace;">en</span> </div> <script type="module"> const group = document.getElementById('group-events'); const display = document.getElementById('active-lang'); group.addEventListener('zn-language-change', (event) => { display.textContent = event.detail.language; }); </script>
Properties
| Property | Type | Default | Description |
|---|---|---|---|
label |
string |
'' |
Names the section, in the form group’s label column |
help-text |
string |
'' |
Sits under the label, above the language select |
language-label |
string |
'Edit Languages' |
The select’s accessible name; not shown on screen |
inline |
boolean |
false |
Drops the panel border, background and padding |
languages |
Record<string, string> |
{en: "EN"} |
Object mapping language codes to display names |
flush |
boolean |
false |
Removes body padding for compact layout |
Events
| Event | Description | Event Detail |
|---|---|---|
zn-language-change |
Emitted when the active language changes | { language: string } |
Slots
| Slot | Description |
|---|---|
| (default) | Place <zn-translations> elements here |
actions |
Buttons for the bottom of the body; align="start" on a child moves it to the left
|
footer |
Content displayed in the grey panel footer |
CSS Parts
| Part | Description |
|---|---|
base |
The outer panel wrapper |
form-group |
The form group holding the caption, the language select and the fields |
language-field |
The container holding the language select, in the group’s chip slot |
language-select |
The select itself |
actions |
The row of buttons at the bottom of the body |
Importing
If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.
To import this component from the CDN using a script tag:
<script type="module" src="https://cdn.jsdelivr.net/npm/@kubex/zinc@1.1.160/dist/components/translation-group/translation-group.js"></script>
To import this component from the CDN using a JavaScript import:
import 'https://cdn.jsdelivr.net/npm/@kubex/zinc@1.1.160/dist/components/translation-group/translation-group.js';
To import this component using a bundler:
import '@kubex/zinc/dist/components/translation-group/translation-group.js';
Slots
| Name | Description |
|---|---|
| (default) | The zn-translations fields the select drives. |
actions
|
Buttons for the bottom of the panel, on the white body rather than the grey footer. They sit on the
right, as zinc’s form action rows do; align="start" moves one to the left. Write them
in the order they should be read — the sides are set by CSS ordering, so markup order is what a
keyboard follows.
|
footer
|
Content displayed in the grey panel footer. |
Learn more about using slots.
Properties
| Name | Description | Reflects | Type | Default |
|---|---|---|---|---|
label
|
The form group’s label. An alias for the inherited caption, which wins where both are
set.
|
string
|
''
|
|
helpText
help-text
|
Sits under the label, above the language select, as help text does in any other form group. |
string
|
''
|
|
inline
|
Drops the panel chrome — border, background and padding — so the group reads as a section of the surrounding form rather than a panel of its own. For groups nested inside another panel, where the fields would otherwise sit indented behind a second border. |
|
boolean
|
false
|
languageLabel
language-label
|
The select’s accessible name. Not shown — the caption is what names the section on screen — but read out by a screen reader, which has nothing else to go on once the visible label is gone. |
string
|
'Edit Languages'
|
|
languages
|
The languages on offer, as language code to display name —
{"en": "English", "fr": "French"}. Writing the code as the name ({"en": "EN"}) is also accepted. en is the language every other one falls back to. Set on every
child, so they do not need their own copy.
|
Record
|
{ 'en': 'EN' }
|
|
updateComplete |
A read-only promise that resolves when the component has finished updating. |
Learn more about attributes and properties.
Events
| Name | React Event | Description | Event Detail |
|---|---|---|---|
zn-language-change |
|
Emitted when the active language changes. Detail: { language: string }. |
- |
Learn more about events.
Custom Properties
| Name | Description | Default |
|---|---|---|
--zn-panel-basis |
The flex-basis of the panel. Can be set using the basis-px attribute. | |
--zn-panel-header-padding |
Padding around the header row. Defaults to --zn-base-gap. |
|
--zn-panel-footer-padding |
Padding around the footer row. |
Learn more about customizing CSS custom properties.
Parts
| Name | Description |
|---|---|
base |
The component’s base wrapper. |
form-group |
The form group holding the caption, the language select and the fields. |
actions |
The row of buttons at the bottom of the body. |
language-field |
The select that chooses the language every child is editing, in the group’s chip slot. |
language-select |
The select itself. |
header |
The header region, when a caption or actions are given. |
header-content |
The padded row inside the header, forwarded from zn-header. |
footer |
The footer region, when the footer slot is filled. |
Learn more about customizing CSS parts.
Dependencies
This component automatically imports the following dependencies.
<zn-chip><zn-example><zn-form-group><zn-icon><zn-opt-group><zn-option><zn-popup><zn-select><zn-tag>