x4js 2.3.25 → 2.3.26
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/aicontext.md +46 -12
- package/package.json +1 -1
- package/src/components/autocomplete/autocomplete.ts +2 -2
- package/src/components/boxes/boxes.module.scss +16 -2
- package/src/components/boxes/boxes.ts +24 -11
- package/src/components/breadcrumb/breadcrumb.ts +1 -2
- package/src/components/btngroup/btngroup.ts +2 -2
- package/src/components/button/button.ts +2 -2
- package/src/components/calendar/calendar.ts +4 -2
- package/src/components/canvas/canvas.ts +1 -2
- package/src/components/chart/chart.ts +3 -3
- package/src/components/checkbox/checkbox.ts +2 -2
- package/src/components/colorinput/colorinput.ts +3 -2
- package/src/components/colorpicker/colorpicker.ts +5 -5
- package/src/components/combobox/combobox.ts +3 -3
- package/src/components/dialog/dialog.ts +2 -2
- package/src/components/dockingview/dockingview.ts +1 -2
- package/src/components/filedrop/filedrop.ts +3 -2
- package/src/components/form/form.ts +4 -3
- package/src/components/gauge/gauge.ts +2 -2
- package/src/components/gridview/gridview.module.scss +8 -5
- package/src/components/gridview/gridview.ts +11 -13
- package/src/components/header/header.ts +2 -2
- package/src/components/icon/icon.ts +1 -2
- package/src/components/image/image.ts +1 -2
- package/src/components/input/input.ts +3 -2
- package/src/components/keyboard/keyboard.ts +2 -2
- package/src/components/label/label.ts +3 -3
- package/src/components/link/link.ts +3 -2
- package/src/components/listbox/listbox.ts +2 -2
- package/src/components/menu/menu.ts +5 -4
- package/src/components/messages/messages.module.scss +29 -5
- package/src/components/messages/messages.ts +42 -50
- package/src/components/notification/notification.ts +3 -2
- package/src/components/panel/panel.ts +2 -2
- package/src/components/popup/popup.ts +2 -2
- package/src/components/progress/progress.ts +1 -2
- package/src/components/propgrid/progrid.module.scss +2 -3
- package/src/components/propgrid/propgrid.ts +2 -2
- package/src/components/radio/radio.ts +1 -2
- package/src/components/rating/rating.ts +2 -2
- package/src/components/select/select.ts +2 -2
- package/src/components/settingsview/settingsview.module.scss +6 -5
- package/src/components/settingsview/settingsview.ts +3 -3
- package/src/components/sizers/sizer.ts +21 -29
- package/src/components/slider/slider.ts +2 -2
- package/src/components/spreadsheet/spreadsheet.ts +8 -10
- package/src/components/switch/switch.ts +2 -2
- package/src/components/tabs/tabs.ts +4 -4
- package/src/components/tag/tag.ts +2 -2
- package/src/components/textarea/textarea.ts +3 -3
- package/src/components/textedit/textedit.ts +2 -2
- package/src/components/themes.scss +2 -0
- package/src/components/tickline/tickline.ts +3 -3
- package/src/components/tooltips/tooltips.ts +2 -2
- package/src/components/treeview/treeview.ts +3 -3
- package/src/components/video/video.ts +1 -2
- package/src/components/viewport/viewport.ts +4 -3
- package/src/core/component.ts +15 -24
- package/src/core/core_application.ts +29 -1
- package/src/core/core_i18n.ts +39 -0
- package/src/core/core_svg.ts +1 -0
- package/src/core/core_tools.ts +83 -24
package/src/core/component.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
|
-
import { isArray, UnsafeHtml, isNumber, Rect, Constructor
|
|
17
|
+
import { isArray, UnsafeHtml, isNumber, Rect, Constructor } from './core_tools';
|
|
18
18
|
import { CoreElement } from './core_element';
|
|
19
19
|
import { AriaAttributes, unitless } from './core_styles';
|
|
20
20
|
import { CoreEvent, EventMap } from './core_events';
|
|
@@ -31,17 +31,19 @@ const FRAGMENT = Symbol( "fragment" );
|
|
|
31
31
|
const RE_NUMBER = /^-?\d+(\.\d*)?$/;
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
*
|
|
34
|
+
* the css classes of a component: the name of each class of its chain, in lower case, after
|
|
35
|
+
* the prefix that class declares itself (not the one of its parent):
|
|
35
36
|
*
|
|
36
37
|
* ```
|
|
37
|
-
* static
|
|
38
|
+
* static classPrefix = "<your prefix>";
|
|
38
39
|
* ```
|
|
39
|
-
*
|
|
40
|
-
*
|
|
40
|
+
*
|
|
41
|
+
* every component of x4 declares "x4" (x4button...); the classes of an application have
|
|
42
|
+
* none unless they declare one
|
|
41
43
|
*/
|
|
42
44
|
|
|
43
45
|
function genClassNames( x: any ): string[] {
|
|
44
|
-
|
|
46
|
+
|
|
45
47
|
let self = Object.getPrototypeOf(x);
|
|
46
48
|
if( self.constructor==Component ) {
|
|
47
49
|
return ["x4-comp","x4"];
|
|
@@ -50,8 +52,8 @@ function genClassNames( x: any ): string[] {
|
|
|
50
52
|
const classes = [];
|
|
51
53
|
while (self && self.constructor !== Component ) {
|
|
52
54
|
const clsname:string = self.constructor.name;
|
|
53
|
-
const
|
|
54
|
-
classes.push(
|
|
55
|
+
const prefix: string = Object.prototype.hasOwnProperty.call(self.constructor,"classPrefix") ? self.constructor.classPrefix : "";
|
|
56
|
+
classes.push( prefix+clsname.toLowerCase() );
|
|
55
57
|
self = Object.getPrototypeOf(self);
|
|
56
58
|
}
|
|
57
59
|
|
|
@@ -156,9 +158,9 @@ export interface ComponentEvents extends EventMap {
|
|
|
156
158
|
* ```
|
|
157
159
|
*/
|
|
158
160
|
|
|
159
|
-
@class_ns("x4")
|
|
160
161
|
export class Component<P extends ComponentProps = ComponentProps, E extends ComponentEvents = ComponentEvents>
|
|
161
162
|
extends CoreElement<E> {
|
|
163
|
+
static classPrefix = "x4";
|
|
162
164
|
|
|
163
165
|
/** The underlying DOM element of the component. */
|
|
164
166
|
readonly dom: Element;
|
|
@@ -907,19 +909,6 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
|
|
|
907
909
|
this.setAttribute( "disabled", !ena ? 'true' : null );
|
|
908
910
|
this.setAttribute( "inert", !ena ? 'true' : null );
|
|
909
911
|
|
|
910
|
-
/*
|
|
911
|
-
boxes are now fieldset, this is native
|
|
912
|
-
if( this.dom instanceof HTMLInputElement || this.dom instanceof HTMLButtonElement ) {
|
|
913
|
-
this.dom.disabled = !ena;
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
// propagate enable state to all input children
|
|
917
|
-
const nodes = this.enumChildComponents( true );
|
|
918
|
-
nodes.forEach( x => {
|
|
919
|
-
x.enable( ena );
|
|
920
|
-
});
|
|
921
|
-
*/
|
|
922
|
-
|
|
923
912
|
return this;
|
|
924
913
|
}
|
|
925
914
|
|
|
@@ -1294,8 +1283,9 @@ export function wrapDOM( el: HTMLElement ): Component {
|
|
|
1294
1283
|
* Automatically generates CSS class: `x4flex`.
|
|
1295
1284
|
*/
|
|
1296
1285
|
|
|
1297
|
-
@class_ns( "x4" )
|
|
1298
1286
|
export class Flex extends Component {
|
|
1287
|
+
static classPrefix = "x4";
|
|
1288
|
+
|
|
1299
1289
|
constructor( ) {
|
|
1300
1290
|
super({})
|
|
1301
1291
|
}
|
|
@@ -1311,8 +1301,9 @@ export class Flex extends Component {
|
|
|
1311
1301
|
* ```
|
|
1312
1302
|
*/
|
|
1313
1303
|
|
|
1314
|
-
@class_ns( "x4" )
|
|
1315
1304
|
export class Space extends Component {
|
|
1305
|
+
static classPrefix = "x4";
|
|
1306
|
+
|
|
1316
1307
|
constructor( width?: number|string, cls?: string ) {
|
|
1317
1308
|
super( { width, cls } )
|
|
1318
1309
|
}
|
|
@@ -19,6 +19,7 @@ import { CoreElement } from './core_element';
|
|
|
19
19
|
import { CoreEvent, EventMap } from './core_events';
|
|
20
20
|
import { asap, getFocusableElements, ITabHandler } from './core_tools';
|
|
21
21
|
import { Shortcuts, ShortcutCallback, ShortcutOptions } from './core_shortcuts';
|
|
22
|
+
import { _setLocale, getCurrentLocale, getCurrentCurrency } from './core_i18n';
|
|
22
23
|
|
|
23
24
|
const socket_sent = Symbol( 'socket' );
|
|
24
25
|
|
|
@@ -249,7 +250,34 @@ export class Application<E extends ApplicationEvents = ApplicationEvents> extend
|
|
|
249
250
|
}
|
|
250
251
|
|
|
251
252
|
/**
|
|
252
|
-
*
|
|
253
|
+
* Forces the locale of the formats of numbers, amounts and dates (formatNumber, formatMoney,
|
|
254
|
+
* formatDate, formatDateTime), and the currency of the amounts. Without it, the locale is the one of the language (`_tr.global.locale`: "fr-FR"
|
|
255
|
+
* for fr, "en-US" for en...) and the currency "EUR".
|
|
256
|
+
* A field of type number is shown by the browser, in its own locale, whatever this one.
|
|
257
|
+
* @param locale - "fr-CH", "en-GB"...; null: the one of the language again
|
|
258
|
+
* @param currency - "CHF", "USD"...; not given: the currency does not change
|
|
259
|
+
* @example
|
|
260
|
+
* Application.setLocale( "fr-CH", "CHF" );
|
|
261
|
+
*/
|
|
262
|
+
|
|
263
|
+
static setLocale( locale: string, currency?: string ) {
|
|
264
|
+
_setLocale( locale, currency );
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/** The locale of the formats: the one forced by setLocale, else the one of the language. */
|
|
268
|
+
|
|
269
|
+
static getLocale( ): string {
|
|
270
|
+
return getCurrentLocale( );
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/** The currency of the amounts: "EUR" unless setLocale gave another. */
|
|
274
|
+
|
|
275
|
+
static getCurrency( ): string {
|
|
276
|
+
return getCurrentCurrency( );
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
*
|
|
253
281
|
*/
|
|
254
282
|
|
|
255
283
|
private _setupKeyboard( ) {
|
package/src/core/core_i18n.ts
CHANGED
|
@@ -255,6 +255,41 @@ export function getCurrentLanguage( ): string {
|
|
|
255
255
|
return current.name;
|
|
256
256
|
}
|
|
257
257
|
|
|
258
|
+
// :: LOCALE ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
259
|
+
|
|
260
|
+
// the formats of numbers, amounts and dates: the locale of the language (_tr.global.locale),
|
|
261
|
+
// unless one is forced (Application.setLocale); the currency of the amounts
|
|
262
|
+
let forced_locale: string = null;
|
|
263
|
+
let currency = "EUR";
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* @internal the locale forced (null: the one of the language), the currency when given
|
|
267
|
+
*/
|
|
268
|
+
|
|
269
|
+
export function _setLocale( locale: string, cur?: string ) {
|
|
270
|
+
forced_locale = locale || null;
|
|
271
|
+
if( cur ) {
|
|
272
|
+
currency = cur;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* the locale of the formats: the one forced by Application.setLocale, else the one of the
|
|
278
|
+
* language ("fr-FR" for fr)
|
|
279
|
+
*/
|
|
280
|
+
|
|
281
|
+
export function getCurrentLocale( ): string {
|
|
282
|
+
return forced_locale ?? _tr.global.locale ?? "fr-FR";
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* the currency of the amounts: "EUR" unless Application.setLocale gave another
|
|
287
|
+
*/
|
|
288
|
+
|
|
289
|
+
export function getCurrentCurrency( ): string {
|
|
290
|
+
return currency;
|
|
291
|
+
}
|
|
292
|
+
|
|
258
293
|
/**
|
|
259
294
|
*
|
|
260
295
|
*/
|
|
@@ -308,6 +343,7 @@ let fr = {
|
|
|
308
343
|
date_input_formats: 'd/m/y|d.m.y|d m y|d-m-y|dmy',
|
|
309
344
|
date_format: 'D/M/Y',
|
|
310
345
|
date_time_format: 'D/M/Y H:I:S',
|
|
346
|
+
locale: 'fr-FR', // the formats of numbers, amounts, dates (Intl)
|
|
311
347
|
|
|
312
348
|
day_short: [ 'dim', 'lun', 'mar', 'mer', 'jeu', 'ven', 'sam' ],
|
|
313
349
|
day_long: [ 'dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi' ],
|
|
@@ -385,6 +421,7 @@ let en = {
|
|
|
385
421
|
date_input_formats: 'm/d/y|m.d.y|m d y|m-d-y|mdy',
|
|
386
422
|
date_format: 'M/D/Y',
|
|
387
423
|
date_time_format: 'M/D/Y H:I:S',
|
|
424
|
+
locale: 'en-US', // the formats of numbers, amounts, dates (Intl)
|
|
388
425
|
|
|
389
426
|
day_short: [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ],
|
|
390
427
|
day_long: [ 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday' ],
|
|
@@ -462,6 +499,7 @@ let es = {
|
|
|
462
499
|
date_input_formats: 'd/m/y|d.m.y|d m y|d-m-y|dmy',
|
|
463
500
|
date_format: 'D/M/Y',
|
|
464
501
|
date_time_format: 'D/M/Y H:I:S',
|
|
502
|
+
locale: 'es-ES', // the formats of numbers, amounts, dates (Intl)
|
|
465
503
|
|
|
466
504
|
day_short: [ 'dom', 'lun', 'mar', 'mié', 'jue', 'vie', 'sáb' ],
|
|
467
505
|
day_long: [ 'domingo', 'lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado' ],
|
|
@@ -539,6 +577,7 @@ let de = {
|
|
|
539
577
|
date_input_formats: 'd.m.y|d/m/y|d m y|d-m-y|dmy',
|
|
540
578
|
date_format: 'D.M.Y',
|
|
541
579
|
date_time_format: 'D.M.Y H:I:S',
|
|
580
|
+
locale: 'de-DE', // the formats of numbers, amounts, dates (Intl)
|
|
542
581
|
|
|
543
582
|
day_short: [ 'So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa' ],
|
|
544
583
|
day_long: [ 'Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag' ],
|
package/src/core/core_svg.ts
CHANGED
|
@@ -1013,6 +1013,7 @@ export interface SvgProps extends ComponentProps {
|
|
|
1013
1013
|
*/
|
|
1014
1014
|
|
|
1015
1015
|
export class SvgComponent<P extends SvgProps = SvgProps, E extends ComponentEvents = ComponentEvents> extends Component<P,E> {
|
|
1016
|
+
static classPrefix = "x4";
|
|
1016
1017
|
|
|
1017
1018
|
/**
|
|
1018
1019
|
* Creates an instance of `SvgComponent`.
|
package/src/core/core_tools.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
|
-
import { _tr } from "./core_i18n.js";
|
|
17
|
+
import { _tr, _setLocale, getCurrentLocale, getCurrentCurrency } from "./core_i18n.js";
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
// todo: split into 2 files
|
|
@@ -528,33 +528,103 @@ export function camelCase(text: string) {
|
|
|
528
528
|
|
|
529
529
|
// :: DATES ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
530
530
|
|
|
531
|
-
let cur_locale: string = 'fr-FR';
|
|
532
|
-
|
|
533
531
|
/**
|
|
534
|
-
*
|
|
535
|
-
* @param locale
|
|
536
|
-
* TODO: ????
|
|
532
|
+
* forces the locale of the formats (see Application.setLocale)
|
|
533
|
+
* @param locale
|
|
537
534
|
*/
|
|
538
535
|
|
|
539
536
|
export function _date_set_locale(locale: string) {
|
|
540
|
-
|
|
537
|
+
_setLocale( locale );
|
|
541
538
|
}
|
|
542
539
|
|
|
543
540
|
/**
|
|
544
|
-
*
|
|
545
|
-
*
|
|
546
|
-
* @param
|
|
541
|
+
* a date as text: with options, the ones of Intl.DateTimeFormat in the current locale;
|
|
542
|
+
* without, the format of the language (_tr.global.date_format)
|
|
543
|
+
* @param date
|
|
544
|
+
* @param options
|
|
547
545
|
* @example
|
|
548
546
|
* let date = new Date( );
|
|
549
|
-
* let options = { day: 'numeric', month: '
|
|
547
|
+
* let options = { day: 'numeric', month: 'long', year: 'numeric' };
|
|
550
548
|
* let text = date_format( date, options );
|
|
551
549
|
*/
|
|
552
550
|
|
|
553
|
-
export function date_format(date: Date, options?:
|
|
554
|
-
|
|
551
|
+
export function date_format(date: Date, options?: Intl.DateTimeFormatOptions): string {
|
|
552
|
+
if( options ) {
|
|
553
|
+
return new Intl.DateTimeFormat( getCurrentLocale( ), options ).format( date );
|
|
554
|
+
}
|
|
555
|
+
|
|
555
556
|
return formatIntlDate(date);
|
|
556
557
|
}
|
|
557
558
|
|
|
559
|
+
// :: FORMATS ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
560
|
+
|
|
561
|
+
// numbers, amounts and dates in the current locale (the one of the language, or the one
|
|
562
|
+
// Application.setLocale forced): the objects of Intl, made once by locale and options
|
|
563
|
+
const intl_formats = new Map<string, Intl.NumberFormat | Intl.DateTimeFormat>( );
|
|
564
|
+
|
|
565
|
+
function numberFormat( key: string, options: Intl.NumberFormatOptions ) {
|
|
566
|
+
const locale = getCurrentLocale( );
|
|
567
|
+
const id = locale + "|" + key;
|
|
568
|
+
let fmt = intl_formats.get( id ) as Intl.NumberFormat;
|
|
569
|
+
if( !fmt ) {
|
|
570
|
+
fmt = new Intl.NumberFormat( locale, options );
|
|
571
|
+
intl_formats.set( id, fmt );
|
|
572
|
+
}
|
|
573
|
+
return fmt;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
function dateFormat( key: string, options: Intl.DateTimeFormatOptions ) {
|
|
577
|
+
const locale = getCurrentLocale( );
|
|
578
|
+
const id = locale + "|" + key;
|
|
579
|
+
let fmt = intl_formats.get( id ) as Intl.DateTimeFormat;
|
|
580
|
+
if( !fmt ) {
|
|
581
|
+
fmt = new Intl.DateTimeFormat( locale, options );
|
|
582
|
+
intl_formats.set( id, fmt );
|
|
583
|
+
}
|
|
584
|
+
return fmt;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* a number as text in the current locale: "1 234,5" in fr-FR, "1,234.5" in en-US
|
|
589
|
+
* @param value
|
|
590
|
+
* @param decimals - the most decimals shown (Intl: 3 when not given)
|
|
591
|
+
* @param grouping - the separator of thousands, true by default
|
|
592
|
+
*/
|
|
593
|
+
|
|
594
|
+
export function formatNumber( value: number, decimals?: number, grouping = true ): string {
|
|
595
|
+
const options: Intl.NumberFormatOptions = { useGrouping: grouping };
|
|
596
|
+
if( decimals!==undefined ) {
|
|
597
|
+
options.maximumFractionDigits = decimals;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
return numberFormat( "n" + decimals + grouping, options ).format( value );
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* an amount as text in the current locale and currency: "1 234,50 €" in fr-FR
|
|
605
|
+
*/
|
|
606
|
+
|
|
607
|
+
export function formatMoney( value: number ): string {
|
|
608
|
+
const currency = getCurrentCurrency( );
|
|
609
|
+
return numberFormat( "m" + currency, { style: "currency", currency } ).format( value );
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* a date as text in the current locale: "22/10/2026" in fr-FR, "10/22/2026" in en-US
|
|
614
|
+
*/
|
|
615
|
+
|
|
616
|
+
export function formatDate( date: Date ): string {
|
|
617
|
+
return dateFormat( "d", { } ).format( date );
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* a date and its time (hours, minutes) as text in the current locale: "22/10/2026 14:05" in fr-FR
|
|
622
|
+
*/
|
|
623
|
+
|
|
624
|
+
export function formatDateTime( date: Date ): string {
|
|
625
|
+
return dateFormat( "dt", { day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit" } ).format( date );
|
|
626
|
+
}
|
|
627
|
+
|
|
558
628
|
/**
|
|
559
629
|
* difference between 2 dates
|
|
560
630
|
* @return text
|
|
@@ -1002,17 +1072,6 @@ export function getSystemMetrics( part: "scrollbar" | "zoom" ) {
|
|
|
1002
1072
|
|
|
1003
1073
|
|
|
1004
1074
|
|
|
1005
|
-
/**
|
|
1006
|
-
*
|
|
1007
|
-
*/
|
|
1008
|
-
|
|
1009
|
-
export const x4_class_ns_sym = Symbol("class-ns");
|
|
1010
|
-
export function class_ns(ns: string) {
|
|
1011
|
-
return function (constructor: Function) {
|
|
1012
|
-
(constructor as any)[x4_class_ns_sym] = ns;
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
1075
|
/**
|
|
1017
1076
|
*
|
|
1018
1077
|
*/
|