@webqit/webflo 0.20.47 → 0.20.49

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.
@@ -195,16 +195,16 @@ export class ToastElement extends BaseElement {
195
195
  --color-error: var(--toast-color-error, coral);
196
196
  --color-warning: var(--toast-color-warning, coral);
197
197
 
198
- --wq-radius: var(--toast-radius, 1rem);
198
+ --radius: var(--toast-radius, 1rem);
199
199
  --background: var(--toast-background, rgb(30, 30, 30));
200
200
  --shadow: var(--toast-shadow, rgb(30, 30, 30));
201
201
 
202
- --dir: 1;
203
- --translation: calc(var(--toast-translation, 50px) * var(--dir));
204
- --exit-factor: var(--toast-exit-factor, -1);
202
+ --entry-translation-polarity: var(--toast-entry-translation-polarity, 1);
203
+ --translation: calc(var(--toast-translation, 50px) * var(--entry-translation-polarity));
204
+ --exit-translation-polarity: var(--toast--exit-translation-polarity, -1);
205
205
 
206
206
  --entry-transform: translateY(var(--translation));
207
- --exit-transform: translateY(calc(var(--translation) * var(--exit-factor)));
207
+ --exit-transform: translateY(calc(var(--translation) * var(--exit-translation-polarity)));
208
208
  }
209
209
 
210
210
  :host {
@@ -232,7 +232,7 @@ export class ToastElement extends BaseElement {
232
232
  :host(._top) {
233
233
  margin-bottom: auto;
234
234
  margin-top: 0;
235
- --dir: -1;
235
+ --entry-translation-polarity: var(--toast-entry-translation-polarity, -1);
236
236
  }
237
237
 
238
238
  /* ----------- */
@@ -246,7 +246,7 @@ export class ToastElement extends BaseElement {
246
246
 
247
247
  padding-block: 0.8rem;
248
248
  padding-inline: 1.2rem;
249
- border-radius: var(--wq-radius);
249
+ border-radius: var(--radius);
250
250
 
251
251
  color: var(--color-default);
252
252
  background-color: var(--background);
@@ -410,6 +410,7 @@ export class ModalElement extends BaseElement {
410
410
  }
411
411
 
412
412
  get delegatesFocus() { return false; }
413
+ get autoFocus() { return true; }
413
414
 
414
415
  // ----------------
415
416
 
@@ -442,51 +443,61 @@ export class ModalElement extends BaseElement {
442
443
  #headerBoxElement;
443
444
  #footerElement;
444
445
 
445
- updateScrollViewDimensions() {
446
- requestAnimationFrame(() => {
447
- requestAnimationFrame(() => {
448
- let viewWidth, viewHeight;
446
+ _calcViewDimensions() {
447
+ const viewWidth = this.#viewElement.offsetWidth;
448
+ const viewHeight = this.#viewElement.offsetHeight;
449
+ this.style.setProperty('--view-width', viewWidth + 'px');
450
+ this.style.setProperty('--view-height', viewHeight + 'px');
451
+ }
449
452
 
450
- const swipeDismiss = this.classList.contains('_swipe-dismiss');
451
- const minmaxScroll = !!window.getComputedStyle(this).getPropertyValue('--modal-minmax-length');
453
+ _calcHeaderDimensions() {
454
+ this.style.setProperty('--header-box-height', this.#headerBoxElement.offsetHeight + 'px');
455
+ this.style.setProperty('--header-max-height', this.#headerElement.offsetHeight + 'px');
456
+ }
452
457
 
453
- if (swipeDismiss || minmaxScroll) {
454
- requestAnimationFrame(() => {
455
- let left = 0, top = 0;
456
- if (this.matches('._left._horz, ._top:not(._horz)')) {
457
- this.#viewElement.scrollTo({ top, left });
458
- } else {
459
- if (this.classList.contains('_horz')) {
460
- viewWidth = this.#viewElement.offsetWidth;
461
- left = viewWidth - this.#spacingElement.offsetWidth;
462
- } else {
463
- viewHeight = this.#viewElement.offsetHeight;
464
- top = viewHeight - this.#spacingElement.offsetHeight;
465
- }
466
- if (this.#viewElement.scrollTop < top || this.#viewElement.scrollLeft < left) {
467
- this.#viewElement.scrollTo({ top, left });
468
- }
469
- }
470
- });
471
- }
458
+ _calcFooterDimensions() {
459
+ this.style.setProperty('--footer-max-height', this.#footerElement.offsetHeight + 'px');
460
+ }
472
461
 
473
- this.#viewElement.style.setProperty('--header-box-height', this.#headerBoxElement.offsetHeight + 'px');
474
- this.#viewElement.style.setProperty('--header-max-height', this.#headerElement.offsetHeight + 'px');
475
- this.#viewElement.style.setProperty('--footer-max-height', this.#footerElement.offsetHeight + 'px');
462
+ _calcScrollability() {
463
+ this.style.setProperty('--view-scroll-height', this.#viewElement.scrollHeight + 'px');
464
+ this.style.setProperty('--view-scroll-width', this.#viewElement.scrollWidth + 'px');
465
+ }
476
466
 
477
- if (this.classList.contains('_container')) return;
478
- if (viewWidth === undefined) viewWidth = this.#viewElement.offsetWidth;
479
- if (viewHeight === undefined) viewHeight = this.#viewElement.offsetHeight;
467
+ _updateScrollViewDimensions() {
468
+ requestAnimationFrame(() => {
469
+ const swipeDismiss = this.classList.contains('_swipe-dismiss');
470
+ const minmaxScroll = !!window.getComputedStyle(this).getPropertyValue('--modal-minmax-length');
471
+
472
+ if (swipeDismiss || minmaxScroll) {
473
+ requestAnimationFrame(() => {
474
+ let left = 0, top = 0;
475
+ if (this.matches('._left._horz, ._top:not(._horz)')) {
476
+ this.#viewElement.scrollTo({ top, left });
477
+ } else {
478
+ if (this.classList.contains('_horz')) {
479
+ left = this.#sentinelElement.offsetWidth;
480
+ } else {
481
+ top = this.#sentinelElement.offsetHeight;
482
+ }
483
+ if (this.#viewElement.scrollTop < top || this.#viewElement.scrollLeft < left) {
484
+ this.#viewElement.scrollTo({ top, left });
485
+ }
486
+ }
487
+ });
488
+ }
480
489
 
481
- this.#viewElement.style.setProperty('--view-width', viewWidth + 'px');
482
- this.#viewElement.style.setProperty('--view-height', viewHeight + 'px');
483
- });
490
+ this._calcHeaderDimensions();
491
+ this._calcFooterDimensions();
492
+ this._calcScrollability();
493
+ if (this.classList.contains('_container')) return;
494
+ this._calcViewDimensions();
484
495
  });
485
496
  }
486
497
 
487
498
  #unbindMinmaxWorker = null;
488
499
 
489
- bindMinmaxWorker() {
500
+ _bindMinmaxWorker() {
490
501
  const swipeDismiss = this.classList.contains('_swipe-dismiss');
491
502
  const minmaxEvents = this.classList.contains('_minmax-events');
492
503
 
@@ -531,9 +542,8 @@ export class ModalElement extends BaseElement {
531
542
  const handleUserScroll = () => this.#userScrolled = true;
532
543
  this.#viewElement.addEventListener('scroll', handleUserScroll);
533
544
 
534
-
535
- this.updateScrollViewDimensions();
536
- const handleResize = () => this.updateScrollViewDimensions();
545
+ this._updateScrollViewDimensions();
546
+ const handleResize = () => this._updateScrollViewDimensions();
537
547
  window.addEventListener('resize', handleResize);
538
548
 
539
549
  this.#unbindDimensionsWorker?.();
@@ -548,7 +558,7 @@ export class ModalElement extends BaseElement {
548
558
  attributeChangedCallback(name, old, _new) {
549
559
  super.attributeChangedCallback?.(name, old, _new);
550
560
 
551
- if (name === 'class') this.#bindDimensionsWorker();
561
+ if (name === 'class' && old !== _new) this.#bindDimensionsWorker();
552
562
  }
553
563
 
554
564
  connectedCallback() {
@@ -578,10 +588,22 @@ export class ModalElement extends BaseElement {
578
588
 
579
589
  this.addEventListener('toggle', (e) => {
580
590
  if (e.newState === 'open') {
591
+
592
+ // Hack for chrome to force animation rebind on each open phase
593
+ const isBlink =
594
+ CSS.supports('selector(:has(*))') &&
595
+ 'chrome' in globalThis &&
596
+ !('safari' in globalThis);
597
+ if (isBlink) {
598
+ this.style.animation = 'none';
599
+ this.offsetHeight; // force style + layout flush
600
+ this.style.animation = '';
601
+ }
602
+
581
603
  this.#bindDimensionsWorker();
582
- this.bindMinmaxWorker();
604
+ this._bindMinmaxWorker();
583
605
 
584
- if (!this.delegatesFocus
606
+ if (!this.delegatesFocus && this.autoFocus
585
607
  && !this.querySelector('[autofocus]')) {
586
608
  this.shadowRoot.querySelector('[autofocus]')?.focus();
587
609
  }
@@ -605,7 +627,7 @@ export class ModalElement extends BaseElement {
605
627
  <div class="header-box" part="header-box">
606
628
  <slot
607
629
  name="header-box"
608
- onslotchange="this.classList.toggle('has-slotted', !!this.assignedElements().length); this.closest('.view').style.setProperty('--header-box-height', this.closest('.header-box').offsetHeight + 'px');"
630
+ onslotchange="this.classList.toggle('has-slotted', !!this.assignedElements().length); this.getRootNode().host._calcHeaderDimensions();"
609
631
  >${this.headerBoxHTML}</slot>
610
632
  </div>
611
633
 
@@ -618,7 +640,7 @@ export class ModalElement extends BaseElement {
618
640
  <div class="_content" style="flex-grow: 1">
619
641
  <slot
620
642
  name="header"
621
- onslotchange="this.closest('.view').style.setProperty('--header-max-height', this.closest('header').offsetHeight + 'px');"
643
+ onslotchange="this.getRootNode().host._calcHeaderDimensions();"
622
644
  >${this.headerHTML}</slot>
623
645
  </div>
624
646
  </div>
@@ -630,7 +652,7 @@ export class ModalElement extends BaseElement {
630
652
  ${this.headerExtendedHTML || `
631
653
  <slot
632
654
  name="header-extended"
633
- onslotchange="this.closest('.view').style.setProperty('--header-max-height', this.closest('header').offsetHeight + 'px');"
655
+ onslotchange="this.getRootNode().host._calcHeaderDimensions();"
634
656
  ></slot>`}
635
657
 
636
658
  </header>
@@ -645,14 +667,15 @@ export class ModalElement extends BaseElement {
645
667
  </div>
646
668
  </div>
647
669
 
648
- ${this.mainHTML || `<div class="main" part="main">${this.contentHTML || `<slot></slot>`
649
- }</div>`}
670
+ ${this.mainHTML || `<div class="main" part="main">${this.contentHTML || `
671
+ <slot onslotchange="this.getRootNode().host._calcScrollability();"></slot>`
672
+ }</div>`}
650
673
 
651
674
  <footer part="footer">
652
675
  <div class="footer-bar" part="footer-bar">
653
676
  <slot
654
677
  name="footer"
655
- onslotchange="this.classList.toggle('has-slotted', !!this.assignedElements().length); this.closest('.view').style.setProperty('--footer-max-height', this.closest('footer').offsetHeight + 'px');"
678
+ onslotchange="this.classList.toggle('has-slotted', !!this.assignedElements().length); this.getRootNode().host._calcFooterDimensions();"
656
679
  >${this.footerHTML}</slot>
657
680
  </div>
658
681
  </footer>
@@ -662,47 +685,30 @@ export class ModalElement extends BaseElement {
662
685
  <span class="spacing-b"></span>
663
686
 
664
687
  <style>
688
+ /*
689
+ * Start: resets
690
+ */
691
+
665
692
  * {
666
693
  box-sizing: border-box;
667
694
  }
668
695
 
669
- @keyframes untransform {
670
- to { transform: none; }
671
- }
672
-
673
- @keyframes transform-n {
674
- to { transform: var(--transform); }
675
- }
676
-
677
- @keyframes appear {
678
- from { opacity: 0; }
679
- to { opacity: 1; }
680
- }
681
-
682
- @keyframes disappear {
683
- from { opacity: 1; }
684
- to { opacity: 0; }
685
- }
686
-
687
- @keyframes header-chrome {
688
- from { background: var(--header-open-background); }
689
- to { background: var(--header-background); }
690
- }
691
-
692
- @keyframes move-scrollbar-thumb {
693
- from { transform: var(--scrollbar-thumb-start); }
694
- to { transform: var(--scrollbar-thumb-length); }
695
- }
696
-
697
- @keyframes radius0 {
698
- to { --wq-radius: 0; }
699
- }
696
+ /*
697
+ * End: resets
698
+ * Start: general vars
699
+ */
700
700
 
701
701
  :host {
702
- --wq-radius: var(--modal-radius, 1rem);
703
702
  --aero-blur: var(--modal-aero-blur, 10px);
703
+ --backdrop-filter: var(--modal-backdrop-filter, blur(3px));
704
+
705
+ --radius-length: var(--modal-radius, 1rem);
706
+
704
707
  --background: var(--modal-background, rgba(80, 80, 80, 1));
705
708
 
709
+ --background-accent: var(--modal-background-accent, var(--background));
710
+ --color-accent: var(--modal-color-accent, var(--color-default));
711
+
706
712
  --color-default: var(--modal-color-default, whitesmoke);
707
713
  --color-info: var(--modal-color-info, whitesmoke);
708
714
  --color-success: var(--modal-color-success, whitesmoke);
@@ -723,6 +729,8 @@ export class ModalElement extends BaseElement {
723
729
  --footer-color-error: var(--modal-footer-color-error, coral);
724
730
  --footer-background: var(--modal-footer-background, var(--background));
725
731
 
732
+ --close-button-color: var(--modal-close-button-color, var(--color-default));
733
+
726
734
  --expanse-length: var(--modal-expanse-length, 0px);
727
735
  --minmax-length: var(--modal-minmax-length, 0px);
728
736
 
@@ -730,163 +738,515 @@ export class ModalElement extends BaseElement {
730
738
  --scrollbar-thumb-width: var(--modal-scrollbar-thumb-width, 4px);
731
739
  --scrollbar-thumb-height: var(--modal-scrollbar-thumb-height, 30px);
732
740
 
733
- --translation: calc(var(--modal-translation, 50px) * var(--dir));
734
- --exit-factor: var(--modal-exit-factor, -1);
741
+ --entry-exit-translation: calc(var(--modal-translation, 50px) * var(--entry-translation-polarity));
742
+ --exit-translation-polarity: var(--modal-exit-translation-polarity, -1);
743
+
744
+ /* -------- box lengths -------- */
745
+
746
+ --header-max-height: 1.6rem;
747
+ --header-box-height: 0px;
748
+ --footer-max-height: 0px;
749
+
750
+ --header-min-height: calc(var(--header-max-height) - var(--header-box-height));
751
+ --footer-min-height: var(--footer-max-height);
752
+
753
+ --view-inner-height: calc(var(--view-height) - var(--header-min-height) - var(--footer-min-height));
754
+
755
+ --total-minmax-length: calc(var(--minmax-length) + var(--swipe-dismiss-length, 0));
756
+ }
757
+
758
+ :host(._container:not(._horz)) {
759
+ --view-height: calc(100cqh - var(--expanse-length));
760
+ --view-width: 100cqw;
761
+ }
762
+
763
+ :host(._container._horz) {
764
+ --view-height: 100cqh;
765
+ --view-width: calc(100cqw - var(--expanse-length));
735
766
  }
736
767
 
737
- /* -------- internal, dynamic props (root) -------- */
768
+ /*
769
+ * End: general vars
770
+ * Start: entry/exit transition
771
+ */
738
772
 
773
+ :host { --entry-translation-polarity: var(--modal-entry-translation-polarity, 1); }
774
+ :host(:is(._top, ._left)) { --entry-translation-polarity: var(--modal-entry-translation-polarity, -1); }
775
+ :host(._edge-tight) { --exit-translation-polarity: var(--modal-exit-translation-polarity, 1); }
776
+ :host(:not([popover="manual"], ._manual-dismiss):popover-open) { --backdrop-filter: blur(0px); }
777
+
739
778
  :host {
740
- --dir: 1;
741
- --entry-transform: translateY(var(--translation));
742
- --exit-transform: translateY(calc(var(--translation) * var(--exit-factor)));
779
+ --entry-transform: translateY(var(--entry-exit-translation));
780
+ --exit-transform: translateY(calc(var(--entry-exit-translation) * var(--exit-translation-polarity)));
743
781
  }
744
782
 
745
- :host(._swipe-dismiss) .view {
746
- --swipe-dismiss-length: var(--modal-swipe-dismiss-length, calc(var(--view-height) - var(--minmax-length)));
783
+ :host(:is(._left, ._right, ._horz)) {
784
+ --entry-transform: translateX(var(--entry-exit-translation));
785
+ --exit-transform: translateX(calc(var(--entry-exit-translation) * var(--exit-translation-polarity)));
747
786
  }
748
787
 
749
- :host(._horz._swipe-dismiss) .view {
750
- --swipe-dismiss-length: var(--modal-swipe-dismiss-length, calc(var(--view-width) - var(--minmax-length)));
788
+ /* ----------- */
789
+
790
+ :host {
791
+ transition:
792
+ opacity 0.2s,
793
+ transform 0.2s,
794
+ overlay 0.2s allow-discrete,
795
+ display 0.2s allow-discrete;
796
+ transition-timing-function: ease-out;
797
+
798
+ transform: var(--exit-transform);
799
+ opacity: 0;
751
800
  }
752
-
753
- /* transform reversal */
754
801
 
755
- :host(:is(._top, ._left)) { --dir: -1; }
802
+ :host(:popover-open) {
803
+ display: flex;
804
+ opacity: 1;
805
+ transform: none;
806
+ }
756
807
 
757
- /* horizontal axis */
808
+ @starting-style {
809
+ :host(:popover-open) {
810
+ opacity: 0;
811
+ transform: var(--entry-transform);
812
+ }
813
+ }
758
814
 
759
- :host(:is(._left, ._right, ._horz)) {
760
- --entry-transform: translateX(var(--translation));
761
- --exit-transform: translateX(calc(var(--translation) * var(--exit-factor)));
815
+ /* ----------- */
816
+
817
+ :host::backdrop {
818
+ transition:
819
+ display 0.2s allow-discrete,
820
+ overlay 0.2s allow-discrete,
821
+ backdrop-filter 0.2s,
822
+ background 0.2s;
762
823
  }
763
824
 
764
- :host(._edge-tight) { --exit-factor: var(--modal-exit-factor, 1); }
825
+ :host(:popover-open)::backdrop {
826
+ backdrop-filter: var(--backdrop-filter);
827
+ }
765
828
 
766
- /* -------- internal, dynamic props (view) -------- */
829
+ @starting-style {
830
+ :host(:popover-open)::backdrop {
831
+ backdrop-filter: none;
832
+ background: none;
833
+ }
834
+ }
767
835
 
768
- .view {
769
- --header-max-height: 1.6rem;
770
- --header-box-height: 0px;
771
- --footer-max-height: 0px;
836
+ :host(:not([popover="manual"], ._manual-dismiss):popover-open)::backdrop {
837
+ backdrop-filter: blur(0px);
838
+ }
772
839
 
773
- --header-min-height: calc(var(--header-max-height) - var(--header-box-height));
774
- --footer-min-height: var(--footer-max-height);
840
+ /*
841
+ * End: entry/exit transition
842
+ * Start: scroll-driven animations
843
+ */
775
844
 
776
- --view-inner-height: calc(var(--view-height) - var(--header-min-height) - var(--footer-min-height));
777
- --total-minmax-length: var(--minmax-length);
845
+ @keyframes radius-progress {
846
+ from { --wq-internal-var-radius-progress: 0; }
847
+ to { --wq-internal-var-radius-progress: 1; }
848
+ }
849
+
850
+ @keyframes header-box-progress {
851
+ from { --wq-internal-var-header-box-progress: 0; }
852
+ to { --wq-internal-var-header-box-progress: 1; }
853
+ }
854
+
855
+ @keyframes header-box-progress-a {
856
+ from { --wq-internal-var-header-box-progress-a: 0; }
857
+ to { --wq-internal-var-header-box-progress-a: 1; }
858
+ }
859
+
860
+ @keyframes header-box-progress-b {
861
+ from { --wq-internal-var-header-box-progress-b: 0; }
862
+ to { --wq-internal-var-header-box-progress-b: 1; }
863
+ }
864
+
865
+ @keyframes minmax-progress {
866
+ from { --wq-internal-var-minmax-progress: 0; }
867
+ to { --wq-internal-var-minmax-progress: 1; }
868
+ }
869
+
870
+ @keyframes minmax-progress-a {
871
+ from { --wq-internal-var-minmax-progress-a: 0; }
872
+ to { --wq-internal-var-minmax-progress-a: 1; }
873
+ }
874
+
875
+ @keyframes minmax-progress-b {
876
+ from { --wq-internal-var-minmax-progress-b: 0; }
877
+ to { --wq-internal-var-minmax-progress-b: 1; }
878
+ }
879
+
880
+ @keyframes total-minmax-progress {
881
+ from { --wq-internal-var-total-minmax-progress: 0; }
882
+ to { --wq-internal-var-total-minmax-progress: 1; }
883
+ }
884
+
885
+ @keyframes swipe-dismiss-progress {
886
+ from { --wq-internal-var-swipe-dismiss-progress: 0; }
887
+ to { --wq-internal-var-swipe-dismiss-progress: 1; }
888
+ }
889
+
890
+ @keyframes scrollbar-appear-progress {
891
+ from { --wq-internal-var-scrollbar-appear-progress: 0; }
892
+ to { --wq-internal-var-scrollbar-appear-progress: 1; }
893
+ }
894
+
895
+ @keyframes scrollbar-progress {
896
+ from { --wq-internal-var-scrollbar-progress: 0; }
897
+ to { --wq-internal-var-scrollbar-progress: 1; }
898
+ }
899
+
900
+ @keyframes scrollbar-progress-a {
901
+ from { --wq-internal-var-scrollbar-progress-a: 0; }
902
+ to { --wq-internal-var-scrollbar-progress-a: 1; }
903
+ }
904
+
905
+ @keyframes scrollbar-progress-b {
906
+ from { --wq-internal-var-scrollbar-progress-b: 0; }
907
+ to { --wq-internal-var-scrollbar-progress-b: 1; }
908
+ }
909
+
910
+ :host {
911
+ timeline-scope: --view-scroll;
912
+ animation-timeline: --view-scroll;
913
+
914
+ animation-timing-function: linear;
915
+ animation-fill-mode: both;
778
916
 
779
- --y-scroll-effect-exclude: var(--total-minmax-length);
780
- --scrollbar-appear-range: calc(var(--total-minmax-length) - 25px) var(--total-minmax-length);
917
+ animation-name:
918
+ radius-progress,
919
+ header-box-progress,
920
+ header-box-progress-a,
921
+ header-box-progress-b,
922
+ minmax-progress,
923
+ minmax-progress-a,
924
+ minmax-progress-b,
925
+ total-minmax-progress,
926
+ swipe-dismiss-progress,
927
+ scrollbar-appear-progress,
928
+ scrollbar-progress,
929
+ scrollbar-progress-a,
930
+ scrollbar-progress-b;
931
+
932
+ animation-range:
933
+ var(--radius-progress-range, 0 0),
934
+ var(--header-box-progress-range, 0 0),
935
+ var(--header-box-progress-range-a, 0 0),
936
+ var(--header-box-progress-range-b, 0 0),
937
+ var(--minmax-progress-range, 0 0),
938
+ var(--minmax-progress-range-a, 0 0),
939
+ var(--minmax-progress-range-b, 0 0),
940
+ var(--total-minmax-progress-range, 0 0),
941
+ var(--swipe-dismiss-progress-range, 0 0),
942
+ var(--scrollbar-appear-range, 0 0),
943
+ var(--scrollbar-progress-range, 0 0),
944
+ var(--scrollbar-progress-range-a, 0 0),
945
+ var(--scrollbar-progress-range-b, 0 0);
946
+
947
+ animation-direction:
948
+ var(--radius-progress-direction, normal),
949
+ var(--header-box-progress-direction, normal),
950
+ var(--header-box-progress-direction-a, normal),
951
+ var(--header-box-progress-direction-b, normal),
952
+ var(--minmax-progress-direction, normal),
953
+ var(--minmax-progress-direction-a, normal),
954
+ var(--minmax-progress-direction-b, normal),
955
+ var(--total-minmax-progress-direction, normal),
956
+ var(--swipe-dismiss-progress-direction, normal),
957
+ var(--scrollbar-appear-direction, normal),
958
+ var(--scrollbar-progress-direction, normal),
959
+ var(--scrollbar-progress-direction-a, normal),
960
+ var(--scrollbar-progress-direction-b, normal);
961
+ }
962
+
963
+ /* ----------- radius ----------- */
964
+
965
+ :host(._edge-tight._alt-edge-tight:not(._top:not(._horz), ._left._horz)) {
966
+ --radius-progress-range:
967
+ calc(var(--total-minmax-length) - var(--radius-length))
968
+ var(--total-minmax-length);
969
+ }
970
+
971
+ :host(._edge-tight._alt-edge-tight:is(._top:not(._horz), ._left._horz)) {
972
+ --radius-progress-range:
973
+ calc(100% - var(--total-minmax-length))
974
+ calc(100% - (var(--total-minmax-length) - var(--radius-length)));
975
+ --radius-progress-direction: reverse;
976
+ }
977
+
978
+ :host(._edge-tight._alt-edge-tight) {
979
+ --effective-radius: calc(var(--radius-length) * (1 - var(--wq-internal-var-radius-progress)));
980
+ }
981
+
982
+ :host(:not(._edge-tight._alt-edge-tight)) {
983
+ --effective-radius: var(--radius-length);
984
+ }
985
+
986
+ :host {
987
+ --effective-top-left-radius: var(--effective-radius);
988
+ --effective-top-right-radius: var(--effective-radius);
989
+ --effective-bottom-left-radius: var(--effective-radius);
990
+ --effective-bottom-right-radius: var(--effective-radius);
991
+ }
992
+
993
+ :host(._top._edge-tight) {
994
+ --effective-top-left-radius: 0px;
995
+ --effective-top-right-radius: 0px;
996
+ }
997
+
998
+ :host(._bottom._edge-tight) {
999
+ --effective-bottom-left-radius: 0px;
1000
+ --effective-bottom-right-radius: 0px;
1001
+ }
1002
+
1003
+ :host(._left._edge-tight) {
1004
+ --effective-top-left-radius: 0px;
1005
+ --effective-bottom-left-radius: 0px;
1006
+ }
1007
+
1008
+ :host(._right._edge-tight) {
1009
+ --effective-top-right-radius: 0px;
1010
+ --effective-bottom-right-radius: 0px;
1011
+ }
1012
+
1013
+ .view {
1014
+ border-top-left-radius: var(--effective-top-left-radius);
1015
+ border-top-right-radius: var(--effective-top-right-radius);
1016
+ border-bottom-left-radius: var(--effective-bottom-left-radius);
1017
+ border-bottom-right-radius: var(--effective-bottom-right-radius);
1018
+ }
1019
+
1020
+ header {
1021
+ border-top-left-radius: var(--effective-top-left-radius);
1022
+ border-top-right-radius: var(--effective-top-right-radius);
1023
+ }
1024
+
1025
+ .view:not(:has(footer slot:is(.has-slotted, :not(:empty)))) .main {
1026
+ border-bottom-left-radius: var(--effective-bottom-left-radius);
1027
+ border-bottom-right-radius: var(--effective-bottom-right-radius);
1028
+ }
1029
+
1030
+ footer {
1031
+ border-bottom-left-radius: var(--effective-bottom-left-radius);
1032
+ border-bottom-right-radius: var(--effective-bottom-right-radius);
1033
+ }
1034
+
1035
+ /* ----------- minmax ----------- */
1036
+
1037
+ :host {
1038
+ --minmax-progress-range: var(--minmax-progress-range-start) var(--minmax-progress-range-end);
1039
+ --minmax-progress-range-start: 0%;
1040
+ --minmax-progress-range-end: var(--minmax-length);
1041
+
1042
+ --minmax-progress-range-a: var(--minmax-progress-range-a-start) var(--minmax-progress-range-a-end);
1043
+ --minmax-progress-range-a-start: var(--minmax-progress-range-start);
1044
+ --minmax-progress-range-a-end: calc(var(--minmax-progress-range-start) + (var(--minmax-progress-range-end) - var(--minmax-progress-range-start)) / 2);
1045
+
1046
+ --minmax-progress-range-b: var(--minmax-progress-range-b-start) var(--minmax-progress-range-b-end);
1047
+ --minmax-progress-range-b-start: calc(var(--minmax-progress-range-start) + (var(--minmax-progress-range-end) - var(--minmax-progress-range-start)) / 2);
1048
+ --minmax-progress-range-b-end: var(--minmax-progress-range-end);
1049
+
1050
+ --total-minmax-progress-range: var(--total-minmax-progress-range-start) var(--total-minmax-progress-range-end);
1051
+ --total-minmax-progress-range-start: 0%;
1052
+ --total-minmax-progress-range-end: var(--total-minmax-length);
1053
+ }
781
1054
 
782
- --scrollbar-progress-range-start: calc(var(--total-minmax-length) + var(--header-box-height));
783
- --scrollbar-progress-range-end: 100%;
784
- --scrollbar-progress-range: var(--scrollbar-progress-range-start) var(--scrollbar-progress-range-end);
1055
+ :host(:is(._top:not(._horz), ._left._horz)) {
1056
+ --minmax-progress-range-start: calc(100% - var(--minmax-length));
1057
+ --minmax-progress-range-end: 100%;
785
1058
 
786
- --scroll-snap-start: start;
787
- --scroll-snap-end: end;
1059
+ --total-minmax-progress-range-start: calc(100% - var(--total-minmax-length));
1060
+ --total-minmax-progress-range-end: 100%;
1061
+ }
788
1062
 
789
- --radius-top-left: var(--wq-radius);
790
- --radius-top-right: var(--wq-radius);
791
- --radius-bottom-left: var(--wq-radius);
792
- --radius-bottom-right: var(--wq-radius);
1063
+ :host {
1064
+ --effective-minmax-balance-offset: calc(var(--total-minmax-length) / -2 * (1 - var(--wq-internal-var-total-minmax-progress)));
793
1065
  }
794
1066
 
795
- :host(._container) .view {
796
- --view-height: calc(100cqh - var(--expanse-length));
797
- --view-width: 100cqw;
1067
+ :host(:not(._horz, ._top, ._bottom)) .view {
1068
+ transform: translateY(var(--effective-minmax-balance-offset));
798
1069
  }
799
1070
 
800
- :host(._container._horz) .view {
801
- --view-height: 100cqh;
802
- --view-width: calc(100cqw - var(--expanse-length));
1071
+ :host(._horz:not(._left, ._right)) .view {
1072
+ transform: translateX(var(--effective-minmax-balance-offset));
803
1073
  }
804
1074
 
805
- :host(._swipe-dismiss:not(._horz)) .view {
806
- --total-minmax-length: var(--view-height);
1075
+ /* ----------- swipe-dismiss ----------- */
1076
+
1077
+ :host(:not(._horz)) {
1078
+ --swipe-dismiss-length: var(--modal-swipe-dismiss-length, calc(var(--view-height) - var(--minmax-length)));
807
1079
  }
808
1080
 
809
- :host(._swipe-dismiss._horz) .view {
810
- --total-minmax-length: var(--view-width);
1081
+ :host(._horz) {
1082
+ --swipe-dismiss-length: var(--modal-swipe-dismiss-length, calc(var(--view-width) - var(--minmax-length)));
811
1083
  }
812
1084
 
813
- /* transform reversal */
1085
+ :host(:not(._top:not(._horz), ._left._horz)) {
1086
+ --swipe-dismiss-progress-range: 0% var(--swipe-dismiss-length);
1087
+ }
814
1088
 
815
- :host(:is(._top:not(._horz), ._left._horz)) .view {
816
- --scroll-snap-start: end;
817
- --scroll-snap-end: start;
1089
+ :host(:is(._top:not(._horz), ._left._horz)) {
1090
+ --swipe-dismiss-progress-range:
1091
+ calc(100% - var(--swipe-dismiss-length))
1092
+ 100%;
1093
+ --swipe-dismiss-progress-direction: reverse;
1094
+ }
818
1095
 
819
- --y-scroll-effect-exclude: 0px;
820
- --scrollbar-appear-range: -25px 0;
1096
+ :host(._swipe-dismiss) {
1097
+ --effective-swipe-dismiss-opacity: calc(1 * var(--wq-internal-var-swipe-dismiss-progress));
821
1098
  }
822
1099
 
823
- :host(._top:not(._horz)) .view {
1100
+ :host(._swipe-dismiss)::backdrop,
1101
+ :host(._swipe-dismiss._swipe-dismiss-fadeout) .view {
1102
+ opacity: var(--effective-swipe-dismiss-opacity);
1103
+ }
1104
+
1105
+ /* ----------- header-box ----------- */
1106
+
1107
+ :host(:not(._horz)) {
1108
+ --header-box-progress-range:
1109
+ var(--total-minmax-length)
1110
+ calc(var(--total-minmax-length) + var(--header-box-height));
1111
+
1112
+ --header-box-progress-range-a:
1113
+ var(--total-minmax-length)
1114
+ calc(var(--total-minmax-length) + (var(--header-box-height) / 2));
1115
+
1116
+ --header-box-progress-range-b:
1117
+ calc(var(--total-minmax-length) + (var(--header-box-height) / 2))
1118
+ calc(var(--total-minmax-length) + var(--header-box-height));
1119
+
1120
+ --effective-header-box-progress-transform: translateY(calc(35% * var(--wq-internal-var-header-box-progress-a)));
1121
+ --effective-header-box-progress-a-opacity: calc(1 * (1 - var(--wq-internal-var-header-box-progress-a)));
1122
+ --effective-header-box-progress-b-opacity: calc(1 * var(--wq-internal-var-header-box-progress-b));
1123
+
1124
+ .header-box {
1125
+ transform: var(--effective-header-box-progress-transform);
1126
+ opacity: var(--effective-header-box-progress-a-opacity);
1127
+ }
1128
+
1129
+ .header-left {
1130
+ opacity: var(--effective-header-box-progress-b-opacity);
1131
+ }
1132
+ }
1133
+
1134
+ /* ----------- scrollbars and scroll-unfold ----------- */
1135
+
1136
+ :host(:is(._scrollbars, ._scroll-unfold, ._horz)) {
1137
+ --scrollable-length: calc(var(--view-scroll-width) - var(--total-minmax-length) - var(--view-width));
1138
+ }
1139
+
1140
+ :host(:is(._scrollbars, ._scroll-unfold):not(._horz)) {
1141
+ --scrollable-length: calc(var(--view-scroll-height) - var(--total-minmax-length) - var(--header-box-height) - var(--view-height));
1142
+ }
1143
+
1144
+ :host(:is(._scrollbars, ._scroll-unfold)) {
1145
+ --scrollability: calc(1 * min(1, calc(var(--scrollable-length) / 1px)));
1146
+ }
1147
+
1148
+ :host {
1149
+ --scrollbar-appear-range: var(--scrollbar-appear-range-start) var(--scrollbar-appear-range-end);
1150
+ --scrollbar-appear-range-start: calc(var(--total-minmax-length) - 25px);
1151
+ --scrollbar-appear-range-end: var(--total-minmax-length);
1152
+
1153
+ --scrollbar-progress-range: var(--scrollbar-progress-range-start) var(--scrollbar-progress-range-end);
1154
+ --scrollbar-progress-range-start: var(--total-minmax-length);
1155
+ --scrollbar-progress-range-end: 100%;
1156
+
1157
+ --scrollbar-progress-range-a: var(--scrollbar-progress-range-a-start) var(--scrollbar-progress-range-a-end);
1158
+ --scrollbar-progress-range-a-start: var(--scrollbar-progress-range-start);
1159
+ --scrollbar-progress-range-a-end: calc(var(--scrollbar-progress-range-start) + (var(--scrollbar-progress-range-end) - var(--scrollbar-progress-range-start)) / 2);
1160
+
1161
+ --scrollbar-progress-range-b: var(--scrollbar-progress-range-b-start) var(--scrollbar-progress-range-b-end);
1162
+ --scrollbar-progress-range-b-start: calc(var(--scrollbar-progress-range-start) + (var(--scrollbar-progress-range-end) - var(--scrollbar-progress-range-start)) / 2);
1163
+ --scrollbar-progress-range-b-end: var(--scrollbar-progress-range-end);
1164
+ }
1165
+
1166
+ :host(:not(._horz)) {
1167
+ --scrollbar-progress-range-start: calc(var(--total-minmax-length) + var(--header-box-height));
1168
+ }
1169
+
1170
+ :host(._top:not(._horz)) {
1171
+ --scrollbar-appear-range-start: -25px;
1172
+ --scrollbar-appear-range-end: 0%;
1173
+
824
1174
  --scrollbar-progress-range-start: var(--header-box-height);
825
1175
  --scrollbar-progress-range-end: calc(100% - var(--total-minmax-length));
826
1176
  }
827
1177
 
828
- :host(._left._horz) .view {
829
- --scrollbar-progress-range-start: 0;
1178
+ :host(._left._horz) {
1179
+ --scrollbar-appear-range-start: -25px;
1180
+ --scrollbar-appear-range-end: 0%;
1181
+
1182
+ --scrollbar-progress-range-start: 0%;
830
1183
  --scrollbar-progress-range-end: calc(100% - var(--total-minmax-length));
831
1184
  }
832
1185
 
833
- /* curves */
1186
+ :host(._scrollbars) {
1187
+ --effective-scrollbar-appear-opacity: calc(1 * var(--wq-internal-var-scrollbar-appear-progress));
834
1188
 
835
- :host(._top._edge-tight) .view {
836
- --radius-top-left: 0px;
837
- --radius-top-right: 0px;
1189
+ .scrollbar-track {
1190
+ opacity: calc(var(--effective-scrollbar-appear-opacity) * var(--scrollability));
1191
+ }
838
1192
  }
839
1193
 
840
- :host(._bottom._edge-tight) .view {
841
- --radius-bottom-left: 0px;
842
- --radius-bottom-right: 0px;
843
- }
1194
+ :host(._scrollbars:not(._horz)) {
1195
+ --effective-scrollbar-progress: calc((var(--view-inner-height) - 100%) * var(--wq-internal-var-scrollbar-progress));
844
1196
 
845
- :host(._left._edge-tight) .view {
846
- --radius-top-left: 0px;
847
- --radius-bottom-left: 0px;
1197
+ .scrollbar-thumb {
1198
+ transform: translateY(var(--effective-scrollbar-progress));
1199
+ }
848
1200
  }
849
1201
 
850
- :host(._right._edge-tight) .view {
851
- --radius-top-right: 0px;
852
- --radius-bottom-right: 0px;
1202
+ :host(._scrollbars._horz) {
1203
+ --effective-scrollbar-progress: calc((var(--view-width) - 100%) * var(--wq-internal-var-scrollbar-progress));
1204
+
1205
+ .scrollbar-thumb {
1206
+ transform: translateX(var(--effective-scrollbar-progress));
1207
+ }
853
1208
  }
854
1209
 
855
- /* --------- actual styling -------- */
1210
+ :host(._scroll-unfold) {
1211
+ --effective-scroll-unfold-a-opacity: calc(1 * var(--wq-internal-var-scrollbar-progress-b));
1212
+ --effective-scroll-unfold-b-opacity: calc(1 * (1 - var(--wq-internal-var-scrollbar-progress-a)));
1213
+ }
856
1214
 
857
- :host {
858
- background: none;
859
- border: none;
860
- padding: 0;
1215
+ :host(._scroll-unfold:is(._top:not(._horz), ._left._horz)) {
1216
+ .scroll-fold-start {
1217
+ opacity: var(--effective-scroll-unfold-a-opacity);
1218
+ }
861
1219
 
862
- max-height: 100vh;
863
- max-width: 100vw;
864
-
865
- /* Transition */
866
- transition:
867
- opacity 0.2s,
868
- transform 0.2s,
869
- overlay 0.2s allow-discrete,
870
- display 0.2s allow-discrete;
871
- transition-timing-function: ease-out;
872
-
873
- /* Exit state */
874
- transform: var(--exit-transform);
875
- opacity: 0;
1220
+ .scroll-fold-end {
1221
+ opacity: calc(var(--effective-scroll-unfold-b-opacity) * var(--scrollability));
1222
+ }
876
1223
  }
877
-
878
- :host(:not(._horz, ._left, ._right, ._top, ._bottom)) {
879
- max-width: 800px;
1224
+
1225
+ :host(._scroll-unfold:not(._top:not(._horz), ._left._horz)) {
1226
+ .scroll-fold-start {
1227
+ opacity: calc(var(--effective-scroll-unfold-a-opacity) * var(--scrollability));
1228
+ }
1229
+
1230
+ .scroll-fold-end {
1231
+ opacity: var(--effective-scroll-unfold-b-opacity);
1232
+ }
880
1233
  }
881
1234
 
882
- /* edge alignment */
1235
+ /*
1236
+ * End: scroll-driven animations
1237
+ * Start: actual styling
1238
+ */
1239
+
1240
+ /* ----------- anchoring, direction, ordering ----------- */
1241
+
1242
+ /* anchoring */
883
1243
 
884
1244
  :host(._top) { margin-top: 0; }
885
1245
  :host(._bottom) { margin-bottom: 0; }
886
1246
  :host(._left) { margin-left: 0; }
887
1247
  :host(._right) { margin-right: 0; }
888
1248
 
889
- /* flex orientation */
1249
+ /* direction */
890
1250
 
891
1251
  :host,
892
1252
  .view {
@@ -899,16 +1259,30 @@ export class ModalElement extends BaseElement {
899
1259
  flex-direction: row;
900
1260
  }
901
1261
 
902
- :host(:is(._top:not(._horz), ._left._horz)) .view,
903
- :host(:is(._top:not(._horz), ._left._horz)) .view .container {
904
- order: -1;
905
- }
1262
+ /* ordering */
906
1263
 
907
- :host(:is(._top:not(._horz), ._left._horz)) .view .sentinel {
908
- order: 1000;
1264
+ header { order: 1; }
1265
+ .scrollport-anchor { order: 2; justify-content: start; }
1266
+ .main { order: 3; }
1267
+ footer { order: 5; }
1268
+
1269
+ :host(:is(._top:not(._horz), ._left._horz)) {
1270
+ .view,
1271
+ .container {
1272
+ order: -1;
1273
+ }
1274
+
1275
+ .sentinel {
1276
+ order: 1000;
1277
+ }
1278
+
1279
+ .scrollport-anchor {
1280
+ order: 4;
1281
+ justify-content: end;
1282
+ }
909
1283
  }
910
1284
 
911
- /* spacing */
1285
+ /* ----------- spacing ----------- */
912
1286
 
913
1287
  :host>.spacing,
914
1288
  .view>.spacing,
@@ -935,54 +1309,82 @@ export class ModalElement extends BaseElement {
935
1309
 
936
1310
  :host(:not(._horz)) .view>.sentinel { height: var(--swipe-dismiss-length); }
937
1311
  :host(._horz) .view>.sentinel { width: var(--swipe-dismiss-length); }
1312
+
1313
+ /* ----------- scroll-snapping ----------- */
938
1314
 
939
- /* ----------- */
1315
+ :host(:not(._top:not(._horz), ._left._horz)) .view {
1316
+ --scroll-snap-start: start;
1317
+ --scroll-snap-end: end;
1318
+ }
940
1319
 
941
- .view {
942
- position: relative;
943
- flex-grow: 1;
944
- display: flex;
1320
+ :host(:is(._top:not(._horz), ._left._horz)) .view {
1321
+ --scroll-snap-start: end;
1322
+ --scroll-snap-end: start;
1323
+ }
945
1324
 
946
- pointer-events: none;
1325
+ :host(:not(._horz)) .view {
1326
+ scroll-snap-type: y mandatory;
1327
+ }
947
1328
 
948
- overflow-y: auto;
949
- scrollbar-width: none;
1329
+ :host(._horz) .view {
1330
+ scroll-snap-type: x mandatory;
1331
+ }
950
1332
 
951
- border-top-left-radius: var(--radius-top-left);
952
- border-top-right-radius: var(--radius-top-right);
953
- border-bottom-left-radius: var(--radius-bottom-left);
954
- border-bottom-right-radius: var(--radius-bottom-right);
1333
+ .view>.spacing,
1334
+ .view>.sentinel {
1335
+ scroll-snap-align: var(--scroll-snap-start);
1336
+ }
955
1337
 
956
- scroll-timeline-name: --view-scroll;
1338
+ .main {
1339
+ scroll-margin-top: var(--header-min-height);
1340
+ scroll-margin-bottom: var(--footer-min-height);
1341
+ scroll-snap-align: var(--scroll-snap-start);
1342
+ }
957
1343
 
958
- animation-timing-function: linear;
959
- animation-fill-mode: forwards;
960
- animation-name: untransform;
961
- animation-timeline: --view-scroll;
1344
+ :host(:is(._top, ._left._horz)) .main {
1345
+ scroll-snap-align: none;
1346
+ }
962
1347
 
963
- animation-range: 0 var(--total-minmax-length);
1348
+ :host(:is(._top, ._left._horz)) .container {
1349
+ scroll-snap-align: var(--scroll-snap-start);
964
1350
  }
965
1351
 
966
- :host(:not(._horz, ._top, ._bottom, ._edge-tight._alt-edge-tight)) .view {
967
- transform: translateY(calc(var(--total-minmax-length) / -2));
1352
+ header {
1353
+ scroll-snap-align: start;
968
1354
  }
969
1355
 
970
- :host(._horz:not(._left, ._right, ._edge-tight._alt-edge-tight)) .view {
971
- transform: translateX(calc(var(--total-minmax-length) / -2));
1356
+ .header-bar {
1357
+ scroll-snap-align: start;
972
1358
  }
973
1359
 
974
- :host(._edge-tight._alt-edge-tight) .view {
975
- animation-timing-function: linear;
976
- animation-fill-mode: both;
977
- animation-name: radius0;
978
- animation-timeline: --view-scroll;
1360
+ /* ----------- elements ----------- */
979
1361
 
980
- animation-range: calc(var(--total-minmax-length) - var(--wq-radius)) var(--total-minmax-length);
1362
+ :host {
1363
+ background: none;
1364
+ border: none;
1365
+ padding: 0;
1366
+
1367
+ max-height: 100vh;
1368
+ max-width: 100vw;
981
1369
  }
1370
+
1371
+ :host(:not(._horz, ._left, ._right, ._top, ._bottom)) {
1372
+ max-width: 800px;
1373
+ }
1374
+
1375
+ /* view */
1376
+
1377
+ .view {
1378
+ position: relative;
1379
+ flex-grow: 1;
1380
+ display: flex;
982
1381
 
983
- :host(._edge-tight._alt-edge-tight:is(._top:not(._horz), ._left._horz)) .view {
984
- animation-direction: reverse;
985
- animation-range: calc(100% - var(--total-minmax-length)) calc(100% - (var(--total-minmax-length) - var(--wq-radius)));
1382
+ pointer-events: none;
1383
+
1384
+ scroll-timeline-name: --view-scroll;
1385
+
1386
+ overflow-y: auto;
1387
+ scrollbar-width: none;
986
1388
  }
987
1389
 
988
1390
  :host(._horz) .view {
@@ -994,7 +1396,7 @@ export class ModalElement extends BaseElement {
994
1396
 
995
1397
  .view::-webkit-scrollbar { display: none; }
996
1398
 
997
- /* ----------- */
1399
+ /* container */
998
1400
 
999
1401
  .container {
1000
1402
  position: relative;
@@ -1006,25 +1408,20 @@ export class ModalElement extends BaseElement {
1006
1408
  flex-direction: column;
1007
1409
  }
1008
1410
 
1009
- :host(._swipe-dismiss-fadeout) .container {
1010
- animation-timing-function: linear;
1011
- animation-fill-mode: both;
1012
- animation-name: appear;
1013
- animation-timeline: --view-scroll;
1014
- animation-range: 0 var(--swipe-dismiss-length);
1015
- }
1411
+ /* main */
1412
+
1413
+ .main {
1414
+ flex-grow: 1;
1016
1415
 
1017
- :host(._swipe-dismiss-fadeout:is(._top:not(._horz), ._left._horz)) .container {
1018
- animation-name: disappear;
1019
- animation-range: calc(100% - var(--swipe-dismiss-length)) 100%;
1416
+ min-width: var(--view-width);
1417
+ min-height: var(--view-inner-height);
1020
1418
  }
1021
1419
 
1022
- /* ------------ */
1023
-
1420
+ /* header */
1421
+
1024
1422
  header {
1025
1423
  position: sticky;
1026
1424
  top: calc(var(--header-box-height) * -1);
1027
- z-index: 2;
1028
1425
 
1029
1426
  display: flex;
1030
1427
  flex-direction: column;
@@ -1032,38 +1429,15 @@ export class ModalElement extends BaseElement {
1032
1429
  color: var(--header-color-default);
1033
1430
  background: var(--header-background);
1034
1431
 
1035
- border-top-left-radius: var(--radius-top-left);
1036
- border-top-right-radius: var(--radius-top-right);
1037
-
1038
- order: 1;
1039
- }
1040
-
1041
- :host(:not(._horz)) header {
1042
- animation-timing-function: linear;
1043
- animation-fill-mode: both;
1044
- animation-name: header-chrome;
1045
- animation-timeline: --view-scroll;
1046
- animation-range: var(--y-scroll-effect-exclude) calc(var(--y-scroll-effect-exclude) + var(--header-box-height));
1432
+ z-index: 2;
1047
1433
  }
1048
1434
 
1049
- :host(._aero) :is(header, .main, footer) {
1050
- backdrop-filter: blur(var(--aero-blur));
1051
- }
1052
-
1053
1435
  .header-box {
1054
1436
  position: relative;
1055
1437
 
1056
1438
  display: flex;
1057
1439
  align-items: center;
1058
1440
  justify-content: center;
1059
-
1060
- --transform: translateY(35%);
1061
-
1062
- animation-timing-function: linear;
1063
- animation-fill-mode: forwards;
1064
- animation-name: disappear, transform-n;
1065
- animation-timeline: --view-scroll;
1066
- animation-range: var(--y-scroll-effect-exclude) calc(var(--y-scroll-effect-exclude) + (var(--header-box-height) / 2));
1067
1441
  }
1068
1442
 
1069
1443
  :host(._horz) .header-box {
@@ -1072,135 +1446,50 @@ export class ModalElement extends BaseElement {
1072
1446
 
1073
1447
  .header-bar {
1074
1448
  position: relative;
1075
- z-index: 1;
1076
1449
 
1077
1450
  display: flex;
1078
1451
  align-items: start;
1079
1452
  justify-content: space-between;
1080
- }
1081
-
1082
- .header-bar {
1083
1453
  gap: 0.6rem;
1454
+
1084
1455
  padding-block: 0.8rem;
1085
1456
  padding-inline: 1.2rem;
1457
+
1458
+ z-index: 1;
1086
1459
  }
1087
1460
 
1088
1461
  .header-left {
1089
1462
  display: flex;
1090
1463
  align-items: start;
1091
1464
  gap: 0.6rem;
1092
-
1093
- opacity: 0;
1094
-
1095
- animation-timing-function: linear;
1096
- animation-fill-mode: forwards;
1097
- animation-name: appear;
1098
- animation-timeline: --view-scroll;
1099
- animation-range: calc(var(--y-scroll-effect-exclude) + (var(--header-box-height) / 2)) calc(var(--y-scroll-effect-exclude) + var(--header-box-height));
1100
1465
  }
1101
1466
 
1102
1467
  :host(._horz) .header-left,
1103
1468
  header:not(:has(slot[name="header-box"]:is(.has-slotted, :not(:empty)))) .header-left {
1104
- opacity: 1;
1105
- }
1106
-
1107
- :host([type="info"]) header {
1108
- color: var(--header-color-info);
1109
- }
1110
-
1111
- :host([type="success"]) header {
1112
- color: var(--header-color-success);
1469
+ opacity: 1 !important;
1113
1470
  }
1114
1471
 
1115
- :host([type="error"]) header {
1116
- color: var(--header-color-error);
1117
- }
1118
-
1119
- /* ----------- */
1472
+ /* footer */
1120
1473
 
1121
1474
  footer {
1122
1475
  position: sticky;
1123
1476
  bottom: 0;
1124
- z-index: 1;
1125
-
1126
- border-bottom-left-radius: var(--radius-bottom-left);
1127
- border-bottom-right-radius: var(--radius-bottom-right);
1128
1477
 
1129
1478
  color: var(--footer-color-default);
1130
1479
  background: var(--footer-background);
1131
1480
 
1132
- order: 5;
1133
- }
1134
-
1135
- :host([type="info"]) footer {
1136
- color: var(--footer-color-info);
1137
- }
1138
-
1139
- :host([type="success"]) footer {
1140
- color: var(--footer-color-success);
1141
- }
1142
-
1143
- :host([type="error"]) footer {
1144
- color: var(--footer-color-error);
1481
+ z-index: 1;
1145
1482
  }
1146
-
1147
- /* ------------ */
1148
-
1483
+
1149
1484
  footer .footer-bar {
1150
- position: sticky;
1151
- left: 0;
1152
- right: 0;
1153
- }
1154
-
1155
- /* ----------- */
1156
-
1157
- .view {
1158
- scroll-snap-type: y mandatory;
1159
- }
1160
-
1161
- :host(._horz) .view {
1162
- scroll-snap-type: x mandatory;
1163
- }
1164
-
1165
- .view>.spacing,
1166
- .view>.sentinel {
1167
- scroll-snap-align: var(--scroll-snap-start);
1168
- }
1169
-
1170
- .main {
1171
- flex-grow: 1;
1172
-
1173
- min-width: var(--view-width);
1174
- min-height: var(--view-inner-height);
1175
-
1176
- scroll-margin-top: var(--header-min-height);
1177
- scroll-margin-bottom: var(--footer-min-height);
1178
- scroll-snap-align: var(--scroll-snap-start);
1179
-
1180
- order: 3;
1181
- }
1182
-
1183
- :host(:is(._top, ._left._horz)) .main {
1184
- scroll-snap-align: none;
1185
- }
1186
-
1187
- :host(:is(._top, ._left._horz)) .container {
1188
- scroll-snap-align: var(--scroll-snap-start);
1189
- }
1190
-
1191
- header {
1192
- scroll-snap-align: start;
1193
- }
1194
-
1195
- .header-bar {
1196
- scroll-snap-align: start;
1485
+ position: sticky;
1486
+ left: 0;
1487
+ right: 0;
1197
1488
  }
1198
-
1199
- /* ----------- */
1489
+
1490
+ /* scrollport */
1200
1491
 
1201
1492
  .scrollport-anchor {
1202
- order: 2;
1203
-
1204
1493
  position: sticky;
1205
1494
  top: var(--header-min-height);
1206
1495
  bottom: var(--footer-min-height);
@@ -1215,11 +1504,6 @@ export class ModalElement extends BaseElement {
1215
1504
  z-index: 1;
1216
1505
  }
1217
1506
 
1218
- :host(:is(._left._horz, ._top:not(._horz))) .scrollport-anchor {
1219
- justify-content: end;
1220
- order: 4;
1221
- }
1222
-
1223
1507
  .scrollport {
1224
1508
  position: relative;
1225
1509
 
@@ -1234,75 +1518,7 @@ export class ModalElement extends BaseElement {
1234
1518
  height: calc(var(--view-inner-height) - var(--header-box-height));
1235
1519
  }
1236
1520
 
1237
- /* -- scroll unfold -- */
1238
-
1239
- :host(._scroll-unfold) .scrollport {
1240
- display: flex;
1241
- flex-direction: column;
1242
- justify-content: space-between;
1243
- align-items: stretch;
1244
- }
1245
-
1246
- :host(._scroll-unfold._horz) .scrollport {
1247
- flex-direction: row;
1248
- }
1249
-
1250
- :host(._scroll-unfold) .scrollport .scroll-fold {
1251
- position: sticky;
1252
- opacity: 0;
1253
-
1254
- background: var(--background);
1255
-
1256
- mask-repeat: no-repeat;
1257
- mask-size: 100% 100%;
1258
-
1259
- animation-timing-function: linear;
1260
- animation-fill-mode: forwards;
1261
- animation-name: appear;
1262
- animation-timeline: --view-scroll;
1263
-
1264
- animation-range-start: var(--scrollbar-progress-range-start);
1265
- animation-range-end: calc(var(--scrollbar-progress-range-end) + 1px);
1266
- }
1267
-
1268
- :host(._scroll-unfold) .scrollport .scroll-fold-end {
1269
- animation-range-start: calc(var(--scrollbar-progress-range-start) - 1px);
1270
- animation-range-end: var(--scrollbar-progress-range-end);
1271
- }
1272
-
1273
- :host(._scroll-unfold:not(._horz)) .scrollport .scroll-fold {
1274
- top: var(--header-min-height);
1275
- height: 25%;
1276
-
1277
- mask-image: linear-gradient(to bottom, black 0%, transparent 100%);
1278
- -webkit-mask-image: linear-gradient(to bottom, black 0%, transparent 100%);
1279
- }
1280
-
1281
- :host(._scroll-unfold:not(._horz)) .scrollport .scroll-fold-end {
1282
- bottom: var(--footer-min-height);
1283
- top: auto;
1284
- opacity: 1;
1285
- animation-name: disappear;
1286
- transform: scaleY(-1);
1287
- }
1288
-
1289
- :host(._scroll-unfold._horz) .scrollport .scroll-fold {
1290
- left: 0;
1291
- width: 25%;
1292
-
1293
- mask-image: linear-gradient(to right, black 0%, transparent 100%);
1294
- -webkit-mask-image: linear-gradient(to right, black 0%, transparent 100%);
1295
- }
1296
-
1297
- :host(._scroll-unfold._horz) .scrollport .scroll-fold-end {
1298
- right: 0;
1299
- left: auto;
1300
- opacity: 1;
1301
- animation-name: disappear;
1302
- transform: scaleX(-1);
1303
- }
1304
-
1305
- /* -- scrollbar -- */
1521
+ /* -- scrollbars -- */
1306
1522
 
1307
1523
  .scrollbar-track {
1308
1524
  display: none;
@@ -1317,13 +1533,6 @@ export class ModalElement extends BaseElement {
1317
1533
  top: 0;
1318
1534
  right: 0;
1319
1535
  padding-inline: 2px;
1320
-
1321
- opacity: 0;
1322
-
1323
- animation: appear linear;
1324
- animation-timeline: --view-scroll;
1325
- animation-range: var(--scrollbar-appear-range);
1326
- animation-fill-mode: forwards;
1327
1536
  }
1328
1537
 
1329
1538
  :host(._scrollbars._horz) .scrollbar-track {
@@ -1340,116 +1549,71 @@ export class ModalElement extends BaseElement {
1340
1549
  height: var(--scrollbar-thumb-height);
1341
1550
  background: var(--scrollbar-thumb-color);
1342
1551
  border-radius: 10px;
1343
-
1344
- --scrollbar-thumb-start: translateY(0);
1345
- --scrollbar-thumb-length: translateY(calc(var(--view-inner-height) - 100%));
1346
-
1347
- animation: move-scrollbar-thumb linear both;
1348
- animation-timeline: --view-scroll;
1349
- animation-range: var(--scrollbar-progress-range);
1350
1552
  }
1351
1553
 
1352
1554
  :host(._scrollbars._horz) .scrollbar-thumb {
1353
1555
  height: var(--scrollbar-thumb-width);
1354
1556
  width: var(--scrollbar-thumb-height);
1355
-
1356
- --scrollbar-thumb-start: translateX(0);
1357
- --scrollbar-thumb-length: translateX(calc(var(--view-width) - 100%));
1358
1557
  }
1359
1558
 
1360
- /* ----------- */
1559
+ /* scroll unfold */
1361
1560
 
1362
- :host(:popover-open) {
1561
+ :host(._scroll-unfold) .scrollport {
1363
1562
  display: flex;
1364
- opacity: 1;
1365
- transform: none;
1366
- }
1367
-
1368
- @starting-style {
1369
- :host(:popover-open) {
1370
- opacity: 0;
1371
- transform: var(--entry-transform);
1372
- }
1563
+ flex-direction: column;
1564
+ justify-content: space-between;
1565
+ align-items: stretch;
1373
1566
  }
1374
1567
 
1375
- /* ----------- */
1376
-
1377
- :host::backdrop {
1378
- /* Transition */
1379
- transition:
1380
- display 0.2s allow-discrete,
1381
- overlay 0.2s allow-discrete,
1382
- backdrop-filter 0.2s,
1383
- background 0.2s;
1568
+ :host(._scroll-unfold._horz) .scrollport {
1569
+ flex-direction: row;
1384
1570
  }
1385
-
1386
- :host(._swipe-dismiss._container) {
1387
- timeline-scope: --view-scroll;
1571
+
1572
+ :host(._scroll-unfold) .scroll-fold {
1573
+ position: sticky;
1388
1574
  }
1389
1575
 
1390
- :host(._swipe-dismiss._container)::backdrop {
1391
- opacity: 0;
1392
-
1393
- animation-timing-function: linear;
1394
- animation-fill-mode: forwards;
1395
- animation-name: appear;
1396
- animation-timeline: --view-scroll;
1397
-
1398
- animation-range: 0 calc(100cqh - var(--expanse-length) - var(--minmax-length));
1399
- }
1576
+ :host(._scroll-unfold:not(._horz)) {
1577
+ .scroll-fold {
1578
+ height: 25%;
1579
+ }
1400
1580
 
1401
- :host(._swipe-dismiss._container._horz)::backdrop {
1402
- animation-range: 0 calc(100cqw - var(--expanse-length) - var(--minmax-length));
1403
- }
1581
+ .scroll-fold-start {
1582
+ top: var(--header-min-height);
1583
+ background: linear-gradient(to bottom, var(--background) 0%, transparent 100%);
1584
+ }
1404
1585
 
1405
- :host(._swipe-dismiss._container._top:not(._horz))::backdrop,
1406
- :host(._swipe-dismiss._container._left._horz)::backdrop {
1407
- opacity: 1;
1408
- animation-name: disappear;
1586
+ .scroll-fold-end {
1587
+ bottom: var(--footer-min-height);
1588
+ background: linear-gradient(to top, var(--background) 0%, transparent 100%);
1589
+ }
1409
1590
  }
1410
1591
 
1411
- :host(._swipe-dismiss._container._top:not(._horz))::backdrop {
1412
- animation-range: calc(100% - (100cqh - var(--expanse-length) - var(--minmax-length))) 100%;
1413
- }
1592
+ :host(._scroll-unfold._horz) {
1593
+ .scroll-fold {
1594
+ width: 25%;
1595
+ }
1414
1596
 
1415
- :host(._swipe-dismiss._container._left._horz)::backdrop {
1416
- animation-range: calc(100% - (100cqw - var(--expanse-length) - var(--minmax-length))) 100%;
1417
- }
1597
+ .scroll-fold-start {
1598
+ left: 0;
1599
+ background: linear-gradient(to right, var(--background) 0%, transparent 100%);
1600
+ }
1418
1601
 
1419
- :host(:popover-open)::backdrop {
1420
- backdrop-filter: blur(3px);
1602
+ .scroll-fold-end {
1603
+ right: 0;
1604
+ background: linear-gradient(to left, var(--background) 0%, transparent 100%);
1605
+ }
1421
1606
  }
1422
1607
 
1423
- :host(:not([popover="manual"], ._manual-dismiss):popover-open)::backdrop {
1424
- backdrop-filter: blur(0px);
1425
- }
1608
+ /* ----------- theming ----------- */
1426
1609
 
1427
- @starting-style {
1428
- :host(:popover-open)::backdrop {
1429
- backdrop-filter: none;
1430
- background: none;
1431
- }
1432
- }
1433
-
1434
- :host(:popover-open)::before {
1435
- position: fixed;
1436
- inset: 0;
1437
- display: block;
1438
- content: "";
1439
- z-index: -1;
1440
- }
1610
+ /* aero-blur */
1441
1611
 
1442
- .icon {
1443
- display: none;
1444
- opacity: 0.6;
1612
+ :host(._aero) :is(header, .main, footer) {
1613
+ backdrop-filter: blur(var(--aero-blur));
1445
1614
  }
1446
1615
 
1447
- :host([type="info"]) .icon._info,
1448
- :host([type="success"]) .icon._success,
1449
- :host([type="error"]) .icon._error,
1450
- :host([type="warning"]) .icon._warning {
1451
- display: block;
1452
- }
1616
+ /* coloring */
1453
1617
 
1454
1618
  :host([type="info"]) .container {
1455
1619
  color: var(--color-info);
@@ -1472,10 +1636,45 @@ export class ModalElement extends BaseElement {
1472
1636
  background: var(--background);
1473
1637
  }
1474
1638
 
1475
- .view:not(:has(footer slot:is(.has-slotted, :not(:empty)))) .main {
1476
- border-bottom-left-radius: var(--radius-bottom-left);
1477
- border-bottom-right-radius: var(--radius-bottom-right);
1639
+ :host([type="info"]) header {
1640
+ color: var(--header-color-info);
1641
+ }
1642
+
1643
+ :host([type="success"]) header {
1644
+ color: var(--header-color-success);
1645
+ }
1646
+
1647
+ :host([type="error"]) header {
1648
+ color: var(--header-color-error);
1649
+ }
1650
+
1651
+ :host([type="info"]) footer {
1652
+ color: var(--footer-color-info);
1653
+ }
1654
+
1655
+ :host([type="success"]) footer {
1656
+ color: var(--footer-color-success);
1657
+ }
1658
+
1659
+ :host([type="error"]) footer {
1660
+ color: var(--footer-color-error);
1661
+ }
1662
+
1663
+ /* ----------- icons ----------- */
1664
+
1665
+ .icon {
1666
+ display: none;
1667
+ opacity: 0.6;
1668
+ }
1669
+
1670
+ :host([type="info"]) .icon._info,
1671
+ :host([type="success"]) .icon._success,
1672
+ :host([type="error"]) .icon._error,
1673
+ :host([type="warning"]) .icon._warning {
1674
+ display: block;
1478
1675
  }
1676
+
1677
+ /* ----------- controls ----------- */
1479
1678
 
1480
1679
  .close-button {
1481
1680
  padding-inline: 0;
@@ -1484,7 +1683,7 @@ export class ModalElement extends BaseElement {
1484
1683
  justify-content: center;
1485
1684
  appearance: none;
1486
1685
  font-size: inherit;
1487
- color: gray;
1686
+ color: var(--close-button-color);
1488
1687
  cursor: pointer;
1489
1688
  border: none;
1490
1689
  background: none;
@@ -1759,14 +1958,128 @@ export class AlertElement extends DialogElement {
1759
1958
  // ---------------- define
1760
1959
 
1761
1960
  export function defineElements() {
1961
+ // radius
1962
+
1963
+ try {
1964
+ CSS.registerProperty({
1965
+ name: '--wq-internal-var-radius-progress',
1966
+ syntax: '<number>',
1967
+ inherits: true,
1968
+ initialValue: '0'
1969
+ });
1970
+ } catch (e) { }
1971
+
1972
+ // header-box
1973
+
1974
+ try {
1975
+ CSS.registerProperty({
1976
+ name: '--wq-internal-var-header-box-progress',
1977
+ syntax: '<number>',
1978
+ inherits: true,
1979
+ initialValue: '0'
1980
+ });
1981
+ } catch (e) { }
1982
+ try {
1983
+ CSS.registerProperty({
1984
+ name: '--wq-internal-var-header-box-progress-a',
1985
+ syntax: '<number>',
1986
+ inherits: true,
1987
+ initialValue: '0'
1988
+ });
1989
+ } catch (e) { }
1990
+ try {
1991
+ CSS.registerProperty({
1992
+ name: '--wq-internal-var-header-box-progress-b',
1993
+ syntax: '<number>',
1994
+ inherits: true,
1995
+ initialValue: '0'
1996
+ });
1997
+ } catch (e) { }
1998
+
1999
+ // minmax
2000
+
2001
+ try {
2002
+ CSS.registerProperty({
2003
+ name: '--wq-internal-var-minmax-progress',
2004
+ syntax: '<number>',
2005
+ inherits: true,
2006
+ initialValue: '0'
2007
+ });
2008
+ } catch (e) { }
2009
+ try {
2010
+ CSS.registerProperty({
2011
+ name: '--wq-internal-var-minmax-progress-a',
2012
+ syntax: '<number>',
2013
+ inherits: true,
2014
+ initialValue: '0'
2015
+ });
2016
+ } catch (e) { }
2017
+ try {
2018
+ CSS.registerProperty({
2019
+ name: '--wq-internal-var-minmax-progress-b',
2020
+ syntax: '<number>',
2021
+ inherits: true,
2022
+ initialValue: '0'
2023
+ });
2024
+ } catch (e) { }
2025
+
2026
+ // minmax-balance
2027
+
2028
+ try {
2029
+ CSS.registerProperty({
2030
+ name: '--wq-internal-var-total-minmax-progress',
2031
+ syntax: '<number>',
2032
+ inherits: true,
2033
+ initialValue: '0'
2034
+ });
2035
+ } catch (e) { }
2036
+
2037
+ // swipe-dismiss
2038
+
2039
+ try {
2040
+ CSS.registerProperty({
2041
+ name: '--wq-internal-var-swipe-dismiss-progress',
2042
+ syntax: '<number>',
2043
+ inherits: true,
2044
+ initialValue: '0'
2045
+ });
2046
+ } catch (e) { }
2047
+
2048
+ // Scrollbars
2049
+
2050
+ try {
2051
+ CSS.registerProperty({
2052
+ name: '--wq-internal-var-scrollbar-appear-progress',
2053
+ syntax: '<number>',
2054
+ inherits: true,
2055
+ initialValue: '0'
2056
+ });
2057
+ } catch (e) { }
2058
+ try {
2059
+ CSS.registerProperty({
2060
+ name: '--wq-internal-var-scrollbar-progress',
2061
+ syntax: '<number>',
2062
+ inherits: true,
2063
+ initialValue: '0'
2064
+ });
2065
+ } catch (e) { }
2066
+ try {
2067
+ CSS.registerProperty({
2068
+ name: '--wq-internal-var-scrollbar-progress-a',
2069
+ syntax: '<number>',
2070
+ inherits: true,
2071
+ initialValue: '0'
2072
+ });
2073
+ } catch (e) { }
1762
2074
  try {
1763
2075
  CSS.registerProperty({
1764
- name: '--wq-radius',
1765
- syntax: '<length-percentage>',
2076
+ name: '--wq-internal-var-scrollbar-progress-b',
2077
+ syntax: '<number>',
1766
2078
  inherits: true,
1767
2079
  initialValue: '0'
1768
2080
  });
1769
2081
  } catch (e) { }
2082
+
1770
2083
  customElements.define('wq-toast', ToastElement);
1771
2084
  customElements.define('wq-modal', ModalElement);
1772
2085
  customElements.define('wq-dialog', DialogElement);