x4js 2.3.25 → 2.3.27
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 +87 -13
- package/package.json +1 -1
- package/src/components/autocomplete/autocomplete.ts +3 -3
- 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 +5 -3
- package/src/components/canvas/canvas.ts +1 -2
- package/src/components/chart/chart.ts +4 -4
- 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/components.ts +1 -0
- package/src/components/dialog/dialog.ts +2 -2
- package/src/components/dockingview/dockingview.ts +2 -3
- 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 +33 -47
- 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/monaco/monaco.ts +1 -2
- package/src/components/notification/notification.ts +3 -2
- package/src/components/panel/panel.ts +2 -2
- package/src/components/popup/popup.ts +4 -4
- 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 +3 -3
- 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/timeline/timeline.module.scss +147 -0
- package/src/components/timeline/timeline.ts +146 -0
- package/src/components/tooltips/tooltips.ts +2 -2
- package/src/components/treeview/treeview.ts +19 -25
- package/src/components/video/video.ts +1 -2
- package/src/components/viewport/viewport.ts +4 -3
- package/src/core/component.ts +46 -26
- package/src/core/core_application.ts +29 -1
- package/src/core/core_i18n.ts +39 -0
- package/src/core/core_shortcuts.ts +2 -1
- package/src/core/core_svg.ts +1 -0
- package/src/core/core_tools.ts +83 -24
package/aicontext.md
CHANGED
|
@@ -36,7 +36,7 @@ CoreElement<E> named timers + event surface (no DOM)
|
|
|
36
36
|
│ │ ├── BtnGroup, Tabs, Video, Saturation
|
|
37
37
|
│ ├── Button, Input, Icon, Label, SimpleText, Checkbox, Radio, Link, SimpleTextArea
|
|
38
38
|
│ ├── Listbox, Gridview, Treeview, Select, Combobox, Slider, Gauge
|
|
39
|
-
│ ├── Progress, TickLine, Canvas, Image, Spreadsheet, MonacoEditor
|
|
39
|
+
│ ├── Progress, TickLine, Timeline, Canvas, Image, Spreadsheet, MonacoEditor
|
|
40
40
|
│ ├── SvgComponent → Chart
|
|
41
41
|
│ ├── CSizer → HSizer / VSizer
|
|
42
42
|
│ ├── FileDialog, ScrollView, Viewport, DockingView, Flex, Space
|
|
@@ -169,6 +169,15 @@ toggleClass(cls: string): void
|
|
|
169
169
|
setClass(cls: string, set?: boolean): this
|
|
170
170
|
```
|
|
171
171
|
|
|
172
|
+
A component gets one class for each class of its chain: its name in lower case, after the prefix that class
|
|
173
|
+
declares itself with `static classPrefix` (not the one of its parent), then `x4`. Every component of x4 declares
|
|
174
|
+
`static classPrefix = "x4"` (a Button: `x4button x4`); a class of the application declares its own, or none.
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
class Avatar extends Image { static classPrefix = "my"; } // classes: myavatar x4image x4
|
|
178
|
+
class Badge extends Label { } // classes: badge x4label x4
|
|
179
|
+
```
|
|
180
|
+
|
|
172
181
|
### HTML attributes & ARIA
|
|
173
182
|
|
|
174
183
|
```ts
|
|
@@ -218,12 +227,16 @@ queryAll(selector: string): Component[]
|
|
|
218
227
|
firstChild<T>(): T; lastChild<T>(): T
|
|
219
228
|
nextElement<T>(): T; prevElement<T>(): T
|
|
220
229
|
parentElement<T>(cls?: Constructor<T>): T
|
|
230
|
+
closest<T>(selector: string): T // this one or an ancestor whose element matches the css selector; null if none
|
|
231
|
+
contains(other: Component | Node): boolean // other (a node, or the element of a component) is the element of this one or inside it
|
|
221
232
|
childCount(): number
|
|
222
233
|
enumChildComponents(recursive: boolean): Component[]
|
|
223
234
|
enumChildNodes(recursive: boolean): Node[]
|
|
224
235
|
visitChildren(cb: (el: Component) => boolean): void
|
|
225
236
|
static parentElement<T>(dom: Node, cls?: Constructor<T>): T // starts at the parent of dom, not at dom:
|
|
226
237
|
// test componentFromDOM(dom) first for the component of dom itself
|
|
238
|
+
static closest<T>(dom: Element, selector: string): T // starts at dom itself: in a click handler,
|
|
239
|
+
// Component.closest(ev.target as Element, '.item')
|
|
227
240
|
```
|
|
228
241
|
|
|
229
242
|
### Visibility / state / focus / geometry
|
|
@@ -291,6 +304,11 @@ static fireGlobal(msg: string, params?: any): void
|
|
|
291
304
|
static setTheme(name: string): void // the class x4theme-<name> on <html>: "" the light theme (default, no class),
|
|
292
305
|
// "dark" the dark theme of x4, another name a theme of the application
|
|
293
306
|
static getTheme(): string // "" for the light theme, "dark", or the name given to setTheme
|
|
307
|
+
static setLocale(locale: string, currency?: string): void // forces the locale of the formats (formatNumber, formatMoney,
|
|
308
|
+
// formatDate, formatDateTime) over the one of the language; null: the language's
|
|
309
|
+
// again. currency: "EUR" by default, kept when not given
|
|
310
|
+
static getLocale(): string // the forced one, else _tr.global.locale ("fr-FR" for fr, "en-US" for en)
|
|
311
|
+
static getCurrency(): string
|
|
294
312
|
focusNext(next: boolean): boolean
|
|
295
313
|
addShortcut(keys: string | string[], callback: (ev: KeyboardEvent) => void, options?: ShortcutOptions): void // see Shortcuts
|
|
296
314
|
setupSocketMessaging(path?: string, looseCallback?: () => void): void
|
|
@@ -313,6 +331,9 @@ class VBox<P, E> extends Box<P, E>
|
|
|
313
331
|
interface BoxProps extends ComponentProps { tag?: string }
|
|
314
332
|
```
|
|
315
333
|
|
|
334
|
+
A Box is a `<div>` (another element with `tag`). Disabled (`disable()`, the prop `disabled`), its content is inert
|
|
335
|
+
(no click, no focus, no input) and faded by `--box-disabled-opacity` (0.5); a disabled Box in it is not faded twice.
|
|
336
|
+
|
|
316
337
|
### `Box.refs` — typed directory of the children to reach again later
|
|
317
338
|
|
|
318
339
|
Only a `Box` has `refs`: a class derived from `Component` (not from `Box`) has none, and `this.refs.x = ...` there
|
|
@@ -597,6 +618,41 @@ class Rating extends HBox {
|
|
|
597
618
|
}
|
|
598
619
|
```
|
|
599
620
|
|
|
621
|
+
### `Timeline` — events on a line, each with its icon in a round mark
|
|
622
|
+
|
|
623
|
+
```ts
|
|
624
|
+
interface TimelineItem {
|
|
625
|
+
icon?: string // in the round mark
|
|
626
|
+
title: string | UnsafeHtml // in bold
|
|
627
|
+
text?: string | UnsafeHtml // the sentence under it, in grey
|
|
628
|
+
date?: Date // written relative to now, in the locale: "il y a 2 heures", "yesterday"; none: no time shown
|
|
629
|
+
done?: boolean // the mark in the accent; else a grey mark
|
|
630
|
+
}
|
|
631
|
+
interface TimelineProps extends ComponentProps {
|
|
632
|
+
items?: TimelineItem[]
|
|
633
|
+
vertical?: boolean // true by default; false: the events side by side
|
|
634
|
+
renderer?: (item: TimelineItem) => Component // what is beside the mark (the mark and the line stay)
|
|
635
|
+
click?: EventCallback<EvClick> // a click anywhere in an event: ev.context is its TimelineItem
|
|
636
|
+
}
|
|
637
|
+
interface TimelineEvents extends ComponentEvents { click: EvClick }
|
|
638
|
+
class Timeline extends Component<TimelineProps, TimelineEvents> {
|
|
639
|
+
setItems(items: TimelineItem[]): void // the relative times are written here, not updated after
|
|
640
|
+
}
|
|
641
|
+
// the line to the next mark: in the accent when the next event is done, dashed after an event not done
|
|
642
|
+
// CSS vars: --timeline-done-color --timeline-done-icon-color --timeline-todo-color --timeline-todo-icon-color
|
|
643
|
+
// --timeline-title-color --timeline-text-color --timeline-time-color
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
```ts
|
|
647
|
+
new Timeline({
|
|
648
|
+
items: [
|
|
649
|
+
{ icon: branch, title: 'New branch', text: 'fix-notifications, from master', date: created, done: true },
|
|
650
|
+
{ icon: review, title: 'Code review', text: 'Waiting for a reviewer' },
|
|
651
|
+
],
|
|
652
|
+
click: ev => this.openStep(ev.context as TimelineItem),
|
|
653
|
+
})
|
|
654
|
+
```
|
|
655
|
+
|
|
600
656
|
---
|
|
601
657
|
|
|
602
658
|
## Input components
|
|
@@ -1150,8 +1206,9 @@ class PromptBox extends Dialog {
|
|
|
1150
1206
|
class ProgressionBox extends Dialog {
|
|
1151
1207
|
constructor(title: string)
|
|
1152
1208
|
addText(text: string|UnsafeHtml, perc: number): void
|
|
1153
|
-
addError(text: string|UnsafeHtml, perc: number): void //
|
|
1154
|
-
|
|
1209
|
+
addError(text: string|UnsafeHtml, perc: number): void // red, on a light red line, a red bar on its left;
|
|
1210
|
+
// the title bar in red until clear()
|
|
1211
|
+
addWarning(text: string|UnsafeHtml, perc: number): void // the same in orange
|
|
1155
1212
|
addSection(title: string|UnsafeHtml, perc: number): void // a section (<details>, open): the lines that follow go
|
|
1156
1213
|
// in it; a click on its title folds it; its title has the icon
|
|
1157
1214
|
// of the worst of its lines. Without any, the lines go in the log
|
|
@@ -1162,10 +1219,11 @@ class ProgressionBox extends Dialog {
|
|
|
1162
1219
|
// from _tr.global.progression), the icon of the worst;
|
|
1163
1220
|
// else it counts "OK (5s)" and closes the box at 0
|
|
1164
1221
|
}
|
|
1165
|
-
// ProgressionBox: its lines in a <pre
|
|
1222
|
+
// ProgressionBox: its lines in a <pre> in a fixed font, a <div> each (class "line", plus "error" or "warning"),
|
|
1223
|
+
// 10 lines high, scrolled both ways (the box keeps its size), every line as wide as the longest one;
|
|
1166
1224
|
// a string is text, an UnsafeHtml html. Ctrl+A in the lines selects them only (a folded section too).
|
|
1167
|
-
// Colours: --msgbox-log-background, -border, -border-focus, -error-color, -
|
|
1168
|
-
// -scrollbar (the thumb of its scroll bars; their track is its background).
|
|
1225
|
+
// Colours: --msgbox-log-background, -border, -border-focus, -error-color, -error-background,
|
|
1226
|
+
// -warning-color, -warning-background, -scrollbar (the thumb of its scroll bars; their track is its background).
|
|
1169
1227
|
```
|
|
1170
1228
|
|
|
1171
1229
|
### `Notification`
|
|
@@ -1188,7 +1246,8 @@ class Notification extends Popup { display(time_in_s?: number): void } // 0: u
|
|
|
1188
1246
|
```ts
|
|
1189
1247
|
type FormValues = Record<string, any>
|
|
1190
1248
|
interface FormProps extends BoxProps { autoComplete?: boolean }
|
|
1191
|
-
class Form extends Box {
|
|
1249
|
+
class Form<P extends FormProps = FormProps, E extends ComponentEvents = ComponentEvents> extends Box<P, E> {
|
|
1250
|
+
// a class derived from Form declares its events: class EntryForm extends Form<EntryProps, EntryEvents>
|
|
1192
1251
|
setValues(values: FormValues): void
|
|
1193
1252
|
getValues<T extends FormValues>(): T
|
|
1194
1253
|
setAutoComplete(on?: boolean): void // attribute on the <form>: fields without their own follow it, added later too
|
|
@@ -1285,9 +1344,11 @@ class VSplitBox extends VBox // panels stacked, resizable height:
|
|
|
1285
1344
|
// new HSplitBox( { content: [ new Treeview( { width: 250 } ), new Panel( { flex: 1 } ) ] } )
|
|
1286
1345
|
|
|
1287
1346
|
// Low level: only place sizers by hand when a SplitBox does not fit (popup edges, header cells...).
|
|
1288
|
-
class CSizer extends Component // base splitter
|
|
1347
|
+
class CSizer extends Component // base splitter; events start, resize { size, width, height }, stop
|
|
1289
1348
|
class HSizer extends CSizer // horizontal splitter
|
|
1290
1349
|
class VSizer extends CSizer // vertical splitter
|
|
1350
|
+
// A pointercancel (a touch taken by the browser) ends the resize as a pointerup does: stop is fired.
|
|
1351
|
+
// The columns of a Gridview or a Spreadsheet are 16px wide at least (the min-width of a cell).
|
|
1291
1352
|
class ScrollView extends Component { getViewport(): Component }
|
|
1292
1353
|
class Viewport extends Component
|
|
1293
1354
|
class Canvas extends Component { getContext(): CanvasRenderingContext2D; paint(): void }
|
|
@@ -1431,6 +1492,7 @@ component.addShortcut(keys, callback, options?) // a view: while the foc
|
|
|
1431
1492
|
Application.instance().addShortcut(keys, callback, options?) // the whole application, wherever the focus is
|
|
1432
1493
|
|
|
1433
1494
|
shortcutText(keys: string): string // for a tooltip or a menu: "Ctrl+Z", "⌘Z" on a Mac
|
|
1495
|
+
isMac: boolean // true on a Mac, an iPhone or an iPad: Mod is Cmd there
|
|
1434
1496
|
|
|
1435
1497
|
class Shortcuts { // the list itself; rarely used directly
|
|
1436
1498
|
add(keys: string | string[], callback: (ev: KeyboardEvent) => void, options?: ShortcutOptions): void
|
|
@@ -1552,10 +1614,18 @@ isLanguage(name: string): boolean
|
|
|
1552
1614
|
// search search_tip required_field invalid_format invalid_email invalid_number invalid_date
|
|
1553
1615
|
// empty_list err_403 property value copy cut paste filedrop
|
|
1554
1616
|
// diff_date_seconds/minutes/hours, date_input_formats, date_format, date_time_format,
|
|
1617
|
+
// locale ("fr-FR", "en-US", "es-ES", "de-DE": the formats of numbers, amounts, dates),
|
|
1555
1618
|
// day_short[] day_long[] month_short[] month_long[], keyboard.{next,numeric,alpha},
|
|
1556
|
-
// settings.{search,nomatch}
|
|
1619
|
+
// settings.{search,nomatch}, progression.{error,errors,warning,warnings}
|
|
1620
|
+
getCurrentLocale(): string; getCurrentCurrency(): string // as Application.getLocale / getCurrency
|
|
1557
1621
|
```
|
|
1558
1622
|
|
|
1623
|
+
The language gives the texts and the locale of the formats: `selectLanguage("en")` changes both. A regional
|
|
1624
|
+
variant is a language based on another: `createLanguage("fr-ch", "fr")`, `addTranslation("fr-ch", { global: { locale: "fr-CH" } })`.
|
|
1625
|
+
`Application.setLocale(locale, currency)` forces the locale over the language's. The fields of date and the
|
|
1626
|
+
Calendar follow the patterns of the language (`date_format`...), not the locale. A field of type number is shown
|
|
1627
|
+
by the browser, in its own locale, whatever this one.
|
|
1628
|
+
|
|
1559
1629
|
---
|
|
1560
1630
|
|
|
1561
1631
|
## Theme (`themes.scss`)
|
|
@@ -1629,7 +1699,14 @@ pascalCase(s): string; camelCase(s): string; clamp<T>(v, min, max): T
|
|
|
1629
1699
|
measureText(str, size, bold?): number // width in Helvetica, from core_pdf (see PDF)
|
|
1630
1700
|
|
|
1631
1701
|
// Dates
|
|
1632
|
-
date_format(date, options?): string // options
|
|
1702
|
+
date_format(date, options?): string // options: Intl.DateTimeFormat in the locale; without: formatIntlDate(date)
|
|
1703
|
+
|
|
1704
|
+
// Formats in the current locale (Application.setLocale, else the one of the language), Intl made once by locale
|
|
1705
|
+
formatNumber(value, decimals?, grouping = true): string // "1 234,5" in fr-FR; decimals: the most shown
|
|
1706
|
+
formatMoney(value): string // "1 234,50 €": the currency of Application.getCurrency()
|
|
1707
|
+
formatDate(date): string // "22/10/2026"
|
|
1708
|
+
formatDateTime(date): string // "22/10/2026 14:05"
|
|
1709
|
+
// Gridview and Spreadsheet format their columns number, money, date, date-time with them (a formatter comes first)
|
|
1633
1710
|
date_diff(date1, date2, options?): string // "30 secondes", "5 minutes", "2 heures 5 minutes" (either order); options not read
|
|
1634
1711
|
date_to_sql(date, withHours): string; date_sql_utc(date): Date
|
|
1635
1712
|
date_hash(date): number; date_clone(date): Date
|
|
@@ -1648,9 +1725,6 @@ getSystemMetrics(part: "scrollbar"|"zoom"): number
|
|
|
1648
1725
|
setWaitCursor(wait: boolean): void; beep(): void
|
|
1649
1726
|
isUnitLess(name): boolean; isFeatureAvailable(name: "eyedropper"): boolean
|
|
1650
1727
|
|
|
1651
|
-
// Class decorator
|
|
1652
|
-
class_ns(ns: string): ClassDecorator
|
|
1653
|
-
const x4_class_ns_sym: symbol
|
|
1654
1728
|
const unitless // set of unitless CSS props
|
|
1655
1729
|
|
|
1656
1730
|
// System interfaces
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { Component, ComponentEvent, ComponentEvents, EvChange } from '../../core/component';
|
|
18
18
|
import { EventCallback } from '../../core/core_events';
|
|
19
|
-
import {
|
|
19
|
+
import { kbNav } from '../../core/core_tools';
|
|
20
20
|
|
|
21
21
|
import { HBox } from '../boxes/boxes';
|
|
22
22
|
import { DropdownList } from '../combobox/combobox';
|
|
@@ -96,8 +96,8 @@ const render_id_item = ( item: ListItem ) => {
|
|
|
96
96
|
* })
|
|
97
97
|
*/
|
|
98
98
|
|
|
99
|
-
@class_ns( "x4" )
|
|
100
99
|
export class AutoComplete extends TextEdit<AutoCompleteEvents> {
|
|
100
|
+
static classPrefix = "x4";
|
|
101
101
|
|
|
102
102
|
private _popup: DropdownList;
|
|
103
103
|
|
|
@@ -268,7 +268,7 @@ export class AutoComplete extends TextEdit<AutoCompleteEvents> {
|
|
|
268
268
|
private _on_focusout( ev: FocusEvent ) {
|
|
269
269
|
// focus is moving inside the control
|
|
270
270
|
const to = ev.relatedTarget as Node;
|
|
271
|
-
if( to && this.
|
|
271
|
+
if( to && this.contains( to ) ) {
|
|
272
272
|
return;
|
|
273
273
|
}
|
|
274
274
|
|
|
@@ -16,16 +16,30 @@
|
|
|
16
16
|
|
|
17
17
|
@use "../shared.scss";
|
|
18
18
|
|
|
19
|
+
:root {
|
|
20
|
+
--box-disabled-opacity: 0.5; // a disabled Box: its content faded
|
|
21
|
+
}
|
|
22
|
+
|
|
19
23
|
.x4box {
|
|
20
|
-
// reset fieldset
|
|
24
|
+
// reset a box built with tag: "fieldset"
|
|
21
25
|
margin: 0;
|
|
22
|
-
padding: 0;
|
|
26
|
+
padding: 0;
|
|
23
27
|
border: none;
|
|
24
28
|
|
|
25
29
|
min-width: 0;
|
|
26
30
|
min-height: 0;
|
|
27
31
|
flex-shrink: 0;
|
|
28
32
|
align-self: stretch;
|
|
33
|
+
|
|
34
|
+
// disabled: its content inert (enable) and faded
|
|
35
|
+
&[disabled] {
|
|
36
|
+
opacity: var( --box-disabled-opacity );
|
|
37
|
+
|
|
38
|
+
// a disabled Box in a disabled Box: opacity 1 for it, so faded once, not twice
|
|
39
|
+
.x4box[disabled] {
|
|
40
|
+
opacity: 1;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
29
43
|
}
|
|
30
44
|
|
|
31
45
|
.x4hbox {
|
|
@@ -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 { asap,
|
|
17
|
+
import { asap, isArray, isNumber } from '../../core/core_tools';
|
|
18
18
|
import { Component, ComponentEvents, ComponentProps, EvSelectionChange } from "../../core/component"
|
|
19
19
|
import { EventCallback } from '../../core/core_events';
|
|
20
20
|
import { HSizer, VSizer } from '../sizers/sizer';
|
|
@@ -28,6 +28,14 @@ export interface BoxProps extends ComponentProps {
|
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* A generic container component for grouping and laying out child components.
|
|
31
|
+
*
|
|
32
|
+
* A <div>. Disabled (disable( ), the prop disabled), its content is inert (no click, no
|
|
33
|
+
* focus, no input) and faded by --box-disabled-opacity.
|
|
34
|
+
*
|
|
35
|
+
* @cssvar
|
|
36
|
+
* ```
|
|
37
|
+
* --box-disabled-opacity
|
|
38
|
+
* ```
|
|
31
39
|
*
|
|
32
40
|
* The `refs` object is a typed directory of the children you need to reach
|
|
33
41
|
* again later. Assign a child to `refs` as you build the content: the
|
|
@@ -60,11 +68,12 @@ export interface BoxProps extends ComponentProps {
|
|
|
60
68
|
*
|
|
61
69
|
*/
|
|
62
70
|
|
|
63
|
-
@class_ns( "x4" )
|
|
64
71
|
export class Box<P extends BoxProps=BoxProps,E extends ComponentEvents=ComponentEvents> extends Component<P,E> {
|
|
72
|
+
static classPrefix = "x4";
|
|
73
|
+
|
|
65
74
|
protected refs: Record<string,Component> = {};
|
|
66
75
|
constructor( props: P ) {
|
|
67
|
-
super( { tag: "
|
|
76
|
+
super( { tag: "div", ...props } );
|
|
68
77
|
}
|
|
69
78
|
}
|
|
70
79
|
|
|
@@ -74,8 +83,9 @@ export class Box<P extends BoxProps=BoxProps,E extends ComponentEvents=Component
|
|
|
74
83
|
* Arranges child components in a horizontal line.
|
|
75
84
|
*/
|
|
76
85
|
|
|
77
|
-
@class_ns( "x4" )
|
|
78
86
|
export class HBox<P extends BoxProps=BoxProps,E extends ComponentEvents=ComponentEvents> extends Box<P,E> {
|
|
87
|
+
static classPrefix = "x4";
|
|
88
|
+
|
|
79
89
|
}
|
|
80
90
|
|
|
81
91
|
/**
|
|
@@ -84,8 +94,9 @@ export class HBox<P extends BoxProps=BoxProps,E extends ComponentEvents=Componen
|
|
|
84
94
|
* The CSS class for this component is automatically generated as `x4vbox`.
|
|
85
95
|
*/
|
|
86
96
|
|
|
87
|
-
@class_ns( "x4" )
|
|
88
97
|
export class VBox<P extends BoxProps=BoxProps,E extends ComponentEvents=ComponentEvents> extends Box<P,E> {
|
|
98
|
+
static classPrefix = "x4";
|
|
99
|
+
|
|
89
100
|
constructor( p: P ) {
|
|
90
101
|
super( p );
|
|
91
102
|
}
|
|
@@ -136,8 +147,9 @@ function split_content( panels: Component[], horz: boolean ) {
|
|
|
136
147
|
* })
|
|
137
148
|
*/
|
|
138
149
|
|
|
139
|
-
@class_ns( "x4" )
|
|
140
150
|
export class HSplitBox<P extends SplitBoxProps=SplitBoxProps,E extends ComponentEvents=ComponentEvents> extends HBox<P,E> {
|
|
151
|
+
static classPrefix = "x4";
|
|
152
|
+
|
|
141
153
|
constructor( props: P ) {
|
|
142
154
|
super( { ...props, content: split_content( props.content, true ) } );
|
|
143
155
|
}
|
|
@@ -149,8 +161,9 @@ export class HSplitBox<P extends SplitBoxProps=SplitBoxProps,E extends Component
|
|
|
149
161
|
* The CSS class for this component is automatically generated as `x4vsplitbox`.
|
|
150
162
|
*/
|
|
151
163
|
|
|
152
|
-
@class_ns( "x4" )
|
|
153
164
|
export class VSplitBox<P extends SplitBoxProps=SplitBoxProps,E extends ComponentEvents=ComponentEvents> extends VBox<P,E> {
|
|
165
|
+
static classPrefix = "x4";
|
|
166
|
+
|
|
154
167
|
constructor( props: P ) {
|
|
155
168
|
super( { ...props, content: split_content( props.content, false ) } );
|
|
156
169
|
}
|
|
@@ -206,8 +219,8 @@ interface StackItemEx extends StackItem {
|
|
|
206
219
|
* The CSS class for this component is automatically generated as `x4stackbox`.
|
|
207
220
|
*/
|
|
208
221
|
|
|
209
|
-
@class_ns( "x4" )
|
|
210
222
|
export class StackBox<P extends StackBoxProps = StackBoxProps, E extends StackeBoxEvents = StackeBoxEvents> extends Box<StackBoxProps,StackeBoxEvents> {
|
|
223
|
+
static classPrefix = "x4";
|
|
211
224
|
|
|
212
225
|
protected _items: StackItemEx[];
|
|
213
226
|
protected _cur: number;
|
|
@@ -371,8 +384,8 @@ export class StackBox<P extends StackBoxProps = StackBoxProps, E extends StackeB
|
|
|
371
384
|
* The CSS class for this component is automatically generated as `x4assistbox`.
|
|
372
385
|
*/
|
|
373
386
|
|
|
374
|
-
@class_ns( "x4" )
|
|
375
387
|
export class AssistBox extends StackBox {
|
|
388
|
+
static classPrefix = "x4";
|
|
376
389
|
|
|
377
390
|
/**
|
|
378
391
|
* Selects the next or previous page in the stack.
|
|
@@ -433,8 +446,8 @@ export interface GridBoxProps extends Omit<BoxProps,"content"> {
|
|
|
433
446
|
* Auto-generates CSS class: `x4gridbox`.
|
|
434
447
|
*/
|
|
435
448
|
|
|
436
|
-
@class_ns("x4")
|
|
437
449
|
export class GridBox<P extends GridBoxProps=GridBoxProps,E extends ComponentEvents=ComponentEvents> extends Box<P,E> {
|
|
450
|
+
static classPrefix = "x4";
|
|
438
451
|
|
|
439
452
|
constructor( props: P ) {
|
|
440
453
|
super( props );
|
|
@@ -543,8 +556,8 @@ interface MasonryProps extends Omit<BoxProps,"content"> {
|
|
|
543
556
|
* Auto-generates CSS class: `x4masonrybox`.
|
|
544
557
|
*/
|
|
545
558
|
|
|
546
|
-
@class_ns("x4")
|
|
547
559
|
export class MasonryBox extends Box<MasonryProps> {
|
|
560
|
+
static classPrefix = "x4";
|
|
548
561
|
|
|
549
562
|
constructor(props: MasonryProps ) {
|
|
550
563
|
super(props);
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
|
-
import { class_ns } from '../../core/core_tools';
|
|
18
17
|
import { parseRoute, Router } from '../../core/core_router';
|
|
19
18
|
|
|
20
19
|
import { BoxProps, Button, HBox, Icon } from '../components';
|
|
@@ -64,8 +63,8 @@ interface BreadcrumbsProps extends BoxProps{
|
|
|
64
63
|
* ```
|
|
65
64
|
*/
|
|
66
65
|
|
|
67
|
-
@class_ns( "x4" )
|
|
68
66
|
export class Breadcrumbs extends HBox<BreadcrumbsProps,BreadcrumbEvents> {
|
|
67
|
+
static classPrefix = "x4";
|
|
69
68
|
|
|
70
69
|
constructor( props: BreadcrumbsProps ) {
|
|
71
70
|
super( props );
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { Component, ComponentEvents, ComponentProps, Flex, Space } from '../../core/component';
|
|
18
18
|
import { EventCallback } from '../../core/core_events';
|
|
19
|
-
import {
|
|
19
|
+
import { isString } from '../../core/core_tools';
|
|
20
20
|
import { _tr } from '../../core/core_i18n'
|
|
21
21
|
|
|
22
22
|
import { Button } from '../button/button';
|
|
@@ -64,8 +64,8 @@ interface BtnGroupProps extends Omit<ComponentProps,"content"> {
|
|
|
64
64
|
* a packed group draws its buttons with the --ol-button-* variables of Button
|
|
65
65
|
*/
|
|
66
66
|
|
|
67
|
-
@class_ns( "x4" )
|
|
68
67
|
export class BtnGroup extends Box<BtnGroupProps,BtnGroupEvents> {
|
|
68
|
+
static classPrefix = "x4";
|
|
69
69
|
|
|
70
70
|
constructor( props: BtnGroupProps ) {
|
|
71
71
|
super( props );
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { Component, ComponentEvents, ComponentProps, EvClick } from "../../core/component"
|
|
18
18
|
import { EventCallback } from '../../core/core_events';
|
|
19
|
-
import {
|
|
19
|
+
import { isFunction, UnsafeHtml } from '../../core/core_tools';
|
|
20
20
|
|
|
21
21
|
import { Icon } from "../icon/icon"
|
|
22
22
|
import { Menu, MenuElement } from '../menu/menu';
|
|
@@ -113,8 +113,8 @@ export interface ButtonProps extends ComponentProps {
|
|
|
113
113
|
* the --ol-button-* variables are the ones of the outline buttons
|
|
114
114
|
*/
|
|
115
115
|
|
|
116
|
-
@class_ns( "x4" )
|
|
117
116
|
export class Button extends Component<ButtonProps,ButtonEvents> {
|
|
117
|
+
static classPrefix = "x4";
|
|
118
118
|
|
|
119
119
|
#text: Component;
|
|
120
120
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
17
|
import { Component, ComponentEvents, ComponentProps, EvChange, Flex } from '../../core/component'
|
|
18
|
-
import {
|
|
18
|
+
import { date_clone, date_hash, formatIntlDate, Point, unsafeHtml } from "../../core/core_tools"
|
|
19
19
|
import { _tr } from '../../core/core_i18n';
|
|
20
20
|
import { EventCallback } from '../../core/core_events';
|
|
21
21
|
|
|
@@ -70,9 +70,10 @@ interface CalendarProps extends ComponentProps {
|
|
|
70
70
|
* ```
|
|
71
71
|
*/
|
|
72
72
|
|
|
73
|
-
@class_ns( "x4" )
|
|
74
73
|
export class Calendar extends VBox<CalendarProps, CalendarEventMap>
|
|
75
74
|
{
|
|
75
|
+
static classPrefix = "x4";
|
|
76
|
+
|
|
76
77
|
private m_date: Date;
|
|
77
78
|
|
|
78
79
|
constructor(props: CalendarProps) {
|
|
@@ -333,6 +334,7 @@ export class Calendar extends VBox<CalendarProps, CalendarEventMap>
|
|
|
333
334
|
* /
|
|
334
335
|
|
|
335
336
|
export class PopupCalendar extends Popup {
|
|
337
|
+
static classPrefix = "x4";
|
|
336
338
|
|
|
337
339
|
m_cal: Calendar;
|
|
338
340
|
|
|
@@ -356,7 +358,7 @@ export class PopupCalendar extends Popup {
|
|
|
356
358
|
let newfocus = <HTMLElement>e.target;
|
|
357
359
|
|
|
358
360
|
// child of this: ok
|
|
359
|
-
if (this.
|
|
361
|
+
if (this.contains(newfocus)) {
|
|
360
362
|
return;
|
|
361
363
|
}
|
|
362
364
|
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
|
-
import { class_ns } from '../../core/core_tools';
|
|
18
17
|
import { Component, ComponentEvent, ComponentEvents, ComponentProps } from '../../core/component';
|
|
19
18
|
import { EventCallback } from "../../core/core_events"
|
|
20
19
|
import { CanvasEx, createPainter } from './canvas_ex';
|
|
@@ -45,8 +44,8 @@ export interface CanvasProps extends ComponentProps {
|
|
|
45
44
|
* Standard Canvas
|
|
46
45
|
*/
|
|
47
46
|
|
|
48
|
-
@class_ns( "x4" )
|
|
49
47
|
export class Canvas extends Component<CanvasProps, CanvasEventMap> {
|
|
48
|
+
static classPrefix = "x4";
|
|
50
49
|
|
|
51
50
|
private m_iwidth: number = -1;
|
|
52
51
|
private m_iheight: number = -1;
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
import { ComponentEvent, ComponentEvents } from '../../core/component';
|
|
18
18
|
import { EventCallback } from '../../core/core_events';
|
|
19
19
|
import { SvgBuilder, SvgComponent, SvgGroup, SvgPath, SvgProps, SvgShape } from '../../core/core_svg';
|
|
20
|
-
import {
|
|
20
|
+
import { clamp, formatNumber, IRect, isNumber, sanitizeHtml } from '../../core/core_tools';
|
|
21
21
|
|
|
22
22
|
import "./chart.module.scss"
|
|
23
23
|
|
|
@@ -91,7 +91,7 @@ export function chartFormatUnit( value: number, decimals = 2 ) {
|
|
|
91
91
|
|
|
92
92
|
const pow = Math.pow(10, decimals);
|
|
93
93
|
const roundedValue = Math.round(scaledValue * pow) / pow;
|
|
94
|
-
const text = roundedValue
|
|
94
|
+
const text = formatNumber( roundedValue, decimals ); // the decimal separator of the locale
|
|
95
95
|
|
|
96
96
|
return ( value<0 && roundedValue!=0 ? '-' : '' ) + text + units[unitIndex];
|
|
97
97
|
}
|
|
@@ -234,8 +234,8 @@ function drawBar( grp: SvgGroup, x: number, w: number, y0: number, y1: number, r
|
|
|
234
234
|
* ```
|
|
235
235
|
*/
|
|
236
236
|
|
|
237
|
-
@class_ns( "x4" )
|
|
238
237
|
export class Chart extends SvgComponent<ChartProps,ChartEvents> {
|
|
238
|
+
static classPrefix = "x4";
|
|
239
239
|
|
|
240
240
|
private _type: ChartType;
|
|
241
241
|
private _series: ChartSerie[];
|
|
@@ -264,7 +264,7 @@ export class Chart extends SvgComponent<ChartProps,ChartEvents> {
|
|
|
264
264
|
|
|
265
265
|
this.addDOMEvent( "click", ( e ) => {
|
|
266
266
|
const el = ( e.target as Element ).closest( "[data-index]" );
|
|
267
|
-
if( el && this.
|
|
267
|
+
if( el && this.contains( el ) ) {
|
|
268
268
|
const serie = parseInt( el.getAttribute( "data-serie" ) );
|
|
269
269
|
const index = parseInt( el.getAttribute( "data-index" ) );
|
|
270
270
|
this.fire( "click", { serie, index, value: this._series[serie]?.values[index] } );
|
|
@@ -3,7 +3,6 @@ import { EventCallback } from '../../core/core_events';
|
|
|
3
3
|
|
|
4
4
|
import { Input } from '../input/input';
|
|
5
5
|
import { Label } from '../label/label';
|
|
6
|
-
import { class_ns } from '../../core/core_tools';
|
|
7
6
|
|
|
8
7
|
import icons from "../assets/icons";
|
|
9
8
|
|
|
@@ -45,8 +44,9 @@ interface CheckboxProps extends ComponentProps {
|
|
|
45
44
|
* ```
|
|
46
45
|
*/
|
|
47
46
|
|
|
48
|
-
@class_ns( "x4" )
|
|
49
47
|
export class Checkbox extends Component<CheckboxProps,CheckBoxEvents> {
|
|
48
|
+
static classPrefix = "x4";
|
|
49
|
+
|
|
50
50
|
readonly _input: Input;
|
|
51
51
|
|
|
52
52
|
/**
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { Component, ComponentEvents } from '../../core/component';
|
|
18
18
|
import { EventCallback } from '../../core/core_events';
|
|
19
|
-
import { isFeatureAvailable,
|
|
19
|
+
import { isFeatureAvailable, isFunction, IComponentInterface, IFormElement } from '../../core/core_tools';
|
|
20
20
|
import { Color } from '../../core/core_colors';
|
|
21
21
|
|
|
22
22
|
import { BoxProps, HBox } from '../boxes/boxes';
|
|
@@ -84,8 +84,9 @@ interface ColorInputEvents extends ComponentEvents {
|
|
|
84
84
|
* ```
|
|
85
85
|
*/
|
|
86
86
|
|
|
87
|
-
@class_ns( "x4" )
|
|
88
87
|
export class ColorInput extends HBox<ColorInputProps,ColorInputEvents> {
|
|
88
|
+
static classPrefix = "x4";
|
|
89
|
+
|
|
89
90
|
static "$cls-ns" = "x4";
|
|
90
91
|
|
|
91
92
|
private _color: Color; // null: no color
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
17
|
import { Color, Hsv } from '../../core/core_colors';
|
|
18
|
-
import { Rect, clamp,
|
|
18
|
+
import { Rect, clamp, isFeatureAvailable } from '../../core/core_tools';
|
|
19
19
|
|
|
20
20
|
import { Component, ComponentEvent, ComponentEvents, ComponentProps, EvChange } from '../../core/component';
|
|
21
21
|
import { Box, BoxProps, HBox, VBox } from '../boxes/boxes';
|
|
@@ -58,8 +58,8 @@ interface CommonEvents extends ComponentEvents {
|
|
|
58
58
|
*
|
|
59
59
|
*/
|
|
60
60
|
|
|
61
|
-
@class_ns( "x4" )
|
|
62
61
|
export class Saturation extends Box<BoxProps,CommonEvents> {
|
|
62
|
+
static classPrefix = "x4";
|
|
63
63
|
|
|
64
64
|
private mdown = false;
|
|
65
65
|
private irect: Rect;
|
|
@@ -191,8 +191,8 @@ export class Saturation extends Box<BoxProps,CommonEvents> {
|
|
|
191
191
|
* @internal
|
|
192
192
|
*/
|
|
193
193
|
|
|
194
|
-
@class_ns( "x4" )
|
|
195
194
|
class HueSlider extends Box<BoxProps,CommonEvents> {
|
|
195
|
+
static classPrefix = "x4";
|
|
196
196
|
|
|
197
197
|
private thumb: Component;
|
|
198
198
|
private hsv: Hsv = { hue: 1, saturation: 1, value: 1, alpha: 1 };
|
|
@@ -271,8 +271,8 @@ class HueSlider extends Box<BoxProps,CommonEvents> {
|
|
|
271
271
|
* @internal
|
|
272
272
|
*/
|
|
273
273
|
|
|
274
|
-
@class_ns( "x4" )
|
|
275
274
|
class AlphaSlider extends Box<BoxProps,CommonEvents> {
|
|
275
|
+
static classPrefix = "x4";
|
|
276
276
|
|
|
277
277
|
private thumb: Component;
|
|
278
278
|
private color: Component;
|
|
@@ -389,8 +389,8 @@ interface ColorPickerChangeEvents extends ComponentEvents {
|
|
|
389
389
|
* ```
|
|
390
390
|
*/
|
|
391
391
|
|
|
392
|
-
@class_ns( "x4" )
|
|
393
392
|
export class ColorPicker extends VBox<ColorPickerProps,ColorPickerChangeEvents> {
|
|
393
|
+
static classPrefix = "x4";
|
|
394
394
|
|
|
395
395
|
private _base: Color;
|
|
396
396
|
private _hsv: Hsv;
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
17
|
import { Component, ComponentEvents, ComponentProps, EvClick, EvSelectionChange, makeUniqueComponentId } from '../../core/component';
|
|
18
|
-
import {
|
|
18
|
+
import { IComponentInterface, IFormElement, kbNav } from '../../core/core_tools';
|
|
19
19
|
import { EventCallback } from '../../core/core_events';
|
|
20
20
|
|
|
21
21
|
import { Listbox, ListboxID, ListItem } from '../listbox/listbox';
|
|
@@ -42,8 +42,8 @@ interface DropdownProps extends Omit<PopupProps,"content"> {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
@class_ns( "x4" )
|
|
46
45
|
export class DropdownList extends Popup<DropdownProps,DropdownEvents> {
|
|
46
|
+
static classPrefix = "x4";
|
|
47
47
|
|
|
48
48
|
private _list: Listbox;
|
|
49
49
|
|
|
@@ -108,8 +108,8 @@ interface ComboboxProps extends Omit<ComponentProps,"content"> {
|
|
|
108
108
|
* ```
|
|
109
109
|
*/
|
|
110
110
|
|
|
111
|
-
@class_ns( "x4" )
|
|
112
111
|
export class Combobox extends Component<ComboboxProps,ComboboxEvents> {
|
|
112
|
+
static classPrefix = "x4";
|
|
113
113
|
|
|
114
114
|
private _popup: DropdownList;
|
|
115
115
|
//private _label: Label;
|