@lion/ui 0.1.0 → 0.1.1

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 (134) hide show
  1. package/components/calendar/src/LionCalendar.js +2 -3
  2. package/components/calendar/test/lion-calendar.test.js +5 -3
  3. package/components/form-core/src/validate/ValidateMixin.js +7 -3
  4. package/components/form-core/src/validate/validators/DateValidators.js +1 -1
  5. package/components/form-core/test/lion-field.test.js +4 -2
  6. package/components/form-core/test/validate/DateValidators.test.js +1 -1
  7. package/components/form-core/test-suites/FormatMixin.suite.js +1 -1
  8. package/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.js +6 -4
  9. package/components/form-integrations/test/form-validation-integrations.test.js +11 -10
  10. package/components/input-amount/src/LionInputAmount.js +2 -2
  11. package/components/input-amount/src/formatters.js +5 -1
  12. package/components/input-amount/src/parsers.js +1 -1
  13. package/components/input-amount/test/formatters.test.js +5 -3
  14. package/components/input-date/src/LionInputDate.js +1 -1
  15. package/components/input-date/test/lion-input-date.test.js +91 -43
  16. package/components/input-datepicker/src/LionInputDatepicker.js +1 -1
  17. package/components/input-email/src/LionInputEmail.js +1 -1
  18. package/components/input-iban/src/LionInputIban.js +1 -1
  19. package/components/input-iban/src/validators.js +14 -8
  20. package/components/input-range/src/LionInputRange.js +1 -1
  21. package/components/input-tel/src/LionInputTel.js +3 -3
  22. package/components/input-tel/test-suites/LionInputTel.suite.js +3 -2
  23. package/components/input-tel-dropdown/src/LionInputTelDropdown.js +7 -4
  24. package/components/localize/src/LocalizeMixin.js +24 -9
  25. package/components/localize/src/date/formatDate.js +4 -3
  26. package/components/localize/src/date/parseDate.js +5 -3
  27. package/components/localize/src/getLocalizeManager.js +74 -0
  28. package/components/localize/src/number/formatNumber.js +5 -4
  29. package/components/localize/src/number/getCurrencyName.js +3 -2
  30. package/components/localize/src/number/parseNumber.js +3 -2
  31. package/components/localize/src/number/utils/emptyStringWhenNumberNan.js +3 -2
  32. package/components/localize/src/singleton.js +6 -9
  33. package/components/localize/src/utils/getLocale.js +3 -8
  34. package/components/localize/test/LocalizeManager.test.js +1 -1
  35. package/components/localize/test/LocalizeMixin.test.js +17 -15
  36. package/components/localize/test/date/formatDate.test.js +25 -24
  37. package/components/localize/test/date/getDateFormatBasedOnLocale.test.js +8 -3
  38. package/components/localize/test/date/parseDate.test.js +22 -7
  39. package/components/localize/test/getLocalizeManager.test.js +31 -0
  40. package/components/localize/test/localize.test.js +5 -4
  41. package/components/localize/test/number/formatNumber.test.js +31 -29
  42. package/components/localize/test/number/formatNumberToParts.test.js +5 -3
  43. package/components/localize/test/number/getCurrencyName.test.js +1 -1
  44. package/components/localize/test/number/parseNumber.test.js +37 -19
  45. package/components/localize/test/side-effect-free-entrypoint.test.js +38 -0
  46. package/components/localize/test-helpers/localizeTearDown.js +5 -4
  47. package/components/localize/types/LocalizeMixinTypes.ts +8 -1
  48. package/components/pagination/src/LionPagination.js +1 -1
  49. package/components/progress-indicator/src/LionProgressIndicator.js +3 -2
  50. package/components/select/src/LionSelect.js +15 -0
  51. package/components/select/test/lion-select.test.js +25 -0
  52. package/components/validate-messages/src/loadDefaultFeedbackMessages.js +2 -2
  53. package/components/validate-messages/test/loadDefaultFeedbackMessagesNoSideEffects.js +6 -4
  54. package/custom-elements.json +393 -15
  55. package/dist-types/components/calendar/src/LionCalendar.d.ts.map +1 -1
  56. package/dist-types/components/form-core/src/validate/ValidateMixin.d.ts.map +1 -1
  57. package/dist-types/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.d.ts.map +1 -1
  58. package/dist-types/components/input-amount/src/formatters.d.ts.map +1 -1
  59. package/dist-types/components/input-date/src/LionInputDate.d.ts +1 -1
  60. package/dist-types/components/input-iban/src/validators.d.ts.map +1 -1
  61. package/dist-types/components/input-tel/test-suites/LionInputTel.suite.d.ts.map +1 -1
  62. package/dist-types/components/input-tel-dropdown/src/LionInputTelDropdown.d.ts.map +1 -1
  63. package/dist-types/components/localize/src/LocalizeMixin.d.ts.map +1 -1
  64. package/dist-types/components/localize/src/date/formatDate.d.ts.map +1 -1
  65. package/dist-types/components/localize/src/date/parseDate.d.ts.map +1 -1
  66. package/dist-types/components/localize/src/getLocalizeManager.d.ts +60 -0
  67. package/dist-types/components/localize/src/getLocalizeManager.d.ts.map +1 -0
  68. package/dist-types/components/localize/src/number/formatNumber.d.ts.map +1 -1
  69. package/dist-types/components/localize/src/number/getCurrencyName.d.ts.map +1 -1
  70. package/dist-types/components/localize/src/number/parseNumber.d.ts.map +1 -1
  71. package/dist-types/components/localize/src/number/utils/emptyStringWhenNumberNan.d.ts.map +1 -1
  72. package/dist-types/components/localize/src/singleton.d.ts +5 -3
  73. package/dist-types/components/localize/src/singleton.d.ts.map +1 -1
  74. package/dist-types/components/localize/src/utils/getLocale.d.ts.map +1 -1
  75. package/dist-types/components/localize/test/getLocalizeManager.test.d.ts +2 -0
  76. package/dist-types/components/localize/test/getLocalizeManager.test.d.ts.map +1 -0
  77. package/dist-types/components/localize/test/side-effect-free-entrypoint.test.d.ts +2 -0
  78. package/dist-types/components/localize/test/side-effect-free-entrypoint.test.d.ts.map +1 -0
  79. package/dist-types/components/localize/test-helpers/localizeTearDown.d.ts.map +1 -1
  80. package/dist-types/components/localize/types/LocalizeMixinTypes.d.ts +2 -0
  81. package/dist-types/components/localize/types/LocalizeMixinTypes.d.ts.map +1 -1
  82. package/dist-types/components/progress-indicator/src/LionProgressIndicator.d.ts.map +1 -1
  83. package/dist-types/components/select/src/LionSelect.d.ts +1 -0
  84. package/dist-types/components/select/src/LionSelect.d.ts.map +1 -1
  85. package/dist-types/exports/localize-no-side-effects.d.ts +18 -0
  86. package/dist-types/tsconfig.tsbuildinfo +1 -1
  87. package/docs/components/checkbox-group/overview.md +2 -2
  88. package/docs/components/collapsible/overview.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/overview.md +5 -5
  93. package/docs/components/form/overview.md +3 -3
  94. package/docs/components/icon/use-cases.md +1 -1
  95. package/docs/components/input/overview.md +1 -1
  96. package/docs/components/input-amount/overview.md +3 -3
  97. package/docs/components/input-date/overview.md +3 -3
  98. package/docs/components/input-datepicker/overview.md +5 -5
  99. package/docs/components/input-email/overview.md +2 -2
  100. package/docs/components/input-iban/overview.md +2 -2
  101. package/docs/components/input-range/overview.md +2 -2
  102. package/docs/components/input-stepper/overview.md +1 -1
  103. package/docs/components/input-tel/overview.md +1 -1
  104. package/docs/components/input-tel/use-cases.md +6 -6
  105. package/docs/components/input-tel-dropdown/overview.md +1 -1
  106. package/docs/components/radio-group/overview.md +3 -3
  107. package/docs/components/select-rich/use-cases.md +1 -1
  108. package/docs/components/tabs/examples.md +1 -1
  109. package/docs/fundamentals/index.md +4 -4
  110. package/docs/fundamentals/node-tools/providence-analytics/LocalConfiguration.md +1 -1
  111. package/docs/fundamentals/node-tools/providence-analytics/QueryResult.md +1 -1
  112. package/docs/fundamentals/node-tools/providence-analytics/analyzer.md +1 -1
  113. package/docs/fundamentals/node-tools/providence-analytics/dashboard.md +1 -1
  114. package/docs/fundamentals/node-tools/providence-analytics/overview.md +3 -3
  115. package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
  116. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
  117. package/docs/fundamentals/systems/core/overview.md +1 -1
  118. package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
  119. package/docs/fundamentals/systems/form/model-value.md +1 -1
  120. package/docs/fundamentals/systems/form/overview.md +28 -28
  121. package/docs/fundamentals/systems/form/validate.md +1 -1
  122. package/docs/fundamentals/systems/localize/overview.md +4 -4
  123. package/docs/fundamentals/systems/overlays/configuration.md +2 -2
  124. package/docs/fundamentals/systems/overlays/overview.md +5 -5
  125. package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
  126. package/docs/fundamentals/tools/helpers/overview.md +1 -1
  127. package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
  128. package/docs/guides/how-to/create-a-custom-field.md +5 -5
  129. package/docs/guides/how-to/extend-a-native-input.md +2 -2
  130. package/docs/guides/index.md +8 -8
  131. package/docs/guides/principles/index.md +5 -5
  132. package/docs/guides/principles/styling.md +1 -1
  133. package/exports/localize-no-side-effects.js +19 -0
  134. package/package.json +1 -1
@@ -2,7 +2,7 @@ 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';
5
- import { localize } from '@lion/ui/localize.js';
5
+ import { getLocalizeManager } from '@lion/ui/localize-no-side-effects.js';
6
6
  import { getFlagSymbol } from './getFlagSymbol.js';
7
7
 
8
8
  /**
@@ -80,6 +80,7 @@ export class LionInputTelDropdown extends LionInputTel {
80
80
  * @type {TemplateDataForDropdownInputTel}
81
81
  */
82
82
  get _templateDataDropdown() {
83
+ const localizeManager = getLocalizeManager();
83
84
  const refs = {
84
85
  dropdown: {
85
86
  ref: this.refs.dropdown,
@@ -91,10 +92,12 @@ export class LionInputTelDropdown extends LionInputTel {
91
92
  'model-value-changed': this._onDropdownValueChange,
92
93
  },
93
94
  labels: {
94
- selectCountry: localize.msg('lion-input-tel:selectCountry'),
95
- allCountries: this._allCountriesLabel || localize.msg('lion-input-tel:allCountries'),
95
+ selectCountry: localizeManager.msg('lion-input-tel:selectCountry'),
96
+ allCountries:
97
+ this._allCountriesLabel || localizeManager.msg('lion-input-tel:allCountries'),
96
98
  preferredCountries:
97
- this._preferredCountriesLabel || localize.msg('lion-input-tel:suggestedCountries'),
99
+ this._preferredCountriesLabel ||
100
+ localizeManager.msg('lion-input-tel:suggestedCountries'),
98
101
  },
99
102
  },
100
103
  };
@@ -1,7 +1,7 @@
1
1
  import { dedupeMixin } from '@open-wc/dedupe-mixin';
2
2
  import { nothing } from 'lit';
3
3
  import { until } from 'lit/directives/until.js';
4
- import { localize } from './singleton.js';
4
+ import { getLocalizeManager } from './getLocalizeManager.js';
5
5
 
6
6
  /**
7
7
  * @typedef {import('lit/directive.js').DirectiveResult} DirectiveResult
@@ -34,6 +34,8 @@ const LocalizeMixinImplementation = superclass =>
34
34
  constructor() {
35
35
  super();
36
36
 
37
+ this._localizeManager = getLocalizeManager();
38
+
37
39
  /** @private */
38
40
  this.__boundLocalizeOnLocaleChanged =
39
41
  /** @param {...Object} args */
@@ -74,14 +76,23 @@ const LocalizeMixinImplementation = superclass =>
74
76
  if (this.localizeNamespacesLoaded) {
75
77
  this.localizeNamespacesLoaded.then(() => this.onLocaleReady());
76
78
  }
77
- localize.addEventListener('__localeChanging', this.__boundLocalizeOnLocaleChanging);
78
- localize.addEventListener('localeChanged', this.__boundLocalizeOnLocaleChanged);
79
+ this._localizeManager.addEventListener(
80
+ '__localeChanging',
81
+ this.__boundLocalizeOnLocaleChanging,
82
+ );
83
+ this._localizeManager.addEventListener('localeChanged', this.__boundLocalizeOnLocaleChanged);
79
84
  }
80
85
 
81
86
  disconnectedCallback() {
82
87
  super.disconnectedCallback();
83
- localize.removeEventListener('__localeChanging', this.__boundLocalizeOnLocaleChanging);
84
- localize.removeEventListener('localeChanged', this.__boundLocalizeOnLocaleChanged);
88
+ this._localizeManager.removeEventListener(
89
+ '__localeChanging',
90
+ this.__boundLocalizeOnLocaleChanging,
91
+ );
92
+ this._localizeManager.removeEventListener(
93
+ 'localeChanged',
94
+ this.__boundLocalizeOnLocaleChanged,
95
+ );
85
96
  }
86
97
 
87
98
  /**
@@ -93,7 +104,7 @@ const LocalizeMixinImplementation = superclass =>
93
104
  */
94
105
  msgLit(keys, variables, options) {
95
106
  if (this.__localizeMessageSync) {
96
- return localize.msg(keys, variables, options);
107
+ return this._localizeManager.msg(keys, variables, options);
97
108
  }
98
109
 
99
110
  if (!this.localizeNamespacesLoaded) {
@@ -101,7 +112,9 @@ const LocalizeMixinImplementation = superclass =>
101
112
  }
102
113
 
103
114
  return until(
104
- this.localizeNamespacesLoaded.then(() => localize.msg(keys, variables, options)),
115
+ this.localizeNamespacesLoaded.then(() =>
116
+ this._localizeManager.msg(keys, variables, options),
117
+ ),
105
118
  nothing,
106
119
  );
107
120
  }
@@ -125,12 +138,14 @@ const LocalizeMixinImplementation = superclass =>
125
138
 
126
139
  /** @private */
127
140
  __localizeStartLoadingNamespaces() {
128
- this.localizeNamespacesLoaded = localize.loadNamespaces(this.__getUniqueNamespaces());
141
+ this.localizeNamespacesLoaded = this._localizeManager.loadNamespaces(
142
+ this.__getUniqueNamespaces(),
143
+ );
129
144
  }
130
145
 
131
146
  /**
132
147
  * Start loading namespaces on the event that is sent immediately
133
- * when localize.locale changes --> 'localeChanging'
148
+ * when this._localizeManager.locale changes --> 'localeChanging'
134
149
  * @private
135
150
  */
136
151
  __localizeOnLocaleChanging() {
@@ -1,5 +1,5 @@
1
1
  import { getLocale } from '../utils/getLocale.js';
2
- import { localize } from '../singleton.js';
2
+ import { getLocalizeManager } from '../getLocalizeManager.js';
3
3
  import { normalizeIntlDate } from './utils/normalizeIntlDate.js';
4
4
 
5
5
  /** @typedef {import('../../types/LocalizeMixinTypes.js').DatePostProcessor} DatePostProcessor */
@@ -12,6 +12,7 @@ import { normalizeIntlDate } from './utils/normalizeIntlDate.js';
12
12
  * @returns {string}
13
13
  */
14
14
  export function formatDate(date, options) {
15
+ const localizeManager = getLocalizeManager();
15
16
  if (!(date instanceof Date)) {
16
17
  return '';
17
18
  }
@@ -36,8 +37,8 @@ export function formatDate(date, options) {
36
37
  formattedDate = '';
37
38
  }
38
39
 
39
- if (localize.formatDateOptions.postProcessors.size > 0) {
40
- Array.from(localize.formatDateOptions.postProcessors).forEach(([locale, fn]) => {
40
+ if (localizeManager.formatDateOptions.postProcessors.size > 0) {
41
+ Array.from(localizeManager.formatDateOptions.postProcessors).forEach(([locale, fn]) => {
41
42
  if (locale === computedLocale) {
42
43
  formattedDate = fn(formattedDate);
43
44
  }
@@ -1,5 +1,5 @@
1
1
  import { getDateFormatBasedOnLocale } from './getDateFormatBasedOnLocale.js';
2
- import { localize } from '../singleton.js';
2
+ import { getLocalizeManager } from '../getLocalizeManager.js';
3
3
  import { addLeadingZero } from './utils/addLeadingZero.js';
4
4
 
5
5
  /**
@@ -29,10 +29,12 @@ const memoizedGetDateFormatBasedOnLocale = memoize(getDateFormatBasedOnLocale);
29
29
  * @returns {Date | undefined}
30
30
  */
31
31
  export function parseDate(dateString) {
32
+ const localizeManager = getLocalizeManager();
33
+
32
34
  const stringToParse = addLeadingZero(dateString);
33
35
  let parsedString;
34
36
 
35
- switch (memoizedGetDateFormatBasedOnLocale(localize.locale)) {
37
+ switch (memoizedGetDateFormatBasedOnLocale(localizeManager.locale)) {
36
38
  case 'day-month-year':
37
39
  parsedString = `${stringToParse.slice(6, 10)}/${stringToParse.slice(
38
40
  3,
@@ -56,7 +58,7 @@ export function parseDate(dateString) {
56
58
  }
57
59
 
58
60
  const [year, month, day] = parsedString.split('/').map(Number);
59
- const parsedDate = new Date(Date.UTC(year, month - 1, day));
61
+ const parsedDate = new Date(new Date(year, month - 1, day));
60
62
 
61
63
  // Check if parsedDate is not `Invalid Date` or that the date has changed (e.g. the not existing 31.02.2020)
62
64
  if (
@@ -0,0 +1,74 @@
1
+ // @ts-ignore
2
+ import { singletonManager } from 'singleton-manager';
3
+ import { LocalizeManager } from './LocalizeManager.js';
4
+
5
+ /**
6
+ * Side-effect-free alternative for `localize` (the globally shared instance of LocalizeManager).
7
+ * When this function is imported, no side-effect happened yet, i.e. no global instance was registered yet.
8
+ * The side effect-free approach generates:
9
+ * - smaller, optimized bundles
10
+ * - a predictable loading order, that allows for:
11
+ * - deduping strategies when multiple instances of the localizeManager are on a page
12
+ * - providing a customized extension of LocalizeManager
13
+ *
14
+ * Use it like this:
15
+ *
16
+ * ```js
17
+ * function myFunction() {
18
+ * // note that 'localizeManager' is the same as former 'localize'
19
+ * const localizeManager = getLocalizeManger();
20
+ * // ...
21
+ * }
22
+ * ```
23
+ *
24
+ * In a class, we advise a shared instance:
25
+ * ```js
26
+ * class MyClass {
27
+ * constructor() {
28
+ * this._localizeManager = getLocalizeManger();
29
+ * }
30
+ * // ...
31
+ * }
32
+ * ```
33
+ *
34
+ * Make sure to always call this method inside a function or class (otherwise side effects are created)
35
+ *
36
+ * Do you want to register your own LocalizeManager?
37
+ * Make sure it's registered before anyone called `getLocalizeManager()`
38
+ *
39
+ * ```js
40
+ * import { singletonManager } from 'singleton-manager';
41
+ * import { getLocalizeManger } from '@lion/ui/localize-no-side-effects.js';
42
+ *
43
+ * // First register your own LocalizeManager (for deduping or other reasons)
44
+ * singletonManager.set('lion/ui::localize::0.x', class MyLocalizeManager extends LocalizeManager {});
45
+ *
46
+ * // Now, all your code gets the right instance
47
+ * function myFuntion() {
48
+ * const localizeManager = getLocalizeManager();
49
+ * // ...
50
+ * }
51
+ *
52
+ * class myClass() {
53
+ * constructor() {
54
+ * this._localizeManager = getLocalizeManager();
55
+ * // ...
56
+ * }
57
+ * }
58
+ * ```
59
+ *
60
+ * @returns {LocalizeManager}
61
+ */
62
+ export function getLocalizeManager() {
63
+ if (singletonManager.has('@lion/ui::localize::0.x')) {
64
+ return singletonManager.get('@lion/ui::localize::0.x');
65
+ }
66
+
67
+ const localizeManager = new LocalizeManager({
68
+ autoLoadOnLocaleChange: true,
69
+ fallbackLocale: 'en-GB',
70
+ });
71
+ singletonManager.set('@lion/ui::localize::0.x', localizeManager);
72
+
73
+ return localizeManager;
74
+ }
@@ -1,6 +1,6 @@
1
1
  /** @typedef {import('../../types/LocalizeMixinTypes.js').NumberPostProcessor} NumberPostProcessor */
2
2
 
3
- import { localize } from '../singleton.js';
3
+ import { getLocalizeManager } from '../getLocalizeManager.js';
4
4
  import { getLocale } from '../utils/getLocale.js';
5
5
  import { formatNumberToParts } from './formatNumberToParts.js';
6
6
 
@@ -14,12 +14,13 @@ import { formatNumberToParts } from './formatNumberToParts.js';
14
14
  * @returns {string}
15
15
  */
16
16
  export function formatNumber(number, options = /** @type {FormatOptions} */ ({})) {
17
+ const localizeManager = getLocalizeManager();
17
18
  if (number === undefined || number === null) return '';
18
19
  const formattedToParts = formatNumberToParts(number, options);
19
20
  // If number is not a number
20
21
  if (
21
22
  formattedToParts === options.returnIfNaN ||
22
- formattedToParts === localize.formatNumberOptions.returnIfNaN
23
+ formattedToParts === localizeManager.formatNumberOptions.returnIfNaN
23
24
  ) {
24
25
  return /** @type {string} */ (formattedToParts);
25
26
  }
@@ -33,8 +34,8 @@ export function formatNumber(number, options = /** @type {FormatOptions} */ ({})
33
34
 
34
35
  const computedLocale = getLocale(options && options.locale);
35
36
 
36
- if (localize.formatNumberOptions.postProcessors.size > 0) {
37
- Array.from(localize.formatNumberOptions.postProcessors).forEach(([locale, fn]) => {
37
+ if (localizeManager.formatNumberOptions.postProcessors.size > 0) {
38
+ Array.from(localizeManager.formatNumberOptions.postProcessors).forEach(([locale, fn]) => {
38
39
  if (locale === computedLocale) {
39
40
  printNumberOfParts = fn(printNumberOfParts);
40
41
  }
@@ -1,4 +1,4 @@
1
- import { localize } from '../singleton.js';
1
+ import { getLocalizeManager } from '../getLocalizeManager.js';
2
2
  import { formatNumberToParts } from './formatNumberToParts.js';
3
3
  import { forceCurrencyNameForPHPEnGB } from './utils/normalize-get-currency-name/forceCurrencyNameForPHPEnGB.js';
4
4
 
@@ -11,6 +11,7 @@ import { forceCurrencyNameForPHPEnGB } from './utils/normalize-get-currency-name
11
11
  * @returns {string} currency name like 'US dollar'
12
12
  */
13
13
  export function getCurrencyName(currencyIso, options) {
14
+ const localizeManager = getLocalizeManager();
14
15
  const parts = /** @type {FormatNumberPart[]} */ (
15
16
  formatNumberToParts(1, {
16
17
  ...options,
@@ -23,7 +24,7 @@ export function getCurrencyName(currencyIso, options) {
23
24
  .filter(p => p.type === 'currency')
24
25
  .map(o => o.value)
25
26
  .join(' ');
26
- const locale = options?.locale || localize.locale;
27
+ const locale = options?.locale || localizeManager.locale;
27
28
  if (currencyIso === 'PHP' && locale === 'en-GB') {
28
29
  currencyName = forceCurrencyNameForPHPEnGB(currencyName);
29
30
  }
@@ -104,7 +104,8 @@ export function parseNumber(value, options) {
104
104
  if (!containsNumbers) {
105
105
  return undefined;
106
106
  }
107
- const matchedInput = value.match(/[0-9,.\- ]/g);
107
+ const valueM = value.replace(/[−]/g, '-'); // U+002D, Hyphen-Minus, -
108
+ const matchedInput = valueM.match(/[0-9,.\- ]/g);
108
109
  if (!matchedInput) {
109
110
  return undefined;
110
111
  }
@@ -112,7 +113,7 @@ export function parseNumber(value, options) {
112
113
  const parseMode = getParseMode(cleanedInput, options);
113
114
  switch (parseMode) {
114
115
  case 'unparseable': {
115
- const cleanedInputMatchStr = cleanedInput.match(/[0-9]/g)?.join('');
116
+ const cleanedInputMatchStr = cleanedInput.match(/[0-9-]/g)?.join('');
116
117
  if (!cleanedInputMatchStr) {
117
118
  return NaN;
118
119
  }
@@ -1,4 +1,4 @@
1
- import { localize } from '../../singleton.js';
1
+ import { getLocalizeManager } from '../../getLocalizeManager.js';
2
2
 
3
3
  /**
4
4
  * When number is NaN we should return an empty string or returnIfNaN param
@@ -7,5 +7,6 @@ import { localize } from '../../singleton.js';
7
7
  * @returns {string}
8
8
  */
9
9
  export function emptyStringWhenNumberNan(returnIfNaN) {
10
- return returnIfNaN || localize.formatNumberOptions.returnIfNaN;
10
+ const localizeManager = getLocalizeManager();
11
+ return returnIfNaN || localizeManager.formatNumberOptions.returnIfNaN;
11
12
  }
@@ -1,11 +1,8 @@
1
- import { singletonManager } from 'singleton-manager';
2
- import { LocalizeManager } from './LocalizeManager.js';
1
+ import { getLocalizeManager } from './getLocalizeManager.js';
3
2
 
4
- /** @type {LocalizeManager} */
3
+ /**
4
+ * Use the side-effect-free `const localizeManager = getLocalizeManager()` instead.
5
+ * @deprecated
6
+ */
5
7
  // eslint-disable-next-line import/no-mutable-exports
6
- export const localize =
7
- /** @type {LocalizeManager} */ (singletonManager.get('@lion/ui::localize::0.x')) ||
8
- new LocalizeManager({
9
- autoLoadOnLocaleChange: true,
10
- fallbackLocale: 'en-GB',
11
- });
8
+ export const localize = getLocalizeManager();
@@ -1,4 +1,4 @@
1
- import { localize } from '../singleton.js';
1
+ import { getLocalizeManager } from '../getLocalizeManager.js';
2
2
 
3
3
  /**
4
4
  * Gets the locale to use
@@ -7,11 +7,6 @@ import { localize } from '../singleton.js';
7
7
  * @returns {string}
8
8
  */
9
9
  export function getLocale(locale) {
10
- if (locale) {
11
- return locale;
12
- }
13
- if (localize && localize.locale) {
14
- return localize.locale;
15
- }
16
- return 'en-GB';
10
+ const localizeManager = getLocalizeManager();
11
+ return locale || localizeManager?.locale || 'en-GB';
17
12
  }
@@ -4,7 +4,7 @@ import sinon from 'sinon';
4
4
  import { fetchMock } from '@bundled-es-modules/fetch-mock';
5
5
  import { setupFakeImport, resetFakeImport, fakeImport } from '@lion/ui/localize-test-helpers.js';
6
6
 
7
- import { LocalizeManager } from '@lion/ui/localize.js';
7
+ import { LocalizeManager } from '@lion/ui/localize-no-side-effects.js';
8
8
 
9
9
  /**
10
10
  * @param {LocalizeManager} localizeManagerEl
@@ -12,7 +12,7 @@ import {
12
12
  unsafeStatic,
13
13
  } from '@open-wc/testing';
14
14
  import sinon from 'sinon';
15
- import { localize, LocalizeMixin } from '@lion/ui/localize.js';
15
+ import { LocalizeMixin, getLocalizeManager } from '@lion/ui/localize-no-side-effects.js';
16
16
  import {
17
17
  fakeImport,
18
18
  localizeTearDown,
@@ -26,6 +26,8 @@ import {
26
26
  */
27
27
 
28
28
  describe('LocalizeMixin', () => {
29
+ const localizeManager = getLocalizeManager();
30
+
29
31
  afterEach(() => {
30
32
  resetFakeImport();
31
33
  localizeTearDown();
@@ -48,7 +50,7 @@ describe('LocalizeMixin', () => {
48
50
 
49
51
  setupEmptyFakeImportsFor(['my-element'], ['en-GB']);
50
52
 
51
- const loadNamespaceSpy = sinon.spy(localize, 'loadNamespace');
53
+ const loadNamespaceSpy = sinon.spy(localizeManager, 'loadNamespace');
52
54
  await fixture(html`<${tag}></${tag}>`);
53
55
 
54
56
  expect(loadNamespaceSpy.callCount).to.equal(1);
@@ -88,7 +90,7 @@ describe('LocalizeMixin', () => {
88
90
 
89
91
  setupEmptyFakeImportsFor(['default', 'parent-element', 'child-element'], ['en-GB']);
90
92
 
91
- const loadNamespaceSpy = sinon.spy(localize, 'loadNamespace');
93
+ const loadNamespaceSpy = sinon.spy(localizeManager, 'loadNamespace');
92
94
 
93
95
  await fixture(html`<${tag}></${tag}>`);
94
96
  expect(loadNamespaceSpy.callCount).to.equal(3);
@@ -151,7 +153,7 @@ describe('LocalizeMixin', () => {
151
153
 
152
154
  await el.localizeNamespacesLoaded;
153
155
 
154
- localize.locale = 'nl-NL';
156
+ localizeManager.locale = 'nl-NL';
155
157
  await el.localizeNamespacesLoaded;
156
158
  expect(onLocaleChangedSpy.callCount).to.equal(0);
157
159
 
@@ -159,7 +161,7 @@ describe('LocalizeMixin', () => {
159
161
  wrapper.appendChild(el);
160
162
 
161
163
  // Changing locale will result in onLocaleChanged to be invoked
162
- localize.locale = 'ru-RU';
164
+ localizeManager.locale = 'ru-RU';
163
165
  await el.localizeNamespacesLoaded;
164
166
  expect(onLocaleChangedSpy.callCount).to.equal(2);
165
167
  expect(onLocaleChangedSpy.calledWithExactly('ru-RU', 'nl-NL')).to.be.true;
@@ -183,10 +185,10 @@ describe('LocalizeMixin', () => {
183
185
  onLocaleChanged(newLocale, oldLocale) {
184
186
  super.onLocaleChanged(newLocale, oldLocale);
185
187
 
186
- // Can call localize.msg immediately, without having to await localize.loadingComplete
188
+ // Can call localizeManager.msg immediately, without having to await localizeManager.loadingComplete
187
189
  // This is because localeChanged event is fired only after awaiting loading
188
190
  // unless the user disables _autoLoadOnLocaleChange property
189
- this.foo = localize.msg('my-element:foo');
191
+ this.foo = localizeManager.msg('my-element:foo');
190
192
  }
191
193
  }
192
194
 
@@ -198,11 +200,11 @@ describe('LocalizeMixin', () => {
198
200
  const wrapper = await fixture('<div></div>');
199
201
  wrapper.appendChild(el);
200
202
 
201
- localize.locale = 'nl-NL';
203
+ localizeManager.locale = 'nl-NL';
202
204
  await el.localizeNamespacesLoaded;
203
205
  expect(el.foo).to.equal('bar-nl-NL');
204
206
 
205
- localize.locale = 'ru-RU';
207
+ localizeManager.locale = 'ru-RU';
206
208
  await el.localizeNamespacesLoaded;
207
209
  expect(el.foo).to.equal('bar-ru-RU');
208
210
  });
@@ -233,7 +235,7 @@ describe('LocalizeMixin', () => {
233
235
  await el.localizeNamespacesLoaded;
234
236
  expect(onLocaleUpdatedSpy.callCount).to.equal(1);
235
237
 
236
- localize.locale = 'nl-NL';
238
+ localizeManager.locale = 'nl-NL';
237
239
  await el.localizeNamespacesLoaded;
238
240
  expect(onLocaleUpdatedSpy.callCount).to.equal(2);
239
241
  });
@@ -261,7 +263,7 @@ describe('LocalizeMixin', () => {
261
263
 
262
264
  async onLocaleUpdated() {
263
265
  super.onLocaleUpdated();
264
- this.label = localize.msg('my-element:label');
266
+ this.label = localizeManager.msg('my-element:label');
265
267
  }
266
268
  }
267
269
 
@@ -272,7 +274,7 @@ describe('LocalizeMixin', () => {
272
274
  await nextFrame(); // needed as both are added to the micro task que
273
275
  expect(el.label).to.equal('one');
274
276
 
275
- localize.locale = 'nl-NL';
277
+ localizeManager.locale = 'nl-NL';
276
278
  await el.localizeNamespacesLoaded;
277
279
  expect(el.label).to.equal('two');
278
280
  });
@@ -297,7 +299,7 @@ describe('LocalizeMixin', () => {
297
299
 
298
300
  el.connectedCallback();
299
301
 
300
- localize.locale = 'nl-NL';
302
+ localizeManager.locale = 'nl-NL';
301
303
  await el.localizeNamespacesLoaded;
302
304
 
303
305
  // await next frame for requestUpdate to be fired
@@ -325,7 +327,7 @@ describe('LocalizeMixin', () => {
325
327
  const tagString = defineCE(MyElement);
326
328
  const el = /** @type {MyElement} */ (document.createElement(tagString));
327
329
  el.connectedCallback();
328
- const lionLocalizeMessageSpy = sinon.spy(localize, 'msg');
330
+ const lionLocalizeMessageSpy = sinon.spy(localizeManager, 'msg');
329
331
 
330
332
  const messageDirective = el.msgLit('my-element:greeting');
331
333
  expect(lionLocalizeMessageSpy.callCount).to.equal(0);
@@ -442,7 +444,7 @@ describe('LocalizeMixin', () => {
442
444
  if (el.shadowRoot) {
443
445
  const p = /** @type {HTMLParagraphElement} */ (el.shadowRoot.querySelector('p'));
444
446
  expect(p.innerText).to.equal('Hi!');
445
- localize.locale = 'en-US';
447
+ localizeManager.locale = 'en-US';
446
448
  expect(p.innerText).to.equal('Hi!');
447
449
  await el.localizeNamespacesLoaded;
448
450
  await nextFrame(); // needed because msgLit relies on until directive to re-render
@@ -1,5 +1,5 @@
1
1
  import { expect } from '@open-wc/testing';
2
- import { localize, formatDate, parseDate } from '@lion/ui/localize.js';
2
+ import { getLocalizeManager, formatDate, parseDate } from '@lion/ui/localize-no-side-effects.js';
3
3
  import { localizeTearDown } from '@lion/ui/localize-test-helpers.js';
4
4
 
5
5
  const SUPPORTED_LOCALES = {
@@ -41,6 +41,7 @@ const SUPPORTED_LOCALES = {
41
41
  */
42
42
 
43
43
  describe('formatDate', () => {
44
+ const localizeManager = getLocalizeManager();
44
45
  beforeEach(() => {
45
46
  localizeTearDown();
46
47
  });
@@ -50,16 +51,16 @@ describe('formatDate', () => {
50
51
 
51
52
  expect(formatDate(testDate)).to.equal('21/05/2012');
52
53
 
53
- localize.locale = 'nl-NL';
54
+ localizeManager.locale = 'nl-NL';
54
55
  expect(formatDate(testDate)).to.equal('21-05-2012');
55
56
 
56
- localize.locale = 'fr-FR';
57
+ localizeManager.locale = 'fr-FR';
57
58
  expect(formatDate(testDate)).to.equal('21/05/2012');
58
59
 
59
- localize.locale = 'de-DE';
60
+ localizeManager.locale = 'de-DE';
60
61
  expect(formatDate(testDate)).to.equal('21.05.2012');
61
62
 
62
- localize.locale = 'en-US';
63
+ localizeManager.locale = 'en-US';
63
64
  expect(formatDate(testDate)).to.equal('05/21/2012');
64
65
  });
65
66
 
@@ -74,13 +75,13 @@ describe('formatDate', () => {
74
75
  };
75
76
 
76
77
  expect(formatDate(testDate, options)).to.equal('Monday, 21 May 2012');
77
- localize.locale = 'nl-NL';
78
+ localizeManager.locale = 'nl-NL';
78
79
  expect(formatDate(testDate, options)).to.equal('maandag 21 mei 2012');
79
- localize.locale = 'fr-FR';
80
+ localizeManager.locale = 'fr-FR';
80
81
  expect(formatDate(testDate, options)).to.equal('lundi 21 mai 2012');
81
- localize.locale = 'de-DE';
82
+ localizeManager.locale = 'de-DE';
82
83
  expect(formatDate(testDate, options)).to.equal('Montag, 21. Mai 2012');
83
- localize.locale = 'en-US';
84
+ localizeManager.locale = 'en-US';
84
85
  expect(formatDate(testDate, options)).to.equal('Monday, May 21, 2012');
85
86
  });
86
87
 
@@ -93,7 +94,7 @@ describe('formatDate', () => {
93
94
  day: '2-digit',
94
95
  locale: 'en-US',
95
96
  };
96
- localize.locale = 'hu-HU';
97
+ localizeManager.locale = 'hu-HU';
97
98
  let date = /** @type {Date} */ (parseDate('2018-5-28'));
98
99
  expect(formatDate(date)).to.equal('2018. 05. 28.');
99
100
 
@@ -110,7 +111,7 @@ describe('formatDate', () => {
110
111
  day: '2-digit',
111
112
  locale: 'en-US',
112
113
  };
113
- localize.locale = 'bg-BG';
114
+ localizeManager.locale = 'bg-BG';
114
115
  let date = /** @type {Date} */ (parseDate('29-12-2017'));
115
116
  expect(formatDate(date)).to.equal('29.12.2017 г.');
116
117
 
@@ -130,7 +131,7 @@ describe('formatDate', () => {
130
131
  day: '2-digit',
131
132
  locale: 'en-US',
132
133
  };
133
- localize.locale = 'en-US';
134
+ localizeManager.locale = 'en-US';
134
135
  let date = /** @type {Date} */ (parseDate('12-29-1940'));
135
136
  expect(formatDate(date)).to.equal('12/29/1940');
136
137
 
@@ -276,11 +277,11 @@ describe('formatDate', () => {
276
277
 
277
278
  // locale is en-GB
278
279
  expect(formatDate(testDate, options)).to.equal('Monday, 21 May 2012');
279
- localize.locale = 'nl-NL';
280
+ localizeManager.locale = 'nl-NL';
280
281
  expect(formatDate(testDate, options)).to.equal('MAANDAG 21 MEI 2012');
281
- localize.locale = 'de-DE';
282
+ localizeManager.locale = 'de-DE';
282
283
  expect(formatDate(testDate, options)).to.equal('montag, 21. mai 2012');
283
- localize.locale = 'en-US';
284
+ localizeManager.locale = 'en-US';
284
285
  expect(formatDate(testDate, options)).to.equal('Monday, May 21, 2012');
285
286
  });
286
287
 
@@ -293,21 +294,21 @@ describe('formatDate', () => {
293
294
  month: 'long',
294
295
  day: '2-digit',
295
296
  };
296
- localize.setDatePostProcessorForLocale({
297
+ localizeManager.setDatePostProcessorForLocale({
297
298
  locale: 'nl-NL',
298
299
  postProcessor: upperCaseProcessor,
299
300
  });
300
- localize.setDatePostProcessorForLocale({
301
+ localizeManager.setDatePostProcessorForLocale({
301
302
  locale: 'de-DE',
302
303
  postProcessor: upperCaseProcessor,
303
304
  });
304
305
 
305
306
  expect(formatDate(testDate, options)).to.equal('Monday, 21 May 2012');
306
- localize.locale = 'nl-NL';
307
+ localizeManager.locale = 'nl-NL';
307
308
  expect(formatDate(testDate, options)).to.equal('MAANDAG 21 MEI 2012');
308
- localize.locale = 'de-DE';
309
+ localizeManager.locale = 'de-DE';
309
310
  expect(formatDate(testDate, options)).to.equal('MONTAG, 21. MAI 2012');
310
- localize.locale = 'en-US';
311
+ localizeManager.locale = 'en-US';
311
312
  expect(formatDate(testDate, options)).to.equal('Monday, May 21, 2012');
312
313
  });
313
314
 
@@ -326,17 +327,17 @@ describe('formatDate', () => {
326
327
  postProcessors,
327
328
  };
328
329
 
329
- localize.setDatePostProcessorForLocale({
330
+ localizeManager.setDatePostProcessorForLocale({
330
331
  locale: 'de-DE',
331
332
  postProcessor: lowerCaseProcessor,
332
333
  });
333
334
 
334
335
  expect(formatDate(testDate, options)).to.equal('Monday, 21 May 2012');
335
- localize.locale = 'nl-NL';
336
+ localizeManager.locale = 'nl-NL';
336
337
  expect(formatDate(testDate, options)).to.equal('MAANDAG 21 MEI 2012');
337
- localize.locale = 'de-DE';
338
+ localizeManager.locale = 'de-DE';
338
339
  expect(formatDate(testDate, options)).to.equal('MONTAG, 21. MAI 2012');
339
- localize.locale = 'en-US';
340
+ localizeManager.locale = 'en-US';
340
341
  expect(formatDate(testDate, options)).to.equal('Monday, May 21, 2012');
341
342
  });
342
343
  });