@lion/ui 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/calendar/src/LionCalendar.js +2 -3
- package/components/calendar/test/lion-calendar.test.js +5 -3
- package/components/form-core/src/validate/ValidateMixin.js +7 -3
- package/components/form-core/src/validate/validators/DateValidators.js +1 -1
- package/components/form-core/test/lion-field.test.js +4 -2
- package/components/form-core/test/validate/DateValidators.test.js +1 -1
- package/components/form-core/test-suites/FormatMixin.suite.js +1 -1
- package/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.js +6 -4
- package/components/form-integrations/test/form-group-methods.test.js +3 -3
- package/components/form-integrations/test/form-integrations.test.js +3 -3
- package/components/form-integrations/test/form-validation-integrations.test.js +11 -10
- package/components/form-integrations/test/helpers/umbrella-form.js +3 -3
- package/components/input-amount/src/LionInputAmount.js +2 -2
- package/components/input-amount/src/formatters.js +5 -1
- package/components/input-amount/src/parsers.js +1 -1
- package/components/input-amount/test/formatters.test.js +5 -3
- package/components/input-date/src/LionInputDate.js +1 -1
- package/components/input-date/test/lion-input-date.test.js +91 -43
- package/components/input-datepicker/src/LionInputDatepicker.js +1 -1
- package/components/input-email/src/LionInputEmail.js +1 -1
- package/components/input-iban/src/LionInputIban.js +1 -1
- package/components/input-iban/src/validators.js +14 -8
- package/components/input-range/src/LionInputRange.js +1 -1
- package/components/input-tel/src/LionInputTel.js +3 -3
- package/components/input-tel/test-suites/LionInputTel.suite.js +3 -2
- package/components/input-tel-dropdown/src/LionInputTelDropdown.js +7 -4
- package/components/localize/src/LocalizeManager.js +19 -3
- package/components/localize/src/LocalizeMixin.js +24 -9
- package/components/localize/src/date/formatDate.js +4 -3
- package/components/localize/src/date/parseDate.js +5 -3
- package/components/localize/src/getLocalizeManager.js +74 -0
- package/components/localize/src/number/formatNumber.js +5 -4
- package/components/localize/src/number/getCurrencyName.js +3 -2
- package/components/localize/src/number/parseNumber.js +3 -2
- package/components/localize/src/number/utils/emptyStringWhenNumberNan.js +3 -2
- package/components/localize/src/singleton.js +6 -9
- package/components/localize/src/utils/getLocale.js +3 -8
- package/components/localize/test/LocalizeManager.test.js +19 -2
- package/components/localize/test/LocalizeMixin.test.js +17 -15
- package/components/localize/test/date/formatDate.test.js +25 -24
- package/components/localize/test/date/getDateFormatBasedOnLocale.test.js +8 -3
- package/components/localize/test/date/parseDate.test.js +22 -7
- package/components/localize/test/getLocalizeManager.test.js +31 -0
- package/components/localize/test/localize.test.js +5 -4
- package/components/localize/test/number/formatNumber.test.js +31 -29
- package/components/localize/test/number/formatNumberToParts.test.js +5 -3
- package/components/localize/test/number/getCurrencyName.test.js +1 -1
- package/components/localize/test/number/parseNumber.test.js +37 -19
- package/components/localize/test/side-effect-free-entrypoint.test.js +38 -0
- package/components/localize/test-helpers/localizeTearDown.js +5 -4
- package/components/localize/types/LocalizeMixinTypes.ts +8 -1
- package/components/pagination/src/LionPagination.js +1 -1
- package/components/progress-indicator/src/LionProgressIndicator.js +3 -2
- package/components/select/src/LionSelect.js +15 -0
- package/components/select/test/lion-select.test.js +25 -0
- package/components/select-rich/src/LionSelectRich.js +6 -0
- package/components/select-rich/test/lion-select-rich.test.js +33 -0
- package/components/validate-messages/src/loadDefaultFeedbackMessages.js +2 -2
- package/components/validate-messages/test/loadDefaultFeedbackMessagesNoSideEffects.js +6 -4
- package/custom-elements.json +740 -15
- package/dist-types/components/calendar/src/LionCalendar.d.ts.map +1 -1
- package/dist-types/components/form-core/src/validate/ValidateMixin.d.ts.map +1 -1
- package/dist-types/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.d.ts.map +1 -1
- package/dist-types/components/input-amount/src/formatters.d.ts.map +1 -1
- package/dist-types/components/input-date/src/LionInputDate.d.ts +1 -1
- package/dist-types/components/input-iban/src/validators.d.ts.map +1 -1
- package/dist-types/components/input-tel/test-suites/LionInputTel.suite.d.ts.map +1 -1
- package/dist-types/components/input-tel-dropdown/src/LionInputTelDropdown.d.ts.map +1 -1
- package/dist-types/components/localize/src/LocalizeManager.d.ts +6 -2
- package/dist-types/components/localize/src/LocalizeManager.d.ts.map +1 -1
- package/dist-types/components/localize/src/LocalizeMixin.d.ts.map +1 -1
- package/dist-types/components/localize/src/date/formatDate.d.ts.map +1 -1
- package/dist-types/components/localize/src/date/parseDate.d.ts.map +1 -1
- package/dist-types/components/localize/src/getLocalizeManager.d.ts +60 -0
- package/dist-types/components/localize/src/getLocalizeManager.d.ts.map +1 -0
- package/dist-types/components/localize/src/number/formatNumber.d.ts.map +1 -1
- package/dist-types/components/localize/src/number/getCurrencyName.d.ts.map +1 -1
- package/dist-types/components/localize/src/number/parseNumber.d.ts.map +1 -1
- package/dist-types/components/localize/src/number/utils/emptyStringWhenNumberNan.d.ts.map +1 -1
- package/dist-types/components/localize/src/singleton.d.ts +5 -3
- package/dist-types/components/localize/src/singleton.d.ts.map +1 -1
- package/dist-types/components/localize/src/utils/getLocale.d.ts.map +1 -1
- package/dist-types/components/localize/test/getLocalizeManager.test.d.ts +2 -0
- package/dist-types/components/localize/test/getLocalizeManager.test.d.ts.map +1 -0
- package/dist-types/components/localize/test/side-effect-free-entrypoint.test.d.ts +2 -0
- package/dist-types/components/localize/test/side-effect-free-entrypoint.test.d.ts.map +1 -0
- package/dist-types/components/localize/test-helpers/localizeTearDown.d.ts.map +1 -1
- package/dist-types/components/localize/types/LocalizeMixinTypes.d.ts +2 -0
- package/dist-types/components/localize/types/LocalizeMixinTypes.d.ts.map +1 -1
- package/dist-types/components/progress-indicator/src/LionProgressIndicator.d.ts.map +1 -1
- package/dist-types/components/select/src/LionSelect.d.ts +1 -0
- package/dist-types/components/select/src/LionSelect.d.ts.map +1 -1
- package/dist-types/components/select-rich/src/LionSelectRich.d.ts.map +1 -1
- package/dist-types/exports/localize-no-side-effects.d.ts +18 -0
- package/dist-types/exports/types/core.d.ts +3 -0
- package/dist-types/exports/types/core.d.ts.map +1 -1
- package/dist-types/exports/types/form-core.d.ts +16 -0
- package/dist-types/exports/types/form-core.d.ts.map +1 -1
- package/dist-types/exports/types/localize.d.ts +1 -0
- package/dist-types/exports/types/localize.d.ts.map +1 -1
- package/dist-types/exports/types/overlays.d.ts +1 -0
- package/dist-types/exports/types/overlays.d.ts.map +1 -1
- package/dist-types/tsconfig.tsbuildinfo +1 -1
- package/docs/components/checkbox-group/overview.md +2 -2
- package/docs/components/collapsible/overview.md +1 -1
- package/docs/components/combobox/overview.md +1 -1
- package/docs/components/combobox/use-cases.md +1 -1
- package/docs/components/dialog/overview.md +1 -1
- package/docs/components/fieldset/overview.md +5 -5
- package/docs/components/form/overview.md +3 -3
- package/docs/components/form/use-cases.md +2 -2
- package/docs/components/icon/use-cases.md +1 -1
- package/docs/components/input/overview.md +1 -1
- package/docs/components/input-amount/overview.md +3 -3
- package/docs/components/input-date/overview.md +3 -3
- package/docs/components/input-datepicker/overview.md +5 -5
- package/docs/components/input-email/overview.md +2 -2
- package/docs/components/input-iban/overview.md +2 -2
- package/docs/components/input-range/overview.md +2 -2
- package/docs/components/input-stepper/overview.md +1 -1
- package/docs/components/input-tel/overview.md +1 -1
- package/docs/components/input-tel/use-cases.md +6 -6
- package/docs/components/input-tel-dropdown/overview.md +1 -1
- package/docs/components/radio-group/overview.md +3 -3
- package/docs/components/select-rich/use-cases.md +1 -1
- package/docs/components/tabs/examples.md +1 -1
- package/docs/fundamentals/index.md +4 -4
- package/docs/fundamentals/node-tools/providence-analytics/LocalConfiguration.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/QueryResult.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/analyzer.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/dashboard.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/overview.md +3 -3
- package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
- package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
- package/docs/fundamentals/systems/core/overview.md +1 -1
- package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
- package/docs/fundamentals/systems/form/model-value.md +1 -1
- package/docs/fundamentals/systems/form/overview.md +28 -28
- package/docs/fundamentals/systems/form/use-cases.md +3 -3
- package/docs/fundamentals/systems/form/validate.md +1 -1
- package/docs/fundamentals/systems/localize/overview.md +4 -4
- package/docs/fundamentals/systems/overlays/assets/umbrella-form.js +3 -3
- package/docs/fundamentals/systems/overlays/configuration.md +2 -2
- package/docs/fundamentals/systems/overlays/overview.md +5 -5
- package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
- package/docs/fundamentals/tools/helpers/overview.md +1 -1
- package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
- package/docs/guides/how-to/create-a-custom-field.md +5 -5
- package/docs/guides/how-to/extend-a-native-input.md +2 -2
- package/docs/guides/index.md +8 -8
- package/docs/guides/principles/index.md +5 -5
- package/docs/guides/principles/styling.md +1 -1
- package/exports/localize-no-side-effects.js +19 -0
- package/exports/types/core.ts +3 -0
- package/exports/types/form-core.ts +16 -0
- package/exports/types/localize.ts +1 -0
- package/exports/types/overlays.ts +1 -0
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Unparseable } from '@lion/ui/form-core.js';
|
|
2
|
-
import { LocalizeMixin
|
|
2
|
+
import { LocalizeMixin } from '@lion/ui/localize-no-side-effects.js';
|
|
3
3
|
import { LionInput } from '@lion/ui/input.js';
|
|
4
4
|
|
|
5
5
|
import { PhoneUtilManager } from './PhoneUtilManager.js';
|
|
@@ -125,7 +125,7 @@ export class LionInputTel extends LocalizeMixin(LionInput) {
|
|
|
125
125
|
// @ts-expect-error
|
|
126
126
|
// eslint-disable-next-line class-methods-use-this
|
|
127
127
|
get fieldName() {
|
|
128
|
-
return
|
|
128
|
+
return this._localizeManager.msg('lion-input-tel:phoneNumber');
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
/**
|
|
@@ -227,7 +227,7 @@ export class LionInputTel extends LocalizeMixin(LionInput) {
|
|
|
227
227
|
onLocaleUpdated() {
|
|
228
228
|
super.onLocaleUpdated();
|
|
229
229
|
|
|
230
|
-
const localeSplitted =
|
|
230
|
+
const localeSplitted = this._localizeManager.locale.split('-');
|
|
231
231
|
/**
|
|
232
232
|
* @protected
|
|
233
233
|
* @type {RegionCode}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from '@open-wc/testing';
|
|
10
10
|
import sinon from 'sinon';
|
|
11
11
|
import { mimicUserInput } from '@lion/ui/form-core-test-helpers.js';
|
|
12
|
-
import {
|
|
12
|
+
import { getLocalizeManager } from '@lion/ui/localize-no-side-effects.js';
|
|
13
13
|
import { Unparseable } from '@lion/ui/form-core.js';
|
|
14
14
|
import { LionInputTel, PhoneNumber, PhoneUtilManager } from '@lion/ui/input-tel.js';
|
|
15
15
|
import { mockPhoneUtilManager, restorePhoneUtilManager } from '@lion/ui/input-tel-test-helpers.js';
|
|
@@ -23,7 +23,8 @@ const fixture = /** @type {(arg: string | TemplateResult) => Promise<LionInputTe
|
|
|
23
23
|
const fixtureSync = /** @type {(arg: string | TemplateResult) => LionInputTel} */ (_fixtureSync);
|
|
24
24
|
|
|
25
25
|
const getRegionCodeBasedOnLocale = () => {
|
|
26
|
-
const
|
|
26
|
+
const localizeManager = getLocalizeManager();
|
|
27
|
+
const localeSplitted = localizeManager.locale.split('-');
|
|
27
28
|
return /** @type {RegionCode} */ (localeSplitted[localeSplitted.length - 1]).toUpperCase();
|
|
28
29
|
};
|
|
29
30
|
|
|
@@ -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 {
|
|
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:
|
|
95
|
-
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 ||
|
|
99
|
+
this._preferredCountriesLabel ||
|
|
100
|
+
localizeManager.msg('lion-input-tel:suggestedCountries'),
|
|
98
101
|
},
|
|
99
102
|
},
|
|
100
103
|
};
|
|
@@ -18,6 +18,7 @@ export class LocalizeManager {
|
|
|
18
18
|
autoLoadOnLocaleChange = false,
|
|
19
19
|
fallbackLocale = '',
|
|
20
20
|
showKeyAsFallback = false,
|
|
21
|
+
allowOverridesForExistingNamespaces = false,
|
|
21
22
|
} = {}) {
|
|
22
23
|
/** @private */
|
|
23
24
|
this.__delegationTarget = document.createDocumentFragment();
|
|
@@ -28,6 +29,9 @@ export class LocalizeManager {
|
|
|
28
29
|
/** @protected */
|
|
29
30
|
this._showKeyAsFallback = showKeyAsFallback;
|
|
30
31
|
|
|
32
|
+
/** @private */
|
|
33
|
+
this.__allowOverridesForExistingNamespaces = allowOverridesForExistingNamespaces;
|
|
34
|
+
|
|
31
35
|
/**
|
|
32
36
|
* @type {Object.<string, Object.<string, Object>>}
|
|
33
37
|
* @private
|
|
@@ -199,17 +203,29 @@ export class LocalizeManager {
|
|
|
199
203
|
* @param {string} locale
|
|
200
204
|
* @param {string} namespace
|
|
201
205
|
* @param {object} data
|
|
202
|
-
* @throws {Error} Namespace can be added only once, for a given locale
|
|
206
|
+
* @throws {Error} Namespace can be added only once, for a given locale unless allowOverridesForExistingNamespaces
|
|
207
|
+
* is set to `true`
|
|
203
208
|
*/
|
|
204
209
|
addData(locale, namespace, data) {
|
|
205
|
-
if (
|
|
210
|
+
if (
|
|
211
|
+
!this.__allowOverridesForExistingNamespaces &&
|
|
212
|
+
this._isNamespaceInCache(locale, namespace)
|
|
213
|
+
) {
|
|
206
214
|
throw new Error(
|
|
207
215
|
`Namespace "${namespace}" has been already added for the locale "${locale}".`,
|
|
208
216
|
);
|
|
209
217
|
}
|
|
210
218
|
|
|
211
219
|
this.__storage[locale] = this.__storage[locale] || {};
|
|
212
|
-
|
|
220
|
+
|
|
221
|
+
if (this.__allowOverridesForExistingNamespaces) {
|
|
222
|
+
this.__storage[locale][namespace] = {
|
|
223
|
+
...this.__storage[locale][namespace],
|
|
224
|
+
...data,
|
|
225
|
+
};
|
|
226
|
+
} else {
|
|
227
|
+
this.__storage[locale][namespace] = data;
|
|
228
|
+
}
|
|
213
229
|
}
|
|
214
230
|
|
|
215
231
|
/**
|
|
@@ -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 {
|
|
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
|
-
|
|
78
|
-
|
|
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
|
-
|
|
84
|
-
|
|
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
|
|
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(() =>
|
|
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 =
|
|
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
|
|
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 {
|
|
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 (
|
|
40
|
-
Array.from(
|
|
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 {
|
|
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(
|
|
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
|
|
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 {
|
|
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 ===
|
|
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 (
|
|
37
|
-
Array.from(
|
|
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 {
|
|
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 ||
|
|
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
|
|
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 {
|
|
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
|
-
|
|
10
|
+
const localizeManager = getLocalizeManager();
|
|
11
|
+
return returnIfNaN || localizeManager.formatNumberOptions.returnIfNaN;
|
|
11
12
|
}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { LocalizeManager } from './LocalizeManager.js';
|
|
1
|
+
import { getLocalizeManager } from './getLocalizeManager.js';
|
|
3
2
|
|
|
4
|
-
/**
|
|
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 {
|
|
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
|
-
|
|
11
|
-
|
|
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
|
|
@@ -155,7 +155,7 @@ describe('LocalizeManager', () => {
|
|
|
155
155
|
});
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
-
it('prevents mutating existing data for the same locale & namespace', () => {
|
|
158
|
+
it('prevents mutating existing data for the same locale & namespace when "allowOverridesForExistingNamespaces" option is not given in constructor', () => {
|
|
159
159
|
manager = new LocalizeManager();
|
|
160
160
|
const { storage } = getProtectedMembers(manager);
|
|
161
161
|
|
|
@@ -169,6 +169,23 @@ describe('LocalizeManager', () => {
|
|
|
169
169
|
'en-GB': { 'lion-hello': { greeting: 'Hi!' } },
|
|
170
170
|
});
|
|
171
171
|
});
|
|
172
|
+
|
|
173
|
+
it('allows mutating existing data for the same locale & namespace when "allowOverridesForExistingNamespaces" option is set to "true" in constructor', () => {
|
|
174
|
+
manager = new LocalizeManager({ allowOverridesForExistingNamespaces: true });
|
|
175
|
+
const { storage } = getProtectedMembers(manager);
|
|
176
|
+
|
|
177
|
+
manager.addData('en-GB', 'lion-hello', { greeting: 'Hi!' });
|
|
178
|
+
|
|
179
|
+
expect(storage).to.deep.equal({
|
|
180
|
+
'en-GB': { 'lion-hello': { greeting: 'Hi!' } },
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
manager.addData('en-GB', 'lion-hello', { greeting: 'Hi!', alternative: 'Hello!' });
|
|
184
|
+
|
|
185
|
+
expect(storage).to.deep.equal({
|
|
186
|
+
'en-GB': { 'lion-hello': { greeting: 'Hi!', alternative: 'Hello!' } },
|
|
187
|
+
});
|
|
188
|
+
});
|
|
172
189
|
});
|
|
173
190
|
|
|
174
191
|
describe('loading via dynamic imports', () => {
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
unsafeStatic,
|
|
13
13
|
} from '@open-wc/testing';
|
|
14
14
|
import sinon from 'sinon';
|
|
15
|
-
import {
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
203
|
+
localizeManager.locale = 'nl-NL';
|
|
202
204
|
await el.localizeNamespacesLoaded;
|
|
203
205
|
expect(el.foo).to.equal('bar-nl-NL');
|
|
204
206
|
|
|
205
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|