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.mjs 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
@@ -11,11 +11,11 @@
11
11
  const { PI: PI$1, E } = Math;
12
12
  const EPSILON=Number.EPSILON;
13
13
 
14
- const is_primitive = value => typeof value !== 'object' && typeof value !== 'function' || value === null;
14
+ const is_primitive$1 = value => typeof value !== 'object' && typeof value !== 'function' || value === null;
15
15
 
16
16
  const mapfun$1=(fun,...X)=>{
17
17
  const Y=X.map(x=>{
18
- if(is_primitive(x) || x?.__mapfun__) return fun(x)
18
+ if(is_primitive$1(x) || x?.__mapfun__) return fun(x)
19
19
  if(x instanceof Array) return x.map(n=>mapfun$1(fun,n));
20
20
  if(ArrayBuffer.isView(x)) return x.map(n=>fun(n));
21
21
  if(x instanceof Set) return new Set(mapfun$1(fun,...[...x]));
@@ -2227,12 +2227,39 @@ function __init__global__(){
2227
2227
  }
2228
2228
  }
2229
2229
 
2230
+ const parse_props = (props = {}) => {
2231
+
2232
+ const result = {
2233
+ methods: {},
2234
+ events: {},
2235
+ style: {},
2236
+ attrs: {}
2237
+ };
2238
+
2239
+ for (const [key, value] of Object.entries(props)) {
2240
+ if (key === "style") {
2241
+ result.style = value;
2242
+ }
2243
+ else if (key.startsWith("$")) {
2244
+ result.methods[key.slice(1)] = value;
2245
+ }
2246
+ else if (/^on[A-Z]/.test(key)) {
2247
+ result.events[key] = value;
2248
+ }
2249
+ else {
2250
+ result.attrs[key] = value;
2251
+ }
2252
+ }
2253
+
2254
+ return result;
2255
+ };
2256
+
2230
2257
  __init__global__();
2231
2258
  class UIElementCore extends UINode{
2232
2259
  constructor(){
2233
2260
  super();
2234
2261
  }
2235
- init(element, name, type, render){
2262
+ init({element, name, type, render, props = {}, items = []} = {}){
2236
2263
  this.target = globalThis.__Ziko__.__Config__.default.target||globalThis?.document?.body;
2237
2264
  if(typeof element === "string") {
2238
2265
  switch(type){
@@ -2280,9 +2307,26 @@ class UIElementCore extends UINode{
2280
2307
  };
2281
2308
  if(element) Object.assign(this.cache,{element});
2282
2309
  this.items = new UIStore();
2283
- globalThis.__Ziko__.__UI__[this.cache.name]?globalThis.__Ziko__.__UI__[this.cache.name]?.push(this):globalThis.__Ziko__.__UI__[this.cache.name]=[this];
2310
+ globalThis.__Ziko__.__UI__[this.cache.name]
2311
+ ? globalThis.__Ziko__.__UI__[this.cache.name]?.push(this)
2312
+ : globalThis.__Ziko__.__UI__[this.cache.name]=[this];
2284
2313
  element && render && this?.render?.();
2285
2314
  globalThis.__Ziko__.__UI__.push(this);
2315
+
2316
+ // console.log({props})
2317
+ const parsed_props = parse_props(props);
2318
+
2319
+ this.parsed_props = parsed_props;
2320
+
2321
+ this.style(parsed_props.style);
2322
+ this.setAttr(parsed_props.attrs);
2323
+
2324
+ const Events = Object.entries(parsed_props.events);
2325
+
2326
+ Events.forEach(([ev, callback]) => this[ev](callback.bind(this)));
2327
+
2328
+
2329
+ if(items.length > 0) this.append(...items);
2286
2330
  }
2287
2331
  get element(){
2288
2332
  return this.cache.element;
@@ -2390,8 +2434,9 @@ var LifecycleMethods = /*#__PURE__*/Object.freeze({
2390
2434
 
2391
2435
  // if (!globalThis.__Ziko__) __init__global__();
2392
2436
 
2437
+ const STATE_GETTER = Symbol.for("ziko.stateGetter");
2438
+
2393
2439
  function useState(initialValue) {
2394
-
2395
2440
  const state = {
2396
2441
  value: initialValue,
2397
2442
  subscribers: new Set(),
@@ -2401,7 +2446,6 @@ function useState(initialValue) {
2401
2446
  function getValue() {
2402
2447
  return {
2403
2448
  value: state.value,
2404
- isStateGetter: () => true,
2405
2449
  _subscribe: (fn) => {
2406
2450
  state.subscribers.add(fn);
2407
2451
  return () => state.subscribers.delete(fn);
@@ -2409,6 +2453,8 @@ function useState(initialValue) {
2409
2453
  };
2410
2454
  }
2411
2455
 
2456
+ getValue[STATE_GETTER] = true;
2457
+
2412
2458
  function setValue(newValue) {
2413
2459
  if (state.paused) return;
2414
2460
 
@@ -2430,6 +2476,7 @@ function useState(initialValue) {
2430
2476
  if (typeof newValue === "function") {
2431
2477
  newValue = newValue(state.value);
2432
2478
  }
2479
+
2433
2480
  state.value = newValue;
2434
2481
  state.subscribers.forEach((fn) => fn(state.value));
2435
2482
  },
@@ -2439,9 +2486,7 @@ function useState(initialValue) {
2439
2486
  return [getValue, setValue, controller];
2440
2487
  }
2441
2488
 
2442
- const isStateGetter = (arg) => {
2443
- return typeof arg === "function" && arg?.()?.isStateGetter?.() === true;
2444
- };
2489
+ const isStateGetter = (arg) => typeof arg === "function" && arg[STATE_GETTER] === true;
2445
2490
 
2446
2491
  const camel2hyphencase = (text = '') => text.replace(/[A-Z]/g, match => '-' + match.toLowerCase());
2447
2492
 
@@ -2592,8 +2637,8 @@ async function __addItem__(adder, pusher, ...ele) {
2592
2637
  if (["number", "string"].includes(typeof ele[i])) ele[i] = text(ele[i]);
2593
2638
  // Fix Items Latter
2594
2639
  if (ele[i] instanceof Function) {
2595
- const getter = ele[i]();
2596
- if (getter.isStateGetter) {
2640
+ if (isStateGetter(ele[i])) {
2641
+ const getter = ele[i]();
2597
2642
  ele[i] = text(getter.value);
2598
2643
  getter._subscribe(
2599
2644
  (newValue) => (ele[i].element.textContent = newValue),
@@ -3083,7 +3128,7 @@ function register_swipe_event(
3083
3128
  }
3084
3129
 
3085
3130
  let UIElement$1 = class UIElement extends UIElementCore{
3086
- constructor({element, name ='', type='html', render = __Ziko__.__Config__.default.render}={}){
3131
+ constructor({element, name ='', type = 'html', render = __Ziko__.__Config__.default.render, props}={}){
3087
3132
  super();
3088
3133
  this.exp = {
3089
3134
  events : {
@@ -3103,7 +3148,7 @@ let UIElement$1 = class UIElement extends UIElementCore{
3103
3148
  ViewListeners,
3104
3149
  );
3105
3150
 
3106
- if(element)this.init(element, name, type, render);
3151
+ if(element) this.init({element, name, type, render, props});
3107
3152
  }
3108
3153
  on(event_name, callback, {details_setter, category = 'global', isCustom = false, preventDefault = false} = {}){
3109
3154
  if(event_name instanceof Array) event_name.forEach(
@@ -3196,15 +3241,22 @@ let UIElement$1 = class UIElement extends UIElementCore{
3196
3241
 
3197
3242
  };
3198
3243
 
3244
+ const is_primitive = (value) => typeof value !== 'object' && typeof value !== 'function' || value === null;
3245
+
3199
3246
  const call_with_optional_props = (Component) => {
3200
3247
  return (...args) => {
3201
3248
  const first = args[0];
3202
- const isChild = first?.isUIElement?.() || isPrimitive(first) ;
3203
- return isChild
3204
- ? new Component({}, ...args)
3205
- : new Component(first, ...args.slice(1))
3249
+
3250
+ const isChild = first?.isUIElement?.() || is_primitive(first);
3251
+
3252
+ if (isChild) {
3253
+ return new Component({}, ...args);
3254
+ }
3255
+
3256
+ return new Component(first, ...args.slice(1));
3206
3257
  };
3207
- };
3258
+ };
3259
+
3208
3260
  function add_vendor_prefix(property) {
3209
3261
  const propertyUC = property.slice(0, 1).toUpperCase() + property.slice(1);
3210
3262
  const vendors = ['Webkit', 'Moz', 'O', 'ms'];
@@ -3257,9 +3309,9 @@ const CloneElement = (UIElement) => {
3257
3309
  const cloneUI=UIElement=>{
3258
3310
  return Object.assign(Object.create(Object.getPrototypeOf(UIElement)),UIElement)
3259
3311
  };
3260
- function isPrimitive(value) {
3261
- return typeof value !== 'object' && typeof value !== 'function' || value === null;
3262
- }
3312
+ // function isPrimitive(value) {
3313
+ // return typeof value !== 'object' && typeof value !== 'function' || value === null;
3314
+ // }
3263
3315
  const waitElm=(UIElement)=>{
3264
3316
  return new Promise(resolve => {
3265
3317
  if (UIElement) {
@@ -3278,15 +3330,6 @@ const waitElm=(UIElement)=>{
3278
3330
  });
3279
3331
  };
3280
3332
 
3281
- class UIView extends UIElement$1{
3282
- constructor(...items){
3283
- super({element : 'div', name : 'view'});
3284
- this.append(...items);
3285
- }
3286
- }
3287
-
3288
- const View = (...items) => new UIView(...items);
3289
-
3290
3333
  const HTMLTags = [
3291
3334
  'a',
3292
3335
  'abb',
@@ -3431,43 +3474,77 @@ const tags = new Proxy({}, {
3431
3474
  if(HTMLTags.includes(tag)) type = 'html';
3432
3475
  if(SVGTags.includes(tag)) type = 'svg';
3433
3476
  if(MathMLTags.includes(tag)) type = 'mathml';
3434
- return (...args)=>{
3435
- // Fix undefined
3436
- // console.log(isStateGetter(args[0]))
3437
- // console.log(!!args)
3477
+ return (...args) => {
3438
3478
  if(args.length === 0) {
3439
- // console.log('length 0')
3440
3479
  return new UIElement$1({element : tag, name : tag, type})
3441
3480
  }
3442
3481
  if(
3443
3482
  ['string', 'number'].includes(typeof args[0])
3444
3483
  || args[0] instanceof UIElement$1
3445
- || (typeof args[0] === 'function' && args[0]().isStateGetter())
3484
+ || isStateGetter(args[0])
3485
+ || args[0] instanceof HTMLElement
3446
3486
  ) return new UIElement$1({element : tag, name : tag, type}).append(...args);
3447
- // console.log(args[0])
3448
- return new UIElement$1({element : tag, type}).setAttr(args.shift()).append(...args)
3449
- }
3450
- // if(SVGTags.includes(tag)) return (...args) => new UIElement(tag,"",{el_type : "svg"}).append(...args);
3451
- // return (...args)=>{
3452
- // if(!(args[0] instanceof UIElement) && args[0] instanceof Object){
3453
- // let attributes = args.shift()
3454
- // return new UIElement(tag).setAttr(attributes).append(...args)
3455
- // }
3456
- // return new UIElement(tag).append(...args);
3457
- // }
3458
- // // switch(tag){
3459
- // case "html" : globalThis?.document?.createElement("html")
3460
- // case "head" :
3461
- // case "style" :
3462
- // case "link" :
3463
- // case "meta" :
3464
- // case "srcipt":
3465
- // case "body" : return null; break;
3466
- // default : return new UIElement(tag);
3467
- // }
3487
+ return new UIElement$1({element : tag, type, props : args.shift()}).append(...args)
3488
+ }
3468
3489
  }
3469
3490
  });
3470
3491
 
3492
+ function define_wc(name, UI_Constructor, props = {}, { mode = 'open'} = {}) {
3493
+ if (globalThis.customElements?.get(name)) {
3494
+ console.warn(`Custom element "${name}" is already defined`);
3495
+ return;
3496
+ }
3497
+ if(name.search('-') === -1){
3498
+ console.warn(`"${name}" is not a valid custom element name`);
3499
+ return;
3500
+ }
3501
+ globalThis.customElements?.define(
3502
+ name,
3503
+ class extends HTMLElement {
3504
+ static get observedAttributes() {
3505
+ return ['style', ...Object.keys(props)];
3506
+ }
3507
+
3508
+ constructor() {
3509
+ super();
3510
+ this.attachShadow({ mode });
3511
+ this.props = {};
3512
+ this.mask = {
3513
+ ...props,
3514
+ // style: { type: Object }
3515
+ };
3516
+ }
3517
+
3518
+ connectedCallback() {
3519
+ this.render();
3520
+ }
3521
+
3522
+ render() {
3523
+ this.shadowRoot.innerHTML = '';
3524
+ const item = UI_Constructor(this.props);
3525
+ if(item instanceof Array) item.forEach(n => n.mount(this.shadowRoot));
3526
+ else item.mount(this.shadowRoot);
3527
+ }
3528
+
3529
+ attributeChangedCallback(name, _, newValue) {
3530
+ Object.assign(this.props, {
3531
+ [name]: this.mask[name].type(newValue)
3532
+ });
3533
+ this.render();
3534
+ }
3535
+ }
3536
+ );
3537
+ }
3538
+
3539
+ class UIView extends UIElement$1{
3540
+ constructor(...items){
3541
+ super({element : 'div', name : 'view'});
3542
+ this.append(...items);
3543
+ }
3544
+ }
3545
+
3546
+ const View = (...items) => new UIView(...items);
3547
+
3471
3548
  function set_vertical(direction){
3472
3549
  direction == 1
3473
3550
  ? this.style({ flexDirection: "column" })
@@ -3573,7 +3650,7 @@ class UIElement extends UIElementCore{
3573
3650
  }
3574
3651
  }
3575
3652
 
3576
- class ZikoUISuspense extends UIElement{
3653
+ class UISuspense extends UIElement{
3577
3654
  constructor(fallback_ui, callback){
3578
3655
  super({element : "div", name : "suspense"});
3579
3656
  this.setAttr({
@@ -3594,7 +3671,129 @@ class ZikoUISuspense extends UIElement{
3594
3671
  }
3595
3672
  }
3596
3673
 
3597
- const Suspense = (fallback_ui, callback) => new ZikoUISuspense(fallback_ui, callback);
3674
+ const Suspense = (fallback_ui, callback) => new UISuspense(fallback_ui, callback);
3675
+
3676
+ class UISwap extends UIElement$1 {
3677
+ #DISPLAYS_MAP = new WeakMap()
3678
+ constructor({ activeIndex = 0 } = {}, ...items) {
3679
+ super({ element: 'div' });
3680
+ this.style({ display: 'contents' });
3681
+
3682
+ this.states = {
3683
+ activeIndex
3684
+ };
3685
+
3686
+ this.append(...items);
3687
+ requestAnimationFrame(() => {
3688
+ this.render();
3689
+ });
3690
+ }
3691
+ get activeItem(){
3692
+ return this.items[this.states.activeIndex]
3693
+ }
3694
+ render() {
3695
+ this.items.forEach((n, i) => {
3696
+
3697
+ const initialDisplay = getComputedStyle(n.element).display;
3698
+ this.#DISPLAYS_MAP.set(n, initialDisplay);
3699
+
3700
+ if (i !== this.states.activeIndex) {
3701
+ n.style({ display: 'none' });
3702
+ }
3703
+ });
3704
+ }
3705
+ get DS(){
3706
+ return this.#DISPLAYS_MAP
3707
+ }
3708
+ next(n = 1) {
3709
+ return this.activate(this.states.activeIndex + n);
3710
+ }
3711
+ previous(n = 1) {
3712
+ return this.activate(this.states.activeIndex - n);
3713
+ }
3714
+ activate(index) {
3715
+ if (!this.items.length) return this;
3716
+
3717
+ const currentItem = this.items.at(this.states.activeIndex);
3718
+
3719
+ if (currentItem) {
3720
+ currentItem.style({ display: 'none' });
3721
+ }
3722
+
3723
+ const len = this.items.length;
3724
+ this.states.activeIndex = ((index % len) + len) % len;
3725
+
3726
+ const activeItem = this.items.at(this.states.activeIndex);
3727
+ if (activeItem) {
3728
+ const restoredDisplay = this.#DISPLAYS_MAP.get(activeItem) || 'block';
3729
+ activeItem.style({ display: restoredDisplay === 'none' ? 'block' : restoredDisplay });
3730
+ }
3731
+
3732
+ return this;
3733
+ }
3734
+ }
3735
+
3736
+ const Swap = call_with_optional_props(UISwap);
3737
+
3738
+ class UIFragment extends UIElement$1{
3739
+ constructor(...items){
3740
+ super({ element : document.createDocumentFragment()});
3741
+ this.append(...items);
3742
+ }
3743
+ isFragment(){
3744
+ return true
3745
+ }
3746
+ }
3747
+
3748
+ const Fragment = (...items) => new UIFragment(...items);
3749
+
3750
+ class UIFor extends UIFragment{
3751
+ constructor({each, fallback, mapFn = () => {}} = {}){
3752
+ super();
3753
+ this.config = {
3754
+ each,
3755
+ fallback,
3756
+ mapFn
3757
+ };
3758
+ this.append(
3759
+ ...this.config.each.map((n,i) => this.config.mapFn(n, i))
3760
+ );
3761
+ }
3762
+ }
3763
+
3764
+ const For = ({each, fallback, mapFn} = {}) => new UIFor({each, fallback, mapFn});
3765
+
3766
+ class UISwitch extends UIElement$1{
3767
+ constructor(key, cases){
3768
+ super();
3769
+ this.key = key;
3770
+ this.cases = cases;
3771
+ this.init();
3772
+ }
3773
+ init(){
3774
+ Object.values(this.cases).filter(n=>n != this.current).forEach(n=>n.unmount());
3775
+ super.init(this.current.element);
3776
+ }
3777
+ get current(){
3778
+ const matched = Object.keys(this.cases).find(n => n == this.key) ?? 'default';
3779
+ return this.cases[matched]
3780
+ }
3781
+ updateKey(key){
3782
+ this.key = key;
3783
+ this.replaceElementWith(this.current.element);
3784
+ // this.cache.element.replaceWith(this.current.element)
3785
+ // this.cache.element = this.current.element;
3786
+ return this;
3787
+ }
3788
+
3789
+ }
3790
+
3791
+ const Switch=({key, cases})=> new UISwitch(key, cases);
3792
+
3793
+ // export const Switch=({key, cases}) => {
3794
+ // const matched = Object.keys(cases).find(n => n == key) ?? 'default';
3795
+ // return this.cases[matched]()
3796
+ // }
3598
3797
 
3599
3798
  class UIHTMLWrapper extends UIElement$1 {
3600
3799
  constructor(content){
@@ -3658,169 +3857,240 @@ function svg2dom(svgString) {
3658
3857
 
3659
3858
  const SVGWrapper = (content) => new UISVGWrapper(content);
3660
3859
 
3661
- function define_wc(name, UI_Constructor, props = {}, { mode = 'open'} = {}) {
3662
- if (globalThis.customElements?.get(name)) {
3663
- console.warn(`Custom element "${name}" is already defined`);
3664
- return;
3860
+ class UICanvas extends UIElement$1{
3861
+ constructor(w,h){
3862
+ super("canvas","canvas");
3863
+ this.ctx = this.element?.getContext("2d");
3864
+ this.style({
3865
+ border:"1px red solid",
3866
+ });
3867
+ this.transformMatrix = new Matrix([
3868
+ [1,0,0],
3869
+ [0,1,0],
3870
+ [0,0,1]
3871
+ ]);
3872
+ this.axisMatrix = new Matrix([
3873
+ [-10,-10],
3874
+ [10,10]
3875
+ ]);
3876
+ // setTimeout(()=>this.resize(w,h),0);
3877
+ requestAnimationFrame(()=>this.resize(w,h),0);
3878
+ this.on("sizeupdated",()=>this.adjust());
3665
3879
  }
3666
- if(name.search('-') === -1){
3667
- console.warn(`"${name}" is not a valid custom element name`);
3668
- return;
3880
+ get Xmin(){
3881
+ return this.axisMatrix[0][0];
3669
3882
  }
3670
- globalThis.customElements?.define(
3671
- name,
3672
- class extends HTMLElement {
3673
- static get observedAttributes() {
3674
- return ['style', ...Object.keys(props)];
3675
- }
3676
-
3677
- constructor() {
3678
- super();
3679
- this.attachShadow({ mode });
3680
- this.props = {};
3681
- this.mask = {
3682
- ...props,
3683
- // style: { type: Object }
3684
- };
3685
- }
3686
-
3687
- connectedCallback() {
3688
- this.render();
3689
- }
3690
-
3691
- render() {
3692
- this.shadowRoot.innerHTML = '';
3693
- const item = UI_Constructor(this.props);
3694
- if(item instanceof Array) item.forEach(n => n.mount(this.shadowRoot));
3695
- else item.mount(this.shadowRoot);
3696
- }
3697
-
3698
- attributeChangedCallback(name, _, newValue) {
3699
- Object.assign(this.props, {
3700
- [name]: this.mask[name].type(newValue)
3701
- });
3702
- this.render();
3703
- }
3883
+ get Ymin(){
3884
+ return this.axisMatrix[0][1];
3885
+ }
3886
+ get Xmax(){
3887
+ return this.axisMatrix[1][0];
3888
+ }
3889
+ get Ymax(){
3890
+ return this.axisMatrix[1][1];
3891
+ }
3892
+ get ImageData(){
3893
+ return this.ctx.getImageData(0,0,c.Width,c.Height);
3894
+ }
3895
+ draw(all=true){
3896
+ if(all){
3897
+ this.clear();
3898
+ this.items.forEach(element => {
3899
+ element.parent=this;
3900
+ element.draw(this.ctx);
3901
+ });
3704
3902
  }
3705
- );
3706
- }
3707
-
3708
- class UISwitch extends UIElement$1{
3709
- constructor(key, cases){
3710
- super();
3711
- this.key = key;
3712
- this.cases = cases;
3713
- this.init();
3903
+ else {
3904
+ this.items.at(-1).parent=this;
3905
+ this.items.at(-1).draw(this.ctx);
3906
+ }
3907
+ this.maintain();
3908
+ return this;
3714
3909
  }
3715
- init(){
3716
- Object.values(this.cases).filter(n=>n != this.current).forEach(n=>n.unmount());
3717
- super.init(this.current.element);
3910
+ applyTransformMatrix(){
3911
+ this.ctx.setTransform(
3912
+ this.transformMatrix[0][0],
3913
+ this.transformMatrix[1][0],
3914
+ this.transformMatrix[0][1],
3915
+ this.transformMatrix[1][1],
3916
+ this.transformMatrix[0][2],
3917
+ this.transformMatrix[1][2],
3918
+ );
3919
+ return this;
3718
3920
  }
3719
- get current(){
3720
- const matched = Object.keys(this.cases).find(n => n == this.key) ?? 'default';
3721
- return this.cases[matched]
3921
+ resize(w,h){
3922
+ this.size(w,h);
3923
+ this.lineWidth();
3924
+ this.view(this.axisMatrix[0][0], this.axisMatrix[0][1], this.axisMatrix[1][0], this.axisMatrix[1][1]);
3925
+ this.emit("sizeupdated");
3926
+ return this;
3722
3927
  }
3723
- updateKey(key){
3724
- this.key = key;
3725
- this.replaceElementWith(this.current.element);
3726
- // this.cache.element.replaceWith(this.current.element)
3727
- // this.cache.element = this.current.element;
3928
+ adjust(){
3929
+ this.element.width =this.element?.getBoundingClientRect().width;
3930
+ this.element.height =this.element?.getBoundingClientRect().height;
3931
+ this.view(this.axisMatrix[0][0], this.axisMatrix[0][1], this.axisMatrix[1][0], this.axisMatrix[1][1]);
3728
3932
  return this;
3729
3933
  }
3730
-
3731
- }
3732
-
3733
- const Switch=({key, cases})=> new UISwitch(key, cases);
3734
-
3735
- // export const Switch=({key, cases}) => {
3736
- // const matched = Object.keys(cases).find(n => n == key) ?? 'default';
3737
- // return this.cases[matched]()
3738
- // }
3739
-
3740
- class UISwap extends UIElement$1 {
3741
- #DISPLAYS_MAP = new WeakMap()
3742
- constructor({ activeIndex = 0 } = {}, ...items) {
3743
- super({ element: 'div' });
3744
- this.style({ display: 'contents' });
3745
-
3746
- this.states = {
3747
- activeIndex
3748
- };
3934
+ view(xMin,yMin,xMax,yMax){
3935
+ this.transformMatrix[0][0]=this.width/(xMax-xMin); // scaleX
3936
+ this.transformMatrix[1][1]=-this.height/(yMax-yMin); // scaleY
3937
+ this.transformMatrix[0][2]=this.width/2;
3938
+ this.transformMatrix[1][2]=this.height/2;
3939
+ this.axisMatrix=new Matrix([
3940
+ [xMin,yMin],
3941
+ [xMax,yMax]
3942
+ ]);
3749
3943
 
3750
- this.append(...items);
3751
- this.render();
3944
+ this.applyTransformMatrix();
3945
+ this.clear();
3946
+ this.lineWidth(1);
3947
+ this.draw();
3948
+ return this;
3752
3949
  }
3753
- get activeItem(){
3754
- return this.items[this.states.activeIndex]
3950
+ reset(){
3951
+ this.ctx.setTransform(1,0,0,0,0,0);
3952
+ return this;
3755
3953
  }
3756
- render() {
3757
- this.items.forEach((n, i) => {
3758
-
3759
- const initialDisplay = n.element?.style?.display || '';
3760
- this.#DISPLAYS_MAP.set(n, initialDisplay);
3761
-
3762
- if (i !== this.states.activeIndex) {
3763
- n.style({ display: 'none' });
3764
- }
3765
- });
3954
+ append(element){
3955
+ this.items.push(element);
3956
+ this.draw(false);
3957
+ return this;
3766
3958
  }
3767
- next(n = 1) {
3768
- return this.activate(this.states.activeIndex + n);
3959
+ background(color){
3960
+ this.ctx.fillStyle = color;
3961
+ this.ctx.setTransform(1, 0, 0, 1, 0, 0);
3962
+ this.ctx.fillRect(0, 0, this.width, this.height);
3963
+ this.applyTransformMatrix();
3964
+ this.draw();
3769
3965
  }
3770
- previous(n = 1) {
3771
- return this.activate(this.states.activeIndex - n);
3966
+ lineWidth(w){
3967
+ this.ctx.lineWidth=w/this.transformMatrix[0][0];
3968
+ return this
3772
3969
  }
3773
- activate(index) {
3774
- if (!this.items.length) return this;
3775
-
3776
- const currentItem = this.items.at(this.states.activeIndex);
3970
+ getImageData(x=0,y=0,w=this.width,h=this.height){
3971
+ return this.ctx.getImageData(x,y,w,h);
3972
+ }
3973
+ clear(){
3974
+ this.ctx.setTransform(1, 0, 0, 1, 0, 0);
3975
+ this.ctx.clearRect(0, 0, this.width, this.height);
3976
+ this.applyTransformMatrix();
3977
+ return this;
3978
+ }
3979
+ clone(){
3980
+ console.log(this.width);
3981
+ const canvas=new UICanvas();
3982
+ canvas.items=this.items;
3983
+ canvas.transformMatrix=this.transformMatrix;
3984
+ canvas.axisMatrix=this.axisMatrix;
3985
+ Object.assign(canvas.cache,{...this.cache});
3986
+ //waitForUIElm(this)
3987
+ //console.log(element)
3988
+ this.size(this.element.style.width,this.element.style.width);
3989
+ this.applyTransformMatrix();
3990
+ this.draw();
3991
+ this.adjust();
3992
+ return canvas;
3993
+ }
3994
+ toImage() {
3995
+ this.img = document?.createElement("img");
3996
+ this.img.src = this.element?.toDataURL("image/png");
3997
+ return this;
3998
+ }
3999
+ toBlob() {
4000
+ var canvas = this.element;
4001
+ canvas.toBlob(function (blob) {
4002
+ var newImg = document?.createElement("img"),
4003
+ url = URL.createObjectURL(blob);
4004
+ newImg.onload = function () {
4005
+ URL.revokeObjectURL(url);
4006
+ };
4007
+ newImg.src = url;
4008
+ console.log(newImg);
4009
+ });
4010
+ }
4011
+ zoomIn(){
3777
4012
 
3778
- if (currentItem) {
3779
- currentItem.style({ display: 'none' });
3780
- }
4013
+ }
4014
+ zoomOut(){
4015
+
4016
+ }
4017
+ undo(n){
3781
4018
 
3782
- const len = this.items.length;
3783
- this.states.activeIndex = ((index % len) + len) % len;
4019
+ }
4020
+ redo(n){
3784
4021
 
3785
- const activeItem = this.items.at(this.states.activeIndex);
3786
- if (activeItem) {
3787
- const restoredDisplay = this.#DISPLAYS_MAP.get(activeItem) || 'block';
3788
- activeItem.style({ display: restoredDisplay === 'none' ? 'block' : restoredDisplay });
3789
- }
4022
+ }
4023
+ stream(){
3790
4024
 
3791
- return this;
3792
4025
  }
3793
4026
  }
3794
4027
 
3795
- const Swap = call_with_optional_props(UISwap);
4028
+ const Canvas=(w,h)=>new UICanvas(w,h);
3796
4029
 
3797
- class UIFragment extends UIElement$1{
3798
- constructor(...items){
3799
- super({ element : document.createDocumentFragment()});
3800
- this.append(...items);
4030
+ class UISvg extends UIElement$1 {
4031
+ constructor(w=360,h=300) {
4032
+ super("svg","svg");
4033
+ //this.cache={};
4034
+ // this.setAttr("width",w);
4035
+ // this.setAttr("height",h);
4036
+ // this.setAttr({
4037
+ // width : w,
4038
+ // height : h
4039
+ // })
4040
+ this.style({border:"1px black solid"});
4041
+ //this.view(-w/2,-h/2,w/2,h/2);
4042
+ this.size(w, h);
4043
+ this.view(-10,-10,10,10);
4044
+ }
4045
+ size(w, h){
4046
+ this.setAttr({
4047
+ width : w,
4048
+ height : h
4049
+ });
4050
+ return this
4051
+ }
4052
+ view(x1,y1,x2,y2){
4053
+ let width=Math.abs(x2-x1);
4054
+ let height=Math.abs(y2-y1);
4055
+ this.setAttr("viewBox",[x1,y1,width,height].join(" "));
4056
+ this.st.scaleY(-1);
4057
+ return this;
4058
+ }
4059
+ add(...svgElement){
4060
+ for(let i=0;i<svgElement.length;i++){
4061
+ this.element.append(svgElement[i].element);
4062
+ this.items.push(svgElement[i]);
4063
+ }
4064
+ this.maintain();
4065
+ return this;
3801
4066
  }
3802
- isFragment(){
3803
- return true
4067
+ remove(...svgElement){
4068
+ for(let i=0;i<svgElement.length;i++){
4069
+ this.element?.removeChild(svgElement[i].element);
4070
+ this.items=this.items.filter(n=>!svgElement);
4071
+ }
4072
+ this.maintain();
4073
+ return this;
3804
4074
  }
3805
- }
3806
-
3807
- const Fragment = (...items) => new UIFragment(...items);
3808
-
3809
- class UIFor extends UIFragment{
3810
- constructor({each, fallback, mapFn = () => {}} = {}){
3811
- super();
3812
- this.config = {
3813
- each,
3814
- fallback,
3815
- mapFn
3816
- };
3817
- this.append(
3818
- ...this.config.each.map((n,i) => this.config.mapFn(n, i))
3819
- );
4075
+ mask(){
4076
+
3820
4077
  }
3821
- }
4078
+ toString(){
4079
+ return (new XMLSerializer()).serializeToString(this.element);
4080
+ }
4081
+ btoa(){
4082
+ return btoa(this.toString())
4083
+ }
4084
+ toImg(){
4085
+ return 'data:image/svg+xml;base64,'+this.btoa()
4086
+ }
4087
+ toImg2(){
4088
+ return "data:image/svg+xml;charset=utf8,"+this.toString().replaceAll("<","%3C").replaceAll(">","%3E").replaceAll("#","%23").replaceAll('"',"'");
4089
+ }
4090
+
4091
+ }
3822
4092
 
3823
- const For = ({each, fallback, mapFn} = {}) => new UIFor({each, fallback, mapFn});
4093
+ const Svg =(w,h)=>new UISvg(w,h);
3824
4094
 
3825
4095
  const { PI, sqrt: sqrt$1, cos: cos$2, sin: sin$2, acos, pow } = Math;
3826
4096
 
@@ -4391,13 +4661,15 @@ const csv2object = (csv, delimiter = ",") => {
4391
4661
  };
4392
4662
  const csv2json = (csv, delimiter = ",") => JSON.stringify(csv2object(csv,delimiter));
4393
4663
  const csv2sql=(csv, Table)=>{
4664
+ const sanitizeId = s => s.trim().replace(/[^a-zA-Z0-9_]/g, '');
4665
+ const escapeVal = s => "'" + s.trim().replace(/'/g, "''") + "'";
4394
4666
  const lines = csv.trim().trimEnd().split('\n').filter(n=>n);
4395
- const columns = lines[0].split(',');
4396
- let sqlQuery = `INSERT INTO ${Table} (${columns.join(', ')}) Values `;
4667
+ const columns = lines[0].split(',').map(sanitizeId);
4668
+ let sqlQuery = "INSERT INTO " + sanitizeId(Table) + " (" + columns.join(', ') + ") Values ";
4397
4669
  let sqlValues = [];
4398
4670
  for (let i = 1; i < lines.length; i++) {
4399
- const values = lines[i].split(',');
4400
- sqlValues.push(`(${values})`);
4671
+ const values = lines[i].split(',').map(escapeVal);
4672
+ sqlValues.push("(" + values.join(', ') + ")");
4401
4673
  }
4402
4674
  return sqlQuery+sqlValues.join(",\n");
4403
4675
  };
@@ -4514,6 +4786,35 @@ function trimKeys(obj) {
4514
4786
  }, Array.isArray(obj) ? [] : {});
4515
4787
  }
4516
4788
 
4789
+ function parseXML(xmlString) {
4790
+ const parser = new DOMParser();
4791
+ const xmlDoc = parser.parseFromString(xmlString, 'text/xml');
4792
+ const rootNode = xmlDoc.documentElement;
4793
+ const result = parseNode(rootNode);
4794
+ return result;
4795
+ }
4796
+
4797
+ function parseNode(node) {
4798
+ const obj = {
4799
+ type: node.nodeName,
4800
+ attributes: {},
4801
+ children: []
4802
+ };
4803
+ for (let i = 0; i < node.attributes.length; i++) {
4804
+ const attr = node.attributes[i];
4805
+ obj.attributes[attr.name] = attr.value;
4806
+ }
4807
+ for (let i = 0; i < node.childNodes.length; i++) {
4808
+ const child = node.childNodes[i];
4809
+ if (child.nodeType === Node.ELEMENT_NODE) {
4810
+ obj.children.push(parseNode(child));
4811
+ } else if (child.nodeType === Node.TEXT_NODE) {
4812
+ obj.text = child.textContent.trim();
4813
+ }
4814
+ }
4815
+ return obj;
4816
+ }
4817
+
4517
4818
  // import { ZikoHead , useHead} from "../reactivity/hooks/head/index.js";
4518
4819
  class ZikoApp {
4519
4820
  constructor({head = null, wrapper = null, target = null}){
@@ -4805,6 +5106,45 @@ const useReactive = (nested_value) => mapfun(
4805
5106
  nested_value
4806
5107
  );
4807
5108
 
5109
+ const useEffect = (callback, deps = []) =>{
5110
+ const states = deps.filter(isStateGetter);
5111
+
5112
+ let cleanup;
5113
+
5114
+ const execute = () => {
5115
+ // Cleanup previous effect
5116
+ if (typeof cleanup === "function") {
5117
+ cleanup();
5118
+ }
5119
+
5120
+ // Read current state values
5121
+ const values = states.map(state => state().value);
5122
+
5123
+ // Execute effect
5124
+ cleanup = callback(...values);
5125
+ };
5126
+
5127
+ // Subscribe to states
5128
+ const unsubscribers = states.map(state =>
5129
+ state()._subscribe(execute)
5130
+ );
5131
+
5132
+ // Initial execution
5133
+ execute();
5134
+
5135
+ // Return effect cleanup
5136
+ return () => {
5137
+ unsubscribers.forEach(unsubscribe => {
5138
+ unsubscribe();
5139
+ });
5140
+
5141
+ if (typeof cleanup === "function") {
5142
+ cleanup();
5143
+ cleanup = undefined;
5144
+ }
5145
+ };
5146
+ };
5147
+
4808
5148
  class UseThread {
4809
5149
  #worker;
4810
5150
  #callbacks = new Map();
@@ -5227,4 +5567,4 @@ if(globalThis?.document){
5227
5567
  document?.addEventListener("DOMContentLoaded", __Ziko__.__Config__.init());
5228
5568
  }
5229
5569
 
5230
- export { App, ClickAwayEvent, ClickListeners, Clock, CloneElement, Complex, E, EPSILON, EventController, FileBasedRouting, Flex, For, Fragment, HTMLWrapper, KeyListeners, Matrix, PI$1 as PI, PtrListeners, Random, SPA, SVGWrapper, Scheduler, Suspense, Swap, SwipeEvent, Switch, Tick, TimeAnimation, TimeLoop, TimeScheduler, UIElement$1 as UIElement, UIFlex, UIFragment, UIHTMLWrapper, UINode, UISVGWrapper, UISwap, UISwitch, UIView, UseRoot, UseThread, View, ViewEvent, ViewListeners, ZikoApp, ZikoSPA, ZikoUISuspense, ZikoUIText, abs, accum_max, accum_min, accum_prod, accum_product, accum_sum, acos$1 as acos, acosh, acot, add, add_class, add_vendor_prefix, and, animation, apply_fun, arc, asin, asinh, atan, atan2, atanh, back, binomial, call_with_optional_props, cbrt, ceil, clamp, clock, cloneUI, complex, contraharmonic_mean, cos$3 as cos, cosh$2 as cosh, coth, croot, csv2arr, csv2json, csv2matrix, csv2object, csv2sql, debounce, defineParamsGetter, define_wc, deg2rad, discret, div, elastic, ema, exp$1 as exp, floor, fract, geo_mean, harmonic_mean, hypot, in_back, in_bounce, in_circ, in_cubic, in_elastic, in_expo, in_out_back, in_out_bounce, in_out_circ, in_out_cubic, in_out_elastic, in_out_expo, in_out_quad, in_out_quart, in_out_quint, in_out_sin, in_quad, in_quart, in_quint, in_sin, interquartile_mean, iqr, isPrimitive, isStateGetter, json2arr, json2css, json2csv, json2csvFile, json2xml, json2xmlFile, json2yml, json2ymlFile, lerp, linear, linkStyle, ln, loop, map$1 as map, mapfun$1 as mapfun, matrix, matrix2, matrix3, matrix4, max, mean, median, midhinge, midrange, min, modulo, mul, nand, nor, norm, normalize_css_value, not, nthr, or, out_back, out_bounce, out_circ, out_cubic, out_elastic, out_expo, out_quad, out_quart, out_quint, out_sin, percentile, pow$1 as pow, power_mean, q1, q3, rad2deg, register_click_away_event, register_swipe_event, register_view_event, remove_class, rms, rolling_std, rolling_variance, round, sample_std, sample_variance, script, sec, sig, sign, sin$3 as sin, sinh$1 as sinh, sleep, sma, sqrt$2 as sqrt, std, step, step_fps, style, sub, svg2ascii, svg2img, svg2imgUrl, svg2str, tags, tan, tanh, text, throttle, tick, timeTaken, time_memory_Taken, timeout, trimmed_mean, trunc, useDerived, useEventEmitter, useIPC, useLocalStorage, useMediaQuery, useQueryParams, useReactive, useRoot, useSessionStorage, useState, useThread, useTitle, variance, wait, waitElm, waitForUIElm, waitForUIElmSync, watchQueryParams, weighted_mean, weighted_std, weighted_variance, winsorized_mean, wma, xnor, xor };
5570
+ export { App, Canvas, ClickAwayEvent, ClickListeners, Clock, CloneElement, Complex, E, EPSILON, EventController, FileBasedRouting, Flex, For, Fragment, HTMLWrapper, KeyListeners, Matrix, PI$1 as PI, PtrListeners, Random, SPA, STATE_GETTER, SVGWrapper, Scheduler, Suspense, Svg, Swap, SwipeEvent, Switch, Tick, TimeAnimation, TimeLoop, TimeScheduler, UICanvas, UIElement$1 as UIElement, UIFlex, UIFragment, UIHTMLWrapper, UINode, UISVGWrapper, UISuspense, UISvg, UISwap, UISwitch, UIView, UseRoot, UseThread, View, ViewEvent, ViewListeners, ZikoApp, ZikoSPA, ZikoUIText, abs, accum_max, accum_min, accum_prod, accum_product, accum_sum, acos$1 as acos, acosh, acot, add, add_class, add_vendor_prefix, and, animation, apply_fun, arc, asin, asinh, atan, atan2, atanh, back, binomial, call_with_optional_props, cbrt, ceil, clamp, clock, cloneUI, complex, contraharmonic_mean, cos$3 as cos, cosh$2 as cosh, coth, croot, csv2arr, csv2json, csv2matrix, csv2object, csv2sql, debounce, defineParamsGetter, define_wc, deg2rad, discret, div, elastic, ema, exp$1 as exp, floor, fract, geo_mean, harmonic_mean, hypot, in_back, in_bounce, in_circ, in_cubic, in_elastic, in_expo, in_out_back, in_out_bounce, in_out_circ, in_out_cubic, in_out_elastic, in_out_expo, in_out_quad, in_out_quart, in_out_quint, in_out_sin, in_quad, in_quart, in_quint, in_sin, interquartile_mean, iqr, isStateGetter, is_primitive, json2arr, json2css, json2csv, json2csvFile, json2xml, json2xmlFile, json2yml, json2ymlFile, lerp, linear, linkStyle, ln, loop, map$1 as map, mapfun$1 as mapfun, matrix, matrix2, matrix3, matrix4, max, mean, median, midhinge, midrange, min, modulo, mul, nand, nor, norm, normalize_css_value, not, nthr, or, out_back, out_bounce, out_circ, out_cubic, out_elastic, out_expo, out_quad, out_quart, out_quint, out_sin, parseXML, parse_props, percentile, pow$1 as pow, power_mean, q1, q3, rad2deg, register_click_away_event, register_swipe_event, register_view_event, remove_class, rms, rolling_std, rolling_variance, round, sample_std, sample_variance, script, sec, sig, sign, sin$3 as sin, sinh$1 as sinh, sleep, sma, sqrt$2 as sqrt, std, step, step_fps, style, sub, svg2ascii, svg2img, svg2imgUrl, svg2str, tags, tan, tanh, text, throttle, tick, timeTaken, time_memory_Taken, timeout, trimmed_mean, trunc, useDerived, useEffect, useEventEmitter, useIPC, useLocalStorage, useMediaQuery, useQueryParams, useReactive, useRoot, useSessionStorage, useState, useThread, useTitle, variance, wait, waitElm, waitForUIElm, waitForUIElmSync, watchQueryParams, weighted_mean, weighted_std, weighted_variance, winsorized_mean, wma, xnor, xor };