ziko 1.7.0 → 1.9.0

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.
Files changed (59) hide show
  1. package/dist/ziko.cjs +458 -174
  2. package/dist/ziko.js +458 -174
  3. package/dist/ziko.min.js +2 -2
  4. package/dist/ziko.mjs +453 -173
  5. package/package.json +1 -1
  6. package/src/dom/{flex → components/Flex}/index.js +1 -1
  7. package/src/dom/components/{for → For}/index.js +1 -1
  8. package/src/dom/{suspense → components/Suspense}/index.js +3 -7
  9. package/src/dom/components/View/index.js +9 -0
  10. package/src/dom/{graphics/canvas.js → components/graphics/Canvas/index.js} +6 -6
  11. package/src/dom/{graphics/svg.js → components/graphics/Svg/index.js} +4 -4
  12. package/src/dom/components/graphics/index.js +2 -0
  13. package/src/dom/components/index.js +10 -3
  14. package/src/dom/{wrappers/html → components/wrappers/HTMLWrapper}/index.js +1 -1
  15. package/src/dom/{wrappers/svg → components/wrappers/SVGWrapper}/index.js +1 -1
  16. package/src/dom/components/wrappers/index.js +2 -0
  17. package/src/dom/constructors/mixins/dom.js +1 -0
  18. package/src/dom/index.js +0 -8
  19. package/src/hooks/index.d.ts +1 -0
  20. package/src/hooks/index.js +1 -0
  21. package/src/hooks/use-derived.js +24 -17
  22. package/src/hooks/use-effect.d.ts +39 -0
  23. package/src/hooks/use-effect.js +40 -0
  24. package/src/hooks/use-state.d.ts +28 -10
  25. package/src/hooks/use-state.js +3 -1
  26. package/src/symbols/index.d.ts +39 -0
  27. package/src/symbols/index.js +5 -0
  28. package/src/dom/graphics/index.js +0 -2
  29. package/src/dom/logic/index.js +0 -1
  30. package/src/dom/view/index.js +0 -13
  31. package/src/dom/wrappers/index.js +0 -2
  32. package/src/events-dep/binders/coordinates-based-event.js +0 -25
  33. package/src/events-dep/binders/custom-event.js +0 -33
  34. package/src/events-dep/binders/index.js +0 -105
  35. package/src/events-dep/custom-events-registry/click-away.js +0 -38
  36. package/src/events-dep/custom-events-registry/index.js +0 -3
  37. package/src/events-dep/custom-events-registry/swipe.js +0 -76
  38. package/src/events-dep/custom-events-registry/view.js +0 -74
  39. package/src/events-dep/customizers/normalise-coordinates.js +0 -0
  40. package/src/events-dep/details-setter/index.js +0 -4
  41. package/src/events-dep/details-setter/key.js +0 -14
  42. package/src/events-dep/details-setter/mouse.js +0 -35
  43. package/src/events-dep/details-setter/pointer.js +0 -35
  44. package/src/events-dep/details-setter/touch.js +0 -37
  45. package/src/events-dep/events-map/index.js +0 -70
  46. package/src/events-dep/index.js +0 -3
  47. package/src/events-dep/types/__Shared__.d.ts +0 -155
  48. package/src/events-dep/types/clipboard.d.ts +0 -20
  49. package/src/events-dep/types/focus.d.ts +0 -19
  50. package/src/events-dep/types/pointer.d.ts +0 -45
  51. package/src/events-dep/utils.js +0 -38
  52. package/src/events-dep/ziko-event.js +0 -108
  53. package/src/watch/dom-observer/ziko-observer.js +0 -15
  54. /package/src/dom/{flex → components/Flex}/utils/index.js +0 -0
  55. /package/src/dom/components/{fragment → Fragment}/index.d.ts +0 -0
  56. /package/src/dom/components/{fragment → Fragment}/index.js +0 -0
  57. /package/src/dom/components/{swap → Swap}/index.d.ts +0 -0
  58. /package/src/dom/components/{swap → Swap}/index.js +0 -0
  59. /package/src/dom/{logic/switch → components/Switch}/index.js +0 -0
package/dist/ziko.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
  /*
3
3
  Project: ziko.js
4
4
  Author: Zakaria Elalaoui
5
- Date : Fri Aug 07 2026 20:07:58 GMT+0100 (UTC+01:00)
5
+ Date : Wed Aug 26 2026 10:48:40 GMT+0100 (UTC+01:00)
6
6
  Git-Repo : https://github.com/zakarialaoui10/ziko.js
7
7
  Git-Wiki : https://github.com/zakarialaoui10/ziko.js/wiki
8
8
  Released under MIT License
@@ -2432,11 +2432,10 @@ var LifecycleMethods = /*#__PURE__*/Object.freeze({
2432
2432
  unmount: unmount
2433
2433
  });
2434
2434
 
2435
+ const STATE_GETTER = Symbol.for("ziko/hooks/STATE_GETTER");
2436
+
2435
2437
  // import { __init__global__ } from "../__ziko__/index.js";
2436
2438
 
2437
- // if (!globalThis.__Ziko__) __init__global__();
2438
-
2439
- const STATE_GETTER = Symbol.for("ziko.stateGetter");
2440
2439
 
2441
2440
  function useState(initialValue) {
2442
2441
  const state = {
@@ -2640,6 +2639,7 @@ async function __addItem__(adder, pusher, ...ele) {
2640
2639
  // Fix Items Latter
2641
2640
  if (ele[i] instanceof Function) {
2642
2641
  if (isStateGetter(ele[i])) {
2642
+ console.log({s : ele[i]()});
2643
2643
  const getter = ele[i]();
2644
2644
  ele[i] = text(getter.value);
2645
2645
  getter._subscribe(
@@ -3332,15 +3332,6 @@ const waitElm=(UIElement)=>{
3332
3332
  });
3333
3333
  };
3334
3334
 
3335
- class UIView extends UIElement$1{
3336
- constructor(...items){
3337
- super({element : 'div', name : 'view'});
3338
- this.append(...items);
3339
- }
3340
- }
3341
-
3342
- const View = (...items) => new UIView(...items);
3343
-
3344
3335
  const HTMLTags = [
3345
3336
  'a',
3346
3337
  'abb',
@@ -3500,6 +3491,62 @@ const tags = new Proxy({}, {
3500
3491
  }
3501
3492
  });
3502
3493
 
3494
+ function define_wc(name, UI_Constructor, props = {}, { mode = 'open'} = {}) {
3495
+ if (globalThis.customElements?.get(name)) {
3496
+ console.warn(`Custom element "${name}" is already defined`);
3497
+ return;
3498
+ }
3499
+ if(name.search('-') === -1){
3500
+ console.warn(`"${name}" is not a valid custom element name`);
3501
+ return;
3502
+ }
3503
+ globalThis.customElements?.define(
3504
+ name,
3505
+ class extends HTMLElement {
3506
+ static get observedAttributes() {
3507
+ return ['style', ...Object.keys(props)];
3508
+ }
3509
+
3510
+ constructor() {
3511
+ super();
3512
+ this.attachShadow({ mode });
3513
+ this.props = {};
3514
+ this.mask = {
3515
+ ...props,
3516
+ // style: { type: Object }
3517
+ };
3518
+ }
3519
+
3520
+ connectedCallback() {
3521
+ this.render();
3522
+ }
3523
+
3524
+ render() {
3525
+ this.shadowRoot.innerHTML = '';
3526
+ const item = UI_Constructor(this.props);
3527
+ if(item instanceof Array) item.forEach(n => n.mount(this.shadowRoot));
3528
+ else item.mount(this.shadowRoot);
3529
+ }
3530
+
3531
+ attributeChangedCallback(name, _, newValue) {
3532
+ Object.assign(this.props, {
3533
+ [name]: this.mask[name].type(newValue)
3534
+ });
3535
+ this.render();
3536
+ }
3537
+ }
3538
+ );
3539
+ }
3540
+
3541
+ class UIView extends UIElement$1{
3542
+ constructor(...items){
3543
+ super({element : 'div', name : 'view'});
3544
+ this.append(...items);
3545
+ }
3546
+ }
3547
+
3548
+ const View = (...items) => new UIView(...items);
3549
+
3503
3550
  function set_vertical(direction){
3504
3551
  direction == 1
3505
3552
  ? this.style({ flexDirection: "column" })
@@ -3605,7 +3652,7 @@ class UIElement extends UIElementCore{
3605
3652
  }
3606
3653
  }
3607
3654
 
3608
- class ZikoUISuspense extends UIElement{
3655
+ class UISuspense extends UIElement{
3609
3656
  constructor(fallback_ui, callback){
3610
3657
  super({element : "div", name : "suspense"});
3611
3658
  this.setAttr({
@@ -3626,148 +3673,7 @@ class ZikoUISuspense extends UIElement{
3626
3673
  }
3627
3674
  }
3628
3675
 
3629
- const Suspense = (fallback_ui, callback) => new ZikoUISuspense(fallback_ui, callback);
3630
-
3631
- class UIHTMLWrapper extends UIElement$1 {
3632
- constructor(content){
3633
- super({element : 'div', name : 'html_wrappper'});
3634
- this.element.append(html2dom(content));
3635
- this.style({
3636
- display : 'contents'
3637
- });
3638
- }
3639
- }
3640
-
3641
- function html2dom(htmlString) {
3642
- if(globalThis?.DOMParser){
3643
- const parser = new DOMParser();
3644
- const doc = parser.parseFromString(`<div>${htmlString}</div>`, 'text/html');
3645
- doc.body.firstChild.style.display = "contents";
3646
- return doc.body.firstChild;
3647
- }
3648
- }
3649
-
3650
- const HTMLWrapper = (content) => new UIHTMLWrapper(content);
3651
-
3652
- class UISVGWrapper extends UIElement$1 {
3653
- constructor(content){
3654
- super({element : 'div', name : 'html_wrappper'});
3655
- this.element.append(svg2dom(content));
3656
- this.style({
3657
- display : 'contents'
3658
- });
3659
- }
3660
- }
3661
-
3662
- function svg2dom(svgString) {
3663
- if (typeof DOMParser !== "undefined") {
3664
- const parser = new DOMParser();
3665
- const doc = parser.parseFromString(svgString.trim(), "image/svg+xml");
3666
- const svg = doc.documentElement;
3667
-
3668
- if (svg.nodeName === "parsererror") {
3669
- throw new Error("Invalid SVG string");
3670
- }
3671
- if(svg.hasAttribute('xmlns')) return svg
3672
- // TO Fix ...
3673
- const {children, attributes} = svg;
3674
- const element = document.createElementNS("http://www.w3.org/2000/svg", "svg");
3675
- for(let {name, value} of attributes){
3676
- element.setAttribute(name, value);
3677
- }
3678
- element.append(...children);
3679
-
3680
- globalThis.svg = svg;
3681
- globalThis.children = children;
3682
- globalThis.attributes = attributes;
3683
- globalThis.element = element;
3684
- return element;
3685
- }
3686
- throw new Error("DOMParser is not available in this environment");
3687
- }
3688
-
3689
-
3690
-
3691
- const SVGWrapper = (content) => new UISVGWrapper(content);
3692
-
3693
- function define_wc(name, UI_Constructor, props = {}, { mode = 'open'} = {}) {
3694
- if (globalThis.customElements?.get(name)) {
3695
- console.warn(`Custom element "${name}" is already defined`);
3696
- return;
3697
- }
3698
- if(name.search('-') === -1){
3699
- console.warn(`"${name}" is not a valid custom element name`);
3700
- return;
3701
- }
3702
- globalThis.customElements?.define(
3703
- name,
3704
- class extends HTMLElement {
3705
- static get observedAttributes() {
3706
- return ['style', ...Object.keys(props)];
3707
- }
3708
-
3709
- constructor() {
3710
- super();
3711
- this.attachShadow({ mode });
3712
- this.props = {};
3713
- this.mask = {
3714
- ...props,
3715
- // style: { type: Object }
3716
- };
3717
- }
3718
-
3719
- connectedCallback() {
3720
- this.render();
3721
- }
3722
-
3723
- render() {
3724
- this.shadowRoot.innerHTML = '';
3725
- const item = UI_Constructor(this.props);
3726
- if(item instanceof Array) item.forEach(n => n.mount(this.shadowRoot));
3727
- else item.mount(this.shadowRoot);
3728
- }
3729
-
3730
- attributeChangedCallback(name, _, newValue) {
3731
- Object.assign(this.props, {
3732
- [name]: this.mask[name].type(newValue)
3733
- });
3734
- this.render();
3735
- }
3736
- }
3737
- );
3738
- }
3739
-
3740
- class UISwitch extends UIElement$1{
3741
- constructor(key, cases){
3742
- super();
3743
- this.key = key;
3744
- this.cases = cases;
3745
- this.init();
3746
- }
3747
- init(){
3748
- Object.values(this.cases).filter(n=>n != this.current).forEach(n=>n.unmount());
3749
- super.init(this.current.element);
3750
- }
3751
- get current(){
3752
- const matched = Object.keys(this.cases).find(n => n == this.key) ?? 'default';
3753
- return this.cases[matched]
3754
- }
3755
- updateKey(key){
3756
- this.key = key;
3757
- this.replaceElementWith(this.current.element);
3758
- // this.cache.element.replaceWith(this.current.element)
3759
- // this.cache.element = this.current.element;
3760
- return this;
3761
- }
3762
-
3763
- }
3764
-
3765
- const Switch=({key, cases})=> new UISwitch(key, cases);
3766
-
3767
- // export const Switch=({key, cases}) => {
3768
- // const matched = Object.keys(cases).find(n => n == key) ?? 'default';
3769
- // return this.cases[matched]()
3770
- // }
3676
+ const Suspense = (fallback_ui, callback) => new UISuspense(fallback_ui, callback);
3771
3677
 
3772
3678
  class UISwap extends UIElement$1 {
3773
3679
  #DISPLAYS_MAP = new WeakMap()
@@ -3859,6 +3765,335 @@ class UIFor extends UIFragment{
3859
3765
 
3860
3766
  const For = ({each, fallback, mapFn} = {}) => new UIFor({each, fallback, mapFn});
3861
3767
 
3768
+ class UISwitch extends UIElement$1{
3769
+ constructor(key, cases){
3770
+ super();
3771
+ this.key = key;
3772
+ this.cases = cases;
3773
+ this.init();
3774
+ }
3775
+ init(){
3776
+ Object.values(this.cases).filter(n=>n != this.current).forEach(n=>n.unmount());
3777
+ super.init(this.current.element);
3778
+ }
3779
+ get current(){
3780
+ const matched = Object.keys(this.cases).find(n => n == this.key) ?? 'default';
3781
+ return this.cases[matched]
3782
+ }
3783
+ updateKey(key){
3784
+ this.key = key;
3785
+ this.replaceElementWith(this.current.element);
3786
+ // this.cache.element.replaceWith(this.current.element)
3787
+ // this.cache.element = this.current.element;
3788
+ return this;
3789
+ }
3790
+
3791
+ }
3792
+
3793
+ const Switch=({key, cases})=> new UISwitch(key, cases);
3794
+
3795
+ // export const Switch=({key, cases}) => {
3796
+ // const matched = Object.keys(cases).find(n => n == key) ?? 'default';
3797
+ // return this.cases[matched]()
3798
+ // }
3799
+
3800
+ class UIHTMLWrapper extends UIElement$1 {
3801
+ constructor(content){
3802
+ super({element : 'div', name : 'html_wrappper'});
3803
+ this.element.append(html2dom(content));
3804
+ this.style({
3805
+ display : 'contents'
3806
+ });
3807
+ }
3808
+ }
3809
+
3810
+ function html2dom(htmlString) {
3811
+ if(globalThis?.DOMParser){
3812
+ const parser = new DOMParser();
3813
+ const doc = parser.parseFromString(`<div>${htmlString}</div>`, 'text/html');
3814
+ doc.body.firstChild.style.display = "contents";
3815
+ return doc.body.firstChild;
3816
+ }
3817
+ }
3818
+
3819
+ const HTMLWrapper = (content) => new UIHTMLWrapper(content);
3820
+
3821
+ class UISVGWrapper extends UIElement$1 {
3822
+ constructor(content){
3823
+ super({element : 'div', name : 'html_wrappper'});
3824
+ this.element.append(svg2dom(content));
3825
+ this.style({
3826
+ display : 'contents'
3827
+ });
3828
+ }
3829
+ }
3830
+
3831
+ function svg2dom(svgString) {
3832
+ if (typeof DOMParser !== "undefined") {
3833
+ const parser = new DOMParser();
3834
+ const doc = parser.parseFromString(svgString.trim(), "image/svg+xml");
3835
+ const svg = doc.documentElement;
3836
+
3837
+ if (svg.nodeName === "parsererror") {
3838
+ throw new Error("Invalid SVG string");
3839
+ }
3840
+ if(svg.hasAttribute('xmlns')) return svg
3841
+ // TO Fix ...
3842
+ const {children, attributes} = svg;
3843
+ const element = document.createElementNS("http://www.w3.org/2000/svg", "svg");
3844
+ for(let {name, value} of attributes){
3845
+ element.setAttribute(name, value);
3846
+ }
3847
+ element.append(...children);
3848
+
3849
+ globalThis.svg = svg;
3850
+ globalThis.children = children;
3851
+ globalThis.attributes = attributes;
3852
+ globalThis.element = element;
3853
+ return element;
3854
+ }
3855
+ throw new Error("DOMParser is not available in this environment");
3856
+ }
3857
+
3858
+
3859
+
3860
+ const SVGWrapper = (content) => new UISVGWrapper(content);
3861
+
3862
+ class UICanvas extends UIElement$1{
3863
+ constructor(w,h){
3864
+ super("canvas","canvas");
3865
+ this.ctx = this.element?.getContext("2d");
3866
+ this.style({
3867
+ border:"1px red solid",
3868
+ });
3869
+ this.transformMatrix = new Matrix([
3870
+ [1,0,0],
3871
+ [0,1,0],
3872
+ [0,0,1]
3873
+ ]);
3874
+ this.axisMatrix = new Matrix([
3875
+ [-10,-10],
3876
+ [10,10]
3877
+ ]);
3878
+ // setTimeout(()=>this.resize(w,h),0);
3879
+ requestAnimationFrame(()=>this.resize(w,h),0);
3880
+ this.on("sizeupdated",()=>this.adjust());
3881
+ }
3882
+ get Xmin(){
3883
+ return this.axisMatrix[0][0];
3884
+ }
3885
+ get Ymin(){
3886
+ return this.axisMatrix[0][1];
3887
+ }
3888
+ get Xmax(){
3889
+ return this.axisMatrix[1][0];
3890
+ }
3891
+ get Ymax(){
3892
+ return this.axisMatrix[1][1];
3893
+ }
3894
+ get ImageData(){
3895
+ return this.ctx.getImageData(0,0,c.Width,c.Height);
3896
+ }
3897
+ draw(all=true){
3898
+ if(all){
3899
+ this.clear();
3900
+ this.items.forEach(element => {
3901
+ element.parent=this;
3902
+ element.draw(this.ctx);
3903
+ });
3904
+ }
3905
+ else {
3906
+ this.items.at(-1).parent=this;
3907
+ this.items.at(-1).draw(this.ctx);
3908
+ }
3909
+ this.maintain();
3910
+ return this;
3911
+ }
3912
+ applyTransformMatrix(){
3913
+ this.ctx.setTransform(
3914
+ this.transformMatrix[0][0],
3915
+ this.transformMatrix[1][0],
3916
+ this.transformMatrix[0][1],
3917
+ this.transformMatrix[1][1],
3918
+ this.transformMatrix[0][2],
3919
+ this.transformMatrix[1][2],
3920
+ );
3921
+ return this;
3922
+ }
3923
+ resize(w,h){
3924
+ this.size(w,h);
3925
+ this.lineWidth();
3926
+ this.view(this.axisMatrix[0][0], this.axisMatrix[0][1], this.axisMatrix[1][0], this.axisMatrix[1][1]);
3927
+ this.emit("sizeupdated");
3928
+ return this;
3929
+ }
3930
+ adjust(){
3931
+ this.element.width =this.element?.getBoundingClientRect().width;
3932
+ this.element.height =this.element?.getBoundingClientRect().height;
3933
+ this.view(this.axisMatrix[0][0], this.axisMatrix[0][1], this.axisMatrix[1][0], this.axisMatrix[1][1]);
3934
+ return this;
3935
+ }
3936
+ view(xMin,yMin,xMax,yMax){
3937
+ this.transformMatrix[0][0]=this.width/(xMax-xMin); // scaleX
3938
+ this.transformMatrix[1][1]=-this.height/(yMax-yMin); // scaleY
3939
+ this.transformMatrix[0][2]=this.width/2;
3940
+ this.transformMatrix[1][2]=this.height/2;
3941
+ this.axisMatrix=new Matrix([
3942
+ [xMin,yMin],
3943
+ [xMax,yMax]
3944
+ ]);
3945
+
3946
+ this.applyTransformMatrix();
3947
+ this.clear();
3948
+ this.lineWidth(1);
3949
+ this.draw();
3950
+ return this;
3951
+ }
3952
+ reset(){
3953
+ this.ctx.setTransform(1,0,0,0,0,0);
3954
+ return this;
3955
+ }
3956
+ append(element){
3957
+ this.items.push(element);
3958
+ this.draw(false);
3959
+ return this;
3960
+ }
3961
+ background(color){
3962
+ this.ctx.fillStyle = color;
3963
+ this.ctx.setTransform(1, 0, 0, 1, 0, 0);
3964
+ this.ctx.fillRect(0, 0, this.width, this.height);
3965
+ this.applyTransformMatrix();
3966
+ this.draw();
3967
+ }
3968
+ lineWidth(w){
3969
+ this.ctx.lineWidth=w/this.transformMatrix[0][0];
3970
+ return this
3971
+ }
3972
+ getImageData(x=0,y=0,w=this.width,h=this.height){
3973
+ return this.ctx.getImageData(x,y,w,h);
3974
+ }
3975
+ clear(){
3976
+ this.ctx.setTransform(1, 0, 0, 1, 0, 0);
3977
+ this.ctx.clearRect(0, 0, this.width, this.height);
3978
+ this.applyTransformMatrix();
3979
+ return this;
3980
+ }
3981
+ clone(){
3982
+ console.log(this.width);
3983
+ const canvas=new UICanvas();
3984
+ canvas.items=this.items;
3985
+ canvas.transformMatrix=this.transformMatrix;
3986
+ canvas.axisMatrix=this.axisMatrix;
3987
+ Object.assign(canvas.cache,{...this.cache});
3988
+ //waitForUIElm(this)
3989
+ //console.log(element)
3990
+ this.size(this.element.style.width,this.element.style.width);
3991
+ this.applyTransformMatrix();
3992
+ this.draw();
3993
+ this.adjust();
3994
+ return canvas;
3995
+ }
3996
+ toImage() {
3997
+ this.img = document?.createElement("img");
3998
+ this.img.src = this.element?.toDataURL("image/png");
3999
+ return this;
4000
+ }
4001
+ toBlob() {
4002
+ var canvas = this.element;
4003
+ canvas.toBlob(function (blob) {
4004
+ var newImg = document?.createElement("img"),
4005
+ url = URL.createObjectURL(blob);
4006
+ newImg.onload = function () {
4007
+ URL.revokeObjectURL(url);
4008
+ };
4009
+ newImg.src = url;
4010
+ console.log(newImg);
4011
+ });
4012
+ }
4013
+ zoomIn(){
4014
+
4015
+ }
4016
+ zoomOut(){
4017
+
4018
+ }
4019
+ undo(n){
4020
+
4021
+ }
4022
+ redo(n){
4023
+
4024
+ }
4025
+ stream(){
4026
+
4027
+ }
4028
+ }
4029
+
4030
+ const Canvas=(w,h)=>new UICanvas(w,h);
4031
+
4032
+ class UISvg extends UIElement$1 {
4033
+ constructor(w=360,h=300) {
4034
+ super("svg","svg");
4035
+ //this.cache={};
4036
+ // this.setAttr("width",w);
4037
+ // this.setAttr("height",h);
4038
+ // this.setAttr({
4039
+ // width : w,
4040
+ // height : h
4041
+ // })
4042
+ this.style({border:"1px black solid"});
4043
+ //this.view(-w/2,-h/2,w/2,h/2);
4044
+ this.size(w, h);
4045
+ this.view(-10,-10,10,10);
4046
+ }
4047
+ size(w, h){
4048
+ this.setAttr({
4049
+ width : w,
4050
+ height : h
4051
+ });
4052
+ return this
4053
+ }
4054
+ view(x1,y1,x2,y2){
4055
+ let width=Math.abs(x2-x1);
4056
+ let height=Math.abs(y2-y1);
4057
+ this.setAttr("viewBox",[x1,y1,width,height].join(" "));
4058
+ this.st.scaleY(-1);
4059
+ return this;
4060
+ }
4061
+ add(...svgElement){
4062
+ for(let i=0;i<svgElement.length;i++){
4063
+ this.element.append(svgElement[i].element);
4064
+ this.items.push(svgElement[i]);
4065
+ }
4066
+ this.maintain();
4067
+ return this;
4068
+ }
4069
+ remove(...svgElement){
4070
+ for(let i=0;i<svgElement.length;i++){
4071
+ this.element?.removeChild(svgElement[i].element);
4072
+ this.items=this.items.filter(n=>!svgElement);
4073
+ }
4074
+ this.maintain();
4075
+ return this;
4076
+ }
4077
+ mask(){
4078
+
4079
+ }
4080
+ toString(){
4081
+ return (new XMLSerializer()).serializeToString(this.element);
4082
+ }
4083
+ btoa(){
4084
+ return btoa(this.toString())
4085
+ }
4086
+ toImg(){
4087
+ return 'data:image/svg+xml;base64,'+this.btoa()
4088
+ }
4089
+ toImg2(){
4090
+ return "data:image/svg+xml;charset=utf8,"+this.toString().replaceAll("<","%3C").replaceAll(">","%3E").replaceAll("#","%23").replaceAll('"',"'");
4091
+ }
4092
+
4093
+ }
4094
+
4095
+ const Svg =(w,h)=>new UISvg(w,h);
4096
+
3862
4097
  const { PI, sqrt: sqrt$1, cos: cos$2, sin: sin$2, acos, pow } = Math;
3863
4098
 
3864
4099
  const linear = t => t;
@@ -4800,23 +5035,29 @@ function useDerived(deriveFn, sources) {
4800
5035
  let value = deriveFn(...sources.map(s => s().value));
4801
5036
  const subscribers = new Set();
4802
5037
 
4803
- sources.forEach(source => {
4804
- const srcValue = source();
4805
- srcValue._subscribe(() => {
4806
- {
4807
- const newVal = deriveFn(...sources.map(s => s().value));
4808
- if (newVal !== value) {
4809
- value = newVal;
4810
- subscribers.forEach(fn => fn(value));
4811
- }
4812
- }
4813
- });
4814
- });
4815
- return () => ({
5038
+ // const unsubscribers = sources.map(source => {
5039
+ // const srcValue = source();
5040
+
5041
+ // return srcValue._subscribe(() => {
5042
+ // const newVal = deriveFn(...sources.map(s => s().value));
5043
+
5044
+ // if (!Object.is(newVal, value)) {
5045
+ // value = newVal;
5046
+ // subscribers.forEach(fn => fn(value));
5047
+ // }
5048
+ // });
5049
+ // });
5050
+
5051
+ const getter = () => ({
4816
5052
  value,
4817
- isStateGetter : () => true,
4818
- _subscribe: (fn) => subscribers.add(fn)
4819
- })
5053
+ _subscribe: (fn) => {
5054
+ subscribers.add(fn);
5055
+ return () => subscribers.delete(fn);
5056
+ },
5057
+ });
5058
+
5059
+ getter[STATE_GETTER] = true;
5060
+ return getter
4820
5061
  }
4821
5062
 
4822
5063
  const mapfun=(fun,...X)=>{
@@ -4873,6 +5114,45 @@ const useReactive = (nested_value) => mapfun(
4873
5114
  nested_value
4874
5115
  );
4875
5116
 
5117
+ const useEffect = (callback, deps = []) =>{
5118
+ const states = deps.filter(isStateGetter);
5119
+
5120
+ let cleanup;
5121
+
5122
+ const execute = () => {
5123
+ // Cleanup previous effect
5124
+ if (typeof cleanup === "function") {
5125
+ cleanup();
5126
+ }
5127
+
5128
+ // Read current state values
5129
+ const values = states.map(state => state().value);
5130
+
5131
+ // Execute effect
5132
+ cleanup = callback(...values);
5133
+ };
5134
+
5135
+ // Subscribe to states
5136
+ const unsubscribers = states.map(state =>
5137
+ state()._subscribe(execute)
5138
+ );
5139
+
5140
+ // Initial execution
5141
+ execute();
5142
+
5143
+ // Return effect cleanup
5144
+ return () => {
5145
+ unsubscribers.forEach(unsubscribe => {
5146
+ unsubscribe();
5147
+ });
5148
+
5149
+ if (typeof cleanup === "function") {
5150
+ cleanup();
5151
+ cleanup = undefined;
5152
+ }
5153
+ };
5154
+ };
5155
+
4876
5156
  class UseThread {
4877
5157
  #worker;
4878
5158
  #callbacks = new Map();
@@ -5296,6 +5576,7 @@ if(globalThis?.document){
5296
5576
  }
5297
5577
 
5298
5578
  exports.App = App;
5579
+ exports.Canvas = Canvas;
5299
5580
  exports.ClickAwayEvent = ClickAwayEvent;
5300
5581
  exports.ClickListeners = ClickListeners;
5301
5582
  exports.Clock = Clock;
@@ -5315,10 +5596,10 @@ exports.PI = PI$1;
5315
5596
  exports.PtrListeners = PtrListeners;
5316
5597
  exports.Random = Random;
5317
5598
  exports.SPA = SPA;
5318
- exports.STATE_GETTER = STATE_GETTER;
5319
5599
  exports.SVGWrapper = SVGWrapper;
5320
5600
  exports.Scheduler = Scheduler;
5321
5601
  exports.Suspense = Suspense;
5602
+ exports.Svg = Svg;
5322
5603
  exports.Swap = Swap;
5323
5604
  exports.SwipeEvent = SwipeEvent;
5324
5605
  exports.Switch = Switch;
@@ -5326,12 +5607,15 @@ exports.Tick = Tick;
5326
5607
  exports.TimeAnimation = TimeAnimation;
5327
5608
  exports.TimeLoop = TimeLoop;
5328
5609
  exports.TimeScheduler = TimeScheduler;
5610
+ exports.UICanvas = UICanvas;
5329
5611
  exports.UIElement = UIElement$1;
5330
5612
  exports.UIFlex = UIFlex;
5331
5613
  exports.UIFragment = UIFragment;
5332
5614
  exports.UIHTMLWrapper = UIHTMLWrapper;
5333
5615
  exports.UINode = UINode;
5334
5616
  exports.UISVGWrapper = UISVGWrapper;
5617
+ exports.UISuspense = UISuspense;
5618
+ exports.UISvg = UISvg;
5335
5619
  exports.UISwap = UISwap;
5336
5620
  exports.UISwitch = UISwitch;
5337
5621
  exports.UIView = UIView;
@@ -5342,7 +5626,6 @@ exports.ViewEvent = ViewEvent;
5342
5626
  exports.ViewListeners = ViewListeners;
5343
5627
  exports.ZikoApp = ZikoApp;
5344
5628
  exports.ZikoSPA = ZikoSPA;
5345
- exports.ZikoUISuspense = ZikoUISuspense;
5346
5629
  exports.ZikoUIText = ZikoUIText;
5347
5630
  exports.abs = abs;
5348
5631
  exports.accum_max = accum_max;
@@ -5514,6 +5797,7 @@ exports.timeout = timeout;
5514
5797
  exports.trimmed_mean = trimmed_mean;
5515
5798
  exports.trunc = trunc;
5516
5799
  exports.useDerived = useDerived;
5800
+ exports.useEffect = useEffect;
5517
5801
  exports.useEventEmitter = useEventEmitter;
5518
5802
  exports.useIPC = useIPC;
5519
5803
  exports.useLocalStorage = useLocalStorage;