Skip to content

Commit

Permalink
scroll area work
Browse files Browse the repository at this point in the history
  • Loading branch information
huntabyte committed Jul 26, 2024
1 parent 56eb7de commit 76c7b62
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 157 deletions.
98 changes: 69 additions & 29 deletions sites/docs/content/components/scroll-area.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Consistent scroll area across platforms.
---

<script>
import { APISection, ComponentPreviewV2, ScrollAreaDemo, ScrollAreaDemoScroll, ScrollAreaDemoAlways, ScrollAreaDemoAuto, ComponentPreviewMin } from '$lib/components'
import { APISection, ComponentPreviewV2, ScrollAreaDemo, ScrollAreaDemoCustom } from '$lib/components'
export let schemas;
</script>

Expand Down Expand Up @@ -37,6 +37,52 @@ description: Consistent scroll area across platforms.
</ScrollArea.Root>
```

## Reusable Components

If you're planning to use the Scroll Area throughout your application, it's recommended to create a reusable component to reduce the amount of code you need to write each time.

This example shows you how to create a Scroll Area component that accepts a few custom props that make it more capable.

```svelte title="CustomScrollArea.svelte"
<script lang="ts">
import { ScrollArea, type WithoutChild } from "bits-ui";
type Props = WithoutChild<ScrollArea.RootProps> & {
orientation: "vertical" | "horizontal" | "both";
viewportClasses?: string;
};
let {
ref = $bindable(null),
orientation = "vertical",
viewportClasses,
children,
...restProps
}: Props = $props();
</script>
{#snippet Scrollbar({ orientation }: { orientation: "vertical" | "horizontal" })}
<ScrollArea.Scrollbar {orientation}>
<ScrollArea.Thumb />
</ScrollArea.Scrollbar>
{/snippet}
<ScrollArea.Root bind:ref {...restProps}>
<ScrollArea.Viewport class={viewportClasses}>
{@render children?.()}
</ScrollArea.Viewport>
{#if orientation === "vertical" || orientation === "both"}
{@render Scrollbar({ orientation: "vertical" })}
{/if}
{#if orientation === "horizontal" || orientation === "both"}
{@render Scrollbar({ orientation: "horizontal" })}
{/if}
<ScrollArea.Corner />
</ScrollArea.Root>
```

We'll use this custom component in the following examples to demonstrate how to customize the behavior of the Scroll Area.

## Scroll Area Types

### Hover
Expand All @@ -47,54 +93,48 @@ The `hover` type is the default type of the scroll area, demonstrated in the fea

The `scroll` type displays the scrollbars when the user scrolls the content. This is similar to the behavior of MacOS.

```svelte
<ScrollArea.Root type="scroll">
```svelte {1}
<CustomScrollArea type="scroll">
<!-- ... -->
</ScrollArea.Root>
</CustomScrollArea>
```

<ComponentPreviewV2 name="scroll-area-demo-scroll" comp="Scroll Area">

{#snippet preview()}
<ScrollAreaDemoScroll />
{/snippet}

</ComponentPreviewV2>
<ScrollAreaDemoCustom type="scroll" />

### Auto

The `auto` type behaves similarly to your typical browser scrollbars. When the content is larger than the viewport, the scrollbars will appear and remain visible at all times.

```svelte
<ScrollArea.Root type="auto">
```svelte {1}
<CustomScrollArea type="auto">
<!-- ... -->
</ScrollArea.Root>
</CustomScrollArea>
```

<ComponentPreviewV2 name="scroll-area-demo-auto" comp="Scroll Area">

{#snippet preview()}
<ScrollAreaDemoAuto />
{/snippet}

</ComponentPreviewV2>
<ScrollAreaDemoCustom type="auto" />

### Always

The `always` type behaves as if you set `overflow: scroll` on the scroll area. Scrollbars will always be visible, even when the content is smaller than the viewport.

```svelte
<ScrollArea.Root type="always">
```svelte {1}
<CustomScrollArea type="always">
<!-- ... -->
</ScrollArea.Root>
</CustomScrollArea>
```

<ComponentPreviewV2 name="scroll-area-demo-always" comp="Scroll Area">
<ScrollAreaDemoCustom type="always" />

{#snippet preview()}
<ScrollAreaDemoAlways />
{/snippet}
## Customizing the Hide Delay

</ComponentPreviewV2>
You can customize the hide delay of the scrollbars using the `scrollHideDelay` prop.

```svelte {1}
<CustomScrollArea scrollHideDelay={10}>
<!-- ... -->
</CustomScrollArea>
```

<ScrollAreaDemoCustom scrollHideDelay={10} />

<APISection {schemas} />
21 changes: 15 additions & 6 deletions sites/docs/src/lib/components/demo-container.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,30 @@
import { cn } from "$lib/utils/index.js";
type Props = {
align?: "start" | "center" | "end";
size?: "sm" | "default" | "lg";
class?: string;
children: Snippet;
};
let { align = "center", children }: Props = $props();
let { align = "center", size = "default", class: className, children }: Props = $props();
</script>

<div
class="relative rounded-tl-card rounded-tr-card border-2 border-muted bg-zinc-50 !ring-transparent dark:bg-neutral-900/50"
>
<div
class={cn("preview flex min-h-[443px] w-full justify-center p-12", {
"items-center": align === "center",
"items-start": align === "start",
"items-end": align === "end",
})}
class={cn(
"preview flex w-full justify-center p-12",
{
"items-center": align === "center",
"items-start": align === "start",
"items-end": align === "end",
"min-h-[443px]": size === "default",
"min-h-[300px]": size === "sm",
"min-h-[600px]": size === "lg",
},
className
)}
>
{@render children()}
</div>
Expand Down
4 changes: 1 addition & 3 deletions sites/docs/src/lib/components/demos/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ export { default as ProgressDemo } from "./progress-demo.svelte";
export { default as RadioGroupDemo } from "./radio-group-demo.svelte";
export { default as RangeCalendarDemo } from "./range-calendar-demo.svelte";
export { default as ScrollAreaDemo } from "./scroll-area-demo.svelte";
export { default as ScrollAreaDemoAlways } from "./scroll-area-demo-always.svelte";
export { default as ScrollAreaDemoAuto } from "./scroll-area-demo-auto.svelte";
export { default as ScrollAreaDemoScroll } from "./scroll-area-demo-scroll.svelte";
export { default as ScrollAreaDemoCustom } from "./scroll-area-demo-custom.svelte";
export { default as SelectDemo } from "./select-demo.svelte";
export { default as SeparatorDemo } from "./separator-demo.svelte";
export { default as SliderDemo } from "./slider-demo.svelte";
Expand Down
39 changes: 0 additions & 39 deletions sites/docs/src/lib/components/demos/scroll-area-demo-always.svelte

This file was deleted.

39 changes: 0 additions & 39 deletions sites/docs/src/lib/components/demos/scroll-area-demo-auto.svelte

This file was deleted.

77 changes: 77 additions & 0 deletions sites/docs/src/lib/components/demos/scroll-area-demo-custom.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<script lang="ts">
import { ScrollArea, type WithoutChild } from "bits-ui";
import DemoContainer from "../demo-container.svelte";
import { cn } from "$lib/utils/styles.js";
type Props = WithoutChild<ScrollArea.RootProps> & {
orientation: "vertical" | "horizontal" | "both";
viewportClasses?: string;
};
let {
ref = $bindable(null),
orientation = "vertical",
viewportClasses,
children,
...restProps
}: Props = $props();
</script>

{#snippet Scrollbar({ orientation }: { orientation: "vertical" | "horizontal" })}
{#if orientation === "vertical"}
<ScrollArea.Scrollbar
{orientation}
class="flex w-2.5 touch-none select-none rounded-full border-l border-l-transparent bg-muted p-px transition-all duration-200 hover:w-3 hover:bg-dark-10 data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out-0 data-[state=visible]:fade-in-0"
>
<ScrollArea.Thumb
class="flex-1 rounded-full bg-muted-foreground data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out-0 data-[state=visible]:fade-in-0"
/>
</ScrollArea.Scrollbar>
{:else}
<ScrollArea.Scrollbar
{orientation}
class="flex h-2.5 touch-none select-none rounded-full border-t border-t-transparent bg-muted p-px transition-all duration-200 hover:h-3 hover:bg-dark-10 data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out-0 data-[state=visible]:fade-in-0"
>
<ScrollArea.Thumb
class="rounded-full bg-muted-foreground data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out-0 data-[state=visible]:fade-in-0"
/>
</ScrollArea.Scrollbar>
{/if}
{/snippet}

<DemoContainer size="sm">
<ScrollArea.Root
bind:ref
{...restProps}
class="relative overflow-hidden rounded-[10px] border border-dark-10 bg-background-alt px-4 py-4 shadow-card"
>
<ScrollArea.Viewport
class={cn("h-full max-h-[200px] w-full max-w-[200px]", viewportClasses)}
>
{#if children}
{@render children?.()}
{:else}
<h4
class="mb-4 mt-2 text-xl font-semibold leading-none tracking-[-0.01em] text-foreground"
>
Scroll Area
</h4>
<p class="text-wrap text-sm leading-5 text-foreground-alt">
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Dignissimos impedit
rem, repellat deserunt ducimus quasi nisi voluptatem cumque aliquid esse ea
deleniti eveniet incidunt! Deserunt minus laborum accusamus iusto dolorum. Lorem
ipsum dolor sit, amet consectetur adipisicing elit. Blanditiis officiis error
minima eos fugit voluptate excepturi eveniet dolore et, ratione impedit
consequuntur dolorem hic quae corrupti autem? Dolorem, sit voluptatum.
</p>
{/if}
</ScrollArea.Viewport>
{#if orientation === "vertical" || orientation === "both"}
{@render Scrollbar({ orientation: "vertical" })}
{/if}
{#if orientation === "horizontal" || orientation === "both"}
{@render Scrollbar({ orientation: "horizontal" })}
{/if}
<ScrollArea.Corner />
</ScrollArea.Root>
</DemoContainer>
39 changes: 0 additions & 39 deletions sites/docs/src/lib/components/demos/scroll-area-demo-scroll.svelte

This file was deleted.

Loading

0 comments on commit 76c7b62

Please sign in to comment.