lilact 0.16.2 → 0.16.3

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.
@@ -51,44 +51,44 @@ const {css,cx} = emotion;
51
51
  */
52
52
 
53
53
  export function Spinner({
54
- size = 48,
55
- className,
56
- style,
57
- color = "currentColor",
58
- strokeWidth = 3,
59
- "aria-label": ariaLabel = "Loading",
54
+ size = 48,
55
+ className,
56
+ style,
57
+ color = "currentColor",
58
+ strokeWidth = 3,
59
+ "aria-label": ariaLabel = "Loading",
60
60
  }) {
61
- const s = Math.max(1, size)+"px";
62
-
63
- return (
64
- <div
65
- className={className}
66
- style={{
67
- width: "100%",
68
- height: "100%",
69
- display: "grid",
70
- placeItems: "center",
71
- ...style,
72
- }}
73
- aria-label={ariaLabel}
74
- role="status"
75
- >
76
- <div
77
- style={{
78
- width: s,
79
- height: s,
80
- borderRadius: "50%",
81
- border: `${strokeWidth}px solid rgba(0,0,0,0.15)`,
82
- borderTopColor: color,
83
- animation: "ddSpinnerSpin 0.9s linear infinite",
84
- boxSizing: "border-box",
85
- }}
86
- />
87
- <style>{`
88
- @keyframes ddSpinnerSpin { to { transform: rotate(360deg); } }
89
- `}</style>
90
- </div>
91
- );
61
+ const s = Math.max(1, size)+"px";
62
+
63
+ return (
64
+ <div
65
+ className={className}
66
+ style={{
67
+ width: "100%",
68
+ height: "100%",
69
+ display: "grid",
70
+ placeItems: "center",
71
+ ...style,
72
+ }}
73
+ aria-label={ariaLabel}
74
+ role="status"
75
+ >
76
+ <div
77
+ style={{
78
+ width: s,
79
+ height: s,
80
+ borderRadius: "50%",
81
+ border: `${strokeWidth}px solid rgba(0,0,0,0.15)`,
82
+ borderTopColor: color,
83
+ animation: "ddSpinnerSpin 0.9s linear infinite",
84
+ boxSizing: "border-box",
85
+ }}
86
+ />
87
+ <style>{`
88
+ @keyframes ddSpinnerSpin { to { transform: rotate(360deg); } }
89
+ `}</style>
90
+ </div>
91
+ );
92
92
  }
93
93
 
94
94
 
@@ -444,203 +444,202 @@ export function DragHandle({
444
444
  */
445
445
 
446
446
  export const SplitPane = forwardRef(function SplitPane(
447
- {
448
- mode = "horizontal",
449
- position,
450
- defaultPosition = 0.5,
451
- min = 0.1,
452
- max = 0.9,
453
- splitterSize = 8,
454
- onSizeChange,
455
- style,
456
- className,
457
- firstPaneStyle,
458
- secondPaneStyle,
459
- splitterStyle,
460
- children,
461
- },
462
- ref
447
+ {
448
+ mode = "horizontal",
449
+ position,
450
+ defaultPosition = 0.5,
451
+ min = 0.1,
452
+ max = 0.9,
453
+ splitterSize = 8,
454
+ onSizeChange,
455
+ style,
456
+ className,
457
+ firstPaneStyle,
458
+ secondPaneStyle,
459
+ splitterStyle,
460
+ children,
461
+ },
462
+ ref
463
463
  ) {
464
- const initialMode = mode === "vertical" ? "vertical" : "horizontal";
465
- const [internalMode, setInternalMode] = useState(initialMode);
466
-
467
- const [internalPos, setInternalPos] = useState(clamp(defaultPosition, min, max));
468
- const posResolved = position == null ? internalPos : clamp(position, min, max);
469
-
470
- useEffect(() => {
471
- if (position == null) return;
472
- setInternalPos(clamp(position, min, max));
473
- }, [position, min, max]);
474
-
475
- useEffect(() => {
476
- setInternalMode(mode === "vertical" ? "vertical" : "horizontal");
477
- }, [mode]);
478
-
479
- const setPosition = (next) => {
480
- const clamped = clamp(next, min, max);
481
- if (position == null) setInternalPos(clamped);
482
- onSizeChange?.(clamped);
483
- };
484
-
485
- useImperativeHandle(ref, () => ({
486
- setPosition,
487
- setMode: (nextMode) => setInternalMode(nextMode === "vertical" ? "vertical" : "horizontal"),
488
- getPosition: () => posResolved,
489
- getMode: () => internalMode,
490
- }));
491
-
492
- const containerRef = useRef(null);
493
- const sizeRef = useRef({ w: 0, h: 0 });
494
-
495
- useLayoutEffect(() => {
496
- const el = containerRef.current;
497
- if (!el) return;
498
-
499
- const ro = new ResizeObserver(() => {
500
- const rect = el.getBoundingClientRect();
501
- sizeRef.current = { w: rect.width, h: rect.height };
502
- });
503
-
504
- ro.observe(el);
505
- const rect = el.getBoundingClientRect();
506
- sizeRef.current = { w: rect.width, h: rect.height };
507
-
508
- return () => ro.disconnect();
509
- }, []);
510
-
511
- const startPosRef = useRef(posResolved);
512
- const [dragging, setDragging] = useState(false);
513
-
514
- const handleStart = () => {
515
- setDragging(true);
516
- startPosRef.current = posResolved;
517
- };
518
-
519
- // DragHandle in your description: onDelta(x, y, data)
520
- const handleDelta = (x, y, _data) => {
521
- const { w, h } = sizeRef.current;
522
- if (internalMode === "horizontal") {
523
- setPosition(startPosRef.current + x / (w || 1));
524
- } else {
525
- setPosition(startPosRef.current + y / (h || 1));
526
- }
527
- };
528
-
529
- const handleEnd = () => setDragging(false);
530
-
531
- const arr = Children.toArray(children);
532
- const firstChild = arr[0];
533
- const secondChild = arr[1];
534
-
535
- const p = posResolved;
536
-
537
- const pane1StyleAbs =
538
- internalMode === "horizontal"
539
- ? {
540
- position: "absolute",
541
- top: 0,
542
- bottom: 0,
543
- left: 0,
544
- width: `calc(${p} * (100% - ${splitterSize}px))`,
545
- overflow: "auto",
546
- ...(firstPaneStyle || {}),
547
- }
548
- : {
549
- position: "absolute",
550
- left: 0,
551
- right: 0,
552
- top: 0,
553
- height: `calc(${p} * (100% - ${splitterSize}px))`,
554
- overflow: "auto",
555
- ...(firstPaneStyle || {}),
556
- };
557
-
558
- const pane2StyleAbs =
559
- internalMode === "horizontal"
560
- ? {
561
- position: "absolute",
562
- top: 0,
563
- bottom: 0,
564
- left: `calc(${p} * (100% - ${splitterSize}px) + ${splitterSize}px)`,
565
- right: 0,
566
- overflow: "auto",
567
- ...(secondPaneStyle || {}),
568
- }
569
- : {
570
- position: "absolute",
571
- left: 0,
572
- right: 0,
573
- top: `calc(${p} * (100% - ${splitterSize}px) + ${splitterSize}px)`,
574
- bottom: 0,
575
- overflow: "auto",
576
- ...(secondPaneStyle || {}),
577
- };
578
-
579
- // Basic visible default for splitter (so it doesn't "disappear" on mode switch).
580
- // Also give zIndex + background and keep pointer events enabled.
581
- const splitterBase = {
582
- background: "rgba(0,0,0,0.08)",
583
- boxShadow: "inset 0 0 0 1px rgba(0,0,0,0.15)",
584
- zIndex: 10,
585
- };
586
-
587
- const splitterAbsStyle =
588
- internalMode === "horizontal"
589
- ? {
590
- position: "absolute",
591
- top: 0,
592
- bottom: 0,
593
- left: `calc(${p} * (100% - ${splitterSize}px))`,
594
- width: splitterSize,
595
- height: "100%",
596
-
597
- cursor: dragging ? "col-resize" : "col-resize",
598
- touchAction: "none",
599
- pointerEvents: "auto",
600
-
601
- ...splitterBase,
602
- ...(splitterStyle || {}),
603
- }
604
- : {
605
- position: "absolute",
606
- left: 0,
607
- right: 0,
608
- top: `calc(${p} * (100% - ${splitterSize}px))`,
609
- height: splitterSize,
610
- width: "100%",
611
-
612
- cursor: dragging ? "row-resize" : "row-resize",
613
- touchAction: "none",
614
- pointerEvents: "auto",
615
-
616
- ...splitterBase,
617
- ...(splitterStyle || {}),
618
- };
619
-
620
- return (
621
- <div
622
- ref={containerRef}
623
- className={className}
624
- style={{
625
- position: "relative",
626
- width: "100%",
627
- height: "100%",
628
- overflow: "hidden",
629
- ...(style || {}),
630
- }}
631
- >
632
- <div style={pane1StyleAbs}>{firstChild}</div>
633
- <div style={pane2StyleAbs}>{secondChild}</div>
634
-
635
- {/* Keep the DragHandle mounted across mode changes (only its absolute coordinates change). */}
636
- <DragHandle
637
- onStart={handleStart}
638
- onDelta={handleDelta}
639
- onEnd={handleEnd}
640
- style={splitterAbsStyle}
641
- />
642
- </div>
643
- );
464
+ const initialMode = mode === "vertical" ? "vertical" : "horizontal";
465
+ const [internalMode, setInternalMode] = useState(initialMode);
466
+
467
+ const [internalPos, setInternalPos] = useState(clamp(defaultPosition, min, max));
468
+ const posResolved = position == null ? internalPos : clamp(position, min, max);
469
+
470
+ useEffect(() => {
471
+ if (position == null) return;
472
+ setInternalPos(clamp(position, min, max));
473
+ }, [position, min, max]);
474
+
475
+ useEffect(() => {
476
+ setInternalMode(mode === "vertical" ? "vertical" : "horizontal");
477
+ }, [mode]);
478
+
479
+ const setPosition = (next) => {
480
+ const clamped = clamp(next, min, max);
481
+ if (position == null) setInternalPos(clamped);
482
+ onSizeChange?.(clamped);
483
+ };
484
+
485
+ useImperativeHandle(ref, () => ({
486
+ setPosition,
487
+ setMode: (nextMode) => setInternalMode(nextMode === "vertical" ? "vertical" : "horizontal"),
488
+ getPosition: () => posResolved,
489
+ getMode: () => internalMode,
490
+ }));
491
+
492
+ const containerRef = useRef(null);
493
+ const sizeRef = useRef({ w: 0, h: 0 });
494
+
495
+ useLayoutEffect(() => {
496
+ const el = containerRef.current;
497
+ if (!el) return;
498
+
499
+ const ro = new ResizeObserver(() => {
500
+ const rect = el.getBoundingClientRect();
501
+ sizeRef.current = { w: rect.width, h: rect.height };
502
+ });
503
+
504
+ ro.observe(el);
505
+ const rect = el.getBoundingClientRect();
506
+ sizeRef.current = { w: rect.width, h: rect.height };
507
+
508
+ return () => ro.disconnect();
509
+ }, []);
510
+
511
+ const startPosRef = useRef(posResolved);
512
+ const [dragging, setDragging] = useState(false);
513
+
514
+ const handleStart = () => {
515
+ setDragging(true);
516
+ startPosRef.current = posResolved;
517
+ };
518
+
519
+ const handleDelta = (x, y, _data) => {
520
+ const { w, h } = sizeRef.current;
521
+ if (internalMode === "horizontal") {
522
+ setPosition(startPosRef.current + x / (w || 1));
523
+ } else {
524
+ setPosition(startPosRef.current + y / (h || 1));
525
+ }
526
+ };
527
+
528
+ const handleEnd = () => setDragging(false);
529
+
530
+ const arr = Children.toArray(children);
531
+ const firstChild = arr[0];
532
+ const secondChild = arr[1];
533
+
534
+ const p = posResolved;
535
+
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 = {
581
+ background: "rgba(0,0,0,0.08)",
582
+ boxShadow: "inset 0 0 2px rgba(0,0,0,0.25)",
583
+ zIndex: 10,
584
+ };
585
+
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
+ };
618
+
619
+ return (
620
+ <div
621
+ ref={containerRef}
622
+ className={className}
623
+ style={{
624
+ position: "relative",
625
+ width: "100%",
626
+ height: "100%",
627
+ overflow: "hidden",
628
+ ...(style || {}),
629
+ }}
630
+ >
631
+ <div style={pane1StyleAbs}>{firstChild}</div>
632
+ <div style={pane2StyleAbs}>{secondChild}</div>
633
+
634
+ <DragHandle
635
+ onStart={handleStart}
636
+ onDelta={handleDelta}
637
+ onEnd={handleEnd}
638
+ style={splitterAbsStyle}
639
+ className="splitter"
640
+ />
641
+ </div>
642
+ );
644
643
  });
645
644
 
646
645
 
@@ -428,19 +428,31 @@ if(DEBUG) {
428
428
  this.event_detachers[al] =
429
429
  Lilact.addWrappedEventListener(this.element, alc.substring(2), patch[a], {capture: true});
430
430
  }
431
- else if(al==='style') {
432
- if(typeof(patch[a])==='string') {
433
- this.element.style = patch[a];
431
+ else if(a==='style') {
432
+ if(typeof(patch.style)==='string') {
433
+ this.element.style = patch.style;
434
434
  }
435
435
  else {
436
- for(const x in patch[a]) {
436
+ if(this.props?.style) {
437
+ if(typeof(this.props.style)==='string') {
438
+ this.element.style = "";
439
+ }
440
+ else {
441
+ for(let p in this.props.style) {
442
+ if( !patch.style.hasOwnProperty(p) ) {
443
+ this.element.style[p] = "";
444
+ }
445
+ }
446
+ }
447
+ }
448
+ for(const x in patch.style) {
437
449
  if( length_css_attributes_set.has(x) ) {
438
- if(isFinite(patch[a][x])) {
439
- patch[a][x]+='px';
450
+ if(isFinite(patch.style[x])) {
451
+ patch.style[x]+='px';
440
452
  }
441
453
  }
442
454
  }
443
- Object.assign(this.element.style, patch[a]);
455
+ Object.assign(this.element.style, patch.style);
444
456
  }
445
457
  }
446
458
  else if(boolean_html_attributes_set.has(a)) { // not lower cased(al), as it is set as a js property