ziko 1.6.1 → 1.8.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 (67) hide show
  1. package/dist/ziko.cjs +551 -203
  2. package/dist/ziko.js +551 -203
  3. package/dist/ziko.min.js +2 -2
  4. package/dist/ziko.mjs +542 -202
  5. package/package.json +1 -1
  6. package/src/data/converter/csv.js +6 -4
  7. package/src/dom/{flex → components/Flex}/index.js +1 -1
  8. package/src/dom/components/{for → For}/index.js +1 -1
  9. package/src/dom/{suspense → components/Suspense}/index.js +3 -7
  10. package/src/dom/components/View/index.js +9 -0
  11. package/src/dom/{graphics/canvas.js → components/graphics/Canvas/index.js} +6 -6
  12. package/src/dom/{graphics/svg.js → components/graphics/Svg/index.js} +4 -4
  13. package/src/dom/components/graphics/index.js +2 -0
  14. package/src/dom/components/index.js +10 -3
  15. package/src/dom/{wrappers/html → components/wrappers/HTMLWrapper}/index.js +1 -1
  16. package/src/dom/{wrappers/svg → components/wrappers/SVGWrapper}/index.js +1 -1
  17. package/src/dom/components/wrappers/index.js +2 -0
  18. package/src/dom/constructors/UIElement.js +2 -2
  19. package/src/dom/constructors/UIElementCore.js +20 -2
  20. package/src/dom/constructors/mixins/dom.js +3 -2
  21. package/src/dom/index.js +0 -8
  22. package/src/dom/tags/index.js +12 -35
  23. package/src/dom/utils/call_with_optional_props.js +14 -0
  24. package/src/dom/utils/checkers.js +1 -0
  25. package/src/dom/utils/index.js +8 -13
  26. package/src/dom/utils/is_ui_item.js +10 -0
  27. package/src/dom/utils/parse_props.js +26 -0
  28. package/src/hooks/index.d.ts +1 -0
  29. package/src/hooks/index.js +1 -0
  30. package/src/hooks/use-effect.d.ts +39 -0
  31. package/src/hooks/use-effect.js +40 -0
  32. package/src/hooks/use-state.d.ts +28 -10
  33. package/src/hooks/use-state.js +6 -5
  34. package/src/time/animation/index.d.ts +189 -0
  35. package/src/time/index.d.ts +2 -1
  36. package/src/dom/graphics/index.js +0 -2
  37. package/src/dom/logic/index.js +0 -1
  38. package/src/dom/view/index.js +0 -13
  39. package/src/dom/wrappers/index.js +0 -2
  40. package/src/events-dep/binders/coordinates-based-event.js +0 -25
  41. package/src/events-dep/binders/custom-event.js +0 -33
  42. package/src/events-dep/binders/index.js +0 -105
  43. package/src/events-dep/custom-events-registry/click-away.js +0 -38
  44. package/src/events-dep/custom-events-registry/index.js +0 -3
  45. package/src/events-dep/custom-events-registry/swipe.js +0 -76
  46. package/src/events-dep/custom-events-registry/view.js +0 -74
  47. package/src/events-dep/customizers/normalise-coordinates.js +0 -0
  48. package/src/events-dep/details-setter/index.js +0 -4
  49. package/src/events-dep/details-setter/key.js +0 -14
  50. package/src/events-dep/details-setter/mouse.js +0 -35
  51. package/src/events-dep/details-setter/pointer.js +0 -35
  52. package/src/events-dep/details-setter/touch.js +0 -37
  53. package/src/events-dep/events-map/index.js +0 -70
  54. package/src/events-dep/index.js +0 -3
  55. package/src/events-dep/types/__Shared__.d.ts +0 -155
  56. package/src/events-dep/types/clipboard.d.ts +0 -20
  57. package/src/events-dep/types/focus.d.ts +0 -19
  58. package/src/events-dep/types/pointer.d.ts +0 -45
  59. package/src/events-dep/utils.js +0 -38
  60. package/src/events-dep/ziko-event.js +0 -108
  61. package/src/watch/dom-observer/ziko-observer.js +0 -15
  62. /package/src/dom/{flex → components/Flex}/utils/index.js +0 -0
  63. /package/src/dom/components/{fragment → Fragment}/index.d.ts +0 -0
  64. /package/src/dom/components/{fragment → Fragment}/index.js +0 -0
  65. /package/src/dom/components/{swap → Swap}/index.d.ts +0 -0
  66. /package/src/dom/components/{swap → Swap}/index.js +0 -0
  67. /package/src/dom/{logic/switch → components/Switch}/index.js +0 -0
package/dist/ziko.js CHANGED
@@ -2,7 +2,7 @@
2
2
  /*
3
3
  Project: ziko.js
4
4
  Author: Zakaria Elalaoui
5
- Date : Fri Jul 31 2026 17:26:32 GMT+0100 (UTC+01:00)
5
+ Date : Sun Aug 09 2026 11:06:22 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
@@ -17,11 +17,11 @@
17
17
  const { PI: PI$1, E } = Math;
18
18
  const EPSILON=Number.EPSILON;
19
19
 
20
- const is_primitive = value => typeof value !== 'object' && typeof value !== 'function' || value === null;
20
+ const is_primitive$1 = value => typeof value !== 'object' && typeof value !== 'function' || value === null;
21
21
 
22
22
  const mapfun$1=(fun,...X)=>{
23
23
  const Y=X.map(x=>{
24
- if(is_primitive(x) || x?.__mapfun__) return fun(x)
24
+ if(is_primitive$1(x) || x?.__mapfun__) return fun(x)
25
25
  if(x instanceof Array) return x.map(n=>mapfun$1(fun,n));
26
26
  if(ArrayBuffer.isView(x)) return x.map(n=>fun(n));
27
27
  if(x instanceof Set) return new Set(mapfun$1(fun,...[...x]));
@@ -2233,12 +2233,39 @@
2233
2233
  }
2234
2234
  }
2235
2235
 
2236
+ const parse_props = (props = {}) => {
2237
+
2238
+ const result = {
2239
+ methods: {},
2240
+ events: {},
2241
+ style: {},
2242
+ attrs: {}
2243
+ };
2244
+
2245
+ for (const [key, value] of Object.entries(props)) {
2246
+ if (key === "style") {
2247
+ result.style = value;
2248
+ }
2249
+ else if (key.startsWith("$")) {
2250
+ result.methods[key.slice(1)] = value;
2251
+ }
2252
+ else if (/^on[A-Z]/.test(key)) {
2253
+ result.events[key] = value;
2254
+ }
2255
+ else {
2256
+ result.attrs[key] = value;
2257
+ }
2258
+ }
2259
+
2260
+ return result;
2261
+ };
2262
+
2236
2263
  __init__global__();
2237
2264
  class UIElementCore extends UINode{
2238
2265
  constructor(){
2239
2266
  super();
2240
2267
  }
2241
- init(element, name, type, render){
2268
+ init({element, name, type, render, props = {}, items = []} = {}){
2242
2269
  this.target = globalThis.__Ziko__.__Config__.default.target||globalThis?.document?.body;
2243
2270
  if(typeof element === "string") {
2244
2271
  switch(type){
@@ -2286,9 +2313,26 @@
2286
2313
  };
2287
2314
  if(element) Object.assign(this.cache,{element});
2288
2315
  this.items = new UIStore();
2289
- globalThis.__Ziko__.__UI__[this.cache.name]?globalThis.__Ziko__.__UI__[this.cache.name]?.push(this):globalThis.__Ziko__.__UI__[this.cache.name]=[this];
2316
+ globalThis.__Ziko__.__UI__[this.cache.name]
2317
+ ? globalThis.__Ziko__.__UI__[this.cache.name]?.push(this)
2318
+ : globalThis.__Ziko__.__UI__[this.cache.name]=[this];
2290
2319
  element && render && this?.render?.();
2291
2320
  globalThis.__Ziko__.__UI__.push(this);
2321
+
2322
+ // console.log({props})
2323
+ const parsed_props = parse_props(props);
2324
+
2325
+ this.parsed_props = parsed_props;
2326
+
2327
+ this.style(parsed_props.style);
2328
+ this.setAttr(parsed_props.attrs);
2329
+
2330
+ const Events = Object.entries(parsed_props.events);
2331
+
2332
+ Events.forEach(([ev, callback]) => this[ev](callback.bind(this)));
2333
+
2334
+
2335
+ if(items.length > 0) this.append(...items);
2292
2336
  }
2293
2337
  get element(){
2294
2338
  return this.cache.element;
@@ -2396,8 +2440,9 @@
2396
2440
 
2397
2441
  // if (!globalThis.__Ziko__) __init__global__();
2398
2442
 
2443
+ const STATE_GETTER = Symbol.for("ziko.stateGetter");
2444
+
2399
2445
  function useState(initialValue) {
2400
-
2401
2446
  const state = {
2402
2447
  value: initialValue,
2403
2448
  subscribers: new Set(),
@@ -2407,7 +2452,6 @@
2407
2452
  function getValue() {
2408
2453
  return {
2409
2454
  value: state.value,
2410
- isStateGetter: () => true,
2411
2455
  _subscribe: (fn) => {
2412
2456
  state.subscribers.add(fn);
2413
2457
  return () => state.subscribers.delete(fn);
@@ -2415,6 +2459,8 @@
2415
2459
  };
2416
2460
  }
2417
2461
 
2462
+ getValue[STATE_GETTER] = true;
2463
+
2418
2464
  function setValue(newValue) {
2419
2465
  if (state.paused) return;
2420
2466
 
@@ -2436,6 +2482,7 @@
2436
2482
  if (typeof newValue === "function") {
2437
2483
  newValue = newValue(state.value);
2438
2484
  }
2485
+
2439
2486
  state.value = newValue;
2440
2487
  state.subscribers.forEach((fn) => fn(state.value));
2441
2488
  },
@@ -2445,9 +2492,7 @@
2445
2492
  return [getValue, setValue, controller];
2446
2493
  }
2447
2494
 
2448
- const isStateGetter = (arg) => {
2449
- return typeof arg === "function" && arg?.()?.isStateGetter?.() === true;
2450
- };
2495
+ const isStateGetter = (arg) => typeof arg === "function" && arg[STATE_GETTER] === true;
2451
2496
 
2452
2497
  const camel2hyphencase = (text = '') => text.replace(/[A-Z]/g, match => '-' + match.toLowerCase());
2453
2498
 
@@ -2598,8 +2643,8 @@
2598
2643
  if (["number", "string"].includes(typeof ele[i])) ele[i] = text(ele[i]);
2599
2644
  // Fix Items Latter
2600
2645
  if (ele[i] instanceof Function) {
2601
- const getter = ele[i]();
2602
- if (getter.isStateGetter) {
2646
+ if (isStateGetter(ele[i])) {
2647
+ const getter = ele[i]();
2603
2648
  ele[i] = text(getter.value);
2604
2649
  getter._subscribe(
2605
2650
  (newValue) => (ele[i].element.textContent = newValue),
@@ -3089,7 +3134,7 @@
3089
3134
  }
3090
3135
 
3091
3136
  let UIElement$1 = class UIElement extends UIElementCore{
3092
- constructor({element, name ='', type='html', render = __Ziko__.__Config__.default.render}={}){
3137
+ constructor({element, name ='', type = 'html', render = __Ziko__.__Config__.default.render, props}={}){
3093
3138
  super();
3094
3139
  this.exp = {
3095
3140
  events : {
@@ -3109,7 +3154,7 @@
3109
3154
  ViewListeners,
3110
3155
  );
3111
3156
 
3112
- if(element)this.init(element, name, type, render);
3157
+ if(element) this.init({element, name, type, render, props});
3113
3158
  }
3114
3159
  on(event_name, callback, {details_setter, category = 'global', isCustom = false, preventDefault = false} = {}){
3115
3160
  if(event_name instanceof Array) event_name.forEach(
@@ -3202,15 +3247,22 @@
3202
3247
 
3203
3248
  };
3204
3249
 
3250
+ const is_primitive = (value) => typeof value !== 'object' && typeof value !== 'function' || value === null;
3251
+
3205
3252
  const call_with_optional_props = (Component) => {
3206
3253
  return (...args) => {
3207
3254
  const first = args[0];
3208
- const isChild = first?.isUIElement?.() || isPrimitive(first) ;
3209
- return isChild
3210
- ? new Component({}, ...args)
3211
- : new Component(first, ...args.slice(1))
3255
+
3256
+ const isChild = first?.isUIElement?.() || is_primitive(first);
3257
+
3258
+ if (isChild) {
3259
+ return new Component({}, ...args);
3260
+ }
3261
+
3262
+ return new Component(first, ...args.slice(1));
3212
3263
  };
3213
- };
3264
+ };
3265
+
3214
3266
  function add_vendor_prefix(property) {
3215
3267
  const propertyUC = property.slice(0, 1).toUpperCase() + property.slice(1);
3216
3268
  const vendors = ['Webkit', 'Moz', 'O', 'ms'];
@@ -3263,9 +3315,9 @@
3263
3315
  const cloneUI=UIElement=>{
3264
3316
  return Object.assign(Object.create(Object.getPrototypeOf(UIElement)),UIElement)
3265
3317
  };
3266
- function isPrimitive(value) {
3267
- return typeof value !== 'object' && typeof value !== 'function' || value === null;
3268
- }
3318
+ // function isPrimitive(value) {
3319
+ // return typeof value !== 'object' && typeof value !== 'function' || value === null;
3320
+ // }
3269
3321
  const waitElm=(UIElement)=>{
3270
3322
  return new Promise(resolve => {
3271
3323
  if (UIElement) {
@@ -3284,15 +3336,6 @@
3284
3336
  });
3285
3337
  };
3286
3338
 
3287
- class UIView extends UIElement$1{
3288
- constructor(...items){
3289
- super({element : 'div', name : 'view'});
3290
- this.append(...items);
3291
- }
3292
- }
3293
-
3294
- const View = (...items) => new UIView(...items);
3295
-
3296
3339
  const HTMLTags = [
3297
3340
  'a',
3298
3341
  'abb',
@@ -3437,43 +3480,77 @@
3437
3480
  if(HTMLTags.includes(tag)) type = 'html';
3438
3481
  if(SVGTags.includes(tag)) type = 'svg';
3439
3482
  if(MathMLTags.includes(tag)) type = 'mathml';
3440
- return (...args)=>{
3441
- // Fix undefined
3442
- // console.log(isStateGetter(args[0]))
3443
- // console.log(!!args)
3483
+ return (...args) => {
3444
3484
  if(args.length === 0) {
3445
- // console.log('length 0')
3446
3485
  return new UIElement$1({element : tag, name : tag, type})
3447
3486
  }
3448
3487
  if(
3449
3488
  ['string', 'number'].includes(typeof args[0])
3450
3489
  || args[0] instanceof UIElement$1
3451
- || (typeof args[0] === 'function' && args[0]().isStateGetter())
3490
+ || isStateGetter(args[0])
3491
+ || args[0] instanceof HTMLElement
3452
3492
  ) return new UIElement$1({element : tag, name : tag, type}).append(...args);
3453
- // console.log(args[0])
3454
- return new UIElement$1({element : tag, type}).setAttr(args.shift()).append(...args)
3455
- }
3456
- // if(SVGTags.includes(tag)) return (...args) => new UIElement(tag,"",{el_type : "svg"}).append(...args);
3457
- // return (...args)=>{
3458
- // if(!(args[0] instanceof UIElement) && args[0] instanceof Object){
3459
- // let attributes = args.shift()
3460
- // return new UIElement(tag).setAttr(attributes).append(...args)
3461
- // }
3462
- // return new UIElement(tag).append(...args);
3463
- // }
3464
- // // switch(tag){
3465
- // case "html" : globalThis?.document?.createElement("html")
3466
- // case "head" :
3467
- // case "style" :
3468
- // case "link" :
3469
- // case "meta" :
3470
- // case "srcipt":
3471
- // case "body" : return null; break;
3472
- // default : return new UIElement(tag);
3473
- // }
3493
+ return new UIElement$1({element : tag, type, props : args.shift()}).append(...args)
3494
+ }
3474
3495
  }
3475
3496
  });
3476
3497
 
3498
+ function define_wc(name, UI_Constructor, props = {}, { mode = 'open'} = {}) {
3499
+ if (globalThis.customElements?.get(name)) {
3500
+ console.warn(`Custom element "${name}" is already defined`);
3501
+ return;
3502
+ }
3503
+ if(name.search('-') === -1){
3504
+ console.warn(`"${name}" is not a valid custom element name`);
3505
+ return;
3506
+ }
3507
+ globalThis.customElements?.define(
3508
+ name,
3509
+ class extends HTMLElement {
3510
+ static get observedAttributes() {
3511
+ return ['style', ...Object.keys(props)];
3512
+ }
3513
+
3514
+ constructor() {
3515
+ super();
3516
+ this.attachShadow({ mode });
3517
+ this.props = {};
3518
+ this.mask = {
3519
+ ...props,
3520
+ // style: { type: Object }
3521
+ };
3522
+ }
3523
+
3524
+ connectedCallback() {
3525
+ this.render();
3526
+ }
3527
+
3528
+ render() {
3529
+ this.shadowRoot.innerHTML = '';
3530
+ const item = UI_Constructor(this.props);
3531
+ if(item instanceof Array) item.forEach(n => n.mount(this.shadowRoot));
3532
+ else item.mount(this.shadowRoot);
3533
+ }
3534
+
3535
+ attributeChangedCallback(name, _, newValue) {
3536
+ Object.assign(this.props, {
3537
+ [name]: this.mask[name].type(newValue)
3538
+ });
3539
+ this.render();
3540
+ }
3541
+ }
3542
+ );
3543
+ }
3544
+
3545
+ class UIView extends UIElement$1{
3546
+ constructor(...items){
3547
+ super({element : 'div', name : 'view'});
3548
+ this.append(...items);
3549
+ }
3550
+ }
3551
+
3552
+ const View = (...items) => new UIView(...items);
3553
+
3477
3554
  function set_vertical(direction){
3478
3555
  direction == 1
3479
3556
  ? this.style({ flexDirection: "column" })
@@ -3579,7 +3656,7 @@
3579
3656
  }
3580
3657
  }
3581
3658
 
3582
- class ZikoUISuspense extends UIElement{
3659
+ class UISuspense extends UIElement{
3583
3660
  constructor(fallback_ui, callback){
3584
3661
  super({element : "div", name : "suspense"});
3585
3662
  this.setAttr({
@@ -3600,7 +3677,129 @@
3600
3677
  }
3601
3678
  }
3602
3679
 
3603
- const Suspense = (fallback_ui, callback) => new ZikoUISuspense(fallback_ui, callback);
3680
+ const Suspense = (fallback_ui, callback) => new UISuspense(fallback_ui, callback);
3681
+
3682
+ class UISwap extends UIElement$1 {
3683
+ #DISPLAYS_MAP = new WeakMap()
3684
+ constructor({ activeIndex = 0 } = {}, ...items) {
3685
+ super({ element: 'div' });
3686
+ this.style({ display: 'contents' });
3687
+
3688
+ this.states = {
3689
+ activeIndex
3690
+ };
3691
+
3692
+ this.append(...items);
3693
+ requestAnimationFrame(() => {
3694
+ this.render();
3695
+ });
3696
+ }
3697
+ get activeItem(){
3698
+ return this.items[this.states.activeIndex]
3699
+ }
3700
+ render() {
3701
+ this.items.forEach((n, i) => {
3702
+
3703
+ const initialDisplay = getComputedStyle(n.element).display;
3704
+ this.#DISPLAYS_MAP.set(n, initialDisplay);
3705
+
3706
+ if (i !== this.states.activeIndex) {
3707
+ n.style({ display: 'none' });
3708
+ }
3709
+ });
3710
+ }
3711
+ get DS(){
3712
+ return this.#DISPLAYS_MAP
3713
+ }
3714
+ next(n = 1) {
3715
+ return this.activate(this.states.activeIndex + n);
3716
+ }
3717
+ previous(n = 1) {
3718
+ return this.activate(this.states.activeIndex - n);
3719
+ }
3720
+ activate(index) {
3721
+ if (!this.items.length) return this;
3722
+
3723
+ const currentItem = this.items.at(this.states.activeIndex);
3724
+
3725
+ if (currentItem) {
3726
+ currentItem.style({ display: 'none' });
3727
+ }
3728
+
3729
+ const len = this.items.length;
3730
+ this.states.activeIndex = ((index % len) + len) % len;
3731
+
3732
+ const activeItem = this.items.at(this.states.activeIndex);
3733
+ if (activeItem) {
3734
+ const restoredDisplay = this.#DISPLAYS_MAP.get(activeItem) || 'block';
3735
+ activeItem.style({ display: restoredDisplay === 'none' ? 'block' : restoredDisplay });
3736
+ }
3737
+
3738
+ return this;
3739
+ }
3740
+ }
3741
+
3742
+ const Swap = call_with_optional_props(UISwap);
3743
+
3744
+ class UIFragment extends UIElement$1{
3745
+ constructor(...items){
3746
+ super({ element : document.createDocumentFragment()});
3747
+ this.append(...items);
3748
+ }
3749
+ isFragment(){
3750
+ return true
3751
+ }
3752
+ }
3753
+
3754
+ const Fragment = (...items) => new UIFragment(...items);
3755
+
3756
+ class UIFor extends UIFragment{
3757
+ constructor({each, fallback, mapFn = () => {}} = {}){
3758
+ super();
3759
+ this.config = {
3760
+ each,
3761
+ fallback,
3762
+ mapFn
3763
+ };
3764
+ this.append(
3765
+ ...this.config.each.map((n,i) => this.config.mapFn(n, i))
3766
+ );
3767
+ }
3768
+ }
3769
+
3770
+ const For = ({each, fallback, mapFn} = {}) => new UIFor({each, fallback, mapFn});
3771
+
3772
+ class UISwitch extends UIElement$1{
3773
+ constructor(key, cases){
3774
+ super();
3775
+ this.key = key;
3776
+ this.cases = cases;
3777
+ this.init();
3778
+ }
3779
+ init(){
3780
+ Object.values(this.cases).filter(n=>n != this.current).forEach(n=>n.unmount());
3781
+ super.init(this.current.element);
3782
+ }
3783
+ get current(){
3784
+ const matched = Object.keys(this.cases).find(n => n == this.key) ?? 'default';
3785
+ return this.cases[matched]
3786
+ }
3787
+ updateKey(key){
3788
+ this.key = key;
3789
+ this.replaceElementWith(this.current.element);
3790
+ // this.cache.element.replaceWith(this.current.element)
3791
+ // this.cache.element = this.current.element;
3792
+ return this;
3793
+ }
3794
+
3795
+ }
3796
+
3797
+ const Switch=({key, cases})=> new UISwitch(key, cases);
3798
+
3799
+ // export const Switch=({key, cases}) => {
3800
+ // const matched = Object.keys(cases).find(n => n == key) ?? 'default';
3801
+ // return this.cases[matched]()
3802
+ // }
3604
3803
 
3605
3804
  class UIHTMLWrapper extends UIElement$1 {
3606
3805
  constructor(content){
@@ -3664,169 +3863,240 @@
3664
3863
 
3665
3864
  const SVGWrapper = (content) => new UISVGWrapper(content);
3666
3865
 
3667
- function define_wc(name, UI_Constructor, props = {}, { mode = 'open'} = {}) {
3668
- if (globalThis.customElements?.get(name)) {
3669
- console.warn(`Custom element "${name}" is already defined`);
3670
- return;
3866
+ class UICanvas extends UIElement$1{
3867
+ constructor(w,h){
3868
+ super("canvas","canvas");
3869
+ this.ctx = this.element?.getContext("2d");
3870
+ this.style({
3871
+ border:"1px red solid",
3872
+ });
3873
+ this.transformMatrix = new Matrix([
3874
+ [1,0,0],
3875
+ [0,1,0],
3876
+ [0,0,1]
3877
+ ]);
3878
+ this.axisMatrix = new Matrix([
3879
+ [-10,-10],
3880
+ [10,10]
3881
+ ]);
3882
+ // setTimeout(()=>this.resize(w,h),0);
3883
+ requestAnimationFrame(()=>this.resize(w,h),0);
3884
+ this.on("sizeupdated",()=>this.adjust());
3671
3885
  }
3672
- if(name.search('-') === -1){
3673
- console.warn(`"${name}" is not a valid custom element name`);
3674
- return;
3886
+ get Xmin(){
3887
+ return this.axisMatrix[0][0];
3675
3888
  }
3676
- globalThis.customElements?.define(
3677
- name,
3678
- class extends HTMLElement {
3679
- static get observedAttributes() {
3680
- return ['style', ...Object.keys(props)];
3681
- }
3682
-
3683
- constructor() {
3684
- super();
3685
- this.attachShadow({ mode });
3686
- this.props = {};
3687
- this.mask = {
3688
- ...props,
3689
- // style: { type: Object }
3690
- };
3691
- }
3692
-
3693
- connectedCallback() {
3694
- this.render();
3695
- }
3696
-
3697
- render() {
3698
- this.shadowRoot.innerHTML = '';
3699
- const item = UI_Constructor(this.props);
3700
- if(item instanceof Array) item.forEach(n => n.mount(this.shadowRoot));
3701
- else item.mount(this.shadowRoot);
3702
- }
3703
-
3704
- attributeChangedCallback(name, _, newValue) {
3705
- Object.assign(this.props, {
3706
- [name]: this.mask[name].type(newValue)
3707
- });
3708
- this.render();
3709
- }
3889
+ get Ymin(){
3890
+ return this.axisMatrix[0][1];
3891
+ }
3892
+ get Xmax(){
3893
+ return this.axisMatrix[1][0];
3894
+ }
3895
+ get Ymax(){
3896
+ return this.axisMatrix[1][1];
3897
+ }
3898
+ get ImageData(){
3899
+ return this.ctx.getImageData(0,0,c.Width,c.Height);
3900
+ }
3901
+ draw(all=true){
3902
+ if(all){
3903
+ this.clear();
3904
+ this.items.forEach(element => {
3905
+ element.parent=this;
3906
+ element.draw(this.ctx);
3907
+ });
3710
3908
  }
3711
- );
3712
- }
3713
-
3714
- class UISwitch extends UIElement$1{
3715
- constructor(key, cases){
3716
- super();
3717
- this.key = key;
3718
- this.cases = cases;
3719
- this.init();
3909
+ else {
3910
+ this.items.at(-1).parent=this;
3911
+ this.items.at(-1).draw(this.ctx);
3912
+ }
3913
+ this.maintain();
3914
+ return this;
3720
3915
  }
3721
- init(){
3722
- Object.values(this.cases).filter(n=>n != this.current).forEach(n=>n.unmount());
3723
- super.init(this.current.element);
3916
+ applyTransformMatrix(){
3917
+ this.ctx.setTransform(
3918
+ this.transformMatrix[0][0],
3919
+ this.transformMatrix[1][0],
3920
+ this.transformMatrix[0][1],
3921
+ this.transformMatrix[1][1],
3922
+ this.transformMatrix[0][2],
3923
+ this.transformMatrix[1][2],
3924
+ );
3925
+ return this;
3724
3926
  }
3725
- get current(){
3726
- const matched = Object.keys(this.cases).find(n => n == this.key) ?? 'default';
3727
- return this.cases[matched]
3927
+ resize(w,h){
3928
+ this.size(w,h);
3929
+ this.lineWidth();
3930
+ this.view(this.axisMatrix[0][0], this.axisMatrix[0][1], this.axisMatrix[1][0], this.axisMatrix[1][1]);
3931
+ this.emit("sizeupdated");
3932
+ return this;
3728
3933
  }
3729
- updateKey(key){
3730
- this.key = key;
3731
- this.replaceElementWith(this.current.element);
3732
- // this.cache.element.replaceWith(this.current.element)
3733
- // this.cache.element = this.current.element;
3934
+ adjust(){
3935
+ this.element.width =this.element?.getBoundingClientRect().width;
3936
+ this.element.height =this.element?.getBoundingClientRect().height;
3937
+ this.view(this.axisMatrix[0][0], this.axisMatrix[0][1], this.axisMatrix[1][0], this.axisMatrix[1][1]);
3734
3938
  return this;
3735
3939
  }
3736
-
3737
- }
3738
-
3739
- const Switch=({key, cases})=> new UISwitch(key, cases);
3740
-
3741
- // export const Switch=({key, cases}) => {
3742
- // const matched = Object.keys(cases).find(n => n == key) ?? 'default';
3743
- // return this.cases[matched]()
3744
- // }
3745
-
3746
- class UISwap extends UIElement$1 {
3747
- #DISPLAYS_MAP = new WeakMap()
3748
- constructor({ activeIndex = 0 } = {}, ...items) {
3749
- super({ element: 'div' });
3750
- this.style({ display: 'contents' });
3751
-
3752
- this.states = {
3753
- activeIndex
3754
- };
3940
+ view(xMin,yMin,xMax,yMax){
3941
+ this.transformMatrix[0][0]=this.width/(xMax-xMin); // scaleX
3942
+ this.transformMatrix[1][1]=-this.height/(yMax-yMin); // scaleY
3943
+ this.transformMatrix[0][2]=this.width/2;
3944
+ this.transformMatrix[1][2]=this.height/2;
3945
+ this.axisMatrix=new Matrix([
3946
+ [xMin,yMin],
3947
+ [xMax,yMax]
3948
+ ]);
3755
3949
 
3756
- this.append(...items);
3757
- this.render();
3950
+ this.applyTransformMatrix();
3951
+ this.clear();
3952
+ this.lineWidth(1);
3953
+ this.draw();
3954
+ return this;
3758
3955
  }
3759
- get activeItem(){
3760
- return this.items[this.states.activeIndex]
3956
+ reset(){
3957
+ this.ctx.setTransform(1,0,0,0,0,0);
3958
+ return this;
3761
3959
  }
3762
- render() {
3763
- this.items.forEach((n, i) => {
3764
-
3765
- const initialDisplay = n.element?.style?.display || '';
3766
- this.#DISPLAYS_MAP.set(n, initialDisplay);
3767
-
3768
- if (i !== this.states.activeIndex) {
3769
- n.style({ display: 'none' });
3770
- }
3771
- });
3960
+ append(element){
3961
+ this.items.push(element);
3962
+ this.draw(false);
3963
+ return this;
3772
3964
  }
3773
- next(n = 1) {
3774
- return this.activate(this.states.activeIndex + n);
3965
+ background(color){
3966
+ this.ctx.fillStyle = color;
3967
+ this.ctx.setTransform(1, 0, 0, 1, 0, 0);
3968
+ this.ctx.fillRect(0, 0, this.width, this.height);
3969
+ this.applyTransformMatrix();
3970
+ this.draw();
3775
3971
  }
3776
- previous(n = 1) {
3777
- return this.activate(this.states.activeIndex - n);
3972
+ lineWidth(w){
3973
+ this.ctx.lineWidth=w/this.transformMatrix[0][0];
3974
+ return this
3778
3975
  }
3779
- activate(index) {
3780
- if (!this.items.length) return this;
3781
-
3782
- const currentItem = this.items.at(this.states.activeIndex);
3976
+ getImageData(x=0,y=0,w=this.width,h=this.height){
3977
+ return this.ctx.getImageData(x,y,w,h);
3978
+ }
3979
+ clear(){
3980
+ this.ctx.setTransform(1, 0, 0, 1, 0, 0);
3981
+ this.ctx.clearRect(0, 0, this.width, this.height);
3982
+ this.applyTransformMatrix();
3983
+ return this;
3984
+ }
3985
+ clone(){
3986
+ console.log(this.width);
3987
+ const canvas=new UICanvas();
3988
+ canvas.items=this.items;
3989
+ canvas.transformMatrix=this.transformMatrix;
3990
+ canvas.axisMatrix=this.axisMatrix;
3991
+ Object.assign(canvas.cache,{...this.cache});
3992
+ //waitForUIElm(this)
3993
+ //console.log(element)
3994
+ this.size(this.element.style.width,this.element.style.width);
3995
+ this.applyTransformMatrix();
3996
+ this.draw();
3997
+ this.adjust();
3998
+ return canvas;
3999
+ }
4000
+ toImage() {
4001
+ this.img = document?.createElement("img");
4002
+ this.img.src = this.element?.toDataURL("image/png");
4003
+ return this;
4004
+ }
4005
+ toBlob() {
4006
+ var canvas = this.element;
4007
+ canvas.toBlob(function (blob) {
4008
+ var newImg = document?.createElement("img"),
4009
+ url = URL.createObjectURL(blob);
4010
+ newImg.onload = function () {
4011
+ URL.revokeObjectURL(url);
4012
+ };
4013
+ newImg.src = url;
4014
+ console.log(newImg);
4015
+ });
4016
+ }
4017
+ zoomIn(){
3783
4018
 
3784
- if (currentItem) {
3785
- currentItem.style({ display: 'none' });
3786
- }
4019
+ }
4020
+ zoomOut(){
4021
+
4022
+ }
4023
+ undo(n){
3787
4024
 
3788
- const len = this.items.length;
3789
- this.states.activeIndex = ((index % len) + len) % len;
4025
+ }
4026
+ redo(n){
3790
4027
 
3791
- const activeItem = this.items.at(this.states.activeIndex);
3792
- if (activeItem) {
3793
- const restoredDisplay = this.#DISPLAYS_MAP.get(activeItem) || 'block';
3794
- activeItem.style({ display: restoredDisplay === 'none' ? 'block' : restoredDisplay });
3795
- }
4028
+ }
4029
+ stream(){
3796
4030
 
3797
- return this;
3798
4031
  }
3799
4032
  }
3800
4033
 
3801
- const Swap = call_with_optional_props(UISwap);
4034
+ const Canvas=(w,h)=>new UICanvas(w,h);
3802
4035
 
3803
- class UIFragment extends UIElement$1{
3804
- constructor(...items){
3805
- super({ element : document.createDocumentFragment()});
3806
- this.append(...items);
4036
+ class UISvg extends UIElement$1 {
4037
+ constructor(w=360,h=300) {
4038
+ super("svg","svg");
4039
+ //this.cache={};
4040
+ // this.setAttr("width",w);
4041
+ // this.setAttr("height",h);
4042
+ // this.setAttr({
4043
+ // width : w,
4044
+ // height : h
4045
+ // })
4046
+ this.style({border:"1px black solid"});
4047
+ //this.view(-w/2,-h/2,w/2,h/2);
4048
+ this.size(w, h);
4049
+ this.view(-10,-10,10,10);
4050
+ }
4051
+ size(w, h){
4052
+ this.setAttr({
4053
+ width : w,
4054
+ height : h
4055
+ });
4056
+ return this
4057
+ }
4058
+ view(x1,y1,x2,y2){
4059
+ let width=Math.abs(x2-x1);
4060
+ let height=Math.abs(y2-y1);
4061
+ this.setAttr("viewBox",[x1,y1,width,height].join(" "));
4062
+ this.st.scaleY(-1);
4063
+ return this;
4064
+ }
4065
+ add(...svgElement){
4066
+ for(let i=0;i<svgElement.length;i++){
4067
+ this.element.append(svgElement[i].element);
4068
+ this.items.push(svgElement[i]);
4069
+ }
4070
+ this.maintain();
4071
+ return this;
3807
4072
  }
3808
- isFragment(){
3809
- return true
4073
+ remove(...svgElement){
4074
+ for(let i=0;i<svgElement.length;i++){
4075
+ this.element?.removeChild(svgElement[i].element);
4076
+ this.items=this.items.filter(n=>!svgElement);
4077
+ }
4078
+ this.maintain();
4079
+ return this;
3810
4080
  }
3811
- }
3812
-
3813
- const Fragment = (...items) => new UIFragment(...items);
3814
-
3815
- class UIFor extends UIFragment{
3816
- constructor({each, fallback, mapFn = () => {}} = {}){
3817
- super();
3818
- this.config = {
3819
- each,
3820
- fallback,
3821
- mapFn
3822
- };
3823
- this.append(
3824
- ...this.config.each.map((n,i) => this.config.mapFn(n, i))
3825
- );
4081
+ mask(){
4082
+
3826
4083
  }
3827
- }
4084
+ toString(){
4085
+ return (new XMLSerializer()).serializeToString(this.element);
4086
+ }
4087
+ btoa(){
4088
+ return btoa(this.toString())
4089
+ }
4090
+ toImg(){
4091
+ return 'data:image/svg+xml;base64,'+this.btoa()
4092
+ }
4093
+ toImg2(){
4094
+ return "data:image/svg+xml;charset=utf8,"+this.toString().replaceAll("<","%3C").replaceAll(">","%3E").replaceAll("#","%23").replaceAll('"',"'");
4095
+ }
4096
+
4097
+ }
3828
4098
 
3829
- const For = ({each, fallback, mapFn} = {}) => new UIFor({each, fallback, mapFn});
4099
+ const Svg =(w,h)=>new UISvg(w,h);
3830
4100
 
3831
4101
  const { PI, sqrt: sqrt$1, cos: cos$2, sin: sin$2, acos, pow } = Math;
3832
4102
 
@@ -4397,13 +4667,15 @@
4397
4667
  };
4398
4668
  const csv2json = (csv, delimiter = ",") => JSON.stringify(csv2object(csv,delimiter));
4399
4669
  const csv2sql=(csv, Table)=>{
4670
+ const sanitizeId = s => s.trim().replace(/[^a-zA-Z0-9_]/g, '');
4671
+ const escapeVal = s => "'" + s.trim().replace(/'/g, "''") + "'";
4400
4672
  const lines = csv.trim().trimEnd().split('\n').filter(n=>n);
4401
- const columns = lines[0].split(',');
4402
- let sqlQuery = `INSERT INTO ${Table} (${columns.join(', ')}) Values `;
4673
+ const columns = lines[0].split(',').map(sanitizeId);
4674
+ let sqlQuery = "INSERT INTO " + sanitizeId(Table) + " (" + columns.join(', ') + ") Values ";
4403
4675
  let sqlValues = [];
4404
4676
  for (let i = 1; i < lines.length; i++) {
4405
- const values = lines[i].split(',');
4406
- sqlValues.push(`(${values})`);
4677
+ const values = lines[i].split(',').map(escapeVal);
4678
+ sqlValues.push("(" + values.join(', ') + ")");
4407
4679
  }
4408
4680
  return sqlQuery+sqlValues.join(",\n");
4409
4681
  };
@@ -4520,6 +4792,35 @@
4520
4792
  }, Array.isArray(obj) ? [] : {});
4521
4793
  }
4522
4794
 
4795
+ function parseXML(xmlString) {
4796
+ const parser = new DOMParser();
4797
+ const xmlDoc = parser.parseFromString(xmlString, 'text/xml');
4798
+ const rootNode = xmlDoc.documentElement;
4799
+ const result = parseNode(rootNode);
4800
+ return result;
4801
+ }
4802
+
4803
+ function parseNode(node) {
4804
+ const obj = {
4805
+ type: node.nodeName,
4806
+ attributes: {},
4807
+ children: []
4808
+ };
4809
+ for (let i = 0; i < node.attributes.length; i++) {
4810
+ const attr = node.attributes[i];
4811
+ obj.attributes[attr.name] = attr.value;
4812
+ }
4813
+ for (let i = 0; i < node.childNodes.length; i++) {
4814
+ const child = node.childNodes[i];
4815
+ if (child.nodeType === Node.ELEMENT_NODE) {
4816
+ obj.children.push(parseNode(child));
4817
+ } else if (child.nodeType === Node.TEXT_NODE) {
4818
+ obj.text = child.textContent.trim();
4819
+ }
4820
+ }
4821
+ return obj;
4822
+ }
4823
+
4523
4824
  // import { ZikoHead , useHead} from "../reactivity/hooks/head/index.js";
4524
4825
  class ZikoApp {
4525
4826
  constructor({head = null, wrapper = null, target = null}){
@@ -4811,6 +5112,45 @@
4811
5112
  nested_value
4812
5113
  );
4813
5114
 
5115
+ const useEffect = (callback, deps = []) =>{
5116
+ const states = deps.filter(isStateGetter);
5117
+
5118
+ let cleanup;
5119
+
5120
+ const execute = () => {
5121
+ // Cleanup previous effect
5122
+ if (typeof cleanup === "function") {
5123
+ cleanup();
5124
+ }
5125
+
5126
+ // Read current state values
5127
+ const values = states.map(state => state().value);
5128
+
5129
+ // Execute effect
5130
+ cleanup = callback(...values);
5131
+ };
5132
+
5133
+ // Subscribe to states
5134
+ const unsubscribers = states.map(state =>
5135
+ state()._subscribe(execute)
5136
+ );
5137
+
5138
+ // Initial execution
5139
+ execute();
5140
+
5141
+ // Return effect cleanup
5142
+ return () => {
5143
+ unsubscribers.forEach(unsubscribe => {
5144
+ unsubscribe();
5145
+ });
5146
+
5147
+ if (typeof cleanup === "function") {
5148
+ cleanup();
5149
+ cleanup = undefined;
5150
+ }
5151
+ };
5152
+ };
5153
+
4814
5154
  class UseThread {
4815
5155
  #worker;
4816
5156
  #callbacks = new Map();
@@ -5234,6 +5574,7 @@
5234
5574
  }
5235
5575
 
5236
5576
  exports.App = App;
5577
+ exports.Canvas = Canvas;
5237
5578
  exports.ClickAwayEvent = ClickAwayEvent;
5238
5579
  exports.ClickListeners = ClickListeners;
5239
5580
  exports.Clock = Clock;
@@ -5253,9 +5594,11 @@
5253
5594
  exports.PtrListeners = PtrListeners;
5254
5595
  exports.Random = Random;
5255
5596
  exports.SPA = SPA;
5597
+ exports.STATE_GETTER = STATE_GETTER;
5256
5598
  exports.SVGWrapper = SVGWrapper;
5257
5599
  exports.Scheduler = Scheduler;
5258
5600
  exports.Suspense = Suspense;
5601
+ exports.Svg = Svg;
5259
5602
  exports.Swap = Swap;
5260
5603
  exports.SwipeEvent = SwipeEvent;
5261
5604
  exports.Switch = Switch;
@@ -5263,12 +5606,15 @@
5263
5606
  exports.TimeAnimation = TimeAnimation;
5264
5607
  exports.TimeLoop = TimeLoop;
5265
5608
  exports.TimeScheduler = TimeScheduler;
5609
+ exports.UICanvas = UICanvas;
5266
5610
  exports.UIElement = UIElement$1;
5267
5611
  exports.UIFlex = UIFlex;
5268
5612
  exports.UIFragment = UIFragment;
5269
5613
  exports.UIHTMLWrapper = UIHTMLWrapper;
5270
5614
  exports.UINode = UINode;
5271
5615
  exports.UISVGWrapper = UISVGWrapper;
5616
+ exports.UISuspense = UISuspense;
5617
+ exports.UISvg = UISvg;
5272
5618
  exports.UISwap = UISwap;
5273
5619
  exports.UISwitch = UISwitch;
5274
5620
  exports.UIView = UIView;
@@ -5279,7 +5625,6 @@
5279
5625
  exports.ViewListeners = ViewListeners;
5280
5626
  exports.ZikoApp = ZikoApp;
5281
5627
  exports.ZikoSPA = ZikoSPA;
5282
- exports.ZikoUISuspense = ZikoUISuspense;
5283
5628
  exports.ZikoUIText = ZikoUIText;
5284
5629
  exports.abs = abs;
5285
5630
  exports.accum_max = accum_max;
@@ -5357,8 +5702,8 @@
5357
5702
  exports.in_sin = in_sin;
5358
5703
  exports.interquartile_mean = interquartile_mean;
5359
5704
  exports.iqr = iqr;
5360
- exports.isPrimitive = isPrimitive;
5361
5705
  exports.isStateGetter = isStateGetter;
5706
+ exports.is_primitive = is_primitive;
5362
5707
  exports.json2arr = json2arr;
5363
5708
  exports.json2css = json2css;
5364
5709
  exports.json2csv = json2csv;
@@ -5403,6 +5748,8 @@
5403
5748
  exports.out_quart = out_quart;
5404
5749
  exports.out_quint = out_quint;
5405
5750
  exports.out_sin = out_sin;
5751
+ exports.parseXML = parseXML;
5752
+ exports.parse_props = parse_props;
5406
5753
  exports.percentile = percentile;
5407
5754
  exports.pow = pow$1;
5408
5755
  exports.power_mean = power_mean;
@@ -5449,6 +5796,7 @@
5449
5796
  exports.trimmed_mean = trimmed_mean;
5450
5797
  exports.trunc = trunc;
5451
5798
  exports.useDerived = useDerived;
5799
+ exports.useEffect = useEffect;
5452
5800
  exports.useEventEmitter = useEventEmitter;
5453
5801
  exports.useIPC = useIPC;
5454
5802
  exports.useLocalStorage = useLocalStorage;