x4js 2.0.13 → 2.0.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/.vscode/launch.json +14 -0
- package/README.md +5 -0
- package/{lib/src/demo → demo}/main.scss +3 -1
- package/{lib/src/demo/main.tsx → demo/main.ts} +37 -36
- package/demo/package.json +26 -0
- package/demo/scss.d.ts +4 -0
- package/demo/svg.d.ts +1 -0
- package/demo/tsconfig.json +14 -0
- package/lib/README.txt +5 -0
- package/lib/cjs/x4.css +1 -1
- package/lib/cjs/x4.js +2 -1
- package/lib/esm/x4.css +1 -1
- package/lib/esm/x4.mjs +2 -1
- package/lib/src/components/boxes/boxes.module.scss +17 -0
- package/lib/src/components/boxes/boxes.ts +258 -17
- package/lib/src/components/breadcrumb/breadcrumb.scss +56 -28
- package/lib/src/components/breadcrumb/breadcrumb.ts +93 -84
- package/lib/src/components/btngroup/btngroup.module.scss +12 -0
- package/lib/src/components/btngroup/btngroup.ts +41 -8
- package/lib/src/components/button/button.module.scss +23 -5
- package/lib/src/components/button/button.ts +72 -4
- package/lib/src/components/canvas/canvas.module.scss +25 -0
- package/lib/src/components/canvas/canvas.ts +189 -0
- package/lib/src/components/canvas/canvas_ex.ts +276 -0
- package/lib/src/components/checkbox/checkbox.ts +18 -4
- package/lib/src/components/combobox/combobox.module.scss +24 -15
- package/lib/src/components/combobox/combobox.ts +107 -24
- package/lib/src/components/components.ts +7 -0
- package/lib/src/components/dialog/dialog.module.scss +40 -7
- package/lib/src/components/dialog/dialog.ts +166 -31
- package/lib/src/components/filedrop/cloud-arrow-up.svg +1 -0
- package/lib/src/components/filedrop/filedrop.module.scss +70 -0
- package/lib/src/components/filedrop/filedrop.ts +131 -0
- package/lib/src/components/form/form.module.scss +4 -0
- package/lib/src/components/form/form.ts +137 -6
- package/lib/src/components/gridview/arrow-down-light.svg +1 -0
- package/lib/src/components/gridview/arrow-up-light.svg +1 -0
- package/lib/src/components/gridview/gridview.module.scss +324 -0
- package/lib/src/components/gridview/gridview.ts +1175 -0
- package/lib/src/components/icon/icon.module.scss +2 -1
- package/lib/src/components/icon/icon.ts +4 -3
- package/lib/src/components/image/image.module.scss +8 -1
- package/lib/src/components/image/image.ts +105 -6
- package/lib/src/components/input/input.module.scss +8 -3
- package/lib/src/components/input/input.ts +178 -31
- package/lib/src/components/keyboard/arrow-up.svg +1 -0
- package/lib/src/components/keyboard/delete-left.svg +1 -0
- package/lib/src/components/keyboard/eye-slash.svg +1 -0
- package/lib/src/components/keyboard/keyboard.module.scss +134 -0
- package/lib/src/components/keyboard/keyboard.ts +526 -0
- package/lib/src/components/label/label.module.scss +22 -4
- package/lib/src/components/label/label.ts +33 -0
- package/lib/src/components/link/link.ts +81 -78
- package/lib/src/components/listbox/listbox.module.scss +61 -3
- package/lib/src/components/listbox/listbox.ts +164 -56
- package/lib/src/components/menu/menu.module.scss +10 -1
- package/lib/src/components/menu/menu.ts +6 -3
- package/lib/src/components/messages/messages.module.scss +44 -0
- package/lib/src/components/messages/messages.ts +164 -18
- package/lib/src/components/messages/pen-field.svg +1 -0
- package/lib/src/components/normalize.scss +5 -0
- package/lib/src/components/notification/notification.module.scss +4 -2
- package/lib/src/components/notification/notification.ts +2 -4
- package/lib/src/components/panel/panel.module.scss +12 -0
- package/lib/src/components/popup/popup.module.scss +10 -2
- package/lib/src/components/popup/popup.ts +141 -95
- package/lib/src/components/propgrid/folder-closed.svg +1 -0
- package/lib/src/components/propgrid/folder-open.svg +1 -0
- package/lib/src/components/propgrid/progrid.module.scss +112 -0
- package/lib/src/components/propgrid/propgrid.ts +288 -0
- package/lib/src/components/propgrid/updown.svg +4 -0
- package/lib/src/components/radio/radio.module.scss +147 -0
- package/lib/src/components/radio/radio.svg +4 -0
- package/lib/src/components/radio/radio.ts +142 -0
- package/lib/src/components/select/select.module.scss +9 -0
- package/lib/src/components/select/select.ts +134 -0
- package/lib/src/components/shared.scss +47 -0
- package/lib/src/components/sizers/sizer.ts +10 -2
- package/lib/src/components/slider/slider.module.scss +77 -30
- package/lib/src/components/slider/slider.ts +72 -22
- package/lib/src/components/tabs/tabs.module.scss +1 -2
- package/lib/src/components/tabs/tabs.ts +49 -12
- package/lib/src/components/textarea/textarea.module.scss +6 -2
- package/lib/src/components/textarea/textarea.ts +73 -8
- package/lib/src/components/textedit/textedit.module.scss +3 -1
- package/lib/src/components/textedit/textedit.ts +47 -15
- package/lib/src/components/themes.scss +7 -0
- package/lib/src/components/tickline/tickline.module.scss +26 -0
- package/lib/src/components/tickline/tickline.ts +82 -0
- package/lib/src/components/tooltips/comments-question.svg +1 -0
- package/lib/src/components/tooltips/tooltips.scss +30 -9
- package/lib/src/components/tooltips/tooltips.ts +10 -5
- package/lib/src/components/treeview/treeview.module.scss +129 -60
- package/lib/src/components/treeview/treeview.ts +47 -12
- package/lib/src/components/viewport/viewport.module.scss +7 -0
- package/lib/src/core/component.ts +113 -40
- package/lib/src/core/core_application.ts +223 -2
- package/lib/src/core/core_colors.ts +2 -2
- package/lib/src/{components/grid/datastore.ts → core/core_data.ts} +264 -252
- package/lib/src/core/core_dragdrop.ts +3 -3
- package/lib/src/core/core_element.ts +18 -1
- package/lib/src/core/core_events.ts +28 -0
- package/lib/src/core/core_i18n.ts +19 -3
- package/lib/src/core/core_react.ts +79 -0
- package/lib/src/core/core_router.ts +25 -9
- package/lib/src/core/core_state.ts +62 -0
- package/lib/src/core/core_styles.ts +5 -5
- package/lib/src/core/core_svg.ts +174 -12
- package/lib/src/core/core_tools.ts +305 -87
- package/lib/src/x4tsx.d.ts +25 -0
- package/lib/styles/x4.css +1 -1
- package/lib/types/x4js.d.ts +828 -119
- package/package.json +4 -4
- package/scripts/build.mjs +378 -0
- package/scripts/prepack.mjs +346 -0
- package/src/components/base.scss +25 -0
- package/src/components/boxes/boxes.module.scss +54 -0
- package/src/components/boxes/boxes.ts +370 -0
- package/src/components/breadcrumb/breadcrumb.scss +56 -0
- package/src/components/breadcrumb/breadcrumb.ts +93 -0
- package/src/components/breadcrumb/chevron-right.svg +1 -0
- package/src/components/btngroup/btngroup.module.scss +41 -0
- package/src/components/btngroup/btngroup.ts +153 -0
- package/src/components/button/button.module.scss +173 -0
- package/src/components/button/button.ts +185 -0
- package/src/components/calendar/calendar-check-sharp-light.svg +1 -0
- package/src/components/calendar/calendar.module.scss +163 -0
- package/src/components/calendar/calendar.ts +327 -0
- package/src/components/calendar/chevron-left-sharp-light.svg +1 -0
- package/src/components/calendar/chevron-right-sharp-light.svg +1 -0
- package/src/components/canvas/canvas.module.scss +25 -0
- package/src/components/canvas/canvas.ts +189 -0
- package/src/components/canvas/canvas_ex.ts +276 -0
- package/src/components/checkbox/check.svg +4 -0
- package/src/components/checkbox/checkbox.module.scss +142 -0
- package/src/components/checkbox/checkbox.ts +140 -0
- package/src/components/colorinput/colorinput.module.scss +65 -0
- package/src/components/colorinput/colorinput.ts +91 -0
- package/src/components/colorinput/crosshairs-simple-sharp-light.svg +1 -0
- package/src/components/colorpicker/colorpicker.module.scss +133 -0
- package/src/components/colorpicker/colorpicker.ts +482 -0
- package/src/components/combobox/combobox.module.scss +133 -0
- package/src/components/combobox/combobox.ts +275 -0
- package/src/components/combobox/updown.svg +4 -0
- package/src/components/components.ts +41 -0
- package/src/components/dialog/dialog.module.scss +104 -0
- package/src/components/dialog/dialog.ts +229 -0
- package/src/components/dialog/xmark-sharp-light.svg +1 -0
- package/src/components/filedrop/cloud-arrow-up.svg +1 -0
- package/src/components/filedrop/filedrop.module.scss +70 -0
- package/src/components/filedrop/filedrop.ts +131 -0
- package/src/components/form/form.module.scss +38 -0
- package/src/components/form/form.ts +172 -0
- package/src/components/gridview/arrow-down-light.svg +1 -0
- package/src/components/gridview/arrow-up-light.svg +1 -0
- package/src/components/gridview/gridview.module.scss +324 -0
- package/src/components/gridview/gridview.ts +1175 -0
- package/src/components/header/header.module.scss +40 -0
- package/src/components/header/header.ts +130 -0
- package/src/components/icon/icon.module.scss +31 -0
- package/src/components/icon/icon.ts +137 -0
- package/src/components/image/image.module.scss +28 -0
- package/src/components/image/image.ts +168 -0
- package/src/components/input/input.module.scss +74 -0
- package/src/components/input/input.ts +422 -0
- package/src/components/keyboard/arrow-up.svg +1 -0
- package/src/components/keyboard/delete-left.svg +1 -0
- package/src/components/keyboard/eye-slash.svg +1 -0
- package/src/components/keyboard/keyboard.module.scss +134 -0
- package/src/components/keyboard/keyboard.ts +526 -0
- package/src/components/label/label.module.scss +76 -0
- package/src/components/label/label.ts +97 -0
- package/src/components/link/link.ts +81 -0
- package/src/components/listbox/listbox.module.scss +161 -0
- package/src/components/listbox/listbox.ts +539 -0
- package/src/components/menu/caret-right-solid.svg +1 -0
- package/src/components/menu/menu.module.scss +117 -0
- package/src/components/menu/menu.ts +174 -0
- package/src/components/messages/circle-exclamation.svg +1 -0
- package/src/components/messages/messages.module.scss +92 -0
- package/src/components/messages/messages.ts +215 -0
- package/src/components/messages/pen-field.svg +1 -0
- package/src/components/normalize.scss +391 -0
- package/src/components/notification/circle-check-solid.svg +1 -0
- package/src/components/notification/circle-exclamation-solid.svg +1 -0
- package/src/components/notification/circle-notch-light.svg +1 -0
- package/src/components/notification/notification.module.scss +84 -0
- package/src/components/notification/notification.ts +107 -0
- package/src/components/notification/xmark-sharp-light.svg +1 -0
- package/src/components/panel/panel.module.scss +60 -0
- package/src/components/panel/panel.ts +58 -0
- package/src/components/popup/popup.module.scss +51 -0
- package/src/components/popup/popup.ts +442 -0
- package/src/components/progress/progress.module.scss +57 -0
- package/src/components/progress/progress.ts +44 -0
- package/src/components/propgrid/folder-closed.svg +1 -0
- package/src/components/propgrid/folder-open.svg +1 -0
- package/src/components/propgrid/progrid.module.scss +112 -0
- package/src/components/propgrid/propgrid.ts +288 -0
- package/src/components/propgrid/updown.svg +4 -0
- package/src/components/radio/radio.module.scss +147 -0
- package/src/components/radio/radio.svg +4 -0
- package/src/components/radio/radio.ts +142 -0
- package/src/components/rating/rating.module.scss +23 -0
- package/src/components/rating/rating.ts +131 -0
- package/src/components/rating/star-sharp-light.svg +1 -0
- package/src/components/rating/star-sharp-solid.svg +1 -0
- package/src/components/select/select.module.scss +9 -0
- package/src/components/select/select.ts +134 -0
- package/src/components/shared.scss +137 -0
- package/src/components/sizers/sizer.module.scss +90 -0
- package/src/components/sizers/sizer.ts +132 -0
- package/src/components/slider/slider.module.scss +118 -0
- package/src/components/slider/slider.ts +198 -0
- package/src/components/switch/switch.module.scss +127 -0
- package/src/components/switch/switch.ts +62 -0
- package/src/components/tabs/tabs.module.scss +45 -0
- package/src/components/tabs/tabs.ts +205 -0
- package/src/components/textarea/textarea.module.scss +63 -0
- package/src/components/textarea/textarea.ts +125 -0
- package/src/components/textedit/textedit.module.scss +116 -0
- package/src/components/textedit/textedit.ts +115 -0
- package/src/components/themes.scss +88 -0
- package/src/components/tickline/tickline.module.scss +26 -0
- package/src/components/tickline/tickline.ts +82 -0
- package/src/components/tooltips/circle-info-sharp-light.svg +1 -0
- package/src/components/tooltips/comments-question.svg +1 -0
- package/src/components/tooltips/tooltips.scss +72 -0
- package/src/components/tooltips/tooltips.ts +109 -0
- package/src/components/treeview/chevron-down-light.svg +1 -0
- package/src/components/treeview/treeview.module.scss +185 -0
- package/src/components/treeview/treeview.ts +445 -0
- package/src/components/viewport/viewport.module.scss +32 -0
- package/src/components/viewport/viewport.ts +41 -0
- package/src/core/component.ts +1075 -0
- package/src/core/core_application.ts +265 -0
- package/src/core/core_colors.ts +250 -0
- package/src/core/core_data.ts +1310 -0
- package/src/core/core_dom.ts +471 -0
- package/src/core/core_dragdrop.ts +201 -0
- package/src/core/core_element.ts +115 -0
- package/src/core/core_events.ts +177 -0
- package/src/core/core_i18n.ts +393 -0
- package/src/core/core_react.ts +79 -0
- package/src/core/core_router.ts +237 -0
- package/src/core/core_state.ts +62 -0
- package/src/core/core_styles.ts +214 -0
- package/src/core/core_svg.ts +712 -0
- package/src/core/core_tools.ts +906 -0
- package/src/types/scss.d.ts +4 -0
- package/src/types/svg.d.ts +1 -0
- package/src/types/x4react.d.ts +9 -0
- package/src/x4.scss +19 -0
- package/src/x4tsx.d.ts +25 -0
- package/tsconfig.json +14 -0
- package/lib/src/components/grid/gridview.ts +0 -1108
- package/lib/src/components/grid/memdb.ts +0 -325
- /package/{lib/src/demo → demo}/assets/house-light.svg +0 -0
- /package/{lib/src/demo → demo}/assets/radio.svg +0 -0
- /package/{lib/src/demo → demo}/index.html +0 -0
|
@@ -25,7 +25,7 @@ interface DropInfo {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
type DropCallback = ( command: 'enter' | 'leave' | 'drag' | 'drop', el: Component, infos: DropInfo ) => void;
|
|
28
|
-
type FilterCallback = ( el: Component ) => boolean;
|
|
28
|
+
type FilterCallback = ( el: Component, data: DataTransfer ) => boolean;
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
*
|
|
@@ -84,7 +84,7 @@ class DragManager {
|
|
|
84
84
|
registerDropTarget(el: Component, cb: DropCallback, filterCB?: FilterCallback ) {
|
|
85
85
|
|
|
86
86
|
const dragEnter = (ev: DragEvent) => {
|
|
87
|
-
if( filterCB && !filterCB(this.dragSource) ) {
|
|
87
|
+
if( filterCB && !filterCB(this.dragSource,ev.dataTransfer) ) {
|
|
88
88
|
console.log( 'reject ', el );
|
|
89
89
|
ev.dataTransfer.dropEffect = 'none';
|
|
90
90
|
return;
|
|
@@ -98,7 +98,7 @@ class DragManager {
|
|
|
98
98
|
const dragOver = (ev: DragEvent) => {
|
|
99
99
|
//console.log( "dragover", ev.target );
|
|
100
100
|
|
|
101
|
-
if( filterCB && !filterCB(this.dragSource) ) {
|
|
101
|
+
if( filterCB && !filterCB(this.dragSource,ev.dataTransfer) ) {
|
|
102
102
|
console.log( 'reject ', el );
|
|
103
103
|
ev.dataTransfer.dropEffect = 'none';
|
|
104
104
|
return;
|
|
@@ -42,7 +42,7 @@ export class CoreElement<E extends EventMap = EventMap> {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
private __stopTimer( name: string ) {
|
|
45
|
-
const clear = this.#timers
|
|
45
|
+
const clear = this.#timers?.get(name);
|
|
46
46
|
if (clear) { clear(); }
|
|
47
47
|
}
|
|
48
48
|
|
|
@@ -84,6 +84,23 @@ export class CoreElement<E extends EventMap = EventMap> {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
this.#events.addListener( name, listener );
|
|
87
|
+
return {
|
|
88
|
+
off: ( ) => {
|
|
89
|
+
this.#events.removeListener( name, listener );
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* detach
|
|
96
|
+
*/
|
|
97
|
+
|
|
98
|
+
off<K extends keyof E>( name: K, listener: ( ev: E[K] ) => void ) {
|
|
99
|
+
console.assert( listener!==undefined && listener!==null );
|
|
100
|
+
|
|
101
|
+
if( this.#events ) {
|
|
102
|
+
this.#events.removeListener( name, listener );
|
|
103
|
+
}
|
|
87
104
|
}
|
|
88
105
|
|
|
89
106
|
/**
|
|
@@ -91,6 +91,34 @@ export class EventSource<E extends EventMap = EventMap > {
|
|
|
91
91
|
listeners.push(cb);
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
|
+
|
|
95
|
+
return ( ) => {
|
|
96
|
+
this.removeListener( name, callback );
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* stop listening to an event
|
|
102
|
+
* @param eventName - event name
|
|
103
|
+
* @param callback - callback to remove (must be the same as in on )
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
removeListener<K extends keyof E>(name: K, callback: (ev: E[K]) => any) {
|
|
107
|
+
|
|
108
|
+
if (!this._registry ) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let listeners = this._registry.get(name as string);
|
|
113
|
+
if (!listeners) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const cb = callback as EventCallback;
|
|
118
|
+
const idx = listeners.indexOf(cb);
|
|
119
|
+
if (idx !== -1) {
|
|
120
|
+
listeners.splice(idx, 1);
|
|
121
|
+
}
|
|
94
122
|
}
|
|
95
123
|
|
|
96
124
|
fire<K extends keyof E>(name: K, evx: E[K]) {
|
|
@@ -97,7 +97,7 @@ export function addTranslation( name: string, ...parts: any[] ) {
|
|
|
97
97
|
|
|
98
98
|
function _patch( obj: any, by: any ) {
|
|
99
99
|
|
|
100
|
-
for(
|
|
100
|
+
for( const n in by ) {
|
|
101
101
|
const src = by[n];
|
|
102
102
|
if( typeof src === "string" ) {
|
|
103
103
|
obj[n] = src;
|
|
@@ -303,7 +303,15 @@ let fr = {
|
|
|
303
303
|
|
|
304
304
|
copy: 'Copier',
|
|
305
305
|
cut: 'Couper',
|
|
306
|
-
paste: 'Coller'
|
|
306
|
+
paste: 'Coller',
|
|
307
|
+
|
|
308
|
+
filedrop: 'Déposez un fichier',
|
|
309
|
+
|
|
310
|
+
keyboard: {
|
|
311
|
+
next: 'Suivant',
|
|
312
|
+
numeric: '123',
|
|
313
|
+
alpha: 'Abc'
|
|
314
|
+
},
|
|
307
315
|
}
|
|
308
316
|
};
|
|
309
317
|
|
|
@@ -359,7 +367,15 @@ let en = {
|
|
|
359
367
|
|
|
360
368
|
copy: 'Copy',
|
|
361
369
|
cut: 'Cut',
|
|
362
|
-
paste: 'Paste'
|
|
370
|
+
paste: 'Paste',
|
|
371
|
+
|
|
372
|
+
filedrop: 'Drop a file',
|
|
373
|
+
|
|
374
|
+
keyboard: {
|
|
375
|
+
next: 'Next',
|
|
376
|
+
numeric: '123',
|
|
377
|
+
alpha: 'Abc'
|
|
378
|
+
},
|
|
363
379
|
}
|
|
364
380
|
};
|
|
365
381
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ___ ___ __
|
|
3
|
+
* \ \/ / / _
|
|
4
|
+
* \ / /_| |_
|
|
5
|
+
* / \____ _|
|
|
6
|
+
* /__/\__\ |_|.2
|
|
7
|
+
*
|
|
8
|
+
* @file core_react.ts
|
|
9
|
+
* @author Etienne Cochard
|
|
10
|
+
*
|
|
11
|
+
* @copyright (c) 2025 R-libre ingenierie
|
|
12
|
+
*
|
|
13
|
+
* Use of this source code is governed by an MIT-style license
|
|
14
|
+
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
|
+
*
|
|
16
|
+
* to use you must:
|
|
17
|
+
*
|
|
18
|
+
* 1. add this to your tsconfig.json
|
|
19
|
+
* "compilerOptions": {
|
|
20
|
+
* ...
|
|
21
|
+
* "jsx": "preserve",
|
|
22
|
+
* ...
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* 2. be sure that esbuild has this:
|
|
26
|
+
* jsxFactory: "x4create_element",
|
|
27
|
+
* loader: { ".ts": "tsx" }
|
|
28
|
+
*
|
|
29
|
+
*
|
|
30
|
+
* after that, all things like that will be ok
|
|
31
|
+
*
|
|
32
|
+
* import { x4_create_element } from "x4react"
|
|
33
|
+
* const xx = <h1>This is a title</h1>
|
|
34
|
+
*
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
import { Component } from './component.js';
|
|
38
|
+
import { Constructor, isString } from './core_tools.js';
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* x4 is reactive ?
|
|
43
|
+
* hard jsx :)
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
export class x4_react {
|
|
47
|
+
|
|
48
|
+
static create_element( tag: string, props: any, ...content: any[] ): Component;
|
|
49
|
+
static create_element<X extends Component>( tag: string | Constructor<X>, props: X["props"], ...content: any[] ) {
|
|
50
|
+
|
|
51
|
+
props = props || {};
|
|
52
|
+
|
|
53
|
+
let el: Component;
|
|
54
|
+
|
|
55
|
+
// --- simple div ------------------------
|
|
56
|
+
if( isString(tag) ) {
|
|
57
|
+
el = new Component( { tag } );
|
|
58
|
+
Object.entries( props )
|
|
59
|
+
.forEach(([name, value]) => {
|
|
60
|
+
if (name.startsWith('on') && name.toLowerCase() in window) {
|
|
61
|
+
el.dom.addEventListener(name.toLowerCase().substring(2), value)
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
el.setAttribute(name, value )
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
// --- Component ------------------------
|
|
69
|
+
else {
|
|
70
|
+
el = new tag( props );
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if( content && content.length ) {
|
|
74
|
+
el.appendContent( content );
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return el;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -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 { EvError } from './component.js';
|
|
17
|
+
import { EvChange, EvError } from './component.js';
|
|
18
18
|
import { EventMap, EventSource } from './core_events.js';
|
|
19
19
|
|
|
20
20
|
type RouteHandler = ( params: any, path: string ) => void;
|
|
@@ -30,7 +30,7 @@ interface Route {
|
|
|
30
30
|
handler: RouteHandler;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
function parseRoute(str: string | RegExp, loose = false): Segment {
|
|
33
|
+
export function parseRoute(str: string | RegExp, loose = false): Segment {
|
|
34
34
|
|
|
35
35
|
if (str instanceof RegExp) {
|
|
36
36
|
return {
|
|
@@ -60,7 +60,7 @@ function parseRoute(str: string | RegExp, loose = false): Segment {
|
|
|
60
60
|
const ext = tmp.indexOf('.', 1);
|
|
61
61
|
|
|
62
62
|
keys.push(tmp.substring(1, o >= 0 ? o : ext >= 0 ? ext : tmp.length));
|
|
63
|
-
pattern += o >= 0 && ext < 0 ? '(?:/([
|
|
63
|
+
pattern += o >= 0 && ext < 0 ? '(?:/([^/]+?))?' : '/([^/]+?)';
|
|
64
64
|
if (ext >= 0) {
|
|
65
65
|
pattern += (o >= 0 ? '?' : '') + '\\' + tmp.substring(ext);
|
|
66
66
|
}
|
|
@@ -72,11 +72,12 @@ function parseRoute(str: string | RegExp, loose = false): Segment {
|
|
|
72
72
|
|
|
73
73
|
return {
|
|
74
74
|
keys,
|
|
75
|
-
pattern: new RegExp( `^${pattern}${loose ? '(
|
|
75
|
+
pattern: new RegExp( `^${pattern}${loose ? '(?=$|/)' : '/?$'}`, 'i' )
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
interface RouterEvents extends EventMap {
|
|
80
|
+
change: EvChange;
|
|
80
81
|
error: EvError;
|
|
81
82
|
}
|
|
82
83
|
|
|
@@ -116,7 +117,7 @@ export class Router extends EventSource< RouterEvents > {
|
|
|
116
117
|
|
|
117
118
|
this.m_routes = [];
|
|
118
119
|
this.m_useHash = useHash;
|
|
119
|
-
|
|
120
|
+
|
|
120
121
|
window.addEventListener('popstate', (event) => {
|
|
121
122
|
const url = this._getLocation( );
|
|
122
123
|
const found = this._find(url);
|
|
@@ -124,6 +125,8 @@ export class Router extends EventSource< RouterEvents > {
|
|
|
124
125
|
found.handlers.forEach(h => {
|
|
125
126
|
h(found.params,url);
|
|
126
127
|
});
|
|
128
|
+
|
|
129
|
+
this.fire( "change", { value: this._getLocation() } );
|
|
127
130
|
});
|
|
128
131
|
}
|
|
129
132
|
|
|
@@ -140,6 +143,10 @@ export class Router extends EventSource< RouterEvents > {
|
|
|
140
143
|
return this.m_useHash ? '/'+document.location.hash.substring(1) : document.location.pathname;
|
|
141
144
|
}
|
|
142
145
|
|
|
146
|
+
/**
|
|
147
|
+
*
|
|
148
|
+
*/
|
|
149
|
+
|
|
143
150
|
navigate( uri: string, notify = true, replace = false ) {
|
|
144
151
|
|
|
145
152
|
if( !uri.startsWith('/') ) {
|
|
@@ -152,7 +159,7 @@ export class Router extends EventSource< RouterEvents > {
|
|
|
152
159
|
//window.history.pushState({}, '', 'error')
|
|
153
160
|
console.log( 'route not found: '+uri );
|
|
154
161
|
this.fire( "error", {code: 404, message: "route not found" } );
|
|
155
|
-
return;
|
|
162
|
+
return false;
|
|
156
163
|
}
|
|
157
164
|
|
|
158
165
|
if( this.m_useHash ) {
|
|
@@ -171,12 +178,21 @@ export class Router extends EventSource< RouterEvents > {
|
|
|
171
178
|
}
|
|
172
179
|
|
|
173
180
|
if( notify ) {
|
|
174
|
-
found.handlers.forEach( h => {
|
|
175
|
-
|
|
176
|
-
} );
|
|
181
|
+
//found.handlers.forEach( h => {
|
|
182
|
+
// h( found.params, uri );
|
|
183
|
+
//} );
|
|
184
|
+
|
|
185
|
+
found.handlers[0]( found.params, uri );
|
|
177
186
|
}
|
|
187
|
+
|
|
188
|
+
this.fire( "change", { value: this._getLocation() } );
|
|
189
|
+
return true;
|
|
178
190
|
}
|
|
179
191
|
|
|
192
|
+
/**
|
|
193
|
+
*
|
|
194
|
+
*/
|
|
195
|
+
|
|
180
196
|
private _find( url: string ): { params: Record<string,any>, handlers: RouteHandler[] } {
|
|
181
197
|
|
|
182
198
|
let matches = [];
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file core_state.ts
|
|
3
|
+
* @author Etienne Cochard
|
|
4
|
+
* @copyright (c) 2025 R-libre ingenierie, all rights reserved.
|
|
5
|
+
**/
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
type StateData = boolean | number | string | Date | any;
|
|
9
|
+
type State = Record<string,StateData>;
|
|
10
|
+
|
|
11
|
+
export class StateManager {
|
|
12
|
+
|
|
13
|
+
private _state: StateData;
|
|
14
|
+
private _subscribers: Map<string,any>;
|
|
15
|
+
private _currentTracking: Set<string>;
|
|
16
|
+
|
|
17
|
+
constructor(initialState: StateData ) {
|
|
18
|
+
this._state = initialState ? { ...initialState } : {};
|
|
19
|
+
this._subscribers = new Map();
|
|
20
|
+
this._currentTracking = new Set( );
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
getState( path: string, defaultValue: StateData = null) {
|
|
24
|
+
// Optional tracking for reactivity
|
|
25
|
+
if (this._currentTracking) {
|
|
26
|
+
this._currentTracking.add(path);
|
|
27
|
+
}
|
|
28
|
+
// Fast path-based access
|
|
29
|
+
const parts = path.split('.');
|
|
30
|
+
let current = this._state;
|
|
31
|
+
|
|
32
|
+
for (const part of parts) {
|
|
33
|
+
if (current?.[part] === undefined) {
|
|
34
|
+
return defaultValue;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
current = current[part];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return current;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
setState(path: string, value: StateData, context: any = {} ) {
|
|
44
|
+
// Update state
|
|
45
|
+
const parts = path.split('.');
|
|
46
|
+
let current = this._state;
|
|
47
|
+
|
|
48
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
49
|
+
const part = parts[i];
|
|
50
|
+
if (!current[part] || typeof current[part] !== 'object') {
|
|
51
|
+
current[part] = {};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
current = current[part];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
current[parts[parts.length - 1]] = value;
|
|
58
|
+
|
|
59
|
+
// Notify subscribers
|
|
60
|
+
this._notifySubscribers(path, value);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -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 {
|
|
17
|
+
import { isString } from './core_tools.js';
|
|
18
18
|
|
|
19
19
|
export const unitless: Record<string,1> = {
|
|
20
20
|
animationIterationCount: 1,
|
|
@@ -82,8 +82,8 @@ export function isUnitLess( name: string ) {
|
|
|
82
82
|
|
|
83
83
|
export class Stylesheet {
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
readonly m_sheet: CSSStyleSheet;
|
|
86
|
+
readonly m_rules: Map<string, number> = new Map( );
|
|
87
87
|
|
|
88
88
|
constructor() {
|
|
89
89
|
|
|
@@ -91,7 +91,7 @@ export class Stylesheet {
|
|
|
91
91
|
for(let i=0; i<document.styleSheets.length; i++) {
|
|
92
92
|
let sheet = document.styleSheets[i];
|
|
93
93
|
if(sheet.title === name ) {
|
|
94
|
-
return
|
|
94
|
+
return sheet;
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
}
|
|
@@ -101,7 +101,7 @@ export class Stylesheet {
|
|
|
101
101
|
const dom = document.createElement( 'style' );
|
|
102
102
|
dom.setAttribute('id', 'x4-dynamic-css' );
|
|
103
103
|
document.head.appendChild(dom);
|
|
104
|
-
this.m_sheet =
|
|
104
|
+
this.m_sheet = dom.sheet
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
|