lilact 0.24.2 → 0.26.1

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 (38) hide show
  1. package/README.md +1 -1
  2. package/dist/lilact.development.js +169 -60
  3. package/dist/lilact.development.js.map +3 -3
  4. package/dist/lilact.development.min.js +28 -28
  5. package/dist/lilact.development.min.js.map +3 -3
  6. package/dist/lilact.production.min.js +28 -28
  7. package/docs/classes/accessories.ErrorBoundary.html +8 -8
  8. package/docs/classes/accessories.Suspense.html +7 -7
  9. package/docs/classes/components.Component.html +11 -11
  10. package/docs/classes/components.HTMLComponent.html +11 -11
  11. package/docs/classes/components.RootComponent.html +11 -11
  12. package/docs/functions/components.cloneComponent.html +1 -1
  13. package/docs/functions/components.createComponent.html +1 -1
  14. package/docs/functions/components.createPortal.html +1 -1
  15. package/docs/functions/components.createRoot.html +1 -1
  16. package/docs/functions/components.memo.html +1 -1
  17. package/docs/functions/components.render.html +1 -1
  18. package/docs/functions/timers.timeoutPromise.html +7 -2
  19. package/docs/index.html +1 -7
  20. package/docs/static/demos/usedefered.jsx +1 -1
  21. package/docs/static/lilact.development.js +169 -60
  22. package/docs/static/lilact.development.js.map +3 -3
  23. package/docs/static/lilact.development.min.js +28 -28
  24. package/docs/static/lilact.development.min.js.map +3 -3
  25. package/docs/static/lilact.production.min.js +28 -28
  26. package/docs/variables/accessories.SplitPane.html +8 -3
  27. package/docs/variables/components.cloneElement.html +1 -1
  28. package/examples/demos/usedefered.jsx +1 -1
  29. package/examples/lilact.development.js +169 -60
  30. package/examples/lilact.development.js.map +3 -3
  31. package/examples/lilact.development.min.js +28 -28
  32. package/examples/lilact.development.min.js.map +3 -3
  33. package/examples/lilact.production.min.js +28 -28
  34. package/package.json +1 -1
  35. package/src/accessories.jsx +195 -89
  36. package/src/components.jsx +5 -3
  37. package/src/jsx.js +1 -1
  38. package/src/lilact.jsx +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lilact",
3
- "version": "0.24.2",
3
+ "version": "0.26.1",
4
4
  "description": "A Little React/JSX Runtime Implementation for Browser",
5
5
  "repository": "github:arashkazemi/lilact",
6
6
  "homepage": "https://arashkazemi.github.io/lilact/",
@@ -416,14 +416,19 @@ export function DragHandle({
416
416
  * If provided, the component uses this value instead of internal state.
417
417
  * @param defaultPosition - Initial splitter position for uncontrolled usage. Defaults to `0.5`.
418
418
  * @param min - Minimum allowed position. Defaults to `0.1`.
419
+ Can also be a function that will be called with (containerWidth|containerHeight,splitterSize) as arguments
419
420
  * @param max - Maximum allowed position. Defaults to `0.9`.
421
+ Can also be a function that will be called with (containerWidth|containerHeight,splitterSize) as arguments
420
422
  * @param splitterSize - Thickness of the draggable splitter in pixels. Defaults to `8`.
423
+ * @param resizePolicy - The behavior on container resize. Its value can be `proportional`, `fixFirst` or `fixSecond`.
424
+ * Default is `proportional`.
421
425
  * @param onSizeChange - Callback invoked when the position changes. Receives the new normalized position.
422
426
  * @param style - Optional root container styles.
423
427
  * @param className - Optional root container CSS class.
424
428
  * @param leftPaneStyle - Optional styles applied to the left pane (or top pane in vertical mode).
425
429
  * @param rightPaneStyle - Optional styles applied to the right pane (or bottom pane in vertical mode).
426
430
  * @param splitterStyle - Optional styles applied to the splitter element.
431
+ * @param splitterChild - Child to be rendered into the splitter itself.
427
432
  * @param children - Children to be rendered into the two pane containers.
428
433
  *
429
434
  * @example
@@ -452,24 +457,35 @@ export const SplitPane = forwardRef(function SplitPane(
452
457
  max = 0.9,
453
458
  splitterSize = 8,
454
459
  onSizeChange,
460
+ resizePolicy = "proportional",
455
461
  style,
456
462
  className,
457
463
  firstPaneStyle,
458
464
  secondPaneStyle,
459
465
  splitterStyle,
466
+ splitterChild,
460
467
  children,
461
468
  },
462
469
  ref
463
470
  ) {
471
+ const containerRef = useRef(null);
472
+ const sizeRef = useRef({ w: 0, h: 0 });
473
+
464
474
  const initialMode = mode === "vertical" ? "vertical" : "horizontal";
465
475
  const [internalMode, setInternalMode] = useState(initialMode);
466
476
 
467
- const [internalPos, setInternalPos] = useState(clamp(defaultPosition, min, max));
468
- const posResolved = position == null ? internalPos : clamp(position, min, max);
477
+ const [internalPos, setInternalPos] = useState(clamp(defaultPosition, min, max,
478
+ mode==='verical'?sizeRef.current.h:sizeRef.current.w, splitterSize));
479
+
480
+
481
+ let posResolved = position == null ? internalPos : position;
482
+ posResolved = clamp(posResolved, min, max,
483
+ mode==='verical'?sizeRef.current.h:sizeRef.current.w, splitterSize);
469
484
 
470
485
  useEffect(() => {
471
486
  if (position == null) return;
472
- setInternalPos(clamp(position, min, max));
487
+ setInternalPos(clamp(position, min, max,
488
+ mode==='verical'?sizeRef.current.h:sizeRef.current.w, splitterSize));
473
489
  }, [position, min, max]);
474
490
 
475
491
  useEffect(() => {
@@ -477,7 +493,8 @@ export const SplitPane = forwardRef(function SplitPane(
477
493
  }, [mode]);
478
494
 
479
495
  const setPosition = (next) => {
480
- const clamped = clamp(next, min, max);
496
+ const clamped = clamp(next, min, max,
497
+ mode==='verical'?sizeRef.current.h:sizeRef.current.w, splitterSize);
481
498
  if (position == null) setInternalPos(clamped);
482
499
  onSizeChange?.(clamped);
483
500
  };
@@ -489,8 +506,6 @@ export const SplitPane = forwardRef(function SplitPane(
489
506
  getMode: () => internalMode,
490
507
  }));
491
508
 
492
- const containerRef = useRef(null);
493
- const sizeRef = useRef({ w: 0, h: 0 });
494
509
 
495
510
  useLayoutEffect(() => {
496
511
  const el = containerRef.current;
@@ -498,7 +513,65 @@ export const SplitPane = forwardRef(function SplitPane(
498
513
 
499
514
  const ro = new ResizeObserver(() => {
500
515
  const rect = el.getBoundingClientRect();
516
+ const o = sizeRef.current;
501
517
  sizeRef.current = { w: rect.width, h: rect.height };
518
+
519
+
520
+ const EPS = 1e-6;
521
+
522
+ function clamp01(x) {
523
+ return Math.min(1, Math.max(0, x));
524
+ }
525
+
526
+ if (ref.current?.getPosition) {
527
+ const p = ref.current.getPosition();
528
+
529
+ if (resizePolicy === 'fixFirst') {
530
+ if (internalMode === 'vertical') {
531
+ const availOld = o.h - splitterSize;
532
+ const availNew = sizeRef.current.h - splitterSize;
533
+ if (availOld > 0 && availNew > 0) {
534
+ const firstPx = p * availOld; // fixed pane size in px
535
+ const nextP = firstPx / availNew; // recompute normalized
536
+ if (Math.abs(nextP - p) > EPS) setPosition(clamp01(nextP));
537
+ }
538
+ }
539
+ else {
540
+ const availOld = o.w - splitterSize;
541
+ const availNew = sizeRef.current.w - splitterSize;
542
+ if (availOld > 0 && availNew > 0) {
543
+ const firstPx = p * availOld;
544
+ const nextP = firstPx / availNew;
545
+ if (Math.abs(nextP - p) > EPS) setPosition(clamp01(nextP));
546
+ }
547
+ }
548
+ }
549
+ else if (resizePolicy === 'fixSecond') {
550
+ // fixSecond means second pane pixel size stays constant.
551
+ // secondPx = (1-p) * availOld
552
+ // nextP = 1 - secondPx/availNew
553
+ if (internalMode === 'vertical') {
554
+ const availOld = o.h - splitterSize;
555
+ const availNew = sizeRef.current.h - splitterSize;
556
+ if (availOld > 0 && availNew > 0) {
557
+ const secondPx = (1 - p) * availOld;
558
+ const nextP = 1 - (secondPx / availNew);
559
+ if (Math.abs(nextP - p) > EPS) setPosition(clamp01(nextP));
560
+ }
561
+ }
562
+ else {
563
+ const availOld = o.w - splitterSize;
564
+ const availNew = sizeRef.current.w - splitterSize;
565
+ if (availOld > 0 && availNew > 0) {
566
+ const secondPx = (1 - p) * availOld;
567
+ const nextP = 1 - (secondPx / availNew);
568
+ if (Math.abs(nextP - p) > EPS) setPosition(clamp01(nextP));
569
+ }
570
+ }
571
+ }
572
+ }
573
+
574
+
502
575
  });
503
576
 
504
577
  ro.observe(el);
@@ -506,7 +579,7 @@ export const SplitPane = forwardRef(function SplitPane(
506
579
  sizeRef.current = { w: rect.width, h: rect.height };
507
580
 
508
581
  return () => ro.disconnect();
509
- }, []);
582
+ }, [resizePolicy, internalMode]);
510
583
 
511
584
  const startPosRef = useRef(posResolved);
512
585
  const [dragging, setDragging] = useState(false);
@@ -531,90 +604,117 @@ export const SplitPane = forwardRef(function SplitPane(
531
604
  const firstChild = arr[0];
532
605
  const secondChild = arr[1];
533
606
 
607
+
534
608
  const p = posResolved;
609
+ const { w, h } = sizeRef.current;
535
610
 
536
- const pane1StyleAbs =
537
- internalMode === "horizontal"
538
- ? {
539
- position: "absolute",
540
- top: 0,
541
- bottom: 0,
542
- left: 0,
543
- width: `calc(${p} * (100% - ${splitterSize}px))`,
544
- overflow: "auto",
545
- ...(firstPaneStyle || {}),
546
- }
547
- : {
548
- position: "absolute",
549
- left: 0,
550
- right: 0,
551
- top: 0,
552
- height: `calc(${p} * (100% - ${splitterSize}px))`,
553
- overflow: "auto",
554
- ...(firstPaneStyle || {}),
555
- };
556
-
557
- const pane2StyleAbs =
558
- internalMode === "horizontal"
559
- ? {
560
- position: "absolute",
561
- top: 0,
562
- bottom: 0,
563
- left: `calc(${p} * (100% - ${splitterSize}px) + ${splitterSize}px)`,
564
- right: 0,
565
- overflow: "auto",
566
- ...(secondPaneStyle || {}),
567
- }
568
- : {
569
- position: "absolute",
570
- left: 0,
571
- right: 0,
572
- top: `calc(${p} * (100% - ${splitterSize}px) + ${splitterSize}px)`,
573
- bottom: 0,
574
- overflow: "auto",
575
- ...(secondPaneStyle || {}),
576
- };
577
-
578
- // Basic visible default for splitter (so it doesn't "disappear" on mode switch).
579
- // Also give zIndex + background and keep pointer events enabled.
580
- const splitterBase = {
611
+ const computedPane1Style = {
612
+ position: "absolute",
613
+ top: 0,
614
+ left: 0,
615
+ overflow: "auto",
616
+
617
+ ...(firstPaneStyle || {}),
618
+ };
619
+
620
+ const computedPane2Style = {
621
+ position: "absolute",
622
+ bottom: 0,
623
+ right: 0,
624
+ overflow: "auto",
625
+
626
+ ...(secondPaneStyle || {}),
627
+ };
628
+
629
+
630
+ const computedSplitterStyle = {
581
631
  background: "rgba(0,0,0,0.08)",
582
632
  boxShadow: "inset 0 0 2px rgba(0,0,0,0.25)",
583
633
  zIndex: 10,
634
+ position: "absolute",
635
+ cursor: internalMode==='horizontal' ? "col-resize" : "row-resize",
636
+ touchAction: "none",
637
+ pointerEvents: "auto",
638
+ ...(splitterStyle || {}),
584
639
  };
585
640
 
586
- const splitterAbsStyle =
587
- internalMode === "horizontal"
588
- ? {
589
- position: "absolute",
590
- top: 0,
591
- bottom: 0,
592
- left: `calc(${p} * (100% - ${splitterSize}px))`,
593
- width: splitterSize,
594
- height: "100%",
595
-
596
- cursor: dragging ? "col-resize" : "col-resize",
597
- touchAction: "none",
598
- pointerEvents: "auto",
599
-
600
- ...splitterBase,
601
- ...(splitterStyle || {}),
602
- }
603
- : {
604
- position: "absolute",
605
- left: 0,
606
- right: 0,
607
- top: `calc(${p} * (100% - ${splitterSize}px))`,
608
- height: splitterSize,
609
- width: "100%",
610
-
611
- cursor: dragging ? "row-resize" : "row-resize",
612
- touchAction: "none",
613
- pointerEvents: "auto",
614
-
615
- ...splitterBase,
616
- ...(splitterStyle || {}),
617
- };
641
+
642
+ if(internalMode==='horizontal') {
643
+ computedPane1Style.bottom = 0;
644
+ computedPane2Style.top = 0;
645
+
646
+ if(resizePolicy==='fixFirst') {
647
+ computedPane1Style.width = p*(w-splitterSize);
648
+ computedPane2Style.left = computedPane1Style.width+splitterSize;
649
+
650
+ Object.assign( computedSplitterStyle, {
651
+ top: 0,
652
+ bottom: 0,
653
+ left: computedPane1Style.width,
654
+ width: splitterSize,
655
+ });
656
+ }
657
+ else if(resizePolicy==='fixSecond') {
658
+ computedPane2Style.width = (1-p)*(w-splitterSize);
659
+ computedPane1Style.right = computedPane2Style.width+splitterSize;
660
+
661
+ Object.assign( computedSplitterStyle, {
662
+ top: 0,
663
+ bottom: 0,
664
+ right: computedPane2Style.width,
665
+ width: splitterSize,
666
+ });
667
+ }
668
+ else {
669
+ computedPane1Style.width = `calc(${p} * (100% - ${splitterSize}px))`;
670
+ computedPane2Style.left = `calc(${p} * (100% - ${splitterSize}px) + ${splitterSize}px)`;
671
+
672
+ Object.assign( computedSplitterStyle, {
673
+ top: 0,
674
+ bottom: 0,
675
+ left: `calc(${p} * (100% - ${splitterSize}px))`,
676
+ width: splitterSize,
677
+ });
678
+ }
679
+ }
680
+ else {
681
+ computedPane1Style.right = 0;
682
+ computedPane2Style.left = 0;
683
+
684
+ if(resizePolicy==='fixFirst') {
685
+ computedPane1Style.height = p*(h-splitterSize);
686
+ computedPane2Style.top = computedPane1Style.height+splitterSize;
687
+
688
+ Object.assign( computedSplitterStyle, {
689
+ left: 0,
690
+ right: 0,
691
+ top: computedPane1Style.height,
692
+ height: splitterSize,
693
+ });
694
+ }
695
+ else if(resizePolicy==='fixSecond') {
696
+ computedPane2Style.height = (1-p)*(h-splitterSize);
697
+ computedPane1Style.bottom = computedPane2Style.height+splitterSize;
698
+
699
+ Object.assign( computedSplitterStyle, {
700
+ left: 0,
701
+ right: 0,
702
+ bottom: computedPane2Style.height,
703
+ height: splitterSize,
704
+ });
705
+ }
706
+ else {
707
+ computedPane1Style.height = `calc(${p} * (100% - ${splitterSize}px))`;
708
+ computedPane2Style.top = `calc(${p} * (100% - ${splitterSize}px) + ${splitterSize}px)`;
709
+
710
+ Object.assign( computedSplitterStyle, {
711
+ left: 0,
712
+ right: 0,
713
+ top: computedPane1Style.height,
714
+ height: splitterSize,
715
+ });
716
+ }
717
+ }
618
718
 
619
719
  return (
620
720
  <div
@@ -628,19 +728,25 @@ export const SplitPane = forwardRef(function SplitPane(
628
728
  ...(style || {}),
629
729
  }}
630
730
  >
631
- <div style={pane1StyleAbs}>{firstChild}</div>
632
- <div style={pane2StyleAbs}>{secondChild}</div>
731
+ <div style={computedPane1Style}>{firstChild}</div>
732
+ <div style={computedPane2Style}>{secondChild}</div>
633
733
 
634
734
  <DragHandle
635
735
  onStart={handleStart}
636
736
  onDelta={handleDelta}
637
737
  onEnd={handleEnd}
638
- style={splitterAbsStyle}
738
+ style={computedSplitterStyle}
639
739
  className="splitter"
640
- />
740
+ >
741
+ {splitterChild}
742
+ </DragHandle>
641
743
  </div>
642
744
  );
643
745
  });
644
746
 
645
747
 
646
- const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
748
+ const clamp = function(v, min, max, size, splitterSize) {
749
+ if(typeof(min)==='function') { if(size>0) min = min(size, splitterSize); else min=0; }
750
+ if(typeof(max)==='function') { if(size>0) max = max(size, splitterSize); else max=1; }
751
+ return Math.max(min, Math.min(max, v));
752
+ }
@@ -115,8 +115,7 @@ class ComponentCache
115
115
  * used by lilact are kept. The Component class uses it under the hood, so there is a separation
116
116
  * and user can set whatever property they want in the component. Each Lilact.Component
117
117
  * has a core that is accessible via lilact symbol CORE, i.e. component[CORE]. Note
118
- * that you should either define a LILACT:CORE symbol or use the lilact preprocessor
119
- * tools which is a wiser choice.
118
+ * that you should define a LILACT:CORE symbol.
120
119
  *
121
120
  * ComponentCore methods are not to be called by the user. But it can also be used
122
121
  * to store data more efficiently, and I have used it extensively. But it is
@@ -152,6 +151,8 @@ class ComponentCore
152
151
  insert_index
153
152
  loader_args
154
153
 
154
+ is_svg
155
+
155
156
  */
156
157
 
157
158
  component;
@@ -785,6 +786,7 @@ function doUpdates()
785
786
 
786
787
  for(const u of _update_set) u.apply();
787
788
  for(const cb of _update_cbs) cb();
789
+
788
790
  processEffects();
789
791
 
790
792
  }
@@ -1092,7 +1094,7 @@ export class RootComponent extends HTMLComponent
1092
1094
 
1093
1095
  constructor(element, props)
1094
1096
  {
1095
- super(':root', props);
1097
+ super(':root:', props);
1096
1098
 
1097
1099
  if(typeof this.element==='string') {
1098
1100
  element = document.querySelector(element);
package/src/jsx.js CHANGED
@@ -64,7 +64,7 @@ let tab=0;
64
64
 
65
65
 
66
66
  const TOKENIZE_RE =
67
- /(\{|\}|\[|\]|\(|\)|\.\.\.|=>|\?\?=|\?\?|\?\.|===|!==|>>>|<<=|>>=|>>>=|\*\*=|\*\*|&&=|\|\|=|<=|>=|==|!=|<<|>>|\+\+|--|\+=|-=|\*=|\/=|%=|&=|\^=|\|=|=|\+|-|\*|\/|%|&|\^|\||!|~|\?|:|<|>|=|\.|,|;|\n+|[\s^\n]+)/gm;
67
+ /(\{|\}|\[|\]|\(|\)|\.\.\.|=>|\?\?=|\?\?|\?\.|===|!==|>>>|<<=|>>=|>>>=|\*\*=|\*\*|&&=|\|\|=|<=|>=|==|!=|<<|>>|\+\+|--|\+=|-=|\*=|\/=|%=|&=|\^=|\|=|=|\+|-|\*|\/|%|&|\^|\||!|~|\?|:|<|>|=|\.|,|;|\n+|[\s^\n]+)/g;
68
68
 
69
69
 
70
70
  function lookAhead(f, code, index, ...args)
package/src/lilact.jsx CHANGED
@@ -92,7 +92,7 @@ export {transpileJSX, transpilerConfig} from "./jsx";
92
92
  export const Lilact =
93
93
  {
94
94
 
95
- VERSION: "RC.1",
95
+ VERSION: "RC.3",
96
96
 
97
97
  // Configuration
98
98