x4js 1.4.12 → 1.4.15
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/lib/component.d.ts +0 -1
- package/lib/component.js +7 -2
- package/lib/gridview.js +50 -12
- package/lib/layout.js +7 -0
- package/lib/listview.d.ts +2 -2
- package/lib/router.d.ts +10 -2
- package/lib/router.js +98 -18
- package/lib/tabbar.d.ts +3 -1
- package/lib/tabbar.js +31 -12
- package/lib/x4.css +1 -1
- package/lib/x4_events.d.ts +8 -0
- package/lib/x4_events.js +5 -1
- package/package.json +1 -1
- package/src/component.ts +8 -2
- package/src/gridview.ts +65 -18
- package/src/layout.ts +9 -0
- package/src/listview.ts +2 -2
- package/src/router.ts +134 -22
- package/src/tabbar.ts +36 -13
- package/src/x4.less +5 -4
- package/src/x4_events.ts +13 -0
package/lib/component.d.ts
CHANGED
|
@@ -107,7 +107,6 @@ export declare class Component<P extends CProps<BaseComponentEventMap> = CProps<
|
|
|
107
107
|
private static __privateEvents;
|
|
108
108
|
private static __sizeObserver;
|
|
109
109
|
private static __createObserver;
|
|
110
|
-
private static __intersectionObserver;
|
|
111
110
|
private static __capture;
|
|
112
111
|
private static __capture_mask;
|
|
113
112
|
private static __css;
|
package/lib/component.js
CHANGED
|
@@ -89,7 +89,7 @@ class Component extends base_component_1.BaseComponent {
|
|
|
89
89
|
static __privateEvents = {};
|
|
90
90
|
static __sizeObserver; // resize observer
|
|
91
91
|
static __createObserver; // creation observer
|
|
92
|
-
static __intersectionObserver;
|
|
92
|
+
//private static __intersectionObserver: IntersectionObserver; // visibility observer
|
|
93
93
|
static __capture = null;
|
|
94
94
|
static __capture_mask = null;
|
|
95
95
|
static __css = null;
|
|
@@ -101,6 +101,10 @@ class Component extends base_component_1.BaseComponent {
|
|
|
101
101
|
uid: Component.__comp_guid++,
|
|
102
102
|
inrender: false,
|
|
103
103
|
};
|
|
104
|
+
// prepare iprops
|
|
105
|
+
if (this.m_props.cls) {
|
|
106
|
+
this.addClass(this.m_props.cls);
|
|
107
|
+
}
|
|
104
108
|
}
|
|
105
109
|
/**
|
|
106
110
|
*
|
|
@@ -1042,7 +1046,8 @@ class Component extends base_component_1.BaseComponent {
|
|
|
1042
1046
|
this.addClass('@' + (0, tools_1.pascalCase)(clsname));
|
|
1043
1047
|
me = Object.getPrototypeOf(me);
|
|
1044
1048
|
}
|
|
1045
|
-
|
|
1049
|
+
//done in ctor now
|
|
1050
|
+
//this.addClass(this.m_props.cls);
|
|
1046
1051
|
}
|
|
1047
1052
|
/**
|
|
1048
1053
|
* prepend the system class name prefix on a name if needed (if class starts with @)
|
package/lib/gridview.js
CHANGED
|
@@ -289,6 +289,7 @@ class GridView extends layout_1.VLayout {
|
|
|
289
289
|
},
|
|
290
290
|
content: this.m_container
|
|
291
291
|
});
|
|
292
|
+
let flex = false;
|
|
292
293
|
let cols = this.m_columns.map((col, index) => {
|
|
293
294
|
let cls = '@cell';
|
|
294
295
|
if (col.cls) {
|
|
@@ -325,9 +326,16 @@ class GridView extends layout_1.VLayout {
|
|
|
325
326
|
sens: 'right',
|
|
326
327
|
events: { resize: (e) => resizeCol(e) }
|
|
327
328
|
});
|
|
328
|
-
col
|
|
329
|
+
if (col.flex) {
|
|
330
|
+
flex = true;
|
|
331
|
+
}
|
|
332
|
+
col.$hdr = comp;
|
|
329
333
|
return comp;
|
|
330
334
|
});
|
|
335
|
+
cols.push(new component_1.Flex({
|
|
336
|
+
ref: 'flex',
|
|
337
|
+
cls: flex ? '@hidden' : ''
|
|
338
|
+
}));
|
|
331
339
|
// compute full width
|
|
332
340
|
let full_width = 0;
|
|
333
341
|
this.m_columns.forEach((col) => {
|
|
@@ -357,8 +365,13 @@ class GridView extends layout_1.VLayout {
|
|
|
357
365
|
width: col.width
|
|
358
366
|
}
|
|
359
367
|
});
|
|
368
|
+
col.$ftr = comp;
|
|
360
369
|
return comp;
|
|
361
370
|
});
|
|
371
|
+
foots.push(new component_1.Flex({
|
|
372
|
+
ref: 'flex',
|
|
373
|
+
cls: flex ? '@hidden' : ''
|
|
374
|
+
}));
|
|
362
375
|
this.m_footer = new layout_1.HLayout({
|
|
363
376
|
cls: '@footer',
|
|
364
377
|
content: foots,
|
|
@@ -378,8 +391,33 @@ class GridView extends layout_1.VLayout {
|
|
|
378
391
|
]);
|
|
379
392
|
}
|
|
380
393
|
_on_col_resize(col, width) {
|
|
381
|
-
this.m_columns[col]
|
|
382
|
-
|
|
394
|
+
const _col = this.m_columns[col];
|
|
395
|
+
let updateFlex = false;
|
|
396
|
+
if (width >= 0) {
|
|
397
|
+
_col.width = width;
|
|
398
|
+
if (_col.flex) {
|
|
399
|
+
_col.$hdr.removeClass('@flex');
|
|
400
|
+
_col.flex = undefined;
|
|
401
|
+
updateFlex = true;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
else if (width < 0 && !_col.flex) {
|
|
405
|
+
_col.$hdr.addClass('@flex');
|
|
406
|
+
_col.flex = 1;
|
|
407
|
+
updateFlex = true;
|
|
408
|
+
}
|
|
409
|
+
if (updateFlex) {
|
|
410
|
+
let flex = false;
|
|
411
|
+
this.m_columns.forEach(c => {
|
|
412
|
+
if (c.flex) {
|
|
413
|
+
flex = true;
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
this.m_header.itemWithRef('flex')?.show(flex ? false : true);
|
|
417
|
+
if (this.m_footer) {
|
|
418
|
+
this.m_footer.itemWithRef('flex')?.show(flex ? false : true);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
383
421
|
this._updateScroll(true);
|
|
384
422
|
}
|
|
385
423
|
/**
|
|
@@ -391,19 +429,19 @@ class GridView extends layout_1.VLayout {
|
|
|
391
429
|
}
|
|
392
430
|
this.m_columns.forEach((c) => {
|
|
393
431
|
if (c !== col) {
|
|
394
|
-
c.$
|
|
432
|
+
c.$hdr.sorted = false;
|
|
395
433
|
}
|
|
396
434
|
});
|
|
397
|
-
const $
|
|
398
|
-
if ($
|
|
399
|
-
$
|
|
435
|
+
const $hdr = col.$hdr;
|
|
436
|
+
if ($hdr.sorted) {
|
|
437
|
+
$hdr.toggleSens();
|
|
400
438
|
}
|
|
401
439
|
else {
|
|
402
|
-
$
|
|
440
|
+
$hdr.sorted = true;
|
|
403
441
|
}
|
|
404
442
|
if (this.m_dataview) {
|
|
405
443
|
this.m_dataview.sort([
|
|
406
|
-
{ field: col.id, ascending: $
|
|
444
|
+
{ field: col.id, ascending: $hdr.sens == 'dn' ? false : true }
|
|
407
445
|
]);
|
|
408
446
|
}
|
|
409
447
|
}
|
|
@@ -455,7 +493,7 @@ class GridView extends layout_1.VLayout {
|
|
|
455
493
|
let cidx = 0;
|
|
456
494
|
let index = this.m_topIndex;
|
|
457
495
|
let count = this.m_dataview ? this.m_dataview.count : 0;
|
|
458
|
-
let full_width = 0;
|
|
496
|
+
let full_width = 0; // todo: +4 pixel of left border
|
|
459
497
|
let even = this.m_topIndex & 1 ? true : false;
|
|
460
498
|
// compute full width
|
|
461
499
|
this.m_columns.forEach((col) => {
|
|
@@ -587,8 +625,8 @@ class GridView extends layout_1.VLayout {
|
|
|
587
625
|
});
|
|
588
626
|
}
|
|
589
627
|
else {
|
|
590
|
-
this.m_header.setStyleValue('width', full_width);
|
|
591
|
-
this.m_footer?.setStyleValue('width', full_width);
|
|
628
|
+
this.m_header.setStyleValue('width', full_width + 1000);
|
|
629
|
+
this.m_footer?.setStyleValue('width', full_width + 1000);
|
|
592
630
|
this.m_container.setStyle({
|
|
593
631
|
height: count * this.m_itemHeight,
|
|
594
632
|
width: full_width
|
package/lib/layout.js
CHANGED
|
@@ -278,10 +278,17 @@ exports.ScrollView = ScrollView;
|
|
|
278
278
|
// https://medium.com/@andybarefoot/a-masonry-style-layout-using-css-grid-8c663d355ebb
|
|
279
279
|
class Masonry extends component_1.Container {
|
|
280
280
|
constructor(props) {
|
|
281
|
+
const items = props.items;
|
|
282
|
+
props.items = undefined;
|
|
281
283
|
super(props);
|
|
282
284
|
this.setDomEvent('sizechange', () => {
|
|
283
285
|
this.resizeAllItems();
|
|
284
286
|
});
|
|
287
|
+
if (items) {
|
|
288
|
+
items.forEach(i => {
|
|
289
|
+
this.addItem(i);
|
|
290
|
+
});
|
|
291
|
+
}
|
|
285
292
|
}
|
|
286
293
|
resizeItem(item) {
|
|
287
294
|
const style = this.getComputedStyle();
|
package/lib/listview.d.ts
CHANGED
|
@@ -83,7 +83,7 @@ export interface ListViewProps<E extends ListViewEventMap = ListViewEventMap> ex
|
|
|
83
83
|
/**
|
|
84
84
|
* Standard listview class
|
|
85
85
|
*/
|
|
86
|
-
export declare class ListView
|
|
86
|
+
export declare class ListView extends VLayout<ListViewProps, ListViewEventMap> {
|
|
87
87
|
protected m_selection: {
|
|
88
88
|
item: ListViewItem;
|
|
89
89
|
citem: Component;
|
|
@@ -94,7 +94,7 @@ export declare class ListView<T extends ListViewProps = ListViewProps, E extends
|
|
|
94
94
|
protected m_topIndex: number;
|
|
95
95
|
protected m_itemHeight: number;
|
|
96
96
|
protected m_cache: Map<number, Component>;
|
|
97
|
-
constructor(props:
|
|
97
|
+
constructor(props: ListViewProps);
|
|
98
98
|
componentCreated(): void;
|
|
99
99
|
render(props: ListViewProps): void;
|
|
100
100
|
/**
|
package/lib/router.d.ts
CHANGED
|
@@ -26,9 +26,17 @@
|
|
|
26
26
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
27
27
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
28
28
|
**/
|
|
29
|
-
|
|
29
|
+
import { EventSource, EvError, EventMap } from "./x4_events";
|
|
30
|
+
declare type RouteHandler = (params: any, path: string) => void;
|
|
31
|
+
interface RouterEventMap extends EventMap {
|
|
32
|
+
error: EvError;
|
|
33
|
+
}
|
|
34
|
+
export declare class Router extends EventSource<RouterEventMap> {
|
|
30
35
|
private routes;
|
|
31
36
|
constructor();
|
|
32
|
-
get(uri:
|
|
37
|
+
get(uri: string | RegExp, handler: RouteHandler): void;
|
|
33
38
|
init(): void;
|
|
39
|
+
navigate(uri: string, notify?: boolean): void;
|
|
40
|
+
private _find;
|
|
34
41
|
}
|
|
42
|
+
export {};
|
package/lib/router.js
CHANGED
|
@@ -29,31 +29,111 @@
|
|
|
29
29
|
**/
|
|
30
30
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
31
|
exports.Router = void 0;
|
|
32
|
-
|
|
32
|
+
const x4_events_1 = require("./x4_events");
|
|
33
|
+
function parseRoute(str, loose = false) {
|
|
34
|
+
if (str instanceof RegExp) {
|
|
35
|
+
return {
|
|
36
|
+
keys: null,
|
|
37
|
+
pattern: str
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const arr = str.split('/');
|
|
41
|
+
let keys = [];
|
|
42
|
+
let pattern = '';
|
|
43
|
+
if (arr[0] == '') {
|
|
44
|
+
arr.shift();
|
|
45
|
+
}
|
|
46
|
+
for (const tmp of arr) {
|
|
47
|
+
const c = tmp[0];
|
|
48
|
+
if (c === '*') {
|
|
49
|
+
keys.push('wild');
|
|
50
|
+
pattern += '/(.*)';
|
|
51
|
+
}
|
|
52
|
+
else if (c === ':') {
|
|
53
|
+
const o = tmp.indexOf('?', 1);
|
|
54
|
+
const ext = tmp.indexOf('.', 1);
|
|
55
|
+
keys.push(tmp.substring(1, o >= 0 ? o : ext >= 0 ? ext : tmp.length));
|
|
56
|
+
pattern += o < 0 && ext < 0 ? '(?:/([^/]+?))?' : '/([^/]+?)';
|
|
57
|
+
if (ext >= 0) {
|
|
58
|
+
pattern += (o >= 0 ? '?' : '') + '\\' + tmp.substring(ext);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
pattern += '/' + tmp;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
keys,
|
|
67
|
+
pattern: new RegExp(`^${pattern}${loose ? '(?=$|\/)' : '\/?$'}`, 'i')
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
class Router extends x4_events_1.EventSource {
|
|
33
71
|
routes;
|
|
34
72
|
constructor() {
|
|
73
|
+
super();
|
|
35
74
|
this.routes = [];
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
this.routes.push({
|
|
45
|
-
uri,
|
|
46
|
-
callback
|
|
75
|
+
window.addEventListener('popstate', (event) => {
|
|
76
|
+
const url = document.location.pathname;
|
|
77
|
+
const found = this._find(url);
|
|
78
|
+
found.handlers.forEach(h => {
|
|
79
|
+
h(found.params, url);
|
|
80
|
+
});
|
|
47
81
|
});
|
|
48
82
|
}
|
|
83
|
+
get(uri, handler) {
|
|
84
|
+
let { keys, pattern } = parseRoute(uri);
|
|
85
|
+
this.routes.push({ keys, pattern, handler });
|
|
86
|
+
}
|
|
49
87
|
init() {
|
|
50
|
-
this.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
88
|
+
this.navigate(window.location.pathname);
|
|
89
|
+
}
|
|
90
|
+
navigate(uri, notify = true) {
|
|
91
|
+
const found = this._find(uri);
|
|
92
|
+
if (!found || found.handlers.length == 0) {
|
|
93
|
+
//window.history.pushState({}, '', 'error')
|
|
94
|
+
console.log('route not found: ' + uri);
|
|
95
|
+
this.signal("error", (0, x4_events_1.EvError)(404, "route not found"));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
window.history.pushState({}, '', uri);
|
|
99
|
+
if (notify) {
|
|
100
|
+
found.handlers.forEach(h => {
|
|
101
|
+
h(found.params, uri);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
_find(url) {
|
|
106
|
+
let matches = [];
|
|
107
|
+
let params = {};
|
|
108
|
+
let handlers = [];
|
|
109
|
+
for (const tmp of this.routes) {
|
|
110
|
+
if (!tmp.keys) {
|
|
111
|
+
matches = tmp.pattern.exec(url);
|
|
112
|
+
if (!matches) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (matches['groups']) {
|
|
116
|
+
for (const k in matches['groups']) {
|
|
117
|
+
params[k] = matches['groups'][k];
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
handlers = [...handlers, tmp.handler];
|
|
55
121
|
}
|
|
56
|
-
|
|
122
|
+
else if (tmp.keys.length > 0) {
|
|
123
|
+
matches = tmp.pattern.exec(url);
|
|
124
|
+
if (matches === null) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
for (let j = 0; j < tmp.keys.length;) {
|
|
128
|
+
params[tmp.keys[j]] = matches[++j];
|
|
129
|
+
}
|
|
130
|
+
handlers = [...handlers, tmp.handler];
|
|
131
|
+
}
|
|
132
|
+
else if (tmp.pattern.test(url)) {
|
|
133
|
+
handlers = [...handlers, tmp.handler];
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return { params, handlers };
|
|
57
137
|
}
|
|
58
138
|
}
|
|
59
139
|
exports.Router = Router;
|
package/lib/tabbar.d.ts
CHANGED
|
@@ -48,9 +48,11 @@ export declare class TabBar extends Container<TabBarProps, TabBarEventMap> {
|
|
|
48
48
|
private m_pages;
|
|
49
49
|
private m_curPage;
|
|
50
50
|
constructor(props: TabBarProps);
|
|
51
|
+
componentCreated(): void;
|
|
51
52
|
addPage(page: ITabPage): void;
|
|
52
53
|
render(): void;
|
|
53
|
-
select(id: string): void;
|
|
54
|
+
select(id: string | null, notify?: boolean): void;
|
|
54
55
|
private _select;
|
|
56
|
+
get selection(): Component<CProps<import("./base_component").BaseComponentEventMap>, import("./base_component").BaseComponentEventMap>;
|
|
55
57
|
}
|
|
56
58
|
export {};
|
package/lib/tabbar.js
CHANGED
|
@@ -47,8 +47,10 @@ class TabBar extends component_1.Container {
|
|
|
47
47
|
this.addClass('@hlayout');
|
|
48
48
|
}
|
|
49
49
|
this.m_props.pages?.forEach(p => this.addPage(p));
|
|
50
|
+
}
|
|
51
|
+
componentCreated() {
|
|
50
52
|
if (this.m_props.default) {
|
|
51
|
-
this.select(this.m_props.default);
|
|
53
|
+
this.select(this.m_props.default, true);
|
|
52
54
|
}
|
|
53
55
|
}
|
|
54
56
|
addPage(page) {
|
|
@@ -58,28 +60,45 @@ class TabBar extends component_1.Container {
|
|
|
58
60
|
render() {
|
|
59
61
|
let buttons = [];
|
|
60
62
|
this.m_pages.forEach(p => {
|
|
61
|
-
p.btn = new button_1.Button({ cls: p === this.m_curPage ? 'selected' : '', text: p.title, icon: p.icon, click: () => this._select(p) });
|
|
63
|
+
p.btn = new button_1.Button({ cls: p === this.m_curPage ? 'selected' : '', text: p.title, icon: p.icon, click: () => this._select(p, true) });
|
|
62
64
|
buttons.push(p.btn);
|
|
63
65
|
});
|
|
64
66
|
this.setContent(buttons);
|
|
65
67
|
}
|
|
66
|
-
select(id) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
select(id, notify = false) {
|
|
69
|
+
if (!id) {
|
|
70
|
+
this._select(null, notify);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
let page = this.m_pages.find(x => x.id === id);
|
|
74
|
+
if (page) {
|
|
75
|
+
this._select(page, notify);
|
|
76
|
+
}
|
|
70
77
|
}
|
|
71
78
|
}
|
|
72
|
-
_select(p) {
|
|
73
|
-
if (this.
|
|
79
|
+
_select(p, notify) {
|
|
80
|
+
if (this.m_curPage == p) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (this.dom && this.m_curPage) {
|
|
74
84
|
this.m_curPage.btn.removeClass('selected');
|
|
75
|
-
this.m_curPage.page
|
|
85
|
+
if (this.m_curPage.page) {
|
|
86
|
+
this.m_curPage.page.hide();
|
|
87
|
+
}
|
|
76
88
|
}
|
|
77
89
|
this.m_curPage = p;
|
|
78
|
-
|
|
79
|
-
|
|
90
|
+
if (notify) {
|
|
91
|
+
this.signal('change', (0, x4_events_1.EvChange)(p ? p.id : null));
|
|
92
|
+
}
|
|
93
|
+
if (this.dom && this.m_curPage) {
|
|
80
94
|
this.m_curPage.btn.addClass('selected');
|
|
81
|
-
this.m_curPage.page
|
|
95
|
+
if (this.m_curPage.page) {
|
|
96
|
+
this.m_curPage.page.show();
|
|
97
|
+
}
|
|
82
98
|
}
|
|
83
99
|
}
|
|
100
|
+
get selection() {
|
|
101
|
+
return this.m_curPage?.page;
|
|
102
|
+
}
|
|
84
103
|
}
|
|
85
104
|
exports.TabBar = TabBar;
|
package/lib/x4.css
CHANGED
package/lib/x4_events.d.ts
CHANGED
|
@@ -106,6 +106,14 @@ export interface EvDrag extends BasicEvent {
|
|
|
106
106
|
data: any;
|
|
107
107
|
}
|
|
108
108
|
export declare function EvDrag(element: unknown, data: any, ctx: any): EvDrag;
|
|
109
|
+
/**
|
|
110
|
+
* Errors
|
|
111
|
+
*/
|
|
112
|
+
export interface EvError extends BasicEvent {
|
|
113
|
+
code: number;
|
|
114
|
+
message: string;
|
|
115
|
+
}
|
|
116
|
+
export declare function EvError(code: number, message: string): EvError;
|
|
109
117
|
/**
|
|
110
118
|
* this Base interface is used to describe available events & their types
|
|
111
119
|
*
|
package/lib/x4_events.js
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
29
29
|
**/
|
|
30
30
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
-
exports.EventSource = exports.EvDrag = exports.EvMessage = exports.EvTimer = exports.EvContextMenu = exports.EvSelectionChange = exports.EvChange = exports.EvClick = exports.BasicEvent = void 0;
|
|
31
|
+
exports.EventSource = exports.EvError = exports.EvDrag = exports.EvMessage = exports.EvTimer = exports.EvContextMenu = exports.EvSelectionChange = exports.EvChange = exports.EvClick = exports.BasicEvent = void 0;
|
|
32
32
|
// default stopPropagation implementation for Events
|
|
33
33
|
const stopPropagation = function () {
|
|
34
34
|
this.propagationStopped = true;
|
|
@@ -81,6 +81,10 @@ function EvDrag(element, data, ctx) {
|
|
|
81
81
|
return BasicEvent({ element, data, context: ctx });
|
|
82
82
|
}
|
|
83
83
|
exports.EvDrag = EvDrag;
|
|
84
|
+
function EvError(code, message) {
|
|
85
|
+
return BasicEvent({ code, message });
|
|
86
|
+
}
|
|
87
|
+
exports.EvError = EvError;
|
|
84
88
|
/**
|
|
85
89
|
* Event emitter class
|
|
86
90
|
* this class allow you to emit and handle events
|
package/package.json
CHANGED
package/src/component.ts
CHANGED
|
@@ -188,7 +188,7 @@ export class Component<P extends CProps<BaseComponentEventMap> = CProps<BaseComp
|
|
|
188
188
|
private static __privateEvents: any = {};
|
|
189
189
|
private static __sizeObserver: ResizeObserver; // resize observer
|
|
190
190
|
private static __createObserver: MutationObserver; // creation observer
|
|
191
|
-
private static __intersectionObserver: IntersectionObserver; // visibility observer
|
|
191
|
+
//private static __intersectionObserver: IntersectionObserver; // visibility observer
|
|
192
192
|
|
|
193
193
|
private static __capture: ICaptureInfo = null;
|
|
194
194
|
private static __capture_mask = null;
|
|
@@ -202,6 +202,11 @@ export class Component<P extends CProps<BaseComponentEventMap> = CProps<BaseComp
|
|
|
202
202
|
dom_events: {},
|
|
203
203
|
uid: Component.__comp_guid++,
|
|
204
204
|
inrender: false,
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// prepare iprops
|
|
208
|
+
if( this.m_props.cls ) {
|
|
209
|
+
this.addClass( this.m_props.cls );
|
|
205
210
|
}
|
|
206
211
|
}
|
|
207
212
|
|
|
@@ -1389,7 +1394,8 @@ export class Component<P extends CProps<BaseComponentEventMap> = CProps<BaseComp
|
|
|
1389
1394
|
me = Object.getPrototypeOf(me);
|
|
1390
1395
|
}
|
|
1391
1396
|
|
|
1392
|
-
|
|
1397
|
+
//done in ctor now
|
|
1398
|
+
//this.addClass(this.m_props.cls);
|
|
1393
1399
|
}
|
|
1394
1400
|
|
|
1395
1401
|
/**
|
package/src/gridview.ts
CHANGED
|
@@ -36,7 +36,7 @@ const T_UPDATE = Symbol('update');
|
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
import { HLayout, VLayout } from './layout'
|
|
39
|
-
import { Component, ContainerEventMap, EvSize, EvDblClick, CProps, flyWrap, html, HtmlString, SizerOverlay } from './component'
|
|
39
|
+
import { Component, ContainerEventMap, EvSize, EvDblClick, CProps, flyWrap, html, HtmlString, SizerOverlay, Flex } from './component'
|
|
40
40
|
import { Label } from './label'
|
|
41
41
|
import { _tr } from './i18n'
|
|
42
42
|
import * as Formatters from './formatters'
|
|
@@ -76,7 +76,8 @@ export interface GridColumn {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
interface GridColumnInternal extends GridColumn {
|
|
79
|
-
$
|
|
79
|
+
$hdr: ColHeader;
|
|
80
|
+
$ftr: Component;
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
|
|
@@ -421,6 +422,7 @@ export class GridView extends VLayout<GridViewProps, GridViewEventMap> {
|
|
|
421
422
|
content: this.m_container
|
|
422
423
|
});
|
|
423
424
|
|
|
425
|
+
let flex = false;
|
|
424
426
|
let cols = this.m_columns.map((col, index) => {
|
|
425
427
|
|
|
426
428
|
let cls = '@cell';
|
|
@@ -463,10 +465,19 @@ export class GridView extends VLayout<GridViewProps, GridViewEventMap> {
|
|
|
463
465
|
events: {resize: ( e ) => resizeCol(e )}
|
|
464
466
|
});
|
|
465
467
|
|
|
466
|
-
(
|
|
468
|
+
if( col.flex ) {
|
|
469
|
+
flex = true;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
(<any>col).$hdr = comp;
|
|
467
473
|
return comp;
|
|
468
474
|
});
|
|
469
475
|
|
|
476
|
+
(cols as any).push( new Flex( {
|
|
477
|
+
ref: 'flex',
|
|
478
|
+
cls: flex ? '@hidden' : ''
|
|
479
|
+
} ) );
|
|
480
|
+
|
|
470
481
|
// compute full width
|
|
471
482
|
let full_width = 0;
|
|
472
483
|
this.m_columns.forEach((col) => {
|
|
@@ -479,8 +490,7 @@ export class GridView extends VLayout<GridViewProps, GridViewEventMap> {
|
|
|
479
490
|
style: {
|
|
480
491
|
minWidth: full_width
|
|
481
492
|
}
|
|
482
|
-
});
|
|
483
|
-
|
|
493
|
+
});
|
|
484
494
|
|
|
485
495
|
if( this.m_props.hasFooter ) {
|
|
486
496
|
let foots = this.m_columns.map((col, index) => {
|
|
@@ -504,9 +514,15 @@ export class GridView extends VLayout<GridViewProps, GridViewEventMap> {
|
|
|
504
514
|
}
|
|
505
515
|
});
|
|
506
516
|
|
|
517
|
+
(col as GridColumnInternal).$ftr = comp;
|
|
507
518
|
return comp;
|
|
508
519
|
});
|
|
509
520
|
|
|
521
|
+
(foots as any).push( new Flex( {
|
|
522
|
+
ref: 'flex',
|
|
523
|
+
cls: flex ? '@hidden' : ''
|
|
524
|
+
} ) );
|
|
525
|
+
|
|
510
526
|
this.m_footer = new HLayout({
|
|
511
527
|
cls: '@footer',
|
|
512
528
|
content: <any>foots,
|
|
@@ -528,9 +544,40 @@ export class GridView extends VLayout<GridViewProps, GridViewEventMap> {
|
|
|
528
544
|
|
|
529
545
|
}
|
|
530
546
|
|
|
531
|
-
private _on_col_resize(col, width) {
|
|
532
|
-
|
|
533
|
-
this.m_columns[col]
|
|
547
|
+
private _on_col_resize(col: number, width: number) {
|
|
548
|
+
|
|
549
|
+
const _col = this.m_columns[col] as GridColumnInternal;
|
|
550
|
+
|
|
551
|
+
let updateFlex = false;
|
|
552
|
+
|
|
553
|
+
if( width>=0 ) {
|
|
554
|
+
_col.width = width;
|
|
555
|
+
if( _col.flex ) {
|
|
556
|
+
_col.$hdr.removeClass( '@flex' );
|
|
557
|
+
_col.flex = undefined;
|
|
558
|
+
updateFlex = true;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
else if( width<0 && !_col.flex ) {
|
|
562
|
+
_col.$hdr.addClass( '@flex' );
|
|
563
|
+
_col.flex = 1;
|
|
564
|
+
updateFlex = true;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
if( updateFlex ) {
|
|
568
|
+
let flex = false;
|
|
569
|
+
this.m_columns.forEach( c => {
|
|
570
|
+
if( c.flex ) {
|
|
571
|
+
flex = true;
|
|
572
|
+
}
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
this.m_header.itemWithRef( 'flex' )?.show( flex ? false : true );
|
|
576
|
+
if( this.m_footer ) {
|
|
577
|
+
this.m_footer.itemWithRef( 'flex' )?.show( flex ? false : true );
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
534
581
|
this._updateScroll(true);
|
|
535
582
|
}
|
|
536
583
|
|
|
@@ -546,22 +593,22 @@ export class GridView extends VLayout<GridViewProps, GridViewEventMap> {
|
|
|
546
593
|
|
|
547
594
|
this.m_columns.forEach((c) => {
|
|
548
595
|
if (c !== col) {
|
|
549
|
-
(c as GridColumnInternal).$
|
|
596
|
+
(c as GridColumnInternal).$hdr.sorted = false;
|
|
550
597
|
}
|
|
551
598
|
});
|
|
552
599
|
|
|
553
|
-
const $
|
|
600
|
+
const $hdr = (col as GridColumnInternal).$hdr;
|
|
554
601
|
|
|
555
|
-
if ($
|
|
556
|
-
$
|
|
602
|
+
if ($hdr.sorted) {
|
|
603
|
+
$hdr.toggleSens( );
|
|
557
604
|
}
|
|
558
605
|
else {
|
|
559
|
-
$
|
|
606
|
+
$hdr.sorted = true;
|
|
560
607
|
}
|
|
561
608
|
|
|
562
609
|
if (this.m_dataview) {
|
|
563
610
|
this.m_dataview.sort([
|
|
564
|
-
{ field: col.id, ascending: $
|
|
611
|
+
{ field: col.id, ascending: $hdr.sens=='dn' ? false : true }
|
|
565
612
|
]);
|
|
566
613
|
}
|
|
567
614
|
}
|
|
@@ -626,7 +673,8 @@ export class GridView extends VLayout<GridViewProps, GridViewEventMap> {
|
|
|
626
673
|
let cidx = 0;
|
|
627
674
|
let index = this.m_topIndex;
|
|
628
675
|
let count = this.m_dataview ? this.m_dataview.count : 0;
|
|
629
|
-
|
|
676
|
+
|
|
677
|
+
let full_width = 0; // todo: +4 pixel of left border
|
|
630
678
|
let even = this.m_topIndex & 1 ? true : false;
|
|
631
679
|
|
|
632
680
|
// compute full width
|
|
@@ -787,9 +835,8 @@ export class GridView extends VLayout<GridViewProps, GridViewEventMap> {
|
|
|
787
835
|
});
|
|
788
836
|
}
|
|
789
837
|
else {
|
|
790
|
-
this.m_header.setStyleValue('width', full_width);
|
|
791
|
-
this.m_footer?.setStyleValue('width', full_width);
|
|
792
|
-
|
|
838
|
+
this.m_header.setStyleValue('width', full_width + 1000 );
|
|
839
|
+
this.m_footer?.setStyleValue('width', full_width + 1000 );
|
|
793
840
|
this.m_container.setStyle({
|
|
794
841
|
height: count * this.m_itemHeight,
|
|
795
842
|
width: full_width
|
package/src/layout.ts
CHANGED
|
@@ -378,11 +378,20 @@ export class ScrollView extends Component<ScrollViewProps> {
|
|
|
378
378
|
export class Masonry extends Container {
|
|
379
379
|
|
|
380
380
|
constructor(props) {
|
|
381
|
+
const items = props.items;
|
|
382
|
+
props.items = undefined;
|
|
383
|
+
|
|
381
384
|
super(props);
|
|
382
385
|
|
|
383
386
|
this.setDomEvent('sizechange', () => {
|
|
384
387
|
this.resizeAllItems( );
|
|
385
388
|
});
|
|
389
|
+
|
|
390
|
+
if( items ) {
|
|
391
|
+
items.forEach( i => {
|
|
392
|
+
this.addItem( i );
|
|
393
|
+
});
|
|
394
|
+
}
|
|
386
395
|
}
|
|
387
396
|
|
|
388
397
|
resizeItem(item: Component) {
|
package/src/listview.ts
CHANGED
|
@@ -100,7 +100,7 @@ export interface ListViewProps<E extends ListViewEventMap = ListViewEventMap> ex
|
|
|
100
100
|
* Standard listview class
|
|
101
101
|
*/
|
|
102
102
|
|
|
103
|
-
export class ListView
|
|
103
|
+
export class ListView extends VLayout<ListViewProps,ListViewEventMap> {
|
|
104
104
|
|
|
105
105
|
protected m_selection: {
|
|
106
106
|
item: ListViewItem;
|
|
@@ -117,7 +117,7 @@ export class ListView<T extends ListViewProps = ListViewProps, E extends ListVie
|
|
|
117
117
|
|
|
118
118
|
protected m_cache: Map<number, Component>; // recycling elements
|
|
119
119
|
|
|
120
|
-
constructor(props:
|
|
120
|
+
constructor(props: ListViewProps) {
|
|
121
121
|
super(props);
|
|
122
122
|
|
|
123
123
|
this.setDomEvent('keydown', (e) => this._handleKey(e));
|
package/src/router.ts
CHANGED
|
@@ -27,45 +27,157 @@
|
|
|
27
27
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
28
28
|
**/
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
import { EventSource, EvError, EventMap } from "./x4_events"
|
|
31
|
+
|
|
32
|
+
type RouteHandler = ( params: any, path: string ) => void;
|
|
33
|
+
|
|
34
|
+
interface Segment {
|
|
35
|
+
keys: string[],
|
|
36
|
+
pattern: RegExp;
|
|
37
|
+
}
|
|
31
38
|
|
|
32
39
|
interface Route {
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
keys: string[],
|
|
41
|
+
pattern: RegExp;
|
|
42
|
+
handler: RouteHandler;
|
|
35
43
|
}
|
|
36
44
|
|
|
37
|
-
|
|
45
|
+
function parseRoute(str: string | RegExp, loose = false): Segment {
|
|
38
46
|
|
|
39
|
-
|
|
47
|
+
if (str instanceof RegExp) {
|
|
48
|
+
return {
|
|
49
|
+
keys: null,
|
|
50
|
+
pattern: str
|
|
51
|
+
};
|
|
52
|
+
}
|
|
40
53
|
|
|
41
|
-
|
|
42
|
-
|
|
54
|
+
const arr = str.split('/');
|
|
55
|
+
|
|
56
|
+
let keys = [];
|
|
57
|
+
let pattern = '';
|
|
58
|
+
|
|
59
|
+
if( arr[0]=='' ) {
|
|
60
|
+
arr.shift();
|
|
43
61
|
}
|
|
44
62
|
|
|
45
|
-
|
|
63
|
+
for (const tmp of arr) {
|
|
64
|
+
const c = tmp[0];
|
|
46
65
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
66
|
+
if (c === '*') {
|
|
67
|
+
keys.push('wild');
|
|
68
|
+
pattern += '/(.*)';
|
|
69
|
+
}
|
|
70
|
+
else if (c === ':') {
|
|
71
|
+
const o = tmp.indexOf('?', 1);
|
|
72
|
+
const ext = tmp.indexOf('.', 1);
|
|
73
|
+
|
|
74
|
+
keys.push(tmp.substring(1, o >= 0 ? o : ext >= 0 ? ext : tmp.length));
|
|
75
|
+
pattern += o < 0 && ext < 0 ? '(?:/([^/]+?))?' : '/([^/]+?)';
|
|
76
|
+
if (ext >= 0) {
|
|
77
|
+
pattern += (o >= 0 ? '?' : '') + '\\' + tmp.substring(ext);
|
|
51
78
|
}
|
|
52
|
-
}
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
pattern += '/' + tmp;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
keys,
|
|
87
|
+
pattern: new RegExp( `^${pattern}${loose ? '(?=$|\/)' : '\/?$'}`, 'i' )
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
interface RouterEventMap extends EventMap {
|
|
92
|
+
error: EvError;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export class Router extends EventSource< RouterEventMap > {
|
|
96
|
+
|
|
97
|
+
private routes: Route[];
|
|
53
98
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
99
|
+
constructor() {
|
|
100
|
+
super( );
|
|
101
|
+
|
|
102
|
+
this.routes = [];
|
|
103
|
+
|
|
104
|
+
window.addEventListener('popstate', (event) => {
|
|
105
|
+
const url = document.location.pathname;
|
|
106
|
+
const found = this._find(url);
|
|
107
|
+
|
|
108
|
+
found.handlers.forEach(h => {
|
|
109
|
+
h(found.params,url);
|
|
110
|
+
});
|
|
57
111
|
});
|
|
58
112
|
}
|
|
59
113
|
|
|
114
|
+
get(uri: string | RegExp, handler: RouteHandler ) {
|
|
115
|
+
let { keys, pattern } = parseRoute(uri);
|
|
116
|
+
this.routes.push({ keys, pattern, handler });
|
|
117
|
+
}
|
|
118
|
+
|
|
60
119
|
init() {
|
|
61
|
-
this.
|
|
120
|
+
this.navigate( window.location.pathname );
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
navigate( uri: string, notify = true ) {
|
|
124
|
+
|
|
125
|
+
const found = this._find( uri );
|
|
62
126
|
|
|
63
|
-
|
|
64
|
-
|
|
127
|
+
if( !found || found.handlers.length==0 ) {
|
|
128
|
+
//window.history.pushState({}, '', 'error')
|
|
129
|
+
console.log( 'route not found: '+uri );
|
|
130
|
+
this.signal( "error", EvError( 404, "route not found" ) );
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
65
133
|
|
|
66
|
-
|
|
67
|
-
|
|
134
|
+
window.history.pushState({}, '', uri )
|
|
135
|
+
|
|
136
|
+
if( notify ) {
|
|
137
|
+
found.handlers.forEach( h => {
|
|
138
|
+
h( found.params, uri );
|
|
139
|
+
} );
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private _find( url: string ): { params: any, handlers: RouteHandler[] } {
|
|
144
|
+
|
|
145
|
+
let matches = [];
|
|
146
|
+
let params = {};
|
|
147
|
+
let handlers = [];
|
|
148
|
+
|
|
149
|
+
for (const tmp of this.routes ) {
|
|
150
|
+
if (!tmp.keys ) {
|
|
151
|
+
matches = tmp.pattern.exec(url);
|
|
152
|
+
if (!matches) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (matches['groups']) {
|
|
157
|
+
for (const k in matches['groups']) {
|
|
158
|
+
params[k] = matches['groups'][k];
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
handlers = [...handlers, tmp.handler];
|
|
163
|
+
}
|
|
164
|
+
else if (tmp.keys.length > 0) {
|
|
165
|
+
matches = tmp.pattern.exec(url);
|
|
166
|
+
if (matches === null) {
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
for ( let j = 0; j < tmp.keys.length;) {
|
|
171
|
+
params[tmp.keys[j]] = matches[++j];
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
handlers = [...handlers, tmp.handler];
|
|
175
|
+
}
|
|
176
|
+
else if (tmp.pattern.test(url)) {
|
|
177
|
+
handlers = [...handlers, tmp.handler];
|
|
68
178
|
}
|
|
69
|
-
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return { params, handlers };
|
|
70
182
|
}
|
|
71
183
|
}
|
package/src/tabbar.ts
CHANGED
|
@@ -75,9 +75,12 @@ export class TabBar extends Container<TabBarProps,TabBarEventMap> {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
this.m_props.pages?.forEach( p => this.addPage(p) );
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
componentCreated(): void {
|
|
78
81
|
if( this.m_props.default ) {
|
|
79
|
-
this.select( this.m_props.default );
|
|
80
|
-
}
|
|
82
|
+
this.select( this.m_props.default, true );
|
|
83
|
+
}
|
|
81
84
|
}
|
|
82
85
|
|
|
83
86
|
addPage( page: ITabPage ) {
|
|
@@ -88,33 +91,53 @@ export class TabBar extends Container<TabBarProps,TabBarEventMap> {
|
|
|
88
91
|
render( ) {
|
|
89
92
|
let buttons = [];
|
|
90
93
|
this.m_pages.forEach( p => {
|
|
91
|
-
p.btn = new Button( { cls: p===this.m_curPage ? 'selected' : '', text: p.title, icon: p.icon, click: () => this._select(p) } );
|
|
94
|
+
p.btn = new Button( { cls: p===this.m_curPage ? 'selected' : '', text: p.title, icon: p.icon, click: () => this._select(p,true) } );
|
|
92
95
|
buttons.push( p.btn );
|
|
93
96
|
});
|
|
94
97
|
|
|
95
98
|
this.setContent( buttons );
|
|
96
99
|
}
|
|
97
100
|
|
|
98
|
-
select( id: string ) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
select( id: string | null, notify = false ) {
|
|
102
|
+
if( !id ) {
|
|
103
|
+
this._select( null, notify );
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
let page = this.m_pages.find( x => x.id===id );
|
|
107
|
+
if( page ) {
|
|
108
|
+
this._select( page, notify );
|
|
109
|
+
}
|
|
102
110
|
}
|
|
103
111
|
}
|
|
104
112
|
|
|
105
|
-
private _select( p: TabPage ) {
|
|
113
|
+
private _select( p: TabPage, notify: boolean ) {
|
|
106
114
|
|
|
107
|
-
if( this.
|
|
115
|
+
if( this.m_curPage==p ) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if( this.dom && this.m_curPage ) {
|
|
108
120
|
this.m_curPage.btn.removeClass( 'selected' );
|
|
109
|
-
this.m_curPage.page
|
|
121
|
+
if( this.m_curPage.page ) {
|
|
122
|
+
this.m_curPage.page.hide( );
|
|
123
|
+
}
|
|
110
124
|
}
|
|
111
125
|
|
|
112
126
|
this.m_curPage = p;
|
|
113
|
-
this.signal( 'change', EvChange(p ? p.id : null) );
|
|
114
127
|
|
|
115
|
-
if(
|
|
128
|
+
if( notify ) {
|
|
129
|
+
this.signal( 'change', EvChange(p ? p.id : null) );
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if( this.dom && this.m_curPage ) {
|
|
116
133
|
this.m_curPage.btn.addClass( 'selected' );
|
|
117
|
-
this.m_curPage.page
|
|
134
|
+
if( this.m_curPage.page ) {
|
|
135
|
+
this.m_curPage.page.show( );
|
|
136
|
+
}
|
|
118
137
|
}
|
|
119
138
|
}
|
|
139
|
+
|
|
140
|
+
get selection( ) {
|
|
141
|
+
return this.m_curPage?.page;
|
|
142
|
+
}
|
|
120
143
|
}
|
package/src/x4.less
CHANGED
|
@@ -1312,12 +1312,13 @@ textarea {
|
|
|
1312
1312
|
}
|
|
1313
1313
|
}
|
|
1314
1314
|
|
|
1315
|
+
@bwidth: 4px;
|
|
1315
1316
|
|
|
1316
1317
|
.x-spreadsheet,
|
|
1317
1318
|
.x-grid-view {
|
|
1318
1319
|
|
|
1319
1320
|
@def-height: 2em;
|
|
1320
|
-
|
|
1321
|
+
|
|
1321
1322
|
min-height: 0;
|
|
1322
1323
|
overflow: hidden;
|
|
1323
1324
|
background-color: white;
|
|
@@ -1370,7 +1371,7 @@ textarea {
|
|
|
1370
1371
|
|
|
1371
1372
|
.x-row {
|
|
1372
1373
|
position: absolute;
|
|
1373
|
-
width: 100
|
|
1374
|
+
width: calc( 100% - @bwidth ); // todo: border of 1st col
|
|
1374
1375
|
border-bottom: 1px solid #f0f0f0;
|
|
1375
1376
|
align-items: center;
|
|
1376
1377
|
height: @def-height;
|
|
@@ -1400,11 +1401,11 @@ textarea {
|
|
|
1400
1401
|
.x-grid-view {
|
|
1401
1402
|
.x-footer,
|
|
1402
1403
|
.x-header {
|
|
1403
|
-
border-left:
|
|
1404
|
+
border-left: @bwidth solid #f0f0f0;
|
|
1404
1405
|
}
|
|
1405
1406
|
|
|
1406
1407
|
.x-row {
|
|
1407
|
-
border-left:
|
|
1408
|
+
border-left: @bwidth solid transparent;
|
|
1408
1409
|
|
|
1409
1410
|
&:hover {
|
|
1410
1411
|
background-color: rgba(0,0,0,0.1);
|
package/src/x4_events.ts
CHANGED
|
@@ -168,6 +168,19 @@ export function EvDrag(element: unknown, data: any, ctx: any ) {
|
|
|
168
168
|
return BasicEvent<EvDrag>({ element, data, context: ctx });
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Errors
|
|
173
|
+
*/
|
|
174
|
+
|
|
175
|
+
export interface EvError extends BasicEvent {
|
|
176
|
+
code: number;
|
|
177
|
+
message: string;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function EvError( code: number, message: string ) : EvError {
|
|
181
|
+
return BasicEvent<EvError>( {code, message} );
|
|
182
|
+
}
|
|
183
|
+
|
|
171
184
|
|
|
172
185
|
/**
|
|
173
186
|
* this Base interface is used to describe available events & their types
|