// 1. Scrolling shadows are implemented as pseudo elements. This way we can customise them only
//    with custom properties.
//
// 2. Stack scrolling shadows over viewport content while keeping the content interactive.
//
//    - `.scrollingShadows` is positioned absolutely over the `.root`, with auto `z-index` (this is
//      important!), and with `overflow: hidden` to clip the shadows (ie. its pseudo elements).
//    - The `.viewport` is in `.root`'s stacking context and remains interactive because its
//      `z-index` is higher than the auto `z-index` of `.scrollingShadows`.
//
// 3. Optional arrows are positioned relative to the `.root` and stacked on top of scrolling
//    shadows. They can be shifted outside the `ScrollView` area only because `overflow: hidden` is
//    **not** present at `.root`.
//
// 4. Make the `.content`'s bounding rectangle spread beyond the part visible through `.viewport`.
//
// 5. Prevent undesired vertical scrolling that may occur with tables inside.
//
// 6. Make `ScrollView` adjust to flexible layouts.
//
// 7. Hide content overflowing in the other direction because scrollbars would be unreachable under
//    scrolling shadows.
//
// 8. Use the `clip` value for `overflow` to prevent the content from unwanted scrolling on the
//    cross axis during keyboard navigation.

@use "../../styles/tools/accessibility";
@use "../../styles/tools/caret";
@use "../../styles/tools/reset";
@use "../../styles/tools/scrollbar";
@use "../../styles/tools/spacing";
@use "../../styles/tools/transition";

$_arrow-inner-spacing: spacing.of(2);
$_arrow-outer-spacing: spacing.of(4);

@layer components.scroll-view {
    .root {
        position: relative; // 2.
        display: flex;
        flex-direction: column;
        width: 100%;
    }

    // 1.
    .scrollingShadows {
        position: absolute; // 2.
        width: 100%; // 2.
        height: 100%; // 2.
        overflow: hidden; // 2.
        pointer-events: none; // 2.

        &::before,
        &::after {
            @include transition.add((visibility, opacity, transform));

            content: "";
            position: absolute;
            z-index: 2; // 2.
            display: block;
            visibility: hidden;
            opacity: 0;
        }

        &::before {
            background: var(--rui-local-start-shadow-background);
        }

        &::after {
            background: var(--rui-local-end-shadow-background);
        }
    }

    .viewport {
        z-index: 1; // 2.
        width: 100%;
        scroll-behavior: smooth;
    }

    .arrowPrev,
    .arrowNext {
        @include reset.button();
        @include accessibility.min-tap-target();
        @include transition.add((visibility, opacity, transform));

        position: absolute; // 3.
        z-index: 3; // 3.
        display: flex;
        align-items: center;
        justify-content: center;
        visibility: hidden;
        opacity: 0;
    }

    .arrowIcon {
        @include caret.create();
    }

    .isRootVertical {
        height: 100%;
        min-height: 0; // 6.
    }

    .isRootVertical .viewport {
        height: 100%;
        overflow: clip auto; // 7., 8. / 2.
    }

    .isRootVertical .arrowPrev {
        top: 0;
        right: 0;
        left: 0;
        width: 100%;
        padding-top: $_arrow-outer-spacing;
        padding-bottom: $_arrow-inner-spacing;
        color: var(--rui-local-prev-arrow-color);
        transform: translateY(var(--rui-local-prev-arrow-initial-offset));
    }

    .isRootVertical .arrowPrev .arrowIcon {
        @include caret.rotate(180);
    }

    .isRootVertical .arrowNext {
        right: 0;
        bottom: 0;
        left: 0;
        width: 100%;
        padding-top: $_arrow-inner-spacing;
        padding-bottom: $_arrow-outer-spacing;
        color: var(--rui-local-next-arrow-color);
        transform: translateY(calc(-1 * var(--rui-local-next-arrow-initial-offset)));
    }

    .isRootHorizontal {
        min-width: 0; // 6.
    }

    .isRootHorizontal .arrowPrev {
        top: 0;
        bottom: 0;
        left: 0;
        padding-right: $_arrow-inner-spacing;
        padding-left: $_arrow-outer-spacing;
        transform: translateX(var(--rui-local-prev-arrow-initial-offset));
    }

    .isRootHorizontal .arrowPrev .arrowIcon {
        @include caret.rotate(90);
    }

    .isRootHorizontal .arrowNext {
        top: 0;
        right: 0;
        bottom: 0;
        padding-right: $_arrow-outer-spacing;
        padding-left: $_arrow-inner-spacing;
        transform: translateX(calc(-1 * var(--rui-local-next-arrow-initial-offset)));
    }

    .isRootHorizontal .arrowNext .arrowIcon {
        @include caret.rotate(270);
    }

    .isRootVertical .scrollingShadows::before,
    .isRootVertical .scrollingShadows::after {
        right: 0;
        left: 0;
        width: auto;
    }

    .isRootVertical .scrollingShadows::before {
        top: 0;
        height: var(--rui-local-start-shadow-size);
        transform: translateY(var(--rui-local-start-shadow-initial-offset));
    }

    .isRootVertical .scrollingShadows::after {
        bottom: 0;
        height: var(--rui-local-end-shadow-size);
        transform: translateY(calc(-1 * var(--rui-local-end-shadow-initial-offset)));
    }

    .isRootHorizontal .viewport {
        overflow: auto clip; // 2. / 5., 7., 8.
    }

    .isRootHorizontal .content {
        display: inline-flex; // 4.
        min-width: 100%;
        overflow: clip; // 8.
        vertical-align: top;
    }

    .isRootHorizontal .scrollingShadows::before,
    .isRootHorizontal .scrollingShadows::after {
        top: 0;
        bottom: 0;
        height: auto;
    }

    .isRootHorizontal .scrollingShadows::before {
        left: 0;
        width: var(--rui-local-start-shadow-size);
        transform: translateX(var(--rui-local-start-shadow-initial-offset));
    }

    .isRootHorizontal .scrollingShadows::after {
        right: 0;
        width: var(--rui-local-end-shadow-size);
        transform: translateX(calc(-1 * var(--rui-local-end-shadow-initial-offset)));
    }

    .isRootScrolledAtStart .scrollingShadows::before,
    .isRootScrolledAtStart .arrowPrev {
        visibility: visible;
        opacity: 1;
        transform: translate(0, 0);
    }

    .isRootScrolledAtEnd .scrollingShadows::after,
    .isRootScrolledAtEnd .arrowNext {
        visibility: visible;
        opacity: 1;
        transform: translate(0, 0);
    }

    .hasRootScrollbarDisabled .viewport {
        @include scrollbar.hide();
    }
}
