/ src / components / File.svelte
File.svelte
 1  <script lang="ts">
 2    import { tick } from "svelte";
 3  
 4    import ExpandButton from "./ExpandButton.svelte";
 5  
 6    export let collapsable: boolean = false;
 7    export let expanded: boolean = true;
 8    export let sticky: boolean = true;
 9  
10    let header: HTMLDivElement;
11  </script>
12  
13  <style>
14    .header {
15      display: flex;
16      height: 3rem;
17      align-items: center;
18      padding: 0 0.5rem 0 1rem;
19      border: 1px solid var(--color-border-hint);
20      border-top-left-radius: var(--border-radius-small);
21      border-top-right-radius: var(--border-radius-small);
22      background-color: var(--color-background-default);
23      z-index: 2;
24    }
25  
26    .sticky {
27      position: sticky;
28      top: 0;
29    }
30  
31    .collapsed {
32      border-radius: var(--border-radius-small);
33      border: 1px solid var(--color-border-hint);
34    }
35  
36    .left {
37      display: flex;
38      gap: 0.5rem;
39      margin-right: 1rem;
40      align-items: center;
41    }
42  
43    .right {
44      display: flex;
45      gap: 0.5rem;
46      margin-left: auto;
47      overflow: hidden;
48    }
49  
50    .container {
51      position: relative;
52      overflow-x: auto;
53      border: 1px solid var(--color-border-hint);
54      border-top: 0;
55      background: var(--color-background-float);
56      border-bottom-left-radius: var(--border-radius-small);
57      border-bottom-right-radius: var(--border-radius-small);
58    }
59    @media (max-width: 719.98px) {
60      .header {
61        border-radius: 0;
62        border-left: 0;
63        border-right: 0;
64        padding: 0 1rem 0 1rem;
65      }
66      .container {
67        border-radius: 0;
68        border-left: 0;
69        border-right: 0;
70      }
71    }
72  </style>
73  
74  <div bind:this={header} class="header" class:collapsed={!expanded} class:sticky>
75    <div class="left">
76      {#if collapsable}
77        <ExpandButton
78          {expanded}
79          on:toggle={async () => {
80            expanded = !expanded;
81            if (!expanded) {
82              await tick();
83              header.scrollIntoView({ behavior: "smooth", block: "nearest" });
84            }
85          }} />
86      {/if}
87      <slot name="left-header" />
88    </div>
89  
90    <div class="right">
91      <slot name="right-header" {expanded} />
92    </div>
93  </div>
94  
95  {#if expanded}
96    <div class="container">
97      <slot />
98    </div>
99  {/if}