@kubex/zinc 1.1.117 → 1.1.118
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/dist/custom-elements.json +44 -12
- package/dist/vscode.html-custom-data.json +8 -3
- package/dist/web-types.json +17 -7
- package/dist/zn.d.ts +21 -17
- package/dist/zn.min.js +353 -350
- package/docs/pages/components/translation-group.md +20 -18
- package/docs/pages/components/translations.md +3 -2
- package/package.json +1 -1
- package/src/components/form-group/form-group.component.ts +12 -3
- package/src/components/form-group/form-group.test.ts +16 -0
- package/src/components/translation-group/translation-group.component.ts +55 -51
- package/src/components/translation-group/translation-group.scss +10 -74
- package/src/components/translation-group/translation-group.test.ts +76 -38
- package/src/components/translations/translations.component.ts +3 -7
|
@@ -6,13 +6,16 @@ layout: component
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
The Translation Group component wraps multiple `zn-translations` components in a panel-styled container with a shared
|
|
9
|
-
language select. The
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
language select. The fields sit in a [form group](/components/form-group), so the caption, help text and the select
|
|
10
|
+
share its label column and the fields line up with every other form group around them. Closed, the select carries how
|
|
11
|
+
many languages are done as a `1/5` chip; open, each language is marked translated, partial or falling back to English.
|
|
12
|
+
Type to filter the list — by name or by language code, so `de` finds German. Choosing a language switches every child
|
|
13
|
+
at once.
|
|
12
14
|
|
|
13
15
|
```html:preview
|
|
14
16
|
<zn-translation-group
|
|
15
17
|
label="Product Content"
|
|
18
|
+
help-text="Every field is translated one language at a time"
|
|
16
19
|
languages='{"en":"English","fr":"French","de":"German"}'>
|
|
17
20
|
<zn-translations
|
|
18
21
|
label="Name"
|
|
@@ -40,14 +43,16 @@ A translation group with two translation inputs sharing one language select.
|
|
|
40
43
|
</zn-translation-group>
|
|
41
44
|
```
|
|
42
45
|
|
|
43
|
-
###
|
|
46
|
+
### Label and Help Text
|
|
44
47
|
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
`label` names the section in the form group's label column, and `help-text` sits under it — the pair behave as they do
|
|
49
|
+
on any other form group. The language select follows them, in the group's chip position. `language-label` sets the
|
|
50
|
+
select's accessible name — it is not shown, since the caption names the section on screen.
|
|
47
51
|
|
|
48
52
|
```html:preview
|
|
49
53
|
<zn-translation-group
|
|
50
54
|
label="Page Translations"
|
|
55
|
+
help-text="Pick a language to edit every field in it"
|
|
51
56
|
languages='{"en":"English","fr":"French","es":"Spanish"}'>
|
|
52
57
|
<zn-translations label="Heading" name="heading"></zn-translations>
|
|
53
58
|
<zn-translations label="Body" name="body"></zn-translations>
|
|
@@ -209,7 +214,8 @@ The group emits a `zn-language-change` event when the active language changes.
|
|
|
209
214
|
|
|
210
215
|
| Property | Type | Default | Description |
|
|
211
216
|
|------------------|--------------------------|--------------------|---------------------------------------------------|
|
|
212
|
-
| `label` | `string` | `''` |
|
|
217
|
+
| `label` | `string` | `''` | Names the section, in the form group's label column |
|
|
218
|
+
| `help-text` | `string` | `''` | Sits under the label, above the language select |
|
|
213
219
|
| `language-label` | `string` | `'Edit Languages'` | The select's accessible name; not shown on screen |
|
|
214
220
|
| `inline` | `boolean` | `false` | Drops the panel border, background and padding |
|
|
215
221
|
| `languages` | `Record<string, string>` | `{en: "EN"}` | Object mapping language codes to display names |
|
|
@@ -226,19 +232,15 @@ The group emits a `zn-language-change` event when the active language changes.
|
|
|
226
232
|
| Slot | Description |
|
|
227
233
|
|-----------|------------------------------------------------------------|
|
|
228
234
|
| (default) | Place `<zn-translations>` elements here |
|
|
229
|
-
| `label` | Alternative to the `label` attribute for rich HTML content |
|
|
230
235
|
| `actions` | Buttons for the bottom of the body; `align="start"` on a child moves it to the left |
|
|
231
236
|
| `footer` | Content displayed in the grey panel footer |
|
|
232
237
|
|
|
233
|
-
The header carries the caption and the language select alone; nothing else is slotted into it.
|
|
234
|
-
|
|
235
238
|
## CSS Parts
|
|
236
239
|
|
|
237
|
-
| Part | Description
|
|
238
|
-
|
|
239
|
-
| `base` | The outer panel wrapper
|
|
240
|
-
| `
|
|
241
|
-
| `language-field` | The container holding the language select
|
|
242
|
-
| `language-select` | The select itself
|
|
243
|
-
| `actions` | The row of buttons at the bottom of the body
|
|
244
|
-
| `translations` | The body container wrapping the slotted children |
|
|
240
|
+
| Part | Description |
|
|
241
|
+
|-------------------|----------------------------------------------------------------------|
|
|
242
|
+
| `base` | The outer panel wrapper |
|
|
243
|
+
| `form-group` | The form group holding the caption, the language select and the fields |
|
|
244
|
+
| `language-field` | The container holding the language select, in the group's chip slot |
|
|
245
|
+
| `language-select` | The select itself |
|
|
246
|
+
| `actions` | The row of buttons at the bottom of the body |
|
|
@@ -128,8 +128,9 @@ Add `inline-edit` to read the translation as text until it is clicked, through
|
|
|
128
128
|
|
|
129
129
|
### Many Languages
|
|
130
130
|
|
|
131
|
-
Each language becomes an option labelled
|
|
132
|
-
|
|
131
|
+
Each language becomes an option labelled with its configured name — or its code, where `languages` does not name it.
|
|
132
|
+
The select takes any number of them, and its listbox scrolls once the list is longer than the space below it. Type to
|
|
133
|
+
filter the list: matching runs over the code as well as the name, so `de` finds German.
|
|
133
134
|
|
|
134
135
|
```html:preview
|
|
135
136
|
<zn-translations
|
package/package.json
CHANGED
|
@@ -47,6 +47,7 @@ export default class ZnFormGroup extends ZincElement {
|
|
|
47
47
|
|
|
48
48
|
/** The scroller the label is tracked against by hand; null while native sticky is enough. */
|
|
49
49
|
private tracked: HTMLElement | null = null;
|
|
50
|
+
private stickyTop: number = 0;
|
|
50
51
|
private frame: number = 0;
|
|
51
52
|
private rebind: boolean = false;
|
|
52
53
|
private offset: number = 0;
|
|
@@ -103,9 +104,18 @@ export default class ZnFormGroup extends ZincElement {
|
|
|
103
104
|
const column = this.labelColumn;
|
|
104
105
|
if (!column) return;
|
|
105
106
|
|
|
107
|
+
column.style.top = '';
|
|
108
|
+
this.stickyTop = parseFloat(getComputedStyle(column).top) || 0;
|
|
109
|
+
|
|
106
110
|
const anchor = this.nearestScrollContainer(column);
|
|
107
111
|
const scroller = anchor ? this.scrollingAncestor(column) : null;
|
|
108
|
-
|
|
112
|
+
const anchored = !anchor || scroller === anchor;
|
|
113
|
+
|
|
114
|
+
this.trackScroller(anchored ? null : scroller);
|
|
115
|
+
|
|
116
|
+
// A `top` inset against a box that never scrolls has nothing to hold the label back from:
|
|
117
|
+
// it only pushes the label down the page, so drop it and let the transform do the work.
|
|
118
|
+
if (!anchored) column.style.top = '0px';
|
|
109
119
|
}
|
|
110
120
|
|
|
111
121
|
private trackScroller(scroller: HTMLElement | null) {
|
|
@@ -139,11 +149,10 @@ export default class ZnFormGroup extends ZincElement {
|
|
|
139
149
|
const visibleTop = this.tracked === document.scrollingElement
|
|
140
150
|
? 0
|
|
141
151
|
: this.tracked.getBoundingClientRect().top;
|
|
142
|
-
const stickyTop = parseFloat(getComputedStyle(column).top) || 0;
|
|
143
152
|
const restingTop = column.getBoundingClientRect().top - this.offset;
|
|
144
153
|
const travel = Math.max(0, fieldset.clientHeight - column.offsetHeight);
|
|
145
154
|
|
|
146
|
-
offset = Math.min(Math.max(visibleTop + stickyTop - restingTop, 0), travel);
|
|
155
|
+
offset = Math.min(Math.max(visibleTop + this.stickyTop - restingTop, 0), travel);
|
|
147
156
|
}
|
|
148
157
|
|
|
149
158
|
if (Math.round(offset) === Math.round(this.offset)) return;
|
|
@@ -77,6 +77,22 @@ describe('<zn-form-group>', () => {
|
|
|
77
77
|
expect(position(narrow)).to.equal('static');
|
|
78
78
|
});
|
|
79
79
|
|
|
80
|
+
it('leaves the label level with the inputs while nothing scrolls', async () => {
|
|
81
|
+
const el = await fixture<HTMLElement>(html`
|
|
82
|
+
<div style="width: 900px">
|
|
83
|
+
<zn-panel>
|
|
84
|
+
<zn-form-group label="Sticky"><zn-input label="Name"></zn-input></zn-form-group>
|
|
85
|
+
</zn-panel>
|
|
86
|
+
</div>`);
|
|
87
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
88
|
+
|
|
89
|
+
const root = el.querySelector('zn-form-group')!.shadowRoot!;
|
|
90
|
+
const label = root.querySelector('.form-control__text')!.getBoundingClientRect().top;
|
|
91
|
+
const inputs = root.querySelector('.form-control-input')!.getBoundingClientRect().top;
|
|
92
|
+
|
|
93
|
+
expect(label).to.be.closeTo(inputs, 2);
|
|
94
|
+
});
|
|
95
|
+
|
|
80
96
|
it('holds the label in view when a panel sits between the form and the scroll container', async () => {
|
|
81
97
|
const el = await fixture<HTMLElement>(html`
|
|
82
98
|
<div style="max-height: 300px; overflow-y: auto">
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import {classMap} from 'lit/directives/class-map.js';
|
|
2
2
|
import {type CSSResultGroup, html, nothing, type PropertyValues, unsafeCSS} from 'lit';
|
|
3
3
|
import {HasSlotController} from '../../internal/slot';
|
|
4
|
-
import {ifDefined} from 'lit/directives/if-defined.js';
|
|
5
4
|
import {property, state} from 'lit/decorators.js';
|
|
6
5
|
import ZnChip from '../chip';
|
|
7
|
-
import
|
|
6
|
+
import ZnFormGroup from '../form-group';
|
|
8
7
|
import ZnOption from '../option';
|
|
9
8
|
import ZnPanel from '../panel/panel.component';
|
|
10
9
|
import ZnSelect from '../select';
|
|
@@ -19,8 +18,12 @@ import styles from './translation-group.scss';
|
|
|
19
18
|
* @status experimental
|
|
20
19
|
* @since 1.0
|
|
21
20
|
*
|
|
22
|
-
* The
|
|
23
|
-
*
|
|
21
|
+
* The fields sit in a `zn-form-group`, so the caption, help text and the language select share its label column and
|
|
22
|
+
* the fields line up with every other form group around them. Choosing a language switches every child at once, and
|
|
23
|
+
* each child hides its own select while it is in a group — `grouped` is set on them here.
|
|
24
|
+
*
|
|
25
|
+
* The select is searchable. Each option holds its language code as its value, so typing `de` finds German without the
|
|
26
|
+
* code being on show.
|
|
24
27
|
*
|
|
25
28
|
* Closed, the select carries how many target languages are done — `1/5`. Its options each carry a chip aggregated
|
|
26
29
|
* across the children:
|
|
@@ -35,11 +38,11 @@ import styles from './translation-group.scss';
|
|
|
35
38
|
* The children own their values; this component only chooses which language is shown and reports on what they hold.
|
|
36
39
|
* It reads them back on every child `zn-change`, so the chips and the count follow an edit as it is typed.
|
|
37
40
|
*
|
|
38
|
-
* Extends `zn-panel`, so `caption`, `
|
|
39
|
-
*
|
|
41
|
+
* Extends `zn-panel`, so `caption`, `flush`, `transparent` and the `footer` slot behave as they do there. Nested
|
|
42
|
+
* inside another panel, add `inline` to drop the chrome and keep the fields aligned with the surrounding form.
|
|
40
43
|
*
|
|
41
44
|
* @dependency zn-chip
|
|
42
|
-
* @dependency zn-
|
|
45
|
+
* @dependency zn-form-group
|
|
43
46
|
* @dependency zn-option
|
|
44
47
|
* @dependency zn-select
|
|
45
48
|
*
|
|
@@ -49,30 +52,33 @@ import styles from './translation-group.scss';
|
|
|
49
52
|
* @slot actions - Buttons for the bottom of the panel, on the white body rather than the grey footer. They sit on
|
|
50
53
|
* the right, as zinc's form action rows do; `align="start"` moves one to the left. Write them in the order they
|
|
51
54
|
* should be read — the sides are set by CSS ordering, so markup order is what a keyboard follows.
|
|
52
|
-
* @slot footer - Content displayed in the grey panel footer.
|
|
53
|
-
* else is slotted into it.
|
|
55
|
+
* @slot footer - Content displayed in the grey panel footer.
|
|
54
56
|
*
|
|
55
57
|
* @csspart base - The component's base wrapper.
|
|
58
|
+
* @csspart form-group - The form group holding the caption, the language select and the fields.
|
|
56
59
|
* @csspart actions - The row of buttons at the bottom of the body.
|
|
57
|
-
* @csspart language-field - The
|
|
60
|
+
* @csspart language-field - The select that chooses the language every child is editing, in the group's chip slot.
|
|
58
61
|
* @csspart language-select - The select itself.
|
|
59
62
|
*/
|
|
60
63
|
export default class ZnTranslationGroup extends ZnPanel {
|
|
61
64
|
static styles: CSSResultGroup = [ZnPanel.styles, unsafeCSS(styles)];
|
|
62
65
|
static dependencies = {
|
|
63
66
|
'zn-chip': ZnChip,
|
|
64
|
-
'zn-
|
|
67
|
+
'zn-form-group': ZnFormGroup,
|
|
65
68
|
'zn-option': ZnOption,
|
|
66
69
|
'zn-select': ZnSelect
|
|
67
70
|
};
|
|
68
71
|
|
|
69
72
|
private readonly _slotController = new HasSlotController(this, 'actions', 'footer');
|
|
70
73
|
|
|
71
|
-
/** The
|
|
74
|
+
/** The form group's label. An alias for the inherited `caption`, which wins where both are set. */
|
|
72
75
|
@property() label = '';
|
|
73
76
|
|
|
77
|
+
/** Sits under the label, above the language select, as help text does in any other form group. */
|
|
78
|
+
@property({attribute: 'help-text'}) helpText = '';
|
|
79
|
+
|
|
74
80
|
/**
|
|
75
|
-
* Drops the panel chrome — border, background and padding — so the group reads as a section of the form
|
|
81
|
+
* Drops the panel chrome — border, background and padding — so the group reads as a section of the surrounding form
|
|
76
82
|
* rather than a panel of its own. For groups nested inside another panel, where the fields would otherwise sit
|
|
77
83
|
* indented behind a second border.
|
|
78
84
|
*/
|
|
@@ -149,11 +155,9 @@ export default class ZnTranslationGroup extends ZnPanel {
|
|
|
149
155
|
return {type: 'error', label: language === 'en' ? 'Empty' : 'English'};
|
|
150
156
|
}
|
|
151
157
|
|
|
152
|
-
/**
|
|
158
|
+
/** The configured name, or the code where `languages` does not name the language. */
|
|
153
159
|
private displayName(language: string): string {
|
|
154
|
-
|
|
155
|
-
const code = language.toUpperCase();
|
|
156
|
-
return name.toUpperCase() === code ? name : `${name} (${code})`;
|
|
160
|
+
return this.languages[language] ?? language.toUpperCase();
|
|
157
161
|
}
|
|
158
162
|
|
|
159
163
|
/** Children take their language list from the group, so a change to `languages` has to reach them. */
|
|
@@ -206,7 +210,7 @@ export default class ZnTranslationGroup extends ZnPanel {
|
|
|
206
210
|
render() {
|
|
207
211
|
const hasActionsSlot = this._slotController.test('actions');
|
|
208
212
|
const hasFooterSlot = this._slotController.test('footer');
|
|
209
|
-
const
|
|
213
|
+
const caption = this.caption || this.label;
|
|
210
214
|
|
|
211
215
|
// A child's value can carry a language `languages` does not list — server-rendered content outliving a config
|
|
212
216
|
// change. Offer those too, or the translation is stranded in the value with no way to reach it.
|
|
@@ -216,7 +220,6 @@ export default class ZnTranslationGroup extends ZnPanel {
|
|
|
216
220
|
.forEach(code => extra.add(code)));
|
|
217
221
|
const languageCodes = [...Object.keys(this.languages), ...extra];
|
|
218
222
|
const hasMultipleLanguages = languageCodes.length > 1;
|
|
219
|
-
const hasHeader = Boolean(headerCaption) || hasMultipleLanguages;
|
|
220
223
|
|
|
221
224
|
// English is the source every other language falls back to, so it is not itself one of the translations counted.
|
|
222
225
|
const targets = languageCodes.filter(code => code !== 'en');
|
|
@@ -229,49 +232,50 @@ export default class ZnTranslationGroup extends ZnPanel {
|
|
|
229
232
|
};
|
|
230
233
|
|
|
231
234
|
return html`
|
|
232
|
-
<div class="${classMap({
|
|
235
|
+
<div part="base" class="${classMap({
|
|
233
236
|
panel: true,
|
|
234
237
|
'panel--flush': this.flush || this.inline,
|
|
235
238
|
'panel--transparent': this.transparent || this.inline,
|
|
236
239
|
'translation-group--inline': this.inline,
|
|
237
|
-
'panel--has-header': hasHeader,
|
|
238
240
|
'panel--has-actions': hasActionsSlot,
|
|
239
241
|
'panel--has-footer': hasFooterSlot,
|
|
240
242
|
})}">
|
|
241
243
|
|
|
242
244
|
<div class="panel__inner">
|
|
243
|
-
${hasHeader ? html`
|
|
244
|
-
<zn-header class="panel__header"
|
|
245
|
-
caption="${ifDefined(headerCaption || undefined)}"
|
|
246
|
-
transparent>
|
|
247
|
-
${hasMultipleLanguages ? html`
|
|
248
|
-
<div slot="actions" class="translation-group__language-field" part="language-field">
|
|
249
|
-
<zn-select
|
|
250
|
-
label="${this.languageLabel}"
|
|
251
|
-
class="translation-group__language-select"
|
|
252
|
-
part="language-select"
|
|
253
|
-
hoist
|
|
254
|
-
.value="${this._activeLanguage}"
|
|
255
|
-
@zn-change="${this.handleLanguageSelect}"
|
|
256
|
-
@zn-input="${this.handleLanguageInput}">
|
|
257
|
-
<zn-chip slot="suffix" type="${summary.type}">${summary.label}</zn-chip>
|
|
258
|
-
${languageCodes.map(code => {
|
|
259
|
-
const optionState = this.languageState(code);
|
|
260
|
-
return html`
|
|
261
|
-
<zn-option value="${code}">
|
|
262
|
-
${this.displayName(code)}
|
|
263
|
-
<zn-chip slot="suffix" type="${optionState.type}">${optionState.label}</zn-chip>
|
|
264
|
-
</zn-option>`;
|
|
265
|
-
})}
|
|
266
|
-
</zn-select>
|
|
267
|
-
</div>` : nothing}
|
|
268
|
-
</zn-header>` : null}
|
|
269
|
-
|
|
270
245
|
<div class="panel__content">
|
|
271
246
|
<div class="panel__body">
|
|
272
|
-
<
|
|
273
|
-
|
|
274
|
-
|
|
247
|
+
<zn-form-group
|
|
248
|
+
part="form-group"
|
|
249
|
+
label="${caption}"
|
|
250
|
+
help-text="${this.helpText}">
|
|
251
|
+
|
|
252
|
+
${hasMultipleLanguages ? html`
|
|
253
|
+
<div slot="chip" class="translation-group__language-field" part="language-field">
|
|
254
|
+
<zn-select
|
|
255
|
+
label="${this.languageLabel}"
|
|
256
|
+
class="translation-group__language-select"
|
|
257
|
+
part="language-select"
|
|
258
|
+
hoist
|
|
259
|
+
search
|
|
260
|
+
.value="${this._activeLanguage}"
|
|
261
|
+
@zn-change="${this.handleLanguageSelect}"
|
|
262
|
+
@zn-input="${this.handleLanguageInput}">
|
|
263
|
+
<zn-chip slot="suffix" type="${summary.type}">${summary.label}</zn-chip>
|
|
264
|
+
${languageCodes.map(code => {
|
|
265
|
+
const optionState = this.languageState(code);
|
|
266
|
+
return html`
|
|
267
|
+
<zn-option value="${code}">
|
|
268
|
+
${this.displayName(code)}
|
|
269
|
+
<zn-chip slot="suffix" type="${optionState.type}">${optionState.label}</zn-chip>
|
|
270
|
+
</zn-option>`;
|
|
271
|
+
})}
|
|
272
|
+
</zn-select>
|
|
273
|
+
</div>` : nothing}
|
|
274
|
+
|
|
275
|
+
<slot
|
|
276
|
+
@slotchange="${this.handleSlotChange}"
|
|
277
|
+
@zn-change="${this.handleChildChange}"></slot>
|
|
278
|
+
</zn-form-group>
|
|
275
279
|
|
|
276
280
|
${hasActionsSlot ? html`
|
|
277
281
|
<div class="translation-group__actions" part="actions">
|
|
@@ -2,81 +2,15 @@
|
|
|
2
2
|
display: block;
|
|
3
3
|
}
|
|
4
4
|
|
|
5
|
-
// The body
|
|
6
|
-
// controls. The slotted children are `display: contents` through the slot, putting them in this same flex flow.
|
|
5
|
+
// The body holds the form group and the actions row; the gap is what separates them.
|
|
7
6
|
.panel__body {
|
|
8
7
|
gap: var(--zn-spacing-medium);
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
// The
|
|
12
|
-
// the
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.panel__header {
|
|
18
|
-
padding-bottom: var(--zn-spacing-medium);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
.translation-group--inline .panel__header {
|
|
22
|
-
padding: 0 0 var(--zn-spacing-medium);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// zn-header holds its content row at 36px so a caption sits level with action buttons. The select is taller than
|
|
26
|
-
// that and sets the height on its own, so the row hugs whichever of the two is bigger.
|
|
27
|
-
.panel__header::part(content) {
|
|
28
|
-
min-height: 0;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// The actions container is a plain block that clips horizontally: its content would sit at the top rather than level
|
|
32
|
-
// with the caption, and a select flush against its right edge would lose the focus ring.
|
|
33
|
-
.panel__header::part(header-right) {
|
|
34
|
-
display: flex;
|
|
35
|
-
align-items: center;
|
|
36
|
-
justify-content: flex-end;
|
|
37
|
-
overflow: visible;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.translation-group__language-field {
|
|
41
|
-
display: flex;
|
|
42
|
-
align-items: center;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// The trigger shows one language, so it sizes to that.
|
|
46
|
-
.translation-group__language-select {
|
|
47
|
-
width: max-content;
|
|
48
|
-
max-width: 100%;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Left alone the display input hands the trigger its default 20-character intrinsic width, however short the language
|
|
52
|
-
// name is. Where field-sizing is unsupported that width is what is left, which only makes the trigger a little wider.
|
|
53
|
-
.translation-group__language-select::part(display-input) {
|
|
54
|
-
width: auto;
|
|
55
|
-
min-width: 0;
|
|
56
|
-
field-sizing: content;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// The popup syncs its width to the trigger, which is now sized to the current language rather than the longest one in
|
|
60
|
-
// the list. zn-select runs the popup with auto-size="vertical", so --auto-size-available-width is never set and the
|
|
61
|
-
// listbox's own max-width is inert — this is the only thing keeping a long list on screen.
|
|
62
|
-
.translation-group__language-select::part(listbox) {
|
|
63
|
-
min-width: 320px;
|
|
64
|
-
max-width: calc(100vw - var(--zn-spacing-large));
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// The select is chrome in the panel header rather than a field to fill in, so it drops the input's fill and shadow.
|
|
68
|
-
// The border stays, marking it out as something to open.
|
|
69
|
-
.translation-group__language-select::part(combobox) {
|
|
70
|
-
background-color: transparent;
|
|
71
|
-
box-shadow: none;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
.translation-group__language-select:hover::part(combobox) {
|
|
75
|
-
background-color: var(--zn-input-background-color-hover);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.translation-group__language-select:focus-within::part(combobox) {
|
|
79
|
-
box-shadow: 0 0 0 var(--zn-focus-ring-width) var(--zn-input-focus-ring-color);
|
|
10
|
+
// The fields land in the form group's 6-column input grid, but they are assigned to this slot rather than the
|
|
11
|
+
// group's, so its span rules cannot reach them — each takes the full row from here.
|
|
12
|
+
::slotted(:not([slot])) {
|
|
13
|
+
grid-column: 1 / -1;
|
|
80
14
|
}
|
|
81
15
|
|
|
82
16
|
// The select's label is its accessible name only; the caption names the section on screen.
|
|
@@ -92,11 +26,13 @@
|
|
|
92
26
|
border: 0;
|
|
93
27
|
}
|
|
94
28
|
|
|
95
|
-
// Matches zinc's form action rows (.form-actions, zn-form-actions): right-aligned, 16px apart.
|
|
29
|
+
// Matches zinc's form action rows (.form-actions, zn-form-actions): right-aligned, 16px apart. The cap holds the
|
|
30
|
+
// buttons level with the fields' right edge, which zn-form-group sizes to the same container.
|
|
96
31
|
.translation-group__actions {
|
|
97
32
|
display: flex;
|
|
98
33
|
align-items: center;
|
|
99
34
|
gap: var(--zn-spacing-small);
|
|
35
|
+
max-width: var(--zn-container-lg);
|
|
100
36
|
}
|
|
101
37
|
|
|
102
38
|
// The spacer, not an auto margin, is what splits the two sides: an auto margin on every right-hand button would open
|
|
@@ -114,8 +50,8 @@
|
|
|
114
50
|
order: 0;
|
|
115
51
|
}
|
|
116
52
|
|
|
117
|
-
// The panel draws a border between any two body children, and the actions row
|
|
118
|
-
//
|
|
53
|
+
// The panel draws a border between any two body children, and the actions row follows the form group. Matched on
|
|
54
|
+
// .panel--has-actions to out-specify that rule.
|
|
119
55
|
.panel--has-actions .panel__body > .translation-group__actions {
|
|
120
56
|
border: 0;
|
|
121
57
|
}
|