x4js 2.0.13 → 2.0.14
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 +162 -13
- 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 +269 -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 +37 -3
- package/lib/src/components/dialog/dialog.ts +149 -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 +1 -1
- package/lib/src/components/icon/icon.ts +4 -1
- 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 +137 -14
- 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 +525 -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 +4 -1
- 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 +4 -2
- package/lib/src/components/popup/popup.ts +136 -92
- 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 +108 -0
- package/lib/src/components/propgrid/propgrid.ts +271 -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 +9 -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 +43 -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 +31 -4
- 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 +102 -32
- package/lib/src/core/core_application.ts +222 -2
- package/lib/src/core/core_colors.ts +2 -2
- package/lib/src/{components/grid/datastore.ts → core/core_data.ts} +261 -250
- package/lib/src/core/core_dragdrop.ts +3 -3
- package/lib/src/core/core_element.ts +13 -1
- package/lib/src/core/core_events.ts +28 -0
- package/lib/src/core/core_i18n.ts +18 -2
- package/lib/src/core/core_react.ts +79 -0
- package/lib/src/core/core_router.ts +23 -7
- package/lib/src/core/core_styles.ts +5 -5
- package/lib/src/core/core_svg.ts +173 -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 +767 -92
- 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 +278 -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 +269 -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 +105 -0
- package/src/components/dialog/dialog.ts +212 -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 +30 -0
- package/src/components/icon/icon.ts +139 -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 +398 -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 +525 -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 +45 -0
- package/src/components/popup/popup.ts +440 -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 +108 -0
- package/src/components/propgrid/propgrid.ts +271 -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 +131 -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 +199 -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 +110 -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 +1072 -0
- package/src/core/core_application.ts +264 -0
- package/src/core/core_colors.ts +250 -0
- package/src/core/core_data.ts +1309 -0
- package/src/core/core_dom.ts +471 -0
- package/src/core/core_dragdrop.ts +201 -0
- package/src/core/core_element.ts +110 -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_styles.ts +214 -0
- package/src/core/core_svg.ts +711 -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
|
|
|
@@ -86,6 +86,18 @@ export class CoreElement<E extends EventMap = EventMap> {
|
|
|
86
86
|
this.#events.addListener( name, listener );
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
/**
|
|
90
|
+
* detach
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
off<K extends keyof E>( name: K, listener: ( ev: E[K] ) => void ) {
|
|
94
|
+
console.assert( listener!==undefined && listener!==null );
|
|
95
|
+
|
|
96
|
+
if( this.#events ) {
|
|
97
|
+
this.#events.removeListener( name, listener );
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
89
101
|
/**
|
|
90
102
|
*
|
|
91
103
|
*/
|
|
@@ -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]) {
|
|
@@ -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 {
|
|
@@ -77,6 +77,7 @@ function parseRoute(str: string | RegExp, loose = false): Segment {
|
|
|
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 = [];
|
|
@@ -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
|
|
package/lib/src/core/core_svg.ts
CHANGED
|
@@ -69,10 +69,28 @@ class SvgItem {
|
|
|
69
69
|
this._dom = document.createElementNS("http://www.w3.org/2000/svg", tag );
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* @returns the svh element dom
|
|
74
|
+
*/
|
|
75
|
+
|
|
72
76
|
getDom( ) {
|
|
73
77
|
return this._dom;
|
|
74
78
|
}
|
|
75
79
|
|
|
80
|
+
/**
|
|
81
|
+
*
|
|
82
|
+
*/
|
|
83
|
+
|
|
84
|
+
reset( ) {
|
|
85
|
+
const attrs = this._dom.attributes;
|
|
86
|
+
for (let i = attrs.length - 1; i >= 0; i--) {
|
|
87
|
+
this._dom.removeAttribute(attrs[i].name);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
76
94
|
/**
|
|
77
95
|
* change the stroke color
|
|
78
96
|
* @param color
|
|
@@ -126,6 +144,18 @@ class SvgItem {
|
|
|
126
144
|
return this;
|
|
127
145
|
}
|
|
128
146
|
|
|
147
|
+
/**
|
|
148
|
+
* return the given attribute if any
|
|
149
|
+
*/
|
|
150
|
+
|
|
151
|
+
getAttr( name: string ) : string {
|
|
152
|
+
return this._dom.getAttribute( name );
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
getNumAttr( name: string ) {
|
|
156
|
+
return parseInt( this._dom.getAttribute( name ) );
|
|
157
|
+
}
|
|
158
|
+
|
|
129
159
|
/**
|
|
130
160
|
* define a new attribute
|
|
131
161
|
* @param name attibute name
|
|
@@ -165,7 +195,7 @@ class SvgItem {
|
|
|
165
195
|
* @param name class name to add
|
|
166
196
|
*/
|
|
167
197
|
|
|
168
|
-
addClass( cls: string ) {
|
|
198
|
+
addClass( cls: string ): this {
|
|
169
199
|
if( !cls ) return;
|
|
170
200
|
|
|
171
201
|
if( cls.indexOf(' ')>=0 ) {
|
|
@@ -175,6 +205,27 @@ class SvgItem {
|
|
|
175
205
|
else {
|
|
176
206
|
this._dom.classList.add(cls);
|
|
177
207
|
}
|
|
208
|
+
|
|
209
|
+
return this;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* remove a class
|
|
214
|
+
* @param name class name to remove
|
|
215
|
+
*/
|
|
216
|
+
|
|
217
|
+
removeClass( cls: string ): this {
|
|
218
|
+
if( !cls ) return;
|
|
219
|
+
|
|
220
|
+
if( cls.indexOf(' ')>=0 ) {
|
|
221
|
+
const ccs = cls.split( " " );
|
|
222
|
+
this._dom.classList.remove(...ccs);
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
this._dom.classList.remove(cls);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return this;
|
|
178
229
|
}
|
|
179
230
|
|
|
180
231
|
/**
|
|
@@ -191,7 +242,13 @@ class SvgItem {
|
|
|
191
242
|
*/
|
|
192
243
|
|
|
193
244
|
transform( tr: string ): this {
|
|
194
|
-
this.
|
|
245
|
+
const t = this.getAttr( "transform" ) ?? "";
|
|
246
|
+
this.setAttr( "transform", t+' '+tr );
|
|
247
|
+
return this;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
clear_transform( ) {
|
|
251
|
+
this.setAttr( "transform", null );
|
|
195
252
|
return this;
|
|
196
253
|
}
|
|
197
254
|
|
|
@@ -243,6 +300,12 @@ export class SvgPath extends SvgItem {
|
|
|
243
300
|
return this;
|
|
244
301
|
}
|
|
245
302
|
|
|
303
|
+
reset( ) {
|
|
304
|
+
this._path = "";
|
|
305
|
+
super.reset( );
|
|
306
|
+
return this;
|
|
307
|
+
}
|
|
308
|
+
|
|
246
309
|
/**
|
|
247
310
|
* move the current pos
|
|
248
311
|
* @param x new pos x
|
|
@@ -267,6 +330,16 @@ export class SvgPath extends SvgItem {
|
|
|
267
330
|
return this._update( );
|
|
268
331
|
}
|
|
269
332
|
|
|
333
|
+
/**
|
|
334
|
+
* draw a curve
|
|
335
|
+
*/
|
|
336
|
+
|
|
337
|
+
curveTo( x1: number, y1: number, x2: number, y2: number, x3: number, y3: number ) {
|
|
338
|
+
this._path += clean`C${x1},${y1} ${x2},${y2} ${x3},${y3}`;
|
|
339
|
+
return this._update( );
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
|
|
270
343
|
/**
|
|
271
344
|
* close the currentPath
|
|
272
345
|
*/
|
|
@@ -286,13 +359,13 @@ export class SvgPath extends SvgItem {
|
|
|
286
359
|
* @returns this
|
|
287
360
|
*/
|
|
288
361
|
|
|
289
|
-
arc( x: number, y: number, r: number, start: number, end: number ): this {
|
|
362
|
+
arc( x: number, y: number, r: number, start: number, end: number, clockwise= true ): this {
|
|
290
363
|
|
|
291
364
|
const st = p2c( x, y, r, start-90 );
|
|
292
365
|
const en = p2c( x, y, r, end-90 );
|
|
293
366
|
|
|
294
|
-
const flag = end
|
|
295
|
-
this._path += clean`M${st.x},${st.y}A${r},${r} 0 ${flag} 1 ${en.x},${en.y}`;
|
|
367
|
+
const flag = ((end-start) <= 180 ? "0" : "1");
|
|
368
|
+
this._path += clean`M${st.x},${st.y}A${r},${r} 0 ${flag} ${(clockwise ? '1' : '0')} ${en.x},${en.y}`;
|
|
296
369
|
|
|
297
370
|
return this._update( );
|
|
298
371
|
}
|
|
@@ -353,6 +426,42 @@ export class SvgText extends SvgItem {
|
|
|
353
426
|
}
|
|
354
427
|
}
|
|
355
428
|
|
|
429
|
+
/**
|
|
430
|
+
*
|
|
431
|
+
*/
|
|
432
|
+
|
|
433
|
+
export class SvgIcon extends SvgItem {
|
|
434
|
+
constructor( svg: string ) {
|
|
435
|
+
super( "svg" );
|
|
436
|
+
|
|
437
|
+
if( svg.startsWith("data:image/svg+xml,") ) {
|
|
438
|
+
svg = svg.substring( 19 );
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
const parser = new DOMParser();
|
|
442
|
+
const doc = parser.parseFromString( decodeURIComponent(svg), "image/svg+xml");
|
|
443
|
+
|
|
444
|
+
const parserErrorElement = doc.querySelector("parsererror");
|
|
445
|
+
if( parserErrorElement ) {
|
|
446
|
+
console.error( "error while parsing svg:\n"+ parserErrorElement.textContent );
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const svgRoot = doc.documentElement; // The <svg> element from the string
|
|
450
|
+
for( let i=0; i<svgRoot.attributes.length; i++) {
|
|
451
|
+
this._dom.setAttribute( svgRoot.attributes[i].name, svgRoot.attributes[i].value );
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
for( let i=0; i<svgRoot.childNodes.length; i++) {
|
|
455
|
+
const child = svgRoot.childNodes[i];
|
|
456
|
+
if (child.nodeType === 1) {
|
|
457
|
+
this._dom.appendChild(child);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
|
|
356
465
|
/**
|
|
357
466
|
*
|
|
358
467
|
*/
|
|
@@ -420,6 +529,12 @@ export class SvgGroup extends SvgItem {
|
|
|
420
529
|
return item;
|
|
421
530
|
}
|
|
422
531
|
|
|
532
|
+
appendItems<K extends SvgItem>( items: K[] ) {
|
|
533
|
+
items.forEach( item => {
|
|
534
|
+
this._dom.appendChild( item.getDom() );
|
|
535
|
+
} );
|
|
536
|
+
}
|
|
537
|
+
|
|
423
538
|
/**
|
|
424
539
|
*
|
|
425
540
|
*/
|
|
@@ -434,7 +549,7 @@ export class SvgGroup extends SvgItem {
|
|
|
434
549
|
return this.append( text );
|
|
435
550
|
}
|
|
436
551
|
|
|
437
|
-
ellipse( x: number, y: number, r1: number, r2
|
|
552
|
+
ellipse( x: number, y: number, r1: number, r2: number ): SvgShape {
|
|
438
553
|
const shape = new SvgShape( 'ellipse' );
|
|
439
554
|
shape.setAttr( 'cx', num(x)+'' );
|
|
440
555
|
shape.setAttr( 'cy', num(y)+'' );
|
|
@@ -443,6 +558,24 @@ export class SvgGroup extends SvgItem {
|
|
|
443
558
|
return this.append( shape );
|
|
444
559
|
}
|
|
445
560
|
|
|
561
|
+
circle( x: number, y: number, r1: number ): SvgShape {
|
|
562
|
+
const shape = new SvgShape( 'ellipse' );
|
|
563
|
+
shape.setAttr( 'cx', num(x)+'' );
|
|
564
|
+
shape.setAttr( 'cy', num(y)+'' );
|
|
565
|
+
shape.setAttr( 'rx', num(r1)+'' );
|
|
566
|
+
shape.setAttr( 'ry', num(r1)+'' );
|
|
567
|
+
return this.append( shape );
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
icon( svg: string, x: number, y: number, w: number, h: number ): SvgIcon {
|
|
571
|
+
const icon = new SvgIcon( svg );
|
|
572
|
+
icon.setAttr( 'x', num(x)+'' );
|
|
573
|
+
icon.setAttr( 'y', num(y)+'' );
|
|
574
|
+
icon.setAttr( 'width', num(w)+'' );
|
|
575
|
+
icon.setAttr( 'height', num(h)+'' );
|
|
576
|
+
return this.append( icon );
|
|
577
|
+
}
|
|
578
|
+
|
|
446
579
|
rect( x: number, y: number, w: number, h: number ): SvgShape {
|
|
447
580
|
|
|
448
581
|
if( h<0 ) {
|
|
@@ -458,8 +591,12 @@ export class SvgGroup extends SvgItem {
|
|
|
458
591
|
return this.append( shape );
|
|
459
592
|
}
|
|
460
593
|
|
|
461
|
-
group( ) {
|
|
594
|
+
group( id?: string ) {
|
|
462
595
|
const group = new SvgGroup( );
|
|
596
|
+
if( id ) {
|
|
597
|
+
group.setAttr( 'id', id );
|
|
598
|
+
}
|
|
599
|
+
|
|
463
600
|
return this.append( group );
|
|
464
601
|
}
|
|
465
602
|
|
|
@@ -500,20 +637,35 @@ export class SvgGroup extends SvgItem {
|
|
|
500
637
|
|
|
501
638
|
export class SvgBuilder extends SvgGroup {
|
|
502
639
|
private static g_clip_id = 1;
|
|
640
|
+
private static g_pat_id = 1;
|
|
503
641
|
|
|
504
642
|
constructor( ) {
|
|
505
643
|
super( );
|
|
506
644
|
}
|
|
507
645
|
|
|
508
646
|
addClip( x: number, y: number, w: number, h: number ) {
|
|
509
|
-
|
|
510
|
-
const id = 'c-'+SvgBuilder.g_clip_id++;
|
|
647
|
+
const id = 'clip-'+SvgBuilder.g_clip_id++;
|
|
511
648
|
const clip = new SvgGroup( 'clipPath' );
|
|
512
649
|
clip.setAttr('id', id );
|
|
513
650
|
clip.rect( x, y, w, h );
|
|
514
651
|
|
|
515
652
|
this.append(clip);
|
|
516
|
-
return id;
|
|
653
|
+
return {id,clip};
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
addPattern( x: number, y: number, w: number, h: number ) {
|
|
657
|
+
const id = 'pat-'+SvgBuilder.g_pat_id++;
|
|
658
|
+
|
|
659
|
+
const pat = new SvgGroup( 'pattern' );
|
|
660
|
+
pat.setAttr( 'id', id );
|
|
661
|
+
pat.setAttr( 'x', num(x)+'' );
|
|
662
|
+
pat.setAttr( 'y', num(y)+'' );
|
|
663
|
+
pat.setAttr( 'width', num(w)+'' );
|
|
664
|
+
pat.setAttr( 'height', num(h)+'' );
|
|
665
|
+
pat.setAttr( 'patternUnits', "userSpaceOnUse" );
|
|
666
|
+
|
|
667
|
+
this.append(pat);
|
|
668
|
+
return {id,pat};
|
|
517
669
|
}
|
|
518
670
|
}
|
|
519
671
|
|
|
@@ -525,7 +677,7 @@ export class SvgBuilder extends SvgGroup {
|
|
|
525
677
|
|
|
526
678
|
interface SvgProps extends ComponentProps {
|
|
527
679
|
viewbox?: string;
|
|
528
|
-
svg
|
|
680
|
+
svg: SvgBuilder;
|
|
529
681
|
}
|
|
530
682
|
|
|
531
683
|
/**
|
|
@@ -540,11 +692,20 @@ export class SvgComponent<P extends SvgProps = SvgProps> extends Component<P> {
|
|
|
540
692
|
this.setAttribute( 'xmlns', SVG_NS );
|
|
541
693
|
|
|
542
694
|
if( props.viewbox ) {
|
|
543
|
-
this.setAttribute( "
|
|
695
|
+
this.setAttribute( "viewBox", props.viewbox );
|
|
544
696
|
}
|
|
545
697
|
|
|
546
698
|
if( props.svg ) {
|
|
547
699
|
this.dom.appendChild( props.svg.getDom() );
|
|
548
700
|
}
|
|
549
701
|
}
|
|
702
|
+
|
|
703
|
+
setSvg( bld: SvgBuilder ) {
|
|
704
|
+
this.clearContent( );
|
|
705
|
+
this.dom.appendChild( bld.getDom() );
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
addItems( ...items: SvgItem[] ) {
|
|
709
|
+
items.forEach( item => this.dom.appendChild( item.getDom() ) );
|
|
710
|
+
}
|
|
550
711
|
}
|