@lion/ui 0.11.4 → 0.11.5

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 (155) hide show
  1. package/components/calendar/src/LionCalendar.js +3 -0
  2. package/components/calendar/translations/tr.js +11 -0
  3. package/components/form-core/src/localizeNamespaceLoader.js +4 -0
  4. package/components/form-core/src/validate/ValidateMixin.js +6 -6
  5. package/components/form-core/test-suites/ValidateMixin.suite.js +116 -1
  6. package/components/form-core/translations/tr-TR.js +5 -0
  7. package/components/form-core/translations/tr.js +6 -0
  8. package/components/input-datepicker/src/localizeNamespaceLoader.js +7 -1
  9. package/components/input-datepicker/translations/tr-TR.js +5 -0
  10. package/components/input-datepicker/translations/tr.js +3 -0
  11. package/components/input-file/src/LionInputFile.js +39 -11
  12. package/components/input-file/src/LionSelectedFileList.js +0 -1
  13. package/components/input-file/test/lion-input-file.test.js +98 -4
  14. package/components/input-file/translations/bg.js +1 -1
  15. package/components/input-file/translations/cs.js +1 -1
  16. package/components/input-file/translations/de.js +6 -1
  17. package/components/input-file/translations/en.js +6 -2
  18. package/components/input-file/translations/es.js +1 -1
  19. package/components/input-file/translations/fr.js +1 -1
  20. package/components/input-file/translations/hu.js +1 -1
  21. package/components/input-file/translations/it.js +1 -1
  22. package/components/input-file/translations/nl.js +6 -1
  23. package/components/input-file/translations/pl.js +1 -1
  24. package/components/input-file/translations/ro.js +1 -1
  25. package/components/input-file/translations/ru.js +7 -3
  26. package/components/input-file/translations/sk.js +1 -1
  27. package/components/input-file/translations/uk.js +1 -1
  28. package/components/input-file/translations/zh.js +1 -1
  29. package/components/input-stepper/src/LionInputStepper.js +19 -3
  30. package/components/input-stepper/test/lion-input-stepper.test.js +94 -0
  31. package/components/overlays/translations/tr-TR.js +5 -0
  32. package/components/overlays/translations/tr.js +4 -0
  33. package/components/pagination/src/LionPagination.js +2 -0
  34. package/components/pagination/translations/tr.js +6 -0
  35. package/components/validate-messages/src/getLocalizedMessage.js +4 -0
  36. package/components/validate-messages/translations/tr-TR.js +13 -0
  37. package/components/validate-messages/translations/tr.js +56 -0
  38. package/custom-elements.json +49 -38
  39. package/dist-types/components/calendar/src/LionCalendar.d.ts.map +1 -1
  40. package/dist-types/components/calendar/translations/tr.d.ts +11 -0
  41. package/dist-types/components/calendar/translations/tr.d.ts.map +1 -0
  42. package/dist-types/components/form-core/src/localizeNamespaceLoader.d.ts.map +1 -1
  43. package/dist-types/components/form-core/test-suites/ValidateMixin.suite.d.ts.map +1 -1
  44. package/dist-types/components/form-core/translations/tr-TR.d.ts +8 -0
  45. package/dist-types/components/form-core/translations/tr-TR.d.ts.map +1 -0
  46. package/dist-types/components/form-core/translations/tr.d.ts +8 -0
  47. package/dist-types/components/form-core/translations/tr.d.ts.map +1 -0
  48. package/dist-types/components/input-datepicker/src/localizeNamespaceLoader.d.ts.map +1 -1
  49. package/dist-types/components/input-datepicker/translations/tr-TR.d.ts +5 -0
  50. package/dist-types/components/input-datepicker/translations/tr-TR.d.ts.map +1 -0
  51. package/dist-types/components/input-datepicker/translations/tr.d.ts +5 -0
  52. package/dist-types/components/input-datepicker/translations/tr.d.ts.map +1 -0
  53. package/dist-types/components/input-file/src/LionInputFile.d.ts +1 -0
  54. package/dist-types/components/input-file/src/LionInputFile.d.ts.map +1 -1
  55. package/dist-types/components/input-file/src/LionSelectedFileList.d.ts.map +1 -1
  56. package/dist-types/components/input-file/src/localizeNamespaceLoader.d.ts +1 -1
  57. package/dist-types/components/input-file/src/localizeNamespaceLoader.d.ts.map +1 -1
  58. package/dist-types/components/input-file/test/lion-input-file.test.d.ts.map +1 -1
  59. package/dist-types/components/input-file/translations/de-DE.d.ts +5 -0
  60. package/dist-types/components/input-file/translations/de.d.ts +5 -0
  61. package/dist-types/components/input-file/translations/en-AU.d.ts +5 -1
  62. package/dist-types/components/input-file/translations/en-GB.d.ts +5 -1
  63. package/dist-types/components/input-file/translations/en-PH.d.ts +5 -1
  64. package/dist-types/components/input-file/translations/en-US.d.ts +5 -1
  65. package/dist-types/components/input-file/translations/en.d.ts +5 -1
  66. package/dist-types/components/input-file/translations/nl-BE.d.ts +5 -0
  67. package/dist-types/components/input-file/translations/nl-NL.d.ts +5 -0
  68. package/dist-types/components/input-file/translations/nl.d.ts +5 -0
  69. package/dist-types/components/input-file/translations/ru-RU.d.ts +5 -1
  70. package/dist-types/components/input-file/translations/ru.d.ts +5 -1
  71. package/dist-types/components/input-stepper/src/LionInputStepper.d.ts.map +1 -1
  72. package/dist-types/components/overlays/translations/tr-TR.d.ts +6 -0
  73. package/dist-types/components/overlays/translations/tr-TR.d.ts.map +1 -0
  74. package/dist-types/components/overlays/translations/tr.d.ts +6 -0
  75. package/dist-types/components/overlays/translations/tr.d.ts.map +1 -0
  76. package/dist-types/components/pagination/src/LionPagination.d.ts.map +1 -1
  77. package/dist-types/components/pagination/translations/tr.d.ts +8 -0
  78. package/dist-types/components/pagination/translations/tr.d.ts.map +1 -0
  79. package/dist-types/components/validate-messages/src/getLocalizedMessage.d.ts.map +1 -1
  80. package/dist-types/components/validate-messages/translations/tr-TR.d.ts +55 -0
  81. package/dist-types/components/validate-messages/translations/tr-TR.d.ts.map +1 -0
  82. package/dist-types/components/validate-messages/translations/tr.d.ts +73 -0
  83. package/dist-types/components/validate-messages/translations/tr.d.ts.map +1 -0
  84. package/dist-types/tsconfig.tsbuildinfo +1 -1
  85. package/docs/components/checkbox-group/api-table.md +3 -3
  86. package/docs/components/checkbox-group/overview.md +2 -2
  87. package/docs/components/collapsible/overview.md +1 -1
  88. package/docs/components/combobox/api-table.md +1 -1
  89. package/docs/components/combobox/overview.md +1 -1
  90. package/docs/components/combobox/use-cases.md +1 -1
  91. package/docs/components/dialog/overview.md +1 -1
  92. package/docs/components/fieldset/api-table.md +1 -1
  93. package/docs/components/fieldset/overview.md +5 -5
  94. package/docs/components/form/overview.md +3 -3
  95. package/docs/components/form/use-cases.md +2 -2
  96. package/docs/components/icon/use-cases.md +1 -1
  97. package/docs/components/input/api-table.md +1 -1
  98. package/docs/components/input/overview.md +1 -1
  99. package/docs/components/input-amount/api-table.md +1 -1
  100. package/docs/components/input-amount/overview.md +3 -3
  101. package/docs/components/input-date/api-table.md +1 -1
  102. package/docs/components/input-date/overview.md +3 -3
  103. package/docs/components/input-datepicker/api-table.md +1 -1
  104. package/docs/components/input-datepicker/overview.md +5 -5
  105. package/docs/components/input-email/api-table.md +1 -1
  106. package/docs/components/input-email/overview.md +2 -2
  107. package/docs/components/input-file/api-table.md +3 -2
  108. package/docs/components/input-file/overview.md +1 -1
  109. package/docs/components/input-iban/api-table.md +1 -1
  110. package/docs/components/input-iban/overview.md +2 -2
  111. package/docs/components/input-range/api-table.md +1 -1
  112. package/docs/components/input-range/overview.md +2 -2
  113. package/docs/components/input-stepper/api-table.md +1 -1
  114. package/docs/components/input-stepper/overview.md +1 -1
  115. package/docs/components/input-stepper/use-cases.md +16 -0
  116. package/docs/components/input-tel/api-table.md +1 -1
  117. package/docs/components/input-tel/overview.md +1 -1
  118. package/docs/components/input-tel/use-cases.md +6 -6
  119. package/docs/components/input-tel-dropdown/api-table.md +1 -1
  120. package/docs/components/input-tel-dropdown/overview.md +1 -1
  121. package/docs/components/listbox/api-table.md +1 -1
  122. package/docs/components/listbox/use-cases.md +1 -1
  123. package/docs/components/radio-group/api-table.md +2 -2
  124. package/docs/components/radio-group/overview.md +3 -3
  125. package/docs/components/select/api-table.md +1 -1
  126. package/docs/components/select/use-cases.md +1 -1
  127. package/docs/components/select-rich/api-table.md +1 -1
  128. package/docs/components/select-rich/use-cases.md +1 -1
  129. package/docs/components/switch/api-table.md +1 -1
  130. package/docs/components/tabs/examples.md +1 -1
  131. package/docs/components/textarea/api-table.md +1 -1
  132. package/docs/fundamentals/index.md +4 -4
  133. package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
  134. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
  135. package/docs/fundamentals/rationales/accessibility.md +1 -1
  136. package/docs/fundamentals/systems/core/SlotMixin.md +1 -1
  137. package/docs/fundamentals/systems/core/overview.md +1 -1
  138. package/docs/fundamentals/systems/form/api-table.md +1 -1
  139. package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
  140. package/docs/fundamentals/systems/form/model-value.md +1 -1
  141. package/docs/fundamentals/systems/form/overview.md +28 -28
  142. package/docs/fundamentals/systems/form/validate.md +2 -2
  143. package/docs/fundamentals/systems/localize/overview.md +4 -4
  144. package/docs/fundamentals/systems/overlays/configuration.md +2 -2
  145. package/docs/fundamentals/systems/overlays/overview.md +5 -5
  146. package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
  147. package/docs/fundamentals/tools/helpers/overview.md +1 -1
  148. package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
  149. package/docs/guides/how-to/create-a-custom-field.md +5 -5
  150. package/docs/guides/how-to/create-a-form.md +4 -4
  151. package/docs/guides/how-to/extend-a-native-input.md +2 -2
  152. package/docs/guides/index.md +8 -8
  153. package/docs/guides/principles/index.md +5 -5
  154. package/docs/guides/principles/styling.md +1 -1
  155. package/package.json +1 -1
@@ -88,6 +88,9 @@ export class LionCalendar extends LocalizeMixin(LitElement) {
88
88
  case 'sk-SK':
89
89
  case 'sk':
90
90
  return import('@lion/ui/calendar-translations/sk.js');
91
+ case 'tr-TR':
92
+ case 'tr':
93
+ return import('@lion/ui/calendar-translations/tr.js');
91
94
  case 'uk-UA':
92
95
  case 'uk':
93
96
  return import('@lion/ui/calendar-translations/uk.js');
@@ -0,0 +1,11 @@
1
+ export default {
2
+ nextMonth: 'Sonraki ay',
3
+ previousMonth: 'Önceki ay',
4
+ nextFullYear: 'Gelecek yıl',
5
+ previousFullYear: 'Geçen yıl',
6
+ defaultDisabledDate: 'Bu tarih kullanılamaz. Lütfen başka bir tarih seçin.',
7
+ beforeDisabledDate:
8
+ 'Bu tarih kullanılamaz. En erken kullanılabilir tarih: {params}. Lütfen başka bir tarih seçin.',
9
+ afterDisabledDate:
10
+ 'Bu tarih kullanılamaz. En geç kullanılabilir tarih: {params}. Lütfen başka bir tarih seçin.',
11
+ };
@@ -62,6 +62,10 @@ export const localizeNamespaceLoader = /** @param {string} locale */ locale => {
62
62
  return import('@lion/ui/form-core-translations/sk-SK.js');
63
63
  case 'sk':
64
64
  return import('@lion/ui/form-core-translations/sk.js');
65
+ case 'tr-TR':
66
+ return import('@lion/ui/form-core-translations/tr-TR.js');
67
+ case 'tr':
68
+ return import('@lion/ui/form-core-translations/tr.js');
65
69
  case 'uk-UA':
66
70
  return import('@lion/ui/form-core-translations/uk-UA.js');
67
71
  case 'uk':
@@ -8,11 +8,11 @@ import { AsyncQueue } from '../utils/AsyncQueue.js';
8
8
  import { pascalCase } from '../utils/pascalCase.js';
9
9
  import { SyncUpdatableMixin } from '../utils/SyncUpdatableMixin.js';
10
10
  import { LionValidationFeedback } from './LionValidationFeedback.js';
11
- import { ResultValidator as MetaValidator } from './ResultValidator.js';
12
11
  import { Unparseable } from './Unparseable.js';
13
- import { Required } from './validators/Required.js';
14
12
  import { FormControlMixin } from '../FormControlMixin.js';
15
13
  // eslint-disable-next-line no-unused-vars
14
+ import { ResultValidator as MetaValidator } from './ResultValidator.js';
15
+ // eslint-disable-next-line no-unused-vars
16
16
  import { Validator } from './Validator.js';
17
17
  // TODO: [v1] make all @readOnly => @readonly and actually make sure those values cannot be set
18
18
 
@@ -134,7 +134,7 @@ export const ValidateMixinImplementation = superclass =>
134
134
 
135
135
  /**
136
136
  * Combination of validators provided by Application Developer and the default validators
137
- * @type {Validator[]}
137
+ * @type {(Validator | MetaValidator)[]}
138
138
  * @protected
139
139
  */
140
140
  get _allValidators() {
@@ -480,9 +480,9 @@ export const ValidateMixinImplementation = superclass =>
480
480
  const asyncValidators = /** @type {Validator[]} */ [];
481
481
 
482
482
  for (const v of this._allValidators) {
483
- if (v instanceof MetaValidator) {
484
- metaValidators.push(v);
485
- } else if (v instanceof Required) {
483
+ if (/** @type {MetaValidator} */ (v)?.executeOnResults) {
484
+ metaValidators.push(/** @type {MetaValidator} */ (v));
485
+ } else if (/** @type {typeof Validator} */ (v.constructor)?.validatorName === 'Required') {
486
486
  // Required validator was already handled
487
487
  } else if (/** @type {typeof Validator} */ (v.constructor).async) {
488
488
  asyncValidators.push(v);
@@ -130,6 +130,121 @@ export function runValidateMixinSuite(customConfig) {
130
130
  expect(el.hasFeedbackFor).to.deep.equal(['error']);
131
131
  });
132
132
 
133
+ it('determines whether the "Required" validator was already handled by judging the validatorName', async () => {
134
+ class BundledValidator extends EventTarget {
135
+ static ['_$isValidator$'] = true;
136
+
137
+ static validatorName = '';
138
+
139
+ constructor() {
140
+ super();
141
+
142
+ this.type = 'error';
143
+ }
144
+
145
+ get config() {
146
+ // simplified version of the actual config
147
+ return {};
148
+ }
149
+
150
+ execute() {
151
+ // simplified version of the action execution
152
+ return true;
153
+ }
154
+
155
+ onFormControlConnect() {}
156
+
157
+ onFormControlDisconnect() {}
158
+
159
+ async _getMessage() {
160
+ // simplified version of the actual logic
161
+ return 'You need to enter something.';
162
+ }
163
+ }
164
+
165
+ class BundledRequired extends BundledValidator {
166
+ static get validatorName() {
167
+ return 'Required';
168
+ }
169
+ }
170
+
171
+ const el = /** @type {ValidateElement} */ (
172
+ await fixture(html`
173
+ <${tag}
174
+ .validators=${[new BundledRequired()]}
175
+ .modelValue=${'myValue'}
176
+ >${lightDom}</${tag}>
177
+ `)
178
+ );
179
+
180
+ expect(el.hasFeedbackFor).to.deep.equal([]);
181
+ });
182
+
183
+ it('determines whether the passed Validators are ResultValidators judging by the presence of "executeOnResults"', async () => {
184
+ class ValidateElementWithSuccessType extends ValidateElement {
185
+ static get validationTypes() {
186
+ return ['error', 'success'];
187
+ }
188
+ }
189
+
190
+ const elTagString = defineCE(ValidateElementWithSuccessType);
191
+ const elTag = unsafeStatic(elTagString);
192
+
193
+ class BundledValidator extends EventTarget {
194
+ static ['_$isValidator$'] = true;
195
+
196
+ static validatorName = '';
197
+
198
+ constructor() {
199
+ super();
200
+
201
+ this.type = 'error';
202
+ }
203
+
204
+ get config() {
205
+ // simplified version of the actual config
206
+ return {};
207
+ }
208
+
209
+ execute() {
210
+ // simplified version of the action execution
211
+ return true;
212
+ }
213
+
214
+ onFormControlConnect() {}
215
+
216
+ onFormControlDisconnect() {}
217
+
218
+ async _getMessage() {
219
+ // simplified version of the actual logic
220
+ return 'Success message.';
221
+ }
222
+ }
223
+
224
+ class BundledDefaultSuccess extends BundledValidator {
225
+ constructor() {
226
+ super();
227
+
228
+ this.type = 'success';
229
+ }
230
+
231
+ executeOnResults() {
232
+ return true;
233
+ }
234
+ }
235
+
236
+ const el = /** @type {ValidateElement} */ (
237
+ await fixture(html`
238
+ <${elTag}
239
+ .validators=${[new Required(), new BundledDefaultSuccess()]}
240
+ .modelValue=${'myValue'}
241
+ >${lightDom}</${elTag}>
242
+ `)
243
+ );
244
+
245
+ expect(el.hasFeedbackFor).to.deep.equal(['success']);
246
+ });
247
+
133
248
  it('revalidates when ".modelValue" changes', async () => {
134
249
  const el = /** @type {ValidateElement} */ (
135
250
  await fixture(html`
@@ -791,7 +906,7 @@ export function runValidateMixinSuite(customConfig) {
791
906
  // @ts-expect-error
792
907
  new EqualsLength(4, { getMessage: () => html`<div id="test123">test</div>` }),
793
908
  ]}" })]}"
794
- .modelValue="${'123'}"
909
+ .modelValue="${'123'}"
795
910
  label="Custom message for validator instance"
796
911
  ></${tag}>
797
912
  `)
@@ -0,0 +1,5 @@
1
+ import tr from './tr.js';
2
+
3
+ export default {
4
+ ...tr,
5
+ };
@@ -0,0 +1,6 @@
1
+ export default {
2
+ validationError: 'Hatalı',
3
+ validationWarning: 'Uyarı',
4
+ validationSuccess: 'Başarılı',
5
+ validationInfo: 'Bilgilendirme',
6
+ };
@@ -62,7 +62,6 @@ export const localizeNamespaceLoader = /** @param {string} locale */ locale => {
62
62
  import('@lion/ui/overlays-translations/en.js'),
63
63
  import('@lion/ui/input-datepicker-translations/en.js'),
64
64
  ]);
65
-
66
65
  case 'es-ES':
67
66
  return combineLocalizeImports([
68
67
  import('@lion/ui/overlays-translations/es-ES.js'),
@@ -163,6 +162,13 @@ export const localizeNamespaceLoader = /** @param {string} locale */ locale => {
163
162
  import('@lion/ui/overlays-translations/sk.js'),
164
163
  import('@lion/ui/input-datepicker-translations/sk.js'),
165
164
  ]);
165
+ case 'tr-TR':
166
+ return import('@lion/ui/input-datepicker-translations/tr-TR.js');
167
+ case 'tr':
168
+ return combineLocalizeImports([
169
+ import('@lion/ui/overlays-translations/tr.js'),
170
+ import('@lion/ui/input-datepicker-translations/tr.js'),
171
+ ]);
166
172
  case 'uk-UA':
167
173
  return combineLocalizeImports([
168
174
  import('@lion/ui/overlays-translations/uk-UA.js'),
@@ -0,0 +1,5 @@
1
+ import tr from './tr.js';
2
+
3
+ export default {
4
+ ...tr,
5
+ };
@@ -0,0 +1,3 @@
1
+ export default {
2
+ openDatepickerLabel: 'Tarih seçimini aç',
3
+ };
@@ -110,7 +110,7 @@ export class LionInputFile extends ScopedElementsMixin(LocalizeMixin(LionField))
110
110
  * @type {string}
111
111
  */
112
112
  get buttonLabel() {
113
- return this.__buttonLabel || this._buttonNode?.textContent || '';
113
+ return this.__buttonLabel || this._buttonNode?.textContent?.trim() || '';
114
114
  }
115
115
 
116
116
  /**
@@ -164,6 +164,8 @@ export class LionInputFile extends ScopedElementsMixin(LocalizeMixin(LionField))
164
164
  this.enableDropZone = false;
165
165
  this.maxFileSize = MAX_FILE_SIZE;
166
166
  this.accept = '';
167
+ this.buttonLabel = '';
168
+ this._initialButtonLabel = '';
167
169
  /**
168
170
  * @type {InputFile[]}
169
171
  */
@@ -196,7 +198,7 @@ export class LionInputFile extends ScopedElementsMixin(LocalizeMixin(LionField))
196
198
  connectedCallback() {
197
199
  super.connectedCallback();
198
200
  this.__initialUploadResponse = this.uploadResponse;
199
-
201
+ this._initialButtonLabel = this.buttonLabel;
200
202
  this._inputNode.addEventListener('change', this._onChange);
201
203
  this._inputNode.addEventListener('click', this._onClick);
202
204
  }
@@ -214,10 +216,12 @@ export class LionInputFile extends ScopedElementsMixin(LocalizeMixin(LionField))
214
216
  super.onLocaleUpdated();
215
217
  if (this.multiple) {
216
218
  // @ts-ignore
217
- this.buttonLabel = this.msgLit('lion-input-file:selectTextMultipleFile');
219
+ this.buttonLabel =
220
+ this._initialButtonLabel || this.msgLit('lion-input-file:selectTextMultipleFile');
218
221
  } else {
219
222
  // @ts-ignore
220
- this.buttonLabel = this.msgLit('lion-input-file:selectTextSingleFile');
223
+ this.buttonLabel =
224
+ this._initialButtonLabel || this.msgLit('lion-input-file:selectTextSingleFile');
221
225
  }
222
226
  }
223
227
 
@@ -758,15 +762,39 @@ export class LionInputFile extends ScopedElementsMixin(LocalizeMixin(LionField))
758
762
  const selectedFiles = this.querySelector('[slot="after"]');
759
763
  if (selectedFiles) {
760
764
  if (!this._selectedFilesMetaData || this._selectedFilesMetaData.length === 0) {
761
- selectedFiles.textContent = /** @type {string} */ (
762
- this.msgLit('lion-input-file:noFilesSelected')
763
- );
765
+ if (this.uploadOnSelect) {
766
+ selectedFiles.textContent = /** @type {string} */ (
767
+ this.msgLit('lion-input-file:noFilesUploaded')
768
+ );
769
+ } else {
770
+ selectedFiles.textContent = /** @type {string} */ (
771
+ this.msgLit('lion-input-file:noFilesSelected')
772
+ );
773
+ }
764
774
  } else if (this._selectedFilesMetaData.length === 1) {
765
- selectedFiles.textContent = /** @type {string} */ (
766
- errorMessage || this._selectedFilesMetaData[0].systemFile.name
767
- );
775
+ const { name } = this._selectedFilesMetaData[0].systemFile;
776
+ if (this.uploadOnSelect) {
777
+ selectedFiles.textContent = /** @type {string} */ (
778
+ errorMessage || this.msgLit('lion-input-file:fileUploaded') + (name ?? '')
779
+ );
780
+ } else {
781
+ selectedFiles.textContent = /** @type {string} */ (
782
+ errorMessage || this.msgLit('lion-input-file:fileSelected') + (name ?? '')
783
+ );
784
+ }
785
+ } else if (this.uploadOnSelect) {
786
+ selectedFiles.textContent = `${this.msgLit('lion-input-file:filesUploaded', {
787
+ numberOfFiles: this._selectedFilesMetaData.length,
788
+ })} ${
789
+ errorMessage
790
+ ? this.msgLit('lion-input-file:generalValidatorMessage', {
791
+ validatorMessage: errorMessage,
792
+ listOfErroneousFiles: erroneousFilesNames.join(', '),
793
+ })
794
+ : ''
795
+ }`;
768
796
  } else {
769
- selectedFiles.textContent = `${this.msgLit('lion-input-file:numberOfFiles', {
797
+ selectedFiles.textContent = `${this.msgLit('lion-input-file:filesSelected', {
770
798
  numberOfFiles: this._selectedFilesMetaData.length,
771
799
  })} ${
772
800
  errorMessage
@@ -212,7 +212,6 @@ export class LionSelectedFileList extends LocalizeMixin(ScopedElementsMixin(LitE
212
212
 
213
213
  .sr-only {
214
214
  position: absolute;
215
- top: 0;
216
215
  width: 1px;
217
216
  height: 1px;
218
217
  overflow: hidden;
@@ -1,6 +1,8 @@
1
1
  import '@lion/ui/define/lion-input-file.js';
2
2
  import { Required } from '@lion/ui/form-core.js';
3
3
  import { getInputMembers } from '@lion/ui/input-test-helpers.js';
4
+ import { getLocalizeManager } from '@lion/ui/localize-no-side-effects.js';
5
+ import { localizeTearDown } from '@lion/ui/localize-test-helpers.js';
4
6
  import { expect, fixture as _fixture, html, oneEvent, elementUpdated } from '@open-wc/testing';
5
7
  import sinon from 'sinon';
6
8
 
@@ -59,6 +61,10 @@ const file4 = /** @type {InputFile} */ (
59
61
  );
60
62
 
61
63
  describe('lion-input-file', () => {
64
+ const localizeManager = getLocalizeManager();
65
+
66
+ afterEach(localizeTearDown);
67
+
62
68
  it('has a type of "file"', async () => {
63
69
  const el = await fixture(html`<lion-input-file></lion-input-file>`);
64
70
  // @ts-expect-error [allow-protected-in-tests]
@@ -151,6 +157,43 @@ describe('lion-input-file', () => {
151
157
  expect(el._selectedFilesMetaData[0].systemFile.name).to.equal('bar.txt');
152
158
  });
153
159
 
160
+ describe('structure', async () => {
161
+ it('can has a button label by default', async () => {
162
+ const el = await fixture(html`<lion-input-file></lion-input-file>`);
163
+ // @ts-expect-error [allow-protected-in-test]
164
+ expect(el._buttonNode.textContent).to.equal('Select file');
165
+ });
166
+
167
+ it('can has a button label by default when multiple', async () => {
168
+ const el = await fixture(html`<lion-input-file multiple></lion-input-file>`);
169
+ // @ts-expect-error [allow-protected-in-test]
170
+ expect(el._buttonNode.textContent).to.equal('Select files');
171
+ });
172
+
173
+ it('will update the button label on locale change', async () => {
174
+ const el = await fixture(html`<lion-input-file></lion-input-file>`);
175
+ // @ts-expect-error [allow-protected-in-test]
176
+ expect(el._buttonNode.textContent).to.equal('Select file');
177
+
178
+ localizeManager.locale = 'nl-NL';
179
+ await localizeManager.loadingComplete;
180
+ await el.updateComplete;
181
+ // @ts-expect-error [allow-protected-in-test]
182
+ expect(el._buttonNode.textContent).to.equal('Selecteer bestand');
183
+ });
184
+
185
+ it('can overwrite the button label', async () => {
186
+ const el = await fixture(html`<lion-input-file .buttonLabel="${'Foo'}"></lion-input-file>`);
187
+ // @ts-expect-error [allow-protected-in-test]
188
+ expect(el._buttonNode.textContent).to.equal('Foo');
189
+
190
+ el.buttonLabel = 'Bar';
191
+ await el.updateComplete;
192
+ // @ts-expect-error [allow-protected-in-test]
193
+ expect(el._buttonNode.textContent).to.equal('Bar');
194
+ });
195
+ });
196
+
154
197
  describe('invalid file types', async () => {
155
198
  const fileWrongType = /** @type {InputFile} */ (
156
199
  new File(['foobar'], 'foobar.txt', {
@@ -1197,7 +1240,29 @@ describe('lion-input-file', () => {
1197
1240
  );
1198
1241
  });
1199
1242
 
1200
- it('after contains upload name of file when SUCCESS', async () => {
1243
+ it('after contains upload name of file when uploadOnSelect is true and status is SUCCESS', async () => {
1244
+ const uploadResponse = [
1245
+ {
1246
+ name: 'file1.txt',
1247
+ status: 'SUCCESS',
1248
+ errorMessage: '',
1249
+ downloadUrl: '/downloadFile',
1250
+ },
1251
+ ];
1252
+ const el = await fixture(html`
1253
+ <lion-input-file label="Select" upload-on-select></lion-input-file>
1254
+ `);
1255
+
1256
+ expect(el.querySelector('[slot="after"]')?.textContent).to.equal('No files uploaded.');
1257
+ // @ts-expect-error
1258
+ el.uploadResponse = uploadResponse;
1259
+ await el.updateComplete;
1260
+ expect(el.querySelector('[slot="after"]')?.textContent).to.equal(
1261
+ 'Uploaded file: file1.txt',
1262
+ );
1263
+ });
1264
+
1265
+ it('after contains upload name of file when uploadOnSelect is false and status is SUCCESS', async () => {
1201
1266
  const uploadResponse = [
1202
1267
  {
1203
1268
  name: 'file1.txt',
@@ -1212,7 +1277,9 @@ describe('lion-input-file', () => {
1212
1277
  // @ts-expect-error
1213
1278
  el.uploadResponse = uploadResponse;
1214
1279
  await el.updateComplete;
1215
- expect(el.querySelector('[slot="after"]')?.textContent).to.equal('file1.txt');
1280
+ expect(el.querySelector('[slot="after"]')?.textContent).to.equal(
1281
+ 'Selected file: file1.txt',
1282
+ );
1216
1283
  });
1217
1284
 
1218
1285
  it('after contains upload validator message of file when FAIL', async () => {
@@ -1233,7 +1300,34 @@ describe('lion-input-file', () => {
1233
1300
  expect(el.querySelector('[slot="after"]')?.textContent).to.equal('something went wrong');
1234
1301
  });
1235
1302
 
1236
- it('after contains upload status of files when multiple files have been uploaded', async () => {
1303
+ it('after contains upload status of files when uploadOnSelect is true and multiple files have been selected', async () => {
1304
+ const uploadResponse = [
1305
+ {
1306
+ name: 'file1.txt',
1307
+ status: 'SUCCESS',
1308
+ errorMessage: '',
1309
+ downloadUrl: '/downloadFile',
1310
+ },
1311
+ {
1312
+ name: 'file2.txt',
1313
+ status: 'FAIL',
1314
+ errorMessage: 'something went wrong',
1315
+ downloadUrl: '/downloadFile',
1316
+ },
1317
+ ];
1318
+ const el = await fixture(html`
1319
+ <lion-input-file label="Select" multiple upload-on-select></lion-input-file>
1320
+ `);
1321
+ // @ts-expect-error
1322
+ el.uploadResponse = uploadResponse;
1323
+
1324
+ await el.updateComplete;
1325
+ expect(el.querySelector('[slot="after"]')?.textContent?.trim()).to.equal(
1326
+ 'Uploaded files: 2 files. "something went wrong", for file2.txt.',
1327
+ );
1328
+ });
1329
+
1330
+ it('after contains upload status of files when uploadOnSelect is false and multiple files have been selected', async () => {
1237
1331
  const uploadResponse = [
1238
1332
  {
1239
1333
  name: 'file1.txt',
@@ -1256,7 +1350,7 @@ describe('lion-input-file', () => {
1256
1350
 
1257
1351
  await el.updateComplete;
1258
1352
  expect(el.querySelector('[slot="after"]')?.textContent?.trim()).to.equal(
1259
- '2 files. "something went wrong", for file2.txt.',
1353
+ 'Selected files: 2 files. "something went wrong", for file2.txt.',
1260
1354
  );
1261
1355
  });
1262
1356
  });
@@ -4,7 +4,7 @@ export default {
4
4
  allowedFileValidatorComplex:
5
5
  'Моля, качете файл от тип {allowedTypesArray} или {allowedTypesLastItem} с макс. размер {maxSize}.',
6
6
  dragAndDropText: 'Плъзнете и пуснете Вашите файлове тук или',
7
- fileNameDescriptionLabel: 'Име на файл: {fileName}',
7
+ fileNameDescriptionLabel: 'Име на файл: ',
8
8
  generalValidatorMessage: '"{validatorMessage}", за {listOfErroneousFiles}.',
9
9
  noFilesSelected: 'Не са избрани файлове.',
10
10
  numberOfFiles: '{numberOfFiles} файла.',
@@ -5,7 +5,7 @@ export default {
5
5
  allowedFileValidatorComplex:
6
6
  'Nahrajte soubor typu {allowedTypesArray} nebo {allowedTypesLastItem} s max. velikostí {maxSize}.',
7
7
  dragAndDropText: 'Přetáhněte soubory sem nebo',
8
- fileNameDescriptionLabel: 'Název souboru: {fileName}',
8
+ fileNameDescriptionLabel: 'Název souboru: ',
9
9
  generalValidatorMessage: '"{validatorMessage}", pro {listOfErroneousFiles}.',
10
10
  noFilesSelected: 'Nebyly vybrány žádné soubory.',
11
11
  numberOfFiles: '{numberOfFiles} soubory/souborů.',
@@ -4,9 +4,14 @@ export default {
4
4
  allowedFileValidatorComplex:
5
5
  'Laden Sie eine {allowedTypesArray} oder {allowedTypesLastItem}-Datei mit max. {maxSize} hoch.',
6
6
  dragAndDropText: 'Ziehen Sie Ihre Dateien per Drag & Drop hierher oder',
7
- fileNameDescriptionLabel: 'Dateiname: {fileName}',
7
+ fileNameDescriptionLabel: 'Dateiname: ',
8
8
  generalValidatorMessage: '"{validatorMessage}", für {listOfErroneousFiles}.',
9
9
  noFilesSelected: 'Keine Dateien ausgewählt.',
10
+ noFilesUploaded: 'Keine Dateien hochgeladen.',
11
+ fileSelected: 'Ausgewählte Datei: ',
12
+ fileUploaded: 'Hochgeladene Datei: ',
13
+ filesSelected: 'Ausgewählte Dateien: {numberOfFiles} Dateien.',
14
+ filesUploaded: 'Hochgeladene Dateien: {numberOfFiles} Dateien.',
10
15
  numberOfFiles: '{numberOfFiles} Dateien.',
11
16
  removeButtonLabel: 'Datei {fileName} entfernen',
12
17
  selectTextDuplicateFileName: 'Eine Datei mit demselben Dateinamen war bereits vorhanden.',
@@ -4,10 +4,14 @@ export default {
4
4
  allowedFileValidatorComplex:
5
5
  'Please select a {allowedTypesArray} or {allowedTypesLastItem} file with max {maxSize}.',
6
6
  dragAndDropText: 'Drag & Drop your files here or', // TODO: or what? Why is Drag & Drop capitalized?
7
- fileNameDescriptionLabel: 'File name: {fileName}',
7
+ fileNameDescriptionLabel: 'File name: ',
8
8
  generalValidatorMessage: '"{validatorMessage}", for {listOfErroneousFiles}.',
9
9
  noFilesSelected: 'No files selected.',
10
- numberOfFiles: '{numberOfFiles} files.',
10
+ noFilesUploaded: 'No files uploaded.',
11
+ fileSelected: 'Selected file: ',
12
+ fileUploaded: 'Uploaded file: ',
13
+ filesSelected: 'Selected files: {numberOfFiles} files.',
14
+ filesUploaded: 'Uploaded files: {numberOfFiles} files.',
11
15
  removeButtonLabel: 'Remove {fileName} file',
12
16
  selectTextDuplicateFileName: 'A file with same filename was already present.',
13
17
  selectTextMultipleFile: 'Select files',
@@ -4,7 +4,7 @@ export default {
4
4
  allowedFileValidatorComplex:
5
5
  'Cargue un archivo {allowedTypesArray} o {allowedTypesLastItem} de {maxSize} como máximo.',
6
6
  dragAndDropText: 'Arrastre y suelte los archivos aquí o',
7
- fileNameDescriptionLabel: 'Nombre de archivo: {fileName}',
7
+ fileNameDescriptionLabel: 'Nombre de archivo: ',
8
8
  generalValidatorMessage: '"{validatorMessage}", para {listOfErroneousFiles}.',
9
9
  noFilesSelected: 'No se han seleccionado archivos.',
10
10
  numberOfFiles: '{numberOfFiles} archivos.',
@@ -5,7 +5,7 @@ export default {
5
5
  allowedFileValidatorComplex:
6
6
  'Veuillez télécharger un fichier {allowedTypesArray} ou {allowedTypesLastItem} avec une taille maximale de {maxSize}.',
7
7
  dragAndDropText: 'Glissez et déposez vos fichiers ici ou',
8
- fileNameDescriptionLabel: 'Nom de fichier: {fileName}',
8
+ fileNameDescriptionLabel: 'Nom de fichier: ',
9
9
  generalValidatorMessage: '"{validatorMessage}", pour {listOfErroneousFiles}.',
10
10
  noFilesSelected: 'Aucun fichier sélectionné.',
11
11
  numberOfFiles: '{numberOfFiles} fichiers.',
@@ -4,7 +4,7 @@ export default {
4
4
  allowedFileValidatorComplex:
5
5
  'Töltsön fel egy legfeljebb {maxSize} méretű {allowedTypesArray} vagy {allowedTypesLastItem} fájlt.',
6
6
  dragAndDropText: 'Húzza át a fájlokat ide vagy',
7
- fileNameDescriptionLabel: 'Fájlnév: {fileName}',
7
+ fileNameDescriptionLabel: 'Fájlnév: ',
8
8
  generalValidatorMessage: '"{validatorMessage}", ehhez: {listOfErroneousFiles}.',
9
9
  noFilesSelected: 'Nincs fájl kiválasztva.',
10
10
  numberOfFiles: '{numberOfFiles} fájl.',
@@ -4,7 +4,7 @@ export default {
4
4
  allowedFileValidatorComplex:
5
5
  'Caricare un file {allowedTypesArray} o {allowedTypesLastItem} di {maxSize} max.',
6
6
  dragAndDropText: 'Trascinare i file qui o',
7
- fileNameDescriptionLabel: 'Nome file: {fileName}',
7
+ fileNameDescriptionLabel: 'Nome file: ',
8
8
  generalValidatorMessage: '"{validatorMessage}", per {listOfErroneousFiles}.',
9
9
  noFilesSelected: 'Nessun file selezionato.',
10
10
  numberOfFiles: '{numberOfFiles} file.',
@@ -4,10 +4,15 @@ export default {
4
4
  allowedFileValidatorComplex:
5
5
  'Upload een {allowedTypesArray} of {allowedTypesLastItem}-bestand van maximaal {maxSize}.',
6
6
  dragAndDropText: 'Sleep uw bestanden hierheen of',
7
- fileNameDescriptionLabel: 'Bestandsnaam: {fileName}',
7
+ fileNameDescriptionLabel: 'Bestandsnaam: ',
8
8
  generalValidatorMessage: '"{validatorMessage}", voor {listOfErroneousFiles}.',
9
9
  noFilesSelected: 'Geen bestanden geselecteerd.',
10
10
  numberOfFiles: '{numberOfFiles} bestanden.',
11
+ noFilesUploaded: 'Geen bestanden geüpload.',
12
+ fileSelected: 'Geselecteerd bestand: ',
13
+ fileUploaded: 'Geüpload bestand: ',
14
+ filesSelected: 'Geselecteerde bestanden: {numberOfFiles} bestanden.',
15
+ filesUploaded: 'Geüploade bestanden: {numberOfFiles} bestanden.',
11
16
  removeButtonLabel: 'Verwijder het bestand {fileName}',
12
17
  selectTextDuplicateFileName: 'Er bestaat al een bestand met dezelfde bestandsnaam.',
13
18
  selectTextMultipleFile: 'Selecteer bestanden',
@@ -4,7 +4,7 @@ export default {
4
4
  allowedFileValidatorComplex:
5
5
  'Prześlij plik {allowedTypesArray} lub {allowedTypesLastItem} o maks. rozmiarze {maxSize}.',
6
6
  dragAndDropText: 'Przeciągnij i upuść pliki tutaj lub',
7
- fileNameDescriptionLabel: 'Nazwa pliku: {fileName}',
7
+ fileNameDescriptionLabel: 'Nazwa pliku: ',
8
8
  generalValidatorMessage: '"{validatorMessage}", dla {listOfErroneousFiles}.',
9
9
  noFilesSelected: 'Nie wybrano żadnych plików.',
10
10
  numberOfFiles: 'Liczba plików: {numberOfFiles}.',
@@ -4,7 +4,7 @@ export default {
4
4
  allowedFileValidatorComplex:
5
5
  'Încărcaţi un fişier {allowedTypesArray} sau {allowedTypesLastItem} de max. {maxSize}.',
6
6
  dragAndDropText: 'Glisaţi şi fixaţi fişierele aici sau',
7
- fileNameDescriptionLabel: 'Nume fişier: {fileName}',
7
+ fileNameDescriptionLabel: 'Nume fişier: ',
8
8
  generalValidatorMessage: '"{validatorMessage}", pentru {listOfErroneousFiles}.',
9
9
  noFilesSelected: 'Niciun fișier selectat.',
10
10
  numberOfFiles: '{numberOfFiles} fișiere.',
@@ -4,10 +4,14 @@ export default {
4
4
  allowedFileValidatorComplex:
5
5
  'Загрузите файл {allowedTypesArray} или {allowedTypesLastItem} размером не более {maxSize}.',
6
6
  dragAndDropText: 'Перетащите файлы сюда или',
7
- fileNameDescriptionLabel: 'Название файла: {fileName}',
7
+ fileNameDescriptionLabel: 'Название файла: ',
8
8
  generalValidatorMessage: '"{validatorMessage}", для {listOfErroneousFiles}.',
9
- noFilesSelected: 'Файлы не выбраны.',
10
- numberOfFiles: 'Файлов: {numberOfFiles}.',
9
+ noFilesSelected: 'Не выбрано ни одного файла.',
10
+ noFilesUploaded: 'Не загружено ни одного файла.',
11
+ fileSelected: 'Выбранный файл: ',
12
+ fileUploaded: 'Загруженный файл: ',
13
+ filesSelected: 'Выбранные файлы: {numberOfFiles} файлов.',
14
+ filesUploaded: 'Загруженные файлы: {numberOfFiles} файлов.',
11
15
  removeButtonLabel: 'Удалить файл {fileName}',
12
16
  selectTextDuplicateFileName: 'Файл с таким названием уже существует.',
13
17
  selectTextMultipleFile: 'Выберите файлы',