@valtimo/components 13.50.0 → 13.51.0
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/fesm2022/valtimo-components.mjs +129 -73
- package/fesm2022/valtimo-components.mjs.map +1 -1
- package/lib/components/form-io/components/form-io-currency/currency.component.d.ts +15 -11
- package/lib/components/form-io/components/form-io-currency/currency.component.d.ts.map +1 -1
- package/lib/components/form-io/components/form-io-mail-preview/mail-preview.component.d.ts.map +1 -1
- package/lib/components/form-io/components/form-io-mail-preview/sanitize-email-html.d.ts +2 -0
- package/lib/components/form-io/components/form-io-mail-preview/sanitize-email-html.d.ts.map +1 -0
- package/package.json +3 -2
|
@@ -53,9 +53,10 @@ import { ComponentPortal, TemplatePortal } from '@angular/cdk/portal';
|
|
|
53
53
|
import { trigger, transition, style, animate } from '@angular/animations';
|
|
54
54
|
import * as i1$6 from '@angular/cdk/overlay';
|
|
55
55
|
import { OverlayModule, Overlay } from '@angular/cdk/overlay';
|
|
56
|
-
import
|
|
56
|
+
import AutoNumeric from 'autonumeric';
|
|
57
57
|
import flatpickr from 'flatpickr';
|
|
58
58
|
import { Dutch } from 'flatpickr/dist/l10n/nl';
|
|
59
|
+
import createDOMPurify from 'dompurify';
|
|
59
60
|
import * as i2$4 from 'ngx-spinner';
|
|
60
61
|
import { NgxSpinnerModule } from 'ngx-spinner';
|
|
61
62
|
import Search16 from '@carbon/icons/es/search/16';
|
|
@@ -12877,108 +12878,134 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
12877
12878
|
* See the License for the specific language governing permissions and
|
|
12878
12879
|
* limitations under the License.
|
|
12879
12880
|
*/
|
|
12881
|
+
const DEFAULT_LOCALE = 'nl-NL';
|
|
12882
|
+
const DEFAULT_CURRENCY = 'EUR';
|
|
12883
|
+
const RAW_VALUE_MODIFIED_EVENT = 'autoNumeric:rawValueModified';
|
|
12880
12884
|
/**
|
|
12881
12885
|
* Custom formio component for currency number.
|
|
12882
12886
|
*/
|
|
12883
12887
|
class FormIoCurrencyComponent {
|
|
12884
12888
|
constructor() {
|
|
12885
|
-
this.currencyForm = new FormGroup({
|
|
12886
|
-
currencyValue: new FormControl(''),
|
|
12887
|
-
});
|
|
12888
12889
|
this._value = null;
|
|
12889
12890
|
this.valueChange = new EventEmitter();
|
|
12890
|
-
this.
|
|
12891
|
+
this._disabled = false;
|
|
12892
|
+
this._autoNumeric = null;
|
|
12893
|
+
this._rendering = false;
|
|
12894
|
+
this._rawValueModifiedListener = () => this.onRawValueModified();
|
|
12891
12895
|
}
|
|
12892
12896
|
get value() {
|
|
12893
12897
|
return this._value;
|
|
12894
12898
|
}
|
|
12895
12899
|
set value(value) {
|
|
12896
|
-
this._value = value;
|
|
12897
|
-
|
|
12898
|
-
|
|
12899
|
-
|
|
12900
|
-
|
|
12901
|
-
}, { emitEvent: false });
|
|
12900
|
+
this._value = typeof value === 'number' ? value : null;
|
|
12901
|
+
this.renderValue();
|
|
12902
|
+
}
|
|
12903
|
+
get disabled() {
|
|
12904
|
+
return this._disabled;
|
|
12902
12905
|
}
|
|
12903
12906
|
set disabled(value) {
|
|
12904
|
-
|
|
12905
|
-
|
|
12907
|
+
this._disabled = !!value;
|
|
12908
|
+
}
|
|
12909
|
+
ngAfterViewInit() {
|
|
12910
|
+
const element = this.currencyElement.nativeElement;
|
|
12911
|
+
this._autoNumeric = new AutoNumeric(element, this.autoNumericOptions);
|
|
12912
|
+
element.addEventListener(RAW_VALUE_MODIFIED_EVENT, this._rawValueModifiedListener);
|
|
12913
|
+
this.renderValue();
|
|
12914
|
+
}
|
|
12915
|
+
ngOnChanges(changes) {
|
|
12916
|
+
if (this._autoNumeric &&
|
|
12917
|
+
(changes.currencyLocale || changes.currencyCurrency || changes.allowEmptyValue)) {
|
|
12918
|
+
this.withoutEmitting(() => this._autoNumeric.update(this.autoNumericOptions));
|
|
12919
|
+
this.renderValue();
|
|
12906
12920
|
}
|
|
12907
|
-
|
|
12908
|
-
|
|
12921
|
+
}
|
|
12922
|
+
ngOnDestroy() {
|
|
12923
|
+
if (!this._autoNumeric) {
|
|
12924
|
+
return;
|
|
12909
12925
|
}
|
|
12926
|
+
this.currencyElement.nativeElement.removeEventListener(RAW_VALUE_MODIFIED_EVENT, this._rawValueModifiedListener);
|
|
12927
|
+
this._autoNumeric.remove();
|
|
12928
|
+
this._autoNumeric = null;
|
|
12910
12929
|
}
|
|
12911
|
-
|
|
12912
|
-
|
|
12930
|
+
/**
|
|
12931
|
+
* Derives the AutoNumeric formatting from the Intl formatting of the configured locale and
|
|
12932
|
+
* currency, so the input renders amounts exactly as that locale writes them.
|
|
12933
|
+
*/
|
|
12934
|
+
get autoNumericOptions() {
|
|
12935
|
+
const formatter = new Intl.NumberFormat(this.currencyLocale || DEFAULT_LOCALE, {
|
|
12936
|
+
style: 'currency',
|
|
12937
|
+
currency: this.currencyCurrency || DEFAULT_CURRENCY,
|
|
12938
|
+
});
|
|
12939
|
+
const parts = formatter.formatToParts(-1234567.89);
|
|
12940
|
+
const partValue = (type) => parts.find(part => part.type === type)?.value ?? '';
|
|
12941
|
+
const indexOf = (type) => parts.findIndex(part => part.type === type);
|
|
12942
|
+
const currencyIndex = indexOf('currency');
|
|
12943
|
+
const firstIntegerIndex = indexOf('integer');
|
|
12944
|
+
const minusSignIndex = indexOf('minusSign');
|
|
12945
|
+
const currencyIsPrefix = currencyIndex < firstIntegerIndex;
|
|
12946
|
+
const spacing = parts[currencyIsPrefix ? currencyIndex + 1 : currencyIndex - 1];
|
|
12947
|
+
const literal = spacing?.type === 'literal' ? spacing.value : '';
|
|
12948
|
+
const currencySymbol = currencyIsPrefix
|
|
12949
|
+
? `${partValue('currency')}${literal}`
|
|
12950
|
+
: `${literal}${partValue('currency')}`;
|
|
12951
|
+
const negativePositiveSignPlacement = currencyIsPrefix
|
|
12952
|
+
? minusSignIndex < currencyIndex
|
|
12953
|
+
? 'l'
|
|
12954
|
+
: 'r'
|
|
12955
|
+
: minusSignIndex < firstIntegerIndex
|
|
12956
|
+
? 'p'
|
|
12957
|
+
: minusSignIndex < currencyIndex
|
|
12958
|
+
? 'l'
|
|
12959
|
+
: 's';
|
|
12913
12960
|
return {
|
|
12914
|
-
|
|
12915
|
-
|
|
12916
|
-
|
|
12917
|
-
|
|
12918
|
-
|
|
12919
|
-
|
|
12920
|
-
|
|
12961
|
+
currencySymbol,
|
|
12962
|
+
currencySymbolPlacement: currencyIsPrefix ? 'p' : 's',
|
|
12963
|
+
negativePositiveSignPlacement,
|
|
12964
|
+
digitGroupSeparator: partValue('group'),
|
|
12965
|
+
decimalCharacter: partValue('decimal') || '.',
|
|
12966
|
+
decimalPlaces: formatter.resolvedOptions().maximumFractionDigits,
|
|
12967
|
+
emptyInputBehavior: 'always',
|
|
12968
|
+
modifyValueOnWheel: false,
|
|
12921
12969
|
};
|
|
12922
12970
|
}
|
|
12923
|
-
|
|
12924
|
-
this.
|
|
12925
|
-
|
|
12926
|
-
|
|
12927
|
-
|
|
12928
|
-
|
|
12929
|
-
|
|
12930
|
-
|
|
12931
|
-
|
|
12932
|
-
|
|
12971
|
+
onRawValueModified() {
|
|
12972
|
+
if (this._rendering || !this._autoNumeric) {
|
|
12973
|
+
return;
|
|
12974
|
+
}
|
|
12975
|
+
const numericString = this._autoNumeric.getNumericString();
|
|
12976
|
+
const isEmpty = numericString === null || numericString === '';
|
|
12977
|
+
const value = isEmpty ? (this.allowEmptyValue ? null : 0) : Number(numericString);
|
|
12978
|
+
this._value = value;
|
|
12979
|
+
this.valueChange.emit(value);
|
|
12980
|
+
}
|
|
12981
|
+
renderValue() {
|
|
12982
|
+
if (!this._autoNumeric) {
|
|
12983
|
+
return;
|
|
12984
|
+
}
|
|
12985
|
+
this.withoutEmitting(() => {
|
|
12986
|
+
if (typeof this._value === 'number') {
|
|
12987
|
+
this._autoNumeric.set(this._value);
|
|
12933
12988
|
}
|
|
12934
12989
|
else {
|
|
12935
|
-
this.
|
|
12936
|
-
this.valueChange.emit(unmasked);
|
|
12990
|
+
this._autoNumeric.clear();
|
|
12937
12991
|
}
|
|
12938
|
-
}));
|
|
12939
|
-
}
|
|
12940
|
-
ngOnDestroy() {
|
|
12941
|
-
this._subscriptions.unsubscribe();
|
|
12942
|
-
}
|
|
12943
|
-
ngAfterViewInit() {
|
|
12944
|
-
this._currencyInstance = new Currency(this.currencyElement.nativeElement, {
|
|
12945
|
-
maskOpts: this.maskOpts,
|
|
12946
12992
|
});
|
|
12947
|
-
// A value can arrive before the view exists, so its render is redone here with the mask in
|
|
12948
|
-
// place.
|
|
12949
|
-
if (typeof this._value === 'number') {
|
|
12950
|
-
this.renderValue();
|
|
12951
|
-
}
|
|
12952
12993
|
}
|
|
12953
|
-
|
|
12954
|
-
|
|
12955
|
-
|
|
12956
|
-
|
|
12957
|
-
|
|
12958
|
-
|
|
12959
|
-
|
|
12960
|
-
}
|
|
12961
|
-
if (typeof this.currencyCurrency === 'string') {
|
|
12962
|
-
this._currencyInstance.opts.maskOpts.options.currency = this.currencyCurrency;
|
|
12963
|
-
}
|
|
12964
|
-
if (typeof this.allowEmptyValue === 'boolean') {
|
|
12965
|
-
this._currencyInstance.opts.maskOpts.empty = this.allowEmptyValue;
|
|
12966
|
-
}
|
|
12967
|
-
}
|
|
12968
|
-
this.renderValue();
|
|
12994
|
+
withoutEmitting(action) {
|
|
12995
|
+
this._rendering = true;
|
|
12996
|
+
try {
|
|
12997
|
+
action();
|
|
12998
|
+
}
|
|
12999
|
+
finally {
|
|
13000
|
+
this._rendering = false;
|
|
12969
13001
|
}
|
|
12970
|
-
}
|
|
12971
|
-
renderValue() {
|
|
12972
|
-
this.currencyForm.setValue({
|
|
12973
|
-
currencyValue: typeof this._value === 'number' ? Currency.masking(this._value, this.maskOpts) : '',
|
|
12974
|
-
}, { emitEvent: false });
|
|
12975
13002
|
}
|
|
12976
13003
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormIoCurrencyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
12977
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", type: FormIoCurrencyComponent, isStandalone: false, selector: "valtimo-currency", inputs: { value: "value", disabled: "disabled", currencyLocale: "currencyLocale", currencyCurrency: "currencyCurrency", allowEmptyValue: "allowEmptyValue" }, outputs: { valueChange: "valueChange" }, viewQueries: [{ propertyName: "currencyElement", first: true, predicate: ["currencyElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n\n<div class=\"currencyForm-container\"
|
|
13004
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", type: FormIoCurrencyComponent, isStandalone: false, selector: "valtimo-currency", inputs: { value: "value", disabled: "disabled", currencyLocale: "currencyLocale", currencyCurrency: "currencyCurrency", allowEmptyValue: "allowEmptyValue" }, outputs: { valueChange: "valueChange" }, viewQueries: [{ propertyName: "currencyElement", first: true, predicate: ["currencyElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n\n<div class=\"currencyForm-container\">\n <div class=\"input-group\">\n <input\n #currencyElement\n id=\"currency\"\n class=\"form-control\"\n inputmode=\"decimal\"\n [disabled]=\"disabled\"\n />\n </div>\n</div>\n" }); }
|
|
12978
13005
|
}
|
|
12979
13006
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormIoCurrencyComponent, decorators: [{
|
|
12980
13007
|
type: Component,
|
|
12981
|
-
args: [{ selector: 'valtimo-currency', standalone: false, template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n\n<div class=\"currencyForm-container\"
|
|
13008
|
+
args: [{ selector: 'valtimo-currency', standalone: false, template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n\n<div class=\"currencyForm-container\">\n <div class=\"input-group\">\n <input\n #currencyElement\n id=\"currency\"\n class=\"form-control\"\n inputmode=\"decimal\"\n [disabled]=\"disabled\"\n />\n </div>\n</div>\n" }]
|
|
12982
13009
|
}], propDecorators: { currencyElement: [{
|
|
12983
13010
|
type: ViewChild,
|
|
12984
13011
|
args: ['currencyElement']
|
|
@@ -13103,6 +13130,35 @@ function registerFormioFlatpickr() {
|
|
|
13103
13130
|
};
|
|
13104
13131
|
}
|
|
13105
13132
|
|
|
13133
|
+
/*
|
|
13134
|
+
* Copyright 2015-2026 Ritense BV, the Netherlands.
|
|
13135
|
+
*
|
|
13136
|
+
* Licensed under EUPL, Version 1.2 (the "License");
|
|
13137
|
+
* you may not use this file except in compliance with the License.
|
|
13138
|
+
* You may obtain a copy of the License at
|
|
13139
|
+
*
|
|
13140
|
+
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
|
|
13141
|
+
*
|
|
13142
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13143
|
+
* distributed under the License is distributed on an "AS IS" basis,
|
|
13144
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13145
|
+
* See the License for the specific language governing permissions and
|
|
13146
|
+
* limitations under the License.
|
|
13147
|
+
*/
|
|
13148
|
+
const SANITIZE_CONFIG = {
|
|
13149
|
+
FORBID_TAGS: ['form', 'input', 'button', 'textarea', 'select'],
|
|
13150
|
+
};
|
|
13151
|
+
// Use an isolated DOMPurify instance so the anchor hook below does not leak onto
|
|
13152
|
+
// the shared singleton that formiojs (and other libraries) sanitize with.
|
|
13153
|
+
const purifier = createDOMPurify(window);
|
|
13154
|
+
purifier.addHook('afterSanitizeAttributes', node => {
|
|
13155
|
+
if (node.tagName === 'A') {
|
|
13156
|
+
node.setAttribute('target', '_blank');
|
|
13157
|
+
node.setAttribute('rel', 'noopener noreferrer');
|
|
13158
|
+
}
|
|
13159
|
+
});
|
|
13160
|
+
const sanitizeEmailHtml = (html) => purifier.sanitize(html, SANITIZE_CONFIG);
|
|
13161
|
+
|
|
13106
13162
|
/*
|
|
13107
13163
|
* Copyright 2015-2026 Ritense BV, the Netherlands.
|
|
13108
13164
|
*
|
|
@@ -13121,7 +13177,7 @@ function registerFormioFlatpickr() {
|
|
|
13121
13177
|
class FormIoMailPreviewComponent {
|
|
13122
13178
|
set value(v) {
|
|
13123
13179
|
this._value = v;
|
|
13124
|
-
this.safeValue = this.sanitizer.bypassSecurityTrustHtml(v ?? 'Hier wordt het e-mailvoorbeeld getoond.');
|
|
13180
|
+
this.safeValue = this.sanitizer.bypassSecurityTrustHtml(sanitizeEmailHtml(v ?? 'Hier wordt het e-mailvoorbeeld getoond.'));
|
|
13125
13181
|
}
|
|
13126
13182
|
get value() {
|
|
13127
13183
|
return this._value;
|