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.cjs 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
@@ -13,11 +13,11 @@
13
13
  const { PI: PI$1, E } = Math;
14
14
  const EPSILON=Number.EPSILON;
15
15
 
16
- const is_primitive = value => typeof value !== 'object' && typeof value !== 'function' || value === null;
16
+ const is_primitive$1 = value => typeof value !== 'object' && typeof value !== 'function' || value === null;
17
17
 
18
18
  const mapfun$1=(fun,...X)=>{
19
19
  const Y=X.map(x=>{
20
- if(is_primitive(x) || x?.__mapfun__) return fun(x)
20
+ if(is_primitive$1(x) || x?.__mapfun__) return fun(x)
21
21
  if(x instanceof Array) return x.map(n=>mapfun$1(fun,n));
22
22
  if(ArrayBuffer.isView(x)) return x.map(n=>fun(n));
23
23
  if(x instanceof Set) return new Set(mapfun$1(fun,...[...x]));
@@ -2229,12 +2229,39 @@ function __init__global__(){
2229
2229
  }
2230
2230
  }
2231
2231
 
2232
+ const parse_props = (props = {}) => {
2233
+
2234
+ const result = {
2235
+ methods: {},
2236
+ events: {},
2237
+ style: {},
2238
+ attrs: {}
2239
+ };
2240
+
2241
+ for (const [key, value] of Object.entries(props)) {
2242
+ if (key === "style") {
2243
+ result.style = value;
2244
+ }
2245
+ else if (key.startsWith("$")) {
2246
+ result.methods[key.slice(1)] = value;
2247
+ }
2248
+ else if (/^on[A-Z]/.test(key)) {
2249
+ result.events[key] = value;
2250
+ }
2251
+ else {
2252
+ result.attrs[key] = value;
2253
+ }
2254
+ }
2255
+
2256
+ return result;
2257
+ };
2258
+
2232
2259
  __init__global__();
2233
2260
  class UIElementCore extends UINode{
2234
2261
  constructor(){
2235
2262
  super();
2236
2263
  }
2237
- init(element, name, type, render){
2264
+ init({element, name, type, render, props = {}, items = []} = {}){
2238
2265
  this.target = globalThis.__Ziko__.__Config__.default.target||globalThis?.document?.body;
2239
2266
  if(typeof element === "string") {
2240
2267
  switch(type){
@@ -2282,9 +2309,26 @@ class UIElementCore extends UINode{
2282
2309
  };
2283
2310
  if(element) Object.assign(this.cache,{element});
2284
2311
  this.items = new UIStore();
2285
- globalThis.__Ziko__.__UI__[this.cache.name]?globalThis.__Ziko__.__UI__[this.cache.name]?.push(this):globalThis.__Ziko__.__UI__[this.cache.name]=[this];
2312
+ globalThis.__Ziko__.__UI__[this.cache.name]
2313
+ ? globalThis.__Ziko__.__UI__[this.cache.name]?.push(this)
2314
+ : globalThis.__Ziko__.__UI__[this.cache.name]=[this];
2286
2315
  element && render && this?.render?.();
2287
2316
  globalThis.__Ziko__.__UI__.push(this);
2317
+
2318
+ // console.log({props})
2319
+ const parsed_props = parse_props(props);
2320
+
2321
+ this.parsed_props = parsed_props;
2322
+
2323
+ this.style(parsed_props.style);
2324
+ this.setAttr(parsed_props.attrs);
2325
+
2326
+ const Events = Object.entries(parsed_props.events);
2327
+
2328
+ Events.forEach(([ev, callback]) => this[ev](callback.bind(this)));
2329
+
2330
+
2331
+ if(items.length > 0) this.append(...items);
2288
2332
  }
2289
2333
  get element(){
2290
2334
  return this.cache.element;
@@ -2392,8 +2436,9 @@ var LifecycleMethods = /*#__PURE__*/Object.freeze({
2392
2436
 
2393
2437
  // if (!globalThis.__Ziko__) __init__global__();
2394
2438
 
2439
+ const STATE_GETTER = Symbol.for("ziko.stateGetter");
2440
+
2395
2441
  function useState(initialValue) {
2396
-
2397
2442
  const state = {
2398
2443
  value: initialValue,
2399
2444
  subscribers: new Set(),
@@ -2403,7 +2448,6 @@ function useState(initialValue) {
2403
2448
  function getValue() {
2404
2449
  return {
2405
2450
  value: state.value,
2406
- isStateGetter: () => true,
2407
2451
  _subscribe: (fn) => {
2408
2452
  state.subscribers.add(fn);
2409
2453
  return () => state.subscribers.delete(fn);
@@ -2411,6 +2455,8 @@ function useState(initialValue) {
2411
2455
  };
2412
2456
  }
2413
2457
 
2458
+ getValue[STATE_GETTER] = true;
2459
+
2414
2460
  function setValue(newValue) {
2415
2461
  if (state.paused) return;
2416
2462
 
@@ -2432,6 +2478,7 @@ function useState(initialValue) {
2432
2478
  if (typeof newValue === "function") {
2433
2479
  newValue = newValue(state.value);
2434
2480
  }
2481
+
2435
2482
  state.value = newValue;
2436
2483
  state.subscribers.forEach((fn) => fn(state.value));
2437
2484
  },
@@ -2441,9 +2488,7 @@ function useState(initialValue) {
2441
2488
  return [getValue, setValue, controller];
2442
2489
  }
2443
2490
 
2444
- const isStateGetter = (arg) => {
2445
- return typeof arg === "function" && arg?.()?.isStateGetter?.() === true;
2446
- };
2491
+ const isStateGetter = (arg) => typeof arg === "function" && arg[STATE_GETTER] === true;
2447
2492
 
2448
2493
  const camel2hyphencase = (text = '') => text.replace(/[A-Z]/g, match => '-' + match.toLowerCase());
2449
2494
 
@@ -2594,8 +2639,8 @@ async function __addItem__(adder, pusher, ...ele) {
2594
2639
  if (["number", "string"].includes(typeof ele[i])) ele[i] = text(ele[i]);
2595
2640
  // Fix Items Latter
2596
2641
  if (ele[i] instanceof Function) {
2597
- const getter = ele[i]();
2598
- if (getter.isStateGetter) {
2642
+ if (isStateGetter(ele[i])) {
2643
+ const getter = ele[i]();
2599
2644
  ele[i] = text(getter.value);
2600
2645
  getter._subscribe(
2601
2646
  (newValue) => (ele[i].element.textContent = newValue),
@@ -3085,7 +3130,7 @@ function register_swipe_event(
3085
3130
  }
3086
3131
 
3087
3132
  let UIElement$1 = class UIElement extends UIElementCore{
3088
- constructor({element, name ='', type='html', render = __Ziko__.__Config__.default.render}={}){
3133
+ constructor({element, name ='', type = 'html', render = __Ziko__.__Config__.default.render, props}={}){
3089
3134
  super();
3090
3135
  this.exp = {
3091
3136
  events : {
@@ -3105,7 +3150,7 @@ let UIElement$1 = class UIElement extends UIElementCore{
3105
3150
  ViewListeners,
3106
3151
  );
3107
3152
 
3108
- if(element)this.init(element, name, type, render);
3153
+ if(element) this.init({element, name, type, render, props});
3109
3154
  }
3110
3155
  on(event_name, callback, {details_setter, category = 'global', isCustom = false, preventDefault = false} = {}){
3111
3156
  if(event_name instanceof Array) event_name.forEach(
@@ -3198,15 +3243,22 @@ let UIElement$1 = class UIElement extends UIElementCore{
3198
3243
 
3199
3244
  };
3200
3245
 
3246
+ const is_primitive = (value) => typeof value !== 'object' && typeof value !== 'function' || value === null;
3247
+
3201
3248
  const call_with_optional_props = (Component) => {
3202
3249
  return (...args) => {
3203
3250
  const first = args[0];
3204
- const isChild = first?.isUIElement?.() || isPrimitive(first) ;
3205
- return isChild
3206
- ? new Component({}, ...args)
3207
- : new Component(first, ...args.slice(1))
3251
+
3252
+ const isChild = first?.isUIElement?.() || is_primitive(first);
3253
+
3254
+ if (isChild) {
3255
+ return new Component({}, ...args);
3256
+ }
3257
+
3258
+ return new Component(first, ...args.slice(1));
3208
3259
  };
3209
- };
3260
+ };
3261
+
3210
3262
  function add_vendor_prefix(property) {
3211
3263
  const propertyUC = property.slice(0, 1).toUpperCase() + property.slice(1);
3212
3264
  const vendors = ['Webkit', 'Moz', 'O', 'ms'];
@@ -3259,9 +3311,9 @@ const CloneElement = (UIElement) => {
3259
3311
  const cloneUI=UIElement=>{
3260
3312
  return Object.assign(Object.create(Object.getPrototypeOf(UIElement)),UIElement)
3261
3313
  };
3262
- function isPrimitive(value) {
3263
- return typeof value !== 'object' && typeof value !== 'function' || value === null;
3264
- }
3314
+ // function isPrimitive(value) {
3315
+ // return typeof value !== 'object' && typeof value !== 'function' || value === null;
3316
+ // }
3265
3317
  const waitElm=(UIElement)=>{
3266
3318
  return new Promise(resolve => {
3267
3319
  if (UIElement) {
@@ -3280,15 +3332,6 @@ const waitElm=(UIElement)=>{
3280
3332
  });
3281
3333
  };
3282
3334
 
3283
- class UIView extends UIElement$1{
3284
- constructor(...items){
3285
- super({element : 'div', name : 'view'});
3286
- this.append(...items);
3287
- }
3288
- }
3289
-
3290
- const View = (...items) => new UIView(...items);
3291
-
3292
3335
  const HTMLTags = [
3293
3336
  'a',
3294
3337
  'abb',
@@ -3433,43 +3476,77 @@ const tags = new Proxy({}, {
3433
3476
  if(HTMLTags.includes(tag)) type = 'html';
3434
3477
  if(SVGTags.includes(tag)) type = 'svg';
3435
3478
  if(MathMLTags.includes(tag)) type = 'mathml';
3436
- return (...args)=>{
3437
- // Fix undefined
3438
- // console.log(isStateGetter(args[0]))
3439
- // console.log(!!args)
3479
+ return (...args) => {
3440
3480
  if(args.length === 0) {
3441
- // console.log('length 0')
3442
3481
  return new UIElement$1({element : tag, name : tag, type})
3443
3482
  }
3444
3483
  if(
3445
3484
  ['string', 'number'].includes(typeof args[0])
3446
3485
  || args[0] instanceof UIElement$1
3447
- || (typeof args[0] === 'function' && args[0]().isStateGetter())
3486
+ || isStateGetter(args[0])
3487
+ || args[0] instanceof HTMLElement
3448
3488
  ) return new UIElement$1({element : tag, name : tag, type}).append(...args);
3449
- // console.log(args[0])
3450
- return new UIElement$1({element : tag, type}).setAttr(args.shift()).append(...args)
3451
- }
3452
- // if(SVGTags.includes(tag)) return (...args) => new UIElement(tag,"",{el_type : "svg"}).append(...args);
3453
- // return (...args)=>{
3454
- // if(!(args[0] instanceof UIElement) && args[0] instanceof Object){
3455
- // let attributes = args.shift()
3456
- // return new UIElement(tag).setAttr(attributes).append(...args)
3457
- // }
3458
- // return new UIElement(tag).append(...args);
3459
- // }
3460
- // // switch(tag){
3461
- // case "html" : globalThis?.document?.createElement("html")
3462
- // case "head" :
3463
- // case "style" :
3464
- // case "link" :
3465
- // case "meta" :
3466
- // case "srcipt":
3467
- // case "body" : return null; break;
3468
- // default : return new UIElement(tag);
3469
- // }
3489
+ return new UIElement$1({element : tag, type, props : args.shift()}).append(...args)
3490
+ }
3470
3491
  }
3471
3492
  });
3472
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
+
3473
3550
  function set_vertical(direction){
3474
3551
  direction == 1
3475
3552
  ? this.style({ flexDirection: "column" })
@@ -3575,7 +3652,7 @@ class UIElement extends UIElementCore{
3575
3652
  }
3576
3653
  }
3577
3654
 
3578
- class ZikoUISuspense extends UIElement{
3655
+ class UISuspense extends UIElement{
3579
3656
  constructor(fallback_ui, callback){
3580
3657
  super({element : "div", name : "suspense"});
3581
3658
  this.setAttr({
@@ -3596,7 +3673,129 @@ class ZikoUISuspense extends UIElement{
3596
3673
  }
3597
3674
  }
3598
3675
 
3599
- const Suspense = (fallback_ui, callback) => new ZikoUISuspense(fallback_ui, callback);
3676
+ const Suspense = (fallback_ui, callback) => new UISuspense(fallback_ui, callback);
3677
+
3678
+ class UISwap extends UIElement$1 {
3679
+ #DISPLAYS_MAP = new WeakMap()
3680
+ constructor({ activeIndex = 0 } = {}, ...items) {
3681
+ super({ element: 'div' });
3682
+ this.style({ display: 'contents' });
3683
+
3684
+ this.states = {
3685
+ activeIndex
3686
+ };
3687
+
3688
+ this.append(...items);
3689
+ requestAnimationFrame(() => {
3690
+ this.render();
3691
+ });
3692
+ }
3693
+ get activeItem(){
3694
+ return this.items[this.states.activeIndex]
3695
+ }
3696
+ render() {
3697
+ this.items.forEach((n, i) => {
3698
+
3699
+ const initialDisplay = getComputedStyle(n.element).display;
3700
+ this.#DISPLAYS_MAP.set(n, initialDisplay);
3701
+
3702
+ if (i !== this.states.activeIndex) {
3703
+ n.style({ display: 'none' });
3704
+ }
3705
+ });
3706
+ }
3707
+ get DS(){
3708
+ return this.#DISPLAYS_MAP
3709
+ }
3710
+ next(n = 1) {
3711
+ return this.activate(this.states.activeIndex + n);
3712
+ }
3713
+ previous(n = 1) {
3714
+ return this.activate(this.states.activeIndex - n);
3715
+ }
3716
+ activate(index) {
3717
+ if (!this.items.length) return this;
3718
+
3719
+ const currentItem = this.items.at(this.states.activeIndex);
3720
+
3721
+ if (currentItem) {
3722
+ currentItem.style({ display: 'none' });
3723
+ }
3724
+
3725
+ const len = this.items.length;
3726
+ this.states.activeIndex = ((index % len) + len) % len;
3727
+
3728
+ const activeItem = this.items.at(this.states.activeIndex);
3729
+ if (activeItem) {
3730
+ const restoredDisplay = this.#DISPLAYS_MAP.get(activeItem) || 'block';
3731
+ activeItem.style({ display: restoredDisplay === 'none' ? 'block' : restoredDisplay });
3732
+ }
3733
+
3734
+ return this;
3735
+ }
3736
+ }
3737
+
3738
+ const Swap = call_with_optional_props(UISwap);
3739
+
3740
+ class UIFragment extends UIElement$1{
3741
+ constructor(...items){
3742
+ super({ element : document.createDocumentFragment()});
3743
+ this.append(...items);
3744
+ }
3745
+ isFragment(){
3746
+ return true
3747
+ }
3748
+ }
3749
+
3750
+ const Fragment = (...items) => new UIFragment(...items);
3751
+
3752
+ class UIFor extends UIFragment{
3753
+ constructor({each, fallback, mapFn = () => {}} = {}){
3754
+ super();
3755
+ this.config = {
3756
+ each,
3757
+ fallback,
3758
+ mapFn
3759
+ };
3760
+ this.append(
3761
+ ...this.config.each.map((n,i) => this.config.mapFn(n, i))
3762
+ );
3763
+ }
3764
+ }
3765
+
3766
+ const For = ({each, fallback, mapFn} = {}) => new UIFor({each, fallback, mapFn});
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
+ // }
3600
3799
 
3601
3800
  class UIHTMLWrapper extends UIElement$1 {
3602
3801
  constructor(content){
@@ -3660,169 +3859,240 @@ function svg2dom(svgString) {
3660
3859
 
3661
3860
  const SVGWrapper = (content) => new UISVGWrapper(content);
3662
3861
 
3663
- function define_wc(name, UI_Constructor, props = {}, { mode = 'open'} = {}) {
3664
- if (globalThis.customElements?.get(name)) {
3665
- console.warn(`Custom element "${name}" is already defined`);
3666
- return;
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());
3667
3881
  }
3668
- if(name.search('-') === -1){
3669
- console.warn(`"${name}" is not a valid custom element name`);
3670
- return;
3882
+ get Xmin(){
3883
+ return this.axisMatrix[0][0];
3671
3884
  }
3672
- globalThis.customElements?.define(
3673
- name,
3674
- class extends HTMLElement {
3675
- static get observedAttributes() {
3676
- return ['style', ...Object.keys(props)];
3677
- }
3678
-
3679
- constructor() {
3680
- super();
3681
- this.attachShadow({ mode });
3682
- this.props = {};
3683
- this.mask = {
3684
- ...props,
3685
- // style: { type: Object }
3686
- };
3687
- }
3688
-
3689
- connectedCallback() {
3690
- this.render();
3691
- }
3692
-
3693
- render() {
3694
- this.shadowRoot.innerHTML = '';
3695
- const item = UI_Constructor(this.props);
3696
- if(item instanceof Array) item.forEach(n => n.mount(this.shadowRoot));
3697
- else item.mount(this.shadowRoot);
3698
- }
3699
-
3700
- attributeChangedCallback(name, _, newValue) {
3701
- Object.assign(this.props, {
3702
- [name]: this.mask[name].type(newValue)
3703
- });
3704
- this.render();
3705
- }
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
+ });
3706
3904
  }
3707
- );
3708
- }
3709
-
3710
- class UISwitch extends UIElement$1{
3711
- constructor(key, cases){
3712
- super();
3713
- this.key = key;
3714
- this.cases = cases;
3715
- this.init();
3905
+ else {
3906
+ this.items.at(-1).parent=this;
3907
+ this.items.at(-1).draw(this.ctx);
3908
+ }
3909
+ this.maintain();
3910
+ return this;
3716
3911
  }
3717
- init(){
3718
- Object.values(this.cases).filter(n=>n != this.current).forEach(n=>n.unmount());
3719
- super.init(this.current.element);
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;
3720
3922
  }
3721
- get current(){
3722
- const matched = Object.keys(this.cases).find(n => n == this.key) ?? 'default';
3723
- return this.cases[matched]
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;
3724
3929
  }
3725
- updateKey(key){
3726
- this.key = key;
3727
- this.replaceElementWith(this.current.element);
3728
- // this.cache.element.replaceWith(this.current.element)
3729
- // this.cache.element = this.current.element;
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]);
3730
3934
  return this;
3731
3935
  }
3732
-
3733
- }
3734
-
3735
- const Switch=({key, cases})=> new UISwitch(key, cases);
3736
-
3737
- // export const Switch=({key, cases}) => {
3738
- // const matched = Object.keys(cases).find(n => n == key) ?? 'default';
3739
- // return this.cases[matched]()
3740
- // }
3741
-
3742
- class UISwap extends UIElement$1 {
3743
- #DISPLAYS_MAP = new WeakMap()
3744
- constructor({ activeIndex = 0 } = {}, ...items) {
3745
- super({ element: 'div' });
3746
- this.style({ display: 'contents' });
3747
-
3748
- this.states = {
3749
- activeIndex
3750
- };
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
+ ]);
3751
3945
 
3752
- this.append(...items);
3753
- this.render();
3946
+ this.applyTransformMatrix();
3947
+ this.clear();
3948
+ this.lineWidth(1);
3949
+ this.draw();
3950
+ return this;
3754
3951
  }
3755
- get activeItem(){
3756
- return this.items[this.states.activeIndex]
3952
+ reset(){
3953
+ this.ctx.setTransform(1,0,0,0,0,0);
3954
+ return this;
3757
3955
  }
3758
- render() {
3759
- this.items.forEach((n, i) => {
3760
-
3761
- const initialDisplay = n.element?.style?.display || '';
3762
- this.#DISPLAYS_MAP.set(n, initialDisplay);
3763
-
3764
- if (i !== this.states.activeIndex) {
3765
- n.style({ display: 'none' });
3766
- }
3767
- });
3956
+ append(element){
3957
+ this.items.push(element);
3958
+ this.draw(false);
3959
+ return this;
3768
3960
  }
3769
- next(n = 1) {
3770
- return this.activate(this.states.activeIndex + n);
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();
3771
3967
  }
3772
- previous(n = 1) {
3773
- return this.activate(this.states.activeIndex - n);
3968
+ lineWidth(w){
3969
+ this.ctx.lineWidth=w/this.transformMatrix[0][0];
3970
+ return this
3774
3971
  }
3775
- activate(index) {
3776
- if (!this.items.length) return this;
3777
-
3778
- const currentItem = this.items.at(this.states.activeIndex);
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(){
3779
4014
 
3780
- if (currentItem) {
3781
- currentItem.style({ display: 'none' });
3782
- }
4015
+ }
4016
+ zoomOut(){
4017
+
4018
+ }
4019
+ undo(n){
3783
4020
 
3784
- const len = this.items.length;
3785
- this.states.activeIndex = ((index % len) + len) % len;
4021
+ }
4022
+ redo(n){
3786
4023
 
3787
- const activeItem = this.items.at(this.states.activeIndex);
3788
- if (activeItem) {
3789
- const restoredDisplay = this.#DISPLAYS_MAP.get(activeItem) || 'block';
3790
- activeItem.style({ display: restoredDisplay === 'none' ? 'block' : restoredDisplay });
3791
- }
4024
+ }
4025
+ stream(){
3792
4026
 
3793
- return this;
3794
4027
  }
3795
4028
  }
3796
4029
 
3797
- const Swap = call_with_optional_props(UISwap);
4030
+ const Canvas=(w,h)=>new UICanvas(w,h);
3798
4031
 
3799
- class UIFragment extends UIElement$1{
3800
- constructor(...items){
3801
- super({ element : document.createDocumentFragment()});
3802
- this.append(...items);
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;
3803
4068
  }
3804
- isFragment(){
3805
- return true
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;
3806
4076
  }
3807
- }
3808
-
3809
- const Fragment = (...items) => new UIFragment(...items);
3810
-
3811
- class UIFor extends UIFragment{
3812
- constructor({each, fallback, mapFn = () => {}} = {}){
3813
- super();
3814
- this.config = {
3815
- each,
3816
- fallback,
3817
- mapFn
3818
- };
3819
- this.append(
3820
- ...this.config.each.map((n,i) => this.config.mapFn(n, i))
3821
- );
4077
+ mask(){
4078
+
3822
4079
  }
3823
- }
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
+ }
3824
4094
 
3825
- const For = ({each, fallback, mapFn} = {}) => new UIFor({each, fallback, mapFn});
4095
+ const Svg =(w,h)=>new UISvg(w,h);
3826
4096
 
3827
4097
  const { PI, sqrt: sqrt$1, cos: cos$2, sin: sin$2, acos, pow } = Math;
3828
4098
 
@@ -4393,13 +4663,15 @@ const csv2object = (csv, delimiter = ",") => {
4393
4663
  };
4394
4664
  const csv2json = (csv, delimiter = ",") => JSON.stringify(csv2object(csv,delimiter));
4395
4665
  const csv2sql=(csv, Table)=>{
4666
+ const sanitizeId = s => s.trim().replace(/[^a-zA-Z0-9_]/g, '');
4667
+ const escapeVal = s => "'" + s.trim().replace(/'/g, "''") + "'";
4396
4668
  const lines = csv.trim().trimEnd().split('\n').filter(n=>n);
4397
- const columns = lines[0].split(',');
4398
- let sqlQuery = `INSERT INTO ${Table} (${columns.join(', ')}) Values `;
4669
+ const columns = lines[0].split(',').map(sanitizeId);
4670
+ let sqlQuery = "INSERT INTO " + sanitizeId(Table) + " (" + columns.join(', ') + ") Values ";
4399
4671
  let sqlValues = [];
4400
4672
  for (let i = 1; i < lines.length; i++) {
4401
- const values = lines[i].split(',');
4402
- sqlValues.push(`(${values})`);
4673
+ const values = lines[i].split(',').map(escapeVal);
4674
+ sqlValues.push("(" + values.join(', ') + ")");
4403
4675
  }
4404
4676
  return sqlQuery+sqlValues.join(",\n");
4405
4677
  };
@@ -4516,6 +4788,35 @@ function trimKeys(obj) {
4516
4788
  }, Array.isArray(obj) ? [] : {});
4517
4789
  }
4518
4790
 
4791
+ function parseXML(xmlString) {
4792
+ const parser = new DOMParser();
4793
+ const xmlDoc = parser.parseFromString(xmlString, 'text/xml');
4794
+ const rootNode = xmlDoc.documentElement;
4795
+ const result = parseNode(rootNode);
4796
+ return result;
4797
+ }
4798
+
4799
+ function parseNode(node) {
4800
+ const obj = {
4801
+ type: node.nodeName,
4802
+ attributes: {},
4803
+ children: []
4804
+ };
4805
+ for (let i = 0; i < node.attributes.length; i++) {
4806
+ const attr = node.attributes[i];
4807
+ obj.attributes[attr.name] = attr.value;
4808
+ }
4809
+ for (let i = 0; i < node.childNodes.length; i++) {
4810
+ const child = node.childNodes[i];
4811
+ if (child.nodeType === Node.ELEMENT_NODE) {
4812
+ obj.children.push(parseNode(child));
4813
+ } else if (child.nodeType === Node.TEXT_NODE) {
4814
+ obj.text = child.textContent.trim();
4815
+ }
4816
+ }
4817
+ return obj;
4818
+ }
4819
+
4519
4820
  // import { ZikoHead , useHead} from "../reactivity/hooks/head/index.js";
4520
4821
  class ZikoApp {
4521
4822
  constructor({head = null, wrapper = null, target = null}){
@@ -4807,6 +5108,45 @@ const useReactive = (nested_value) => mapfun(
4807
5108
  nested_value
4808
5109
  );
4809
5110
 
5111
+ const useEffect = (callback, deps = []) =>{
5112
+ const states = deps.filter(isStateGetter);
5113
+
5114
+ let cleanup;
5115
+
5116
+ const execute = () => {
5117
+ // Cleanup previous effect
5118
+ if (typeof cleanup === "function") {
5119
+ cleanup();
5120
+ }
5121
+
5122
+ // Read current state values
5123
+ const values = states.map(state => state().value);
5124
+
5125
+ // Execute effect
5126
+ cleanup = callback(...values);
5127
+ };
5128
+
5129
+ // Subscribe to states
5130
+ const unsubscribers = states.map(state =>
5131
+ state()._subscribe(execute)
5132
+ );
5133
+
5134
+ // Initial execution
5135
+ execute();
5136
+
5137
+ // Return effect cleanup
5138
+ return () => {
5139
+ unsubscribers.forEach(unsubscribe => {
5140
+ unsubscribe();
5141
+ });
5142
+
5143
+ if (typeof cleanup === "function") {
5144
+ cleanup();
5145
+ cleanup = undefined;
5146
+ }
5147
+ };
5148
+ };
5149
+
4810
5150
  class UseThread {
4811
5151
  #worker;
4812
5152
  #callbacks = new Map();
@@ -5230,6 +5570,7 @@ if(globalThis?.document){
5230
5570
  }
5231
5571
 
5232
5572
  exports.App = App;
5573
+ exports.Canvas = Canvas;
5233
5574
  exports.ClickAwayEvent = ClickAwayEvent;
5234
5575
  exports.ClickListeners = ClickListeners;
5235
5576
  exports.Clock = Clock;
@@ -5249,9 +5590,11 @@ exports.PI = PI$1;
5249
5590
  exports.PtrListeners = PtrListeners;
5250
5591
  exports.Random = Random;
5251
5592
  exports.SPA = SPA;
5593
+ exports.STATE_GETTER = STATE_GETTER;
5252
5594
  exports.SVGWrapper = SVGWrapper;
5253
5595
  exports.Scheduler = Scheduler;
5254
5596
  exports.Suspense = Suspense;
5597
+ exports.Svg = Svg;
5255
5598
  exports.Swap = Swap;
5256
5599
  exports.SwipeEvent = SwipeEvent;
5257
5600
  exports.Switch = Switch;
@@ -5259,12 +5602,15 @@ exports.Tick = Tick;
5259
5602
  exports.TimeAnimation = TimeAnimation;
5260
5603
  exports.TimeLoop = TimeLoop;
5261
5604
  exports.TimeScheduler = TimeScheduler;
5605
+ exports.UICanvas = UICanvas;
5262
5606
  exports.UIElement = UIElement$1;
5263
5607
  exports.UIFlex = UIFlex;
5264
5608
  exports.UIFragment = UIFragment;
5265
5609
  exports.UIHTMLWrapper = UIHTMLWrapper;
5266
5610
  exports.UINode = UINode;
5267
5611
  exports.UISVGWrapper = UISVGWrapper;
5612
+ exports.UISuspense = UISuspense;
5613
+ exports.UISvg = UISvg;
5268
5614
  exports.UISwap = UISwap;
5269
5615
  exports.UISwitch = UISwitch;
5270
5616
  exports.UIView = UIView;
@@ -5275,7 +5621,6 @@ exports.ViewEvent = ViewEvent;
5275
5621
  exports.ViewListeners = ViewListeners;
5276
5622
  exports.ZikoApp = ZikoApp;
5277
5623
  exports.ZikoSPA = ZikoSPA;
5278
- exports.ZikoUISuspense = ZikoUISuspense;
5279
5624
  exports.ZikoUIText = ZikoUIText;
5280
5625
  exports.abs = abs;
5281
5626
  exports.accum_max = accum_max;
@@ -5353,8 +5698,8 @@ exports.in_quint = in_quint;
5353
5698
  exports.in_sin = in_sin;
5354
5699
  exports.interquartile_mean = interquartile_mean;
5355
5700
  exports.iqr = iqr;
5356
- exports.isPrimitive = isPrimitive;
5357
5701
  exports.isStateGetter = isStateGetter;
5702
+ exports.is_primitive = is_primitive;
5358
5703
  exports.json2arr = json2arr;
5359
5704
  exports.json2css = json2css;
5360
5705
  exports.json2csv = json2csv;
@@ -5399,6 +5744,8 @@ exports.out_quad = out_quad;
5399
5744
  exports.out_quart = out_quart;
5400
5745
  exports.out_quint = out_quint;
5401
5746
  exports.out_sin = out_sin;
5747
+ exports.parseXML = parseXML;
5748
+ exports.parse_props = parse_props;
5402
5749
  exports.percentile = percentile;
5403
5750
  exports.pow = pow$1;
5404
5751
  exports.power_mean = power_mean;
@@ -5445,6 +5792,7 @@ exports.timeout = timeout;
5445
5792
  exports.trimmed_mean = trimmed_mean;
5446
5793
  exports.trunc = trunc;
5447
5794
  exports.useDerived = useDerived;
5795
+ exports.useEffect = useEffect;
5448
5796
  exports.useEventEmitter = useEventEmitter;
5449
5797
  exports.useIPC = useIPC;
5450
5798
  exports.useLocalStorage = useLocalStorage;