@lion/ui 0.0.3 → 0.0.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 (190) hide show
  1. package/components/calendar/src/LionCalendar.js +10 -4
  2. package/components/combobox/src/LionCombobox.js +6 -4
  3. package/components/core/src/DisabledMixin.js +6 -4
  4. package/components/core/src/DisabledWithTabIndexMixin.js +6 -4
  5. package/components/core/src/SlotMixin.js +180 -42
  6. package/components/core/test/SlotMixin.test.js +341 -138
  7. package/components/core/types/SlotMixinTypes.ts +13 -2
  8. package/components/form-core/src/FormatMixin.js +10 -8
  9. package/components/form-core/src/InteractionStateMixin.js +8 -6
  10. package/components/form-core/src/choice-group/ChoiceInputMixin.js +6 -4
  11. package/components/form-core/src/utils/SyncUpdatableMixin.js +9 -4
  12. package/components/form-core/test/utils/SyncUpdatableMixin.test.js +6 -4
  13. package/components/form-core/test-suites/ValidateMixin.suite.js +1 -1
  14. package/components/form-core/test-suites/form-group/FormGroupMixin.suite.js +2 -2
  15. package/components/input/src/LionInput.js +6 -4
  16. package/components/input-datepicker/src/LionInputDatepicker.js +6 -4
  17. package/components/input-tel/src/LionInputTel.js +7 -22
  18. package/components/input-tel/src/PhoneUtilManager.js +9 -5
  19. package/components/input-tel/src/formatters.js +8 -10
  20. package/components/input-tel/src/parsers.js +3 -4
  21. package/components/input-tel/src/preprocessors.js +2 -4
  22. package/components/input-tel/src/validators.js +4 -6
  23. package/components/input-tel/test/validators.test.js +8 -5
  24. package/components/input-tel-dropdown/src/LionInputTelDropdown.js +41 -32
  25. package/components/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.js +5 -6
  26. package/components/listbox/src/LionOption.js +6 -4
  27. package/components/localize/types/LocalizeMixinTypes.ts +1 -1
  28. package/components/overlays/src/OverlayMixin.js +6 -5
  29. package/components/overlays/src/OverlaysManager.js +21 -4
  30. package/components/overlays/src/globalOverlaysStyle.js +10 -0
  31. package/components/overlays/test/OverlaysManager.test.js +76 -0
  32. package/components/overlays/test-suites/OverlayMixin.suite.js +20 -14
  33. package/components/select-rich/src/LionSelectRich.js +6 -4
  34. package/components/switch/src/LionSwitchButton.js +6 -7
  35. package/custom-elements.json +2002 -291
  36. package/dist-types/components/accordion/src/LionAccordion.d.ts +1 -1
  37. package/dist-types/components/button/src/LionButton.d.ts +1 -1
  38. package/dist-types/components/calendar/src/LionCalendar.d.ts +7 -41
  39. package/dist-types/components/calendar/src/LionCalendar.d.ts.map +1 -1
  40. package/dist-types/components/checkbox-group/src/LionCheckboxGroup.d.ts +1 -1
  41. package/dist-types/components/checkbox-group/src/LionCheckboxIndeterminate.d.ts +0 -4
  42. package/dist-types/components/checkbox-group/src/LionCheckboxIndeterminate.d.ts.map +1 -1
  43. package/dist-types/components/collapsible/src/LionCollapsible.d.ts +1 -1
  44. package/dist-types/components/combobox/src/LionCombobox.d.ts +5 -3
  45. package/dist-types/components/combobox/src/LionCombobox.d.ts.map +1 -1
  46. package/dist-types/components/core/src/DisabledMixin.d.ts.map +1 -1
  47. package/dist-types/components/core/src/DisabledWithTabIndexMixin.d.ts.map +1 -1
  48. package/dist-types/components/core/src/SlotMixin.d.ts +3 -1
  49. package/dist-types/components/core/src/SlotMixin.d.ts.map +1 -1
  50. package/dist-types/components/core/test/SlotMixin.test.d.ts +1 -1
  51. package/dist-types/components/core/test/SlotMixin.test.d.ts.map +1 -1
  52. package/dist-types/components/core/types/SlotMixinTypes.d.ts +10 -2
  53. package/dist-types/components/core/types/SlotMixinTypes.d.ts.map +1 -1
  54. package/dist-types/components/dialog/src/LionDialog.d.ts +1 -1
  55. package/dist-types/components/fieldset/src/LionFieldset.d.ts +1 -1
  56. package/dist-types/components/form-core/src/FormatMixin.d.ts.map +1 -1
  57. package/dist-types/components/form-core/src/InteractionStateMixin.d.ts.map +1 -1
  58. package/dist-types/components/form-core/src/LionField.d.ts +1 -1
  59. package/dist-types/components/form-core/src/choice-group/ChoiceInputMixin.d.ts.map +1 -1
  60. package/dist-types/components/form-core/src/utils/SyncUpdatableMixin.d.ts.map +1 -1
  61. package/dist-types/components/form-core/src/validate/LionValidationFeedback.d.ts +1 -1
  62. package/dist-types/components/form-core/test-suites/FormRegistrationMixins.suite.d.ts +1 -1
  63. package/dist-types/components/form-integrations/test/helpers/umbrella-form.d.ts +1 -1
  64. package/dist-types/components/helpers/src/SbActionLogger.d.ts +1 -1
  65. package/dist-types/components/helpers/src/SbLocaleSwitcher.d.ts +1 -1
  66. package/dist-types/components/icon/src/LionIcon.d.ts +1 -1
  67. package/dist-types/components/input/src/LionInput.d.ts +5 -3
  68. package/dist-types/components/input/src/LionInput.d.ts.map +1 -1
  69. package/dist-types/components/input-amount/src/LionInputAmount.d.ts +1 -37
  70. package/dist-types/components/input-amount/src/LionInputAmount.d.ts.map +1 -1
  71. package/dist-types/components/input-date/src/LionInputDate.d.ts +1 -37
  72. package/dist-types/components/input-date/src/LionInputDate.d.ts.map +1 -1
  73. package/dist-types/components/input-datepicker/src/LionCalendarOverlayFrame.d.ts +2 -38
  74. package/dist-types/components/input-datepicker/src/LionCalendarOverlayFrame.d.ts.map +1 -1
  75. package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts +0 -5
  76. package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts.map +1 -1
  77. package/dist-types/components/input-email/src/LionInputEmail.d.ts +1 -37
  78. package/dist-types/components/input-email/src/LionInputEmail.d.ts.map +1 -1
  79. package/dist-types/components/input-iban/src/LionInputIban.d.ts +1 -37
  80. package/dist-types/components/input-iban/src/LionInputIban.d.ts.map +1 -1
  81. package/dist-types/components/input-tel/src/LionInputTel.d.ts +3 -63
  82. package/dist-types/components/input-tel/src/LionInputTel.d.ts.map +1 -1
  83. package/dist-types/components/input-tel/src/PhoneUtilManager.d.ts +8 -4
  84. package/dist-types/components/input-tel/src/PhoneUtilManager.d.ts.map +1 -1
  85. package/dist-types/components/input-tel/src/formatters.d.ts +0 -2
  86. package/dist-types/components/input-tel/src/formatters.d.ts.map +1 -1
  87. package/dist-types/components/input-tel/src/parsers.d.ts +0 -2
  88. package/dist-types/components/input-tel/src/parsers.d.ts.map +1 -1
  89. package/dist-types/components/input-tel/src/preprocessors.d.ts +0 -2
  90. package/dist-types/components/input-tel/src/preprocessors.d.ts.map +1 -1
  91. package/dist-types/components/input-tel/src/validators.d.ts +0 -1
  92. package/dist-types/components/input-tel/src/validators.d.ts.map +1 -1
  93. package/dist-types/components/input-tel/test/validators.test.d.ts +1 -1
  94. package/dist-types/components/input-tel/test/validators.test.d.ts.map +1 -1
  95. package/dist-types/components/input-tel-dropdown/src/LionInputTelDropdown.d.ts +20 -16
  96. package/dist-types/components/input-tel-dropdown/src/LionInputTelDropdown.d.ts.map +1 -1
  97. package/dist-types/components/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.d.ts.map +1 -1
  98. package/dist-types/components/listbox/src/LionListbox.d.ts +1 -1
  99. package/dist-types/components/listbox/src/LionOption.d.ts +6 -4
  100. package/dist-types/components/listbox/src/LionOption.d.ts.map +1 -1
  101. package/dist-types/components/listbox/src/LionOptions.d.ts +1 -1
  102. package/dist-types/components/localize/src/LocalizeMixin.d.ts +1 -37
  103. package/dist-types/components/localize/src/LocalizeMixin.d.ts.map +1 -1
  104. package/dist-types/components/localize/types/LocalizeMixinTypes.d.ts +1 -1
  105. package/dist-types/components/localize/types/LocalizeMixinTypes.d.ts.map +1 -1
  106. package/dist-types/components/overlays/src/OverlayMixin.d.ts.map +1 -1
  107. package/dist-types/components/overlays/src/OverlaysManager.d.ts +4 -0
  108. package/dist-types/components/overlays/src/OverlaysManager.d.ts.map +1 -1
  109. package/dist-types/components/overlays/src/globalOverlaysStyle.d.ts.map +1 -1
  110. package/dist-types/components/overlays/test/OverlaysManager.test.d.ts.map +1 -1
  111. package/dist-types/components/overlays/test-suites/OverlayMixin.suite.d.ts.map +1 -1
  112. package/dist-types/components/pagination/src/LionPagination.d.ts +2 -38
  113. package/dist-types/components/pagination/src/LionPagination.d.ts.map +1 -1
  114. package/dist-types/components/progress-indicator/src/LionProgressIndicator.d.ts +2 -38
  115. package/dist-types/components/progress-indicator/src/LionProgressIndicator.d.ts.map +1 -1
  116. package/dist-types/components/radio-group/src/LionRadioGroup.d.ts +1 -1
  117. package/dist-types/components/select-rich/src/LionSelectRich.d.ts +5 -3
  118. package/dist-types/components/select-rich/src/LionSelectRich.d.ts.map +1 -1
  119. package/dist-types/components/steps/src/LionStep.d.ts +1 -1
  120. package/dist-types/components/steps/src/LionSteps.d.ts +1 -1
  121. package/dist-types/components/switch/src/LionSwitchButton.d.ts +6 -7
  122. package/dist-types/components/switch/src/LionSwitchButton.d.ts.map +1 -1
  123. package/dist-types/components/tabs/src/LionTabs.d.ts +1 -1
  124. package/dist-types/components/tooltip/src/LionTooltip.d.ts +1 -1
  125. package/dist-types/exports/types/core.d.ts +2 -0
  126. package/dist-types/exports/types/core.d.ts.map +1 -0
  127. package/dist-types/exports/types/form-core.d.ts +3 -0
  128. package/dist-types/exports/types/form-core.d.ts.map +1 -0
  129. package/dist-types/exports/types/input-tel-dropdown.d.ts +3 -0
  130. package/dist-types/exports/types/input-tel-dropdown.d.ts.map +1 -0
  131. package/dist-types/exports/types/input-tel.d.ts +2 -0
  132. package/dist-types/exports/types/input-tel.d.ts.map +1 -0
  133. package/dist-types/exports/types/localize.d.ts +4 -0
  134. package/dist-types/exports/types/localize.d.ts.map +1 -0
  135. package/dist-types/exports/types/overlays.d.ts +5 -0
  136. package/dist-types/exports/types/overlays.d.ts.map +1 -0
  137. package/dist-types/tsconfig.tsbuildinfo +1 -1
  138. package/docs/components/checkbox-group/overview.md +2 -2
  139. package/docs/components/collapsible/overview.md +1 -1
  140. package/docs/components/combobox/overview.md +1 -1
  141. package/docs/components/combobox/use-cases.md +1 -1
  142. package/docs/components/dialog/overview.md +1 -1
  143. package/docs/components/fieldset/overview.md +5 -5
  144. package/docs/components/form/overview.md +3 -3
  145. package/docs/components/icon/use-cases.md +1 -1
  146. package/docs/components/input/overview.md +1 -1
  147. package/docs/components/input-amount/overview.md +3 -3
  148. package/docs/components/input-date/overview.md +3 -3
  149. package/docs/components/input-datepicker/overview.md +5 -5
  150. package/docs/components/input-email/overview.md +2 -2
  151. package/docs/components/input-iban/overview.md +2 -2
  152. package/docs/components/input-range/overview.md +2 -2
  153. package/docs/components/input-stepper/overview.md +1 -1
  154. package/docs/components/input-tel/overview.md +1 -1
  155. package/docs/components/input-tel/use-cases.md +6 -6
  156. package/docs/components/input-tel-dropdown/overview.md +1 -1
  157. package/docs/components/radio-group/overview.md +3 -3
  158. package/docs/components/select-rich/use-cases.md +1 -1
  159. package/docs/components/tabs/examples.md +1 -1
  160. package/docs/fundamentals/index.md +4 -4
  161. package/docs/fundamentals/node-tools/providence-analytics/LocalConfiguration.md +1 -1
  162. package/docs/fundamentals/node-tools/providence-analytics/QueryResult.md +1 -1
  163. package/docs/fundamentals/node-tools/providence-analytics/analyzer.md +1 -1
  164. package/docs/fundamentals/node-tools/providence-analytics/dashboard.md +1 -1
  165. package/docs/fundamentals/node-tools/providence-analytics/overview.md +3 -3
  166. package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
  167. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
  168. package/docs/fundamentals/systems/core/overview.md +1 -1
  169. package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
  170. package/docs/fundamentals/systems/form/model-value.md +1 -1
  171. package/docs/fundamentals/systems/form/overview.md +28 -28
  172. package/docs/fundamentals/systems/form/validate.md +1 -1
  173. package/docs/fundamentals/systems/localize/overview.md +4 -4
  174. package/docs/fundamentals/systems/overlays/configuration.md +2 -2
  175. package/docs/fundamentals/systems/overlays/overview.md +5 -5
  176. package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
  177. package/docs/fundamentals/tools/helpers/overview.md +1 -1
  178. package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
  179. package/docs/guides/how-to/create-a-custom-field.md +5 -5
  180. package/docs/guides/how-to/extend-a-native-input.md +2 -2
  181. package/docs/guides/index.md +8 -8
  182. package/docs/guides/principles/index.md +5 -5
  183. package/docs/guides/principles/styling.md +1 -1
  184. package/exports/types/core.ts +1 -0
  185. package/exports/types/form-core.ts +2 -0
  186. package/exports/types/input-tel-dropdown.ts +2 -0
  187. package/exports/types/input-tel.ts +1 -0
  188. package/exports/types/localize.ts +3 -0
  189. package/exports/types/overlays.ts +4 -0
  190. package/package.json +8 -5
@@ -64,7 +64,7 @@ export function runValidateMixinSuite(customConfig) {
64
64
  * - *feedback-node*
65
65
  * The 'this._feedbackNode' property (usually a getter) that returns/contains a reference to
66
66
  * the output container for validation feedback. Messages will be written to this element
67
- * based on user defined or default validity feedback visibility conditions.
67
+ * based on user-defined or default validity feedback visibility conditions.
68
68
  *
69
69
  * - *show-{type}-feedback-condition*
70
70
  * The 'this.hasErrorVisible value that stores whether the
@@ -1234,7 +1234,7 @@ export function runFormGroupMixinSuite(cfg = {}) {
1234
1234
  </${tag}>
1235
1235
  `)
1236
1236
  );
1237
- const childFieldsetEl = el.querySelector(tagString);
1237
+ const childFieldsetEl = /** @type {FormGroup} */ (el.querySelector(tagString));
1238
1238
  const resetGroupSpy = sinon.spy(childFieldsetEl, 'resetGroup');
1239
1239
  el.resetGroup();
1240
1240
  expect(resetGroupSpy.callCount).to.equal(1);
@@ -1270,7 +1270,7 @@ export function runFormGroupMixinSuite(cfg = {}) {
1270
1270
  </${tag}>
1271
1271
  `)
1272
1272
  );
1273
- const childFieldsetEl = el.querySelector(tagString);
1273
+ const childFieldsetEl = /** @type {FormGroup} */ (el.querySelector(tagString));
1274
1274
  const clearGroupSpy = sinon.spy(childFieldsetEl, 'clearGroup');
1275
1275
  el.clearGroup();
1276
1276
  expect(clearGroupSpy.callCount).to.equal(1);
@@ -64,11 +64,13 @@ export class LionInput extends NativeTextFieldMixin(LionField) {
64
64
  }
65
65
 
66
66
  /**
67
- * @param {PropertyKey} [name]
68
- * @param {?} [oldValue]
67
+ * @param {string} [name]
68
+ * @param {unknown} [oldValue]
69
+ * @param {import('lit').PropertyDeclaration} [options]
70
+ * @returns {void}
69
71
  */
70
- requestUpdate(name, oldValue) {
71
- super.requestUpdate(name, oldValue);
72
+ requestUpdate(name, oldValue, options) {
73
+ super.requestUpdate(name, oldValue, options);
72
74
  if (name === 'readOnly') {
73
75
  this.__delegateReadOnly();
74
76
  }
@@ -211,11 +211,13 @@ export class LionInputDatepicker extends ScopedElementsMixin(
211
211
  }
212
212
 
213
213
  /**
214
- * @param {PropertyKey} name
215
- * @param {?} oldValue
214
+ * @param {string} [name]
215
+ * @param {unknown} [oldValue]
216
+ * @param {import('lit').PropertyDeclaration} [options]
217
+ * @returns {void}
216
218
  */
217
- requestUpdate(name, oldValue) {
218
- super.requestUpdate(name, oldValue);
219
+ requestUpdate(name, oldValue, options) {
220
+ super.requestUpdate(name, oldValue, options);
219
221
 
220
222
  if (name === 'disabled' || name === 'readOnly') {
221
223
  this.__toggleInvokerDisabled();
@@ -14,7 +14,7 @@ import { localizeNamespaceLoader } from './localizeNamespaceLoader.js';
14
14
  * @typedef {import('awesome-phonenumber').PhoneNumberFormat} PhoneNumberFormat
15
15
  * @typedef {import('awesome-phonenumber').PhoneNumberTypes} PhoneNumberTypes
16
16
  * @typedef {import('../../form-core/types/FormatMixinTypes.js').FormatOptions} FormatOptions
17
- * @typedef {* & import('awesome-phonenumber').default} AwesomePhoneNumber
17
+ * @typedef {* & import('awesome-phonenumber')} AwesomePhoneNumber
18
18
  * @typedef {FormatOptions & {regionCode: RegionCode; formatStrategy: PhoneNumberFormat; formatCountryCodeStyle: string;}} FormatOptionsTel
19
19
  */
20
20
 
@@ -28,7 +28,6 @@ export class LionInputTel extends LocalizeMixin(LionInput) {
28
28
  formatCountryCodeStyle: { type: String, attribute: 'format-country-code-style' },
29
29
  activeRegion: { type: String },
30
30
  _phoneUtil: { type: Object, state: true },
31
- _needsLightDomRender: { type: Number, state: true },
32
31
  };
33
32
 
34
33
  static localizeNamespaces = [
@@ -72,10 +71,12 @@ export class LionInputTel extends LocalizeMixin(LionInput) {
72
71
  get activePhoneNumberType() {
73
72
  let pn;
74
73
  try {
75
- pn = this._phoneUtil && this._phoneUtil(this.modelValue, this.activeRegion);
74
+ pn =
75
+ this._phoneUtil &&
76
+ this._phoneUtil.parsePhoneNumber(this.modelValue, { regionCode: this.activeRegion });
76
77
  // eslint-disable-next-line no-empty
77
78
  } catch (_) {}
78
- return pn?.g?.type || 'unknown';
79
+ return pn?.type || 'unknown';
79
80
  }
80
81
 
81
82
  // @ts-ignore read only
@@ -169,14 +170,6 @@ export class LionInputTel extends LocalizeMixin(LionInput) {
169
170
  ? /** @type {AwesomePhoneNumber} */ (PhoneUtilManager.PhoneUtil)
170
171
  : null;
171
172
 
172
- /**
173
- * Helper that triggers a light dom render aligned with update loop.
174
- * TODO: combine with render fn of SlotMixin
175
- * @protected
176
- * @type {number}
177
- */
178
- this._needsLightDomRender = 0;
179
-
180
173
  if (!PhoneUtilManager.isLoaded) {
181
174
  PhoneUtilManager.loadComplete.then(() => {
182
175
  this._onPhoneNumberUtilReady();
@@ -305,20 +298,11 @@ export class LionInputTel extends LocalizeMixin(LionInput) {
305
298
  // This should trigger a rerender in shadow dom
306
299
  this._phoneUtil = /** @type {AwesomePhoneNumber} */ (PhoneUtilManager.PhoneUtil);
307
300
  // This should trigger a rerender in light dom
308
- this._scheduleLightDomRender();
309
301
  // Format when libPhoneNumber is loaded
310
302
  this._calculateValues({ source: null });
311
303
  this.__calculateActiveRegion();
312
304
  }
313
305
 
314
- /**
315
- * This allows to hook into the update hook
316
- * @protected
317
- */
318
- _scheduleLightDomRender() {
319
- this._needsLightDomRender += 1;
320
- }
321
-
322
306
  /**
323
307
  * @private
324
308
  */
@@ -334,7 +318,8 @@ export class LionInputTel extends LocalizeMixin(LionInput) {
334
318
  const value = !(this.modelValue instanceof Unparseable)
335
319
  ? this.modelValue
336
320
  : this.value.match(regex)?.join('');
337
- const regionDerivedFromValue = value && this._phoneUtil && this._phoneUtil(value).g?.regionCode;
321
+ const regionDerivedFromValue =
322
+ value && this._phoneUtil && this._phoneUtil.parsePhoneNumber(value).regionCode;
338
323
 
339
324
  if (regionDerivedFromValue && this._allowedOrAllRegions.includes(regionDerivedFromValue)) {
340
325
  this._setActiveRegion(regionDerivedFromValue);
@@ -2,21 +2,25 @@
2
2
  let resolveLoaded;
3
3
 
4
4
  /**
5
- * - Handles lazy loading of the (relatively large) google-libphonenumber library, allowing
5
+ * @typedef {* & import('awesome-phonenumber')} AwesomePhoneNumber
6
+ */
7
+
8
+ /**
9
+ * - Handles lazy loading of the awesome-phonenumber library (relatively large, but way lighter than google-libphonenumber), allowing
6
10
  * for quick first paints
7
11
  * - Maintains one instance of phoneNumberUtil that can be shared across multiple places
8
12
  * - Allows for easy mocking in unit tests
9
13
  */
10
14
  export class PhoneUtilManager {
11
15
  static async loadLibPhoneNumber() {
12
- const PhoneUtil = (await import('awesome-phonenumber')).default;
13
- this.PhoneUtil = PhoneUtil;
16
+ const PhoneUtil = /** @type {AwesomePhoneNumber} */ (await import('awesome-phonenumber'));
17
+ this.PhoneUtil = { ...PhoneUtil };
14
18
  resolveLoaded(undefined);
15
19
  return PhoneUtil;
16
20
  }
17
21
 
18
22
  /**
19
- * Check if google-libphonenumber has been loaded
23
+ * Check if awesome-phonenumber has been loaded
20
24
  */
21
25
  static get isLoaded() {
22
26
  return Boolean(this.PhoneUtil);
@@ -24,7 +28,7 @@ export class PhoneUtilManager {
24
28
  }
25
29
 
26
30
  /**
27
- * Wait till google-libphonenumber has been loaded
31
+ * Wait till awesome-phonenumber has been loaded
28
32
  * @example
29
33
  * ```js
30
34
  * await PhoneUtilManager.loadComplete;
@@ -3,7 +3,6 @@ import { PhoneUtilManager } from './PhoneUtilManager.js';
3
3
  /**
4
4
  * @typedef {import('awesome-phonenumber').PhoneNumberFormat} PhoneNumberFormat
5
5
  * @typedef {import('../types/index.js').RegionCode} RegionCode
6
- * @typedef {* & import('awesome-phonenumber').default} AwesomePhoneNumber
7
6
  */
8
7
 
9
8
  /**
@@ -42,33 +41,32 @@ export function formatPhoneNumber(
42
41
  return modelValue;
43
42
  }
44
43
 
45
- // eslint-disable-next-line prefer-destructuring
46
- const PhoneUtil = /** @type {AwesomePhoneNumber} */ (PhoneUtilManager.PhoneUtil);
44
+ const AwesomePhoneNumber = PhoneUtilManager.PhoneUtil;
47
45
 
48
46
  let pn;
49
47
  try {
50
- pn = new PhoneUtil(modelValue, regionCode);
48
+ pn = AwesomePhoneNumber.parsePhoneNumber(modelValue, { regionCode });
51
49
  // eslint-disable-next-line no-empty
52
50
  } catch (_) {}
53
51
 
54
- if (modelValue?.length >= 4 && modelValue?.length <= 16 && pn?.isValid()) {
52
+ if (modelValue?.length >= 4 && modelValue?.length <= 16 && pn?.valid) {
55
53
  let formattedValue;
56
54
 
57
55
  switch (formatStrategy) {
58
56
  case 'e164':
59
- formattedValue = pn.getNumber('e164'); // -> '+46707123456' (default)
57
+ formattedValue = pn.number.e164; // -> '+46707123456' (default)
60
58
  break;
61
59
  case 'international':
62
- formattedValue = pn.getNumber('international'); // -> '+46 70 712 34 56'
60
+ formattedValue = pn.number.international; // -> '+46 70 712 34 56'
63
61
  break;
64
62
  case 'national':
65
- formattedValue = pn.getNumber('national'); // -> '070-712 34 56'
63
+ formattedValue = pn.number.national; // -> '070-712 34 56'
66
64
  break;
67
65
  case 'rfc3966':
68
- formattedValue = pn.getNumber('rfc3966'); // -> 'tel:+46-70-712-34-56'
66
+ formattedValue = pn.number.rfc3966; // -> 'tel:+46-70-712-34-56'
69
67
  break;
70
68
  case 'significant':
71
- formattedValue = pn.getNumber('significant'); // -> '707123456'
69
+ formattedValue = pn.number.significant; // -> '707123456'
72
70
  break;
73
71
  default:
74
72
  break;
@@ -2,7 +2,6 @@ import { PhoneUtilManager } from './PhoneUtilManager.js';
2
2
 
3
3
  /**
4
4
  * @typedef {import('../types/index.js').RegionCode} RegionCode
5
- * @typedef {* & import('awesome-phonenumber').default} AwesomePhoneNumber
6
5
  */
7
6
 
8
7
  /**
@@ -17,17 +16,17 @@ export function parsePhoneNumber(viewValue, { regionCode }) {
17
16
  }
18
17
 
19
18
  // eslint-disable-next-line prefer-destructuring
20
- const PhoneNumber = /** @type {AwesomePhoneNumber} */ (PhoneUtilManager.PhoneUtil);
19
+ const AwesomePhoneNumber = PhoneUtilManager.PhoneUtil;
21
20
  const regex = /[+0-9]+/gi;
22
21
  const strippedViewValue = viewValue.match(regex)?.join('');
23
22
  let pn;
24
23
  try {
25
- pn = PhoneNumber(strippedViewValue, regionCode);
24
+ pn = AwesomePhoneNumber.parsePhoneNumber(strippedViewValue, { regionCode });
26
25
  // eslint-disable-next-line no-empty
27
26
  } catch (_) {}
28
27
 
29
28
  if (pn) {
30
- return pn.getNumber('e164');
29
+ return pn.number.e164;
31
30
  }
32
31
 
33
32
  return viewValue;
@@ -4,7 +4,6 @@ import { PhoneUtilManager } from './PhoneUtilManager.js';
4
4
  /**
5
5
  * @typedef {import('../types/index.js').RegionCode} RegionCode
6
6
  * @typedef {import('awesome-phonenumber').PhoneNumberFormat} PhoneNumberFormat
7
- * @typedef {* & import('awesome-phonenumber').default} AwesomePhoneNumber
8
7
  */
9
8
 
10
9
  /**
@@ -27,9 +26,8 @@ export function liveFormatPhoneNumber(
27
26
  return undefined;
28
27
  }
29
28
 
30
- // eslint-disable-next-line prefer-destructuring
31
- const PhoneNumber = /** @type {AwesomePhoneNumber} */ (PhoneUtilManager.PhoneUtil);
32
- const ayt = PhoneNumber.getAsYouType(regionCode);
29
+ const AwesomePhoneNumber = PhoneUtilManager.PhoneUtil;
30
+ const ayt = AwesomePhoneNumber.getAsYouType(regionCode);
33
31
 
34
32
  for (const char of viewValue) {
35
33
  if (char !== '') {
@@ -3,7 +3,6 @@ import { PhoneUtilManager } from './PhoneUtilManager.js';
3
3
 
4
4
  /**
5
5
  * @typedef {import('../types/index.js').RegionCode} RegionCode
6
- * @typedef {* & import('awesome-phonenumber').default} AwesomePhoneNumber
7
6
  * @typedef {import('../../form-core/types/validate/validate.js').FeedbackMessageData} FeedbackMessageData
8
7
  */
9
8
 
@@ -13,22 +12,21 @@ import { PhoneUtilManager } from './PhoneUtilManager.js';
13
12
  * @returns {false|'invalid-country-code'|'unknown'|'too-long'|'too-short'}
14
13
  */
15
14
  function hasFeedback(modelValue, regionCode) {
16
- // eslint-disable-next-line prefer-destructuring
17
- const PhoneNumber = /** @type {AwesomePhoneNumber} */ (PhoneUtilManager.PhoneUtil);
15
+ const AwesomePhoneNumber = PhoneUtilManager.PhoneUtil;
18
16
  let invalidCountryCode = false;
19
17
 
20
18
  if (regionCode && modelValue?.length >= 4 && modelValue?.length <= 16) {
21
19
  let pn;
22
20
  try {
23
- pn = PhoneNumber(modelValue, regionCode);
24
- invalidCountryCode = pn.g.regionCode !== regionCode;
21
+ pn = AwesomePhoneNumber.parsePhoneNumber(modelValue, { regionCode });
22
+ invalidCountryCode = pn.regionCode !== regionCode;
25
23
  if (invalidCountryCode) {
26
24
  return 'invalid-country-code';
27
25
  }
28
26
  // eslint-disable-next-line no-empty
29
27
  } catch (_) {}
30
28
  // too-short/too-long info seems to be not there (we get 'is-possible'?)
31
- const enumValue = !pn.isValid() ? pn.g.possibility : false;
29
+ const enumValue = !pn.valid ? pn.possibility : false;
32
30
  if (enumValue === 'is-possible') {
33
31
  return 'unknown';
34
32
  }
@@ -4,7 +4,7 @@ import { PhoneNumber, PhoneUtilManager } from '@lion/ui/input-tel.js';
4
4
  import { mockPhoneUtilManager, restorePhoneUtilManager } from '@lion/ui/input-tel-test-helpers.js';
5
5
 
6
6
  /**
7
- * @typedef {* & import('awesome-phonenumber').default} AwesomePhoneNumber
7
+ * @typedef {* & import('awesome-phonenumber')} AwesomePhoneNumber
8
8
  */
9
9
 
10
10
  // For enum output, see: https://www.npmjs.com/package/awesome-phonenumber
@@ -24,6 +24,7 @@ describe('PhoneNumber validation', () => {
24
24
  expect(validator.execute('foo', 'NL')).to.equal('unknown');
25
25
  });
26
26
 
27
+ // TODO: this changed after awesome-phonenumber v4. Skip for now, look into this later
27
28
  it('is invalid when wrong country code is entered, returns "invalid-country-code"', () => {
28
29
  const validator = new PhoneNumber();
29
30
  // 32 is BE region code
@@ -47,12 +48,13 @@ describe('PhoneNumber validation', () => {
47
48
 
48
49
  it('handles validation via awesome-phonenumber', () => {
49
50
  const validator = new PhoneNumber();
50
- const spy = sinon.spy(PhoneUtilManager, 'PhoneUtil');
51
+ // @ts-ignore
52
+ const spy = sinon.spy(PhoneUtilManager.PhoneUtil, 'parsePhoneNumber');
51
53
  validator.execute('0123456789', 'NL');
52
54
  expect(spy).to.have.been.calledOnce;
53
- expect(spy.lastCall.args[1]).to.equal('NL');
55
+ expect(spy.lastCall.args[1]).to.eql({ regionCode: 'NL' });
54
56
  validator.execute('0123456789', 'DE');
55
- expect(spy.lastCall.args[1]).to.equal('DE');
57
+ expect(spy.lastCall.args[1]).to.eql({ regionCode: 'DE' });
56
58
  spy.restore();
57
59
  });
58
60
 
@@ -75,7 +77,8 @@ describe('PhoneNumber validation', () => {
75
77
 
76
78
  it('waits for the lib to be loaded before execution completes when still in async mode', async () => {
77
79
  const validator = new PhoneNumber();
78
- const spy = sinon.spy(PhoneUtilManager, 'PhoneUtil');
80
+ // @ts-ignore
81
+ const spy = sinon.spy(PhoneUtilManager.PhoneUtil, 'parsePhoneNumber');
79
82
  const validationResult = validator.execute('061234', 'NL');
80
83
  expect(validationResult).to.be.instanceOf(Promise);
81
84
  expect(spy).to.not.have.been.called;
@@ -1,4 +1,4 @@
1
- import { html, render, css } from 'lit';
1
+ import { html, css } from 'lit';
2
2
  import { ref, createRef } from 'lit/directives/ref.js';
3
3
 
4
4
  import { LionInputTel } from '@lion/ui/input-tel.js';
@@ -27,7 +27,6 @@ import { getFlagSymbol } from './getFlagSymbol.js';
27
27
  * @typedef {import('../types/index.js').OnDropdownChangeEvent} OnDropdownChangeEvent
28
28
  * @typedef {import('../types/index.js').DropdownRef} DropdownRef
29
29
  * @typedef {import('../types/index.js').RegionMeta} RegionMeta
30
- * @typedef {* & import('awesome-phonenumber').default} AwesomePhoneNumber
31
30
  * @typedef {import('../../select-rich/src/LionSelectRich.js').LionSelectRich} LionSelectRich
32
31
  * @typedef {import('../../overlays/src/OverlayController.js').OverlayController} OverlayController
33
32
  * @typedef {TemplateDataForDropdownInputTel & {data: {regionMetaList:RegionMeta[]}}} TemplateDataForIntlInputTel
@@ -99,6 +98,7 @@ export class LionInputTelDropdown extends LionInputTel {
99
98
  },
100
99
  },
101
100
  };
101
+
102
102
  return {
103
103
  refs,
104
104
  data: {
@@ -155,7 +155,7 @@ export class LionInputTelDropdown extends LionInputTel {
155
155
  css`
156
156
  /**
157
157
  * We need to align the height of the dropdown with the height of the text field.
158
- * We target the HTMLDivElement 'this.__dropdownRenderParent' here. Its child,
158
+ * We target the HTMLDivElement (render wrapper from SlotMixin) here. Its child,
159
159
  * [data-ref=dropdown], recieves a 100% height as well via inline styles (since we
160
160
  * can't target from shadow styles).
161
161
  */
@@ -171,7 +171,15 @@ export class LionInputTelDropdown extends LionInputTel {
171
171
  get slots() {
172
172
  return {
173
173
  ...super.slots,
174
- prefix: () => this.__dropdownRenderParent,
174
+ prefix: () => {
175
+ const ctor = /** @type {typeof LionInputTelDropdown} */ (this.constructor);
176
+ const { templates } = ctor;
177
+
178
+ return {
179
+ template: templates.dropdown(this._templateDataDropdown),
180
+ afterRender: this.__syncRegionWithDropdown,
181
+ };
182
+ },
175
183
  };
176
184
  }
177
185
 
@@ -186,7 +194,6 @@ export class LionInputTelDropdown extends LionInputTel {
186
194
  type: 'region',
187
195
  });
188
196
  this.__createRegionMeta();
189
- this._scheduleLightDomRender();
190
197
  }
191
198
 
192
199
  /**
@@ -219,25 +226,30 @@ export class LionInputTelDropdown extends LionInputTel {
219
226
  */
220
227
  this._preferredCountriesLabel = '';
221
228
 
222
- /** @type {HTMLDivElement} */
223
- this.__dropdownRenderParent = document.createElement('div');
224
-
225
229
  /**
226
230
  * Contains everything needed for rendering region options:
227
231
  * region code, country code, display name according to locale, display name
232
+ * @private
228
233
  * @type {RegionMeta[]}
229
234
  */
230
235
  this.__regionMetaList = [];
231
236
 
232
237
  /**
233
238
  * A filtered `this.__regionMetaList`, containing all regions provided in `preferredRegions`
239
+ * @private
234
240
  * @type {RegionMeta[]}
235
241
  */
236
242
  this.__regionMetaListPreferred = [];
237
243
 
238
- /** @type {EventListener} */
244
+ /**
245
+ * @protected
246
+ * @type {EventListener}
247
+ */
239
248
  this._onDropdownValueChange = this._onDropdownValueChange.bind(this);
240
- /** @type {EventListener} */
249
+ /**
250
+ * @private
251
+ * @type {EventListener}
252
+ */
241
253
  this.__syncRegionWithDropdown = this.__syncRegionWithDropdown.bind(this);
242
254
  }
243
255
 
@@ -259,9 +271,6 @@ export class LionInputTelDropdown extends LionInputTel {
259
271
  updated(changedProperties) {
260
272
  super.updated(changedProperties);
261
273
 
262
- if (changedProperties.has('_needsLightDomRender')) {
263
- this.__renderDropdown();
264
- }
265
274
  if (changedProperties.has('activeRegion')) {
266
275
  this.__syncRegionWithDropdown();
267
276
  }
@@ -279,6 +288,9 @@ export class LionInputTelDropdown extends LionInputTel {
279
288
  }
280
289
  }
281
290
 
291
+ /**
292
+ * @protected
293
+ */
282
294
  _initModelValueBasedOnDropdown() {
283
295
  if (!this._initialModelValue && !this.dirty && this._phoneUtil) {
284
296
  const countryCode = this._phoneUtil.getCountryCodeForRegionCode(this.activeRegion);
@@ -326,6 +338,7 @@ export class LionInputTelDropdown extends LionInputTel {
326
338
  if (prevActiveRegion !== this.activeRegion && !this.focused && this._phoneUtil) {
327
339
  const prevCountryCode = this._phoneUtil.getCountryCodeForRegionCode(prevActiveRegion);
328
340
  const countryCode = this._phoneUtil.getCountryCodeForRegionCode(this.activeRegion);
341
+
329
342
  if (this.value.includes(`+${prevCountryCode}`)) {
330
343
  this.modelValue = this._callParser(
331
344
  this.value.replace(`+${prevCountryCode}`, `+${countryCode}`),
@@ -350,25 +363,6 @@ export class LionInputTelDropdown extends LionInputTel {
350
363
  }
351
364
  }
352
365
 
353
- /**
354
- * Abstract away rendering to light dom, so that we can rerender when needed
355
- * @private
356
- */
357
- __renderDropdown() {
358
- const ctor = /** @type {typeof LionInputTelDropdown} */ (this.constructor);
359
- // If the user locally overrode the templates, get those on the instance
360
- const templates = this.templates || ctor.templates;
361
- render(
362
- templates.dropdown(this._templateDataDropdown),
363
- this.__dropdownRenderParent,
364
- /** @type {RenderOptions} */ ({
365
- scopeName: this.localName,
366
- eventContext: this,
367
- }),
368
- );
369
- this.__syncRegionWithDropdown();
370
- }
371
-
372
366
  /**
373
367
  * @private
374
368
  */
@@ -411,6 +405,7 @@ export class LionInputTelDropdown extends LionInputTel {
411
405
  if (!this._allowedOrAllRegions?.length || !this.__namesForLocale) {
412
406
  return;
413
407
  }
408
+
414
409
  this.__regionMetaList = [];
415
410
  this.__regionMetaListPreferred = [];
416
411
  this._allowedOrAllRegions.forEach(regionCode => {
@@ -436,4 +431,18 @@ export class LionInputTelDropdown extends LionInputTel {
436
431
  });
437
432
  });
438
433
  }
434
+
435
+ /**
436
+ * Usually, we don't use composition in regular LionFields (non choice-groups). Here we use a LionSelect(Rich) inside.
437
+ * We don't want to repropagate any children, since an Application Developer is not concerned with these internals (see repropate logic in FormControlMixin)
438
+ * Also, we don't want to give (wrong) info to InteractionStateMixin, that will set the wrong interaction states based on child info.
439
+ * TODO: Make "this._repropagationRole !== 'child'" the default for FormControlMixin
440
+ * (so that FormControls used within are never repropagated for LionFields)
441
+ * @protected
442
+ * @configure FormControlMixin: don't repropagate any children
443
+ */
444
+ // eslint-disable-next-line class-methods-use-this
445
+ _repropagationCondition() {
446
+ return false;
447
+ }
439
448
  }
@@ -91,8 +91,7 @@ export function runInputTelDropdownSuite({ klass } = { klass: LionInputTelDropdo
91
91
 
92
92
  it('syncs value of dropdown on init if input has no value does not influence interaction states', async () => {
93
93
  const el = await fixture(html` <${tag}></${tag}> `);
94
- // TODO find out why its get dirty again
95
- // expect(el.dirty).to.be.false;
94
+ expect(el.dirty).to.be.false;
96
95
  expect(el.prefilled).to.be.false;
97
96
  });
98
97
 
@@ -111,8 +110,7 @@ export function runInputTelDropdownSuite({ klass } = { klass: LionInputTelDropdo
111
110
 
112
111
  it('sets correct interaction states on init if input has a value', async () => {
113
112
  const el = await fixture(html` <${tag} .modelValue="${'+31612345678'}"></${tag}> `);
114
- // TODO find out why its get dirty again
115
- // expect(el.dirty).to.be.false;
113
+ expect(el.dirty).to.be.false;
116
114
  expect(el.prefilled).to.be.true;
117
115
  });
118
116
 
@@ -245,10 +243,10 @@ export function runInputTelDropdownSuite({ klass } = { klass: LionInputTelDropdo
245
243
  const { resolveLoaded } = mockPhoneUtilManager();
246
244
  const el = await fixture(html` <${tag} .allowedRegions="${['DE']}"></${tag}> `);
247
245
  // @ts-ignore
248
- const spy = sinon.spy(el, '_scheduleLightDomRender');
246
+ const spy = sinon.spy(el, '__rerenderSlot');
249
247
  resolveLoaded(undefined);
250
248
  await aTimeout(0);
251
- expect(spy).to.have.been.calledOnce;
249
+ expect(spy).to.have.been.calledWith('prefix');
252
250
  restorePhoneUtilManager();
253
251
  spy.restore();
254
252
  });
@@ -323,6 +321,7 @@ export function runInputTelDropdownSuite({ klass } = { klass: LionInputTelDropdo
323
321
  mimicUserChangingDropdown(el.refs.dropdown.value, 'BE');
324
322
  await el.updateComplete;
325
323
  await el.updateComplete;
324
+
326
325
  expect(el.value).to.equal('+32 612345678');
327
326
  });
328
327
 
@@ -78,11 +78,13 @@ export class LionOption extends DisabledMixin(
78
78
  }
79
79
 
80
80
  /**
81
- * @param {string} name
82
- * @param {unknown} oldValue
81
+ * @param {string} [name]
82
+ * @param {unknown} [oldValue]
83
+ * @param {import('lit').PropertyDeclaration} [options]
84
+ * @returns {void}
83
85
  */
84
- requestUpdate(name, oldValue) {
85
- super.requestUpdate(name, oldValue);
86
+ requestUpdate(name, oldValue, options) {
87
+ super.requestUpdate(name, oldValue, options);
86
88
 
87
89
  if (name === 'active' && this.active !== oldValue) {
88
90
  this.dispatchEvent(new Event('active-changed', { bubbles: true }));
@@ -58,7 +58,7 @@ export interface msgOptions {
58
58
  locale?: string;
59
59
  }
60
60
 
61
- declare class LocalizeMixinHost {
61
+ export declare class LocalizeMixinHost {
62
62
  static get localizeNamespaces(): StringToFunctionMap[];
63
63
 
64
64
  static get waitForLocalizeNamespaces(): boolean;
@@ -58,12 +58,13 @@ export const OverlayMixinImplementation = superclass =>
58
58
  }
59
59
 
60
60
  /**
61
- * @override
62
- * @param {string} name
63
- * @param {any} oldValue
61
+ * @param {string} [name]
62
+ * @param {unknown} [oldValue]
63
+ * @param {import('lit').PropertyDeclaration} [options]
64
+ * @returns {void}
64
65
  */
65
- requestUpdate(name, oldValue) {
66
- super.requestUpdate(name, oldValue);
66
+ requestUpdate(name, oldValue, options) {
67
+ super.requestUpdate(name, oldValue, options);
67
68
  if (name === 'opened' && this.opened !== oldValue) {
68
69
  this.dispatchEvent(new Event('opened-changed'));
69
70
  }