File size: 3,507 Bytes
41a5ab2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
<script lang="ts">

	import * as Sheet from '$lib/components/ui/sheet/index.js';

	import { cn, type WithElementRef } from '$lib/components/ui/utils.js';

	import type { HTMLAttributes } from 'svelte/elements';

	import { SIDEBAR_WIDTH_MOBILE } from './constants.js';

	import { useSidebar } from './context.svelte.js';



	let {

		ref = $bindable(null),

		side = 'left',

		variant = 'sidebar',

		collapsible = 'offcanvas',

		class: className,

		children,

		...restProps

	}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {

		side?: 'left' | 'right';

		variant?: 'sidebar' | 'floating' | 'inset';

		collapsible?: 'offcanvas' | 'icon' | 'none';

	} = $props();



	const sidebar = useSidebar();

</script>

{#if collapsible === 'none'}
	<div

		class={cn(

			'flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground',

			className

		)}

		bind:this={ref}

		{...restProps}

	>
		{@render children?.()}
	</div>
{:else if sidebar.isMobile}
	<Sheet.Root bind:open={() => sidebar.openMobile, (v) => sidebar.setOpenMobile(v)} {...restProps}>
		<Sheet.Content

			data-sidebar="sidebar"

			data-slot="sidebar"

			data-mobile="true"

			class="z-99999 w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground sm:z-99 [&>button]:hidden"

			style="--sidebar-width: {SIDEBAR_WIDTH_MOBILE};"

			{side}

		>
			<Sheet.Header class="sr-only">
				<Sheet.Title>Sidebar</Sheet.Title>
				<Sheet.Description>Displays the mobile sidebar.</Sheet.Description>
			</Sheet.Header>
			<div class="flex h-full w-full flex-col">
				{@render children?.()}
			</div>
		</Sheet.Content>
	</Sheet.Root>
{:else}
	<div

		bind:this={ref}

		class="group peer hidden text-sidebar-foreground md:block"

		data-state={sidebar.state}

		data-collapsible={sidebar.state === 'collapsed' ? collapsible : ''}

		data-variant={variant}

		data-side={side}

		data-slot="sidebar"

	>
		<!-- This is what handles the sidebar gap on desktop -->
		<div

			data-slot="sidebar-gap"

			class={cn(

				'relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear',

				'group-data-[collapsible=offcanvas]:w-0',

				'group-data-[side=right]:rotate-180',

				variant === 'floating' || variant === 'inset'

					? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]'

					: 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)'

			)}

		></div>
		<div

			data-slot="sidebar-container"

			class={cn(

				'fixed inset-y-0 z-999 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:z-0 md:flex',

				side === 'left'

					? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'

					: 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',

				// Adjust the padding for floating and inset variants.

				variant === 'floating' || variant === 'inset'

					? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]'

					: 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)',

				className

			)}

			{...restProps}

		>
			<div

				data-sidebar="sidebar"

				data-slot="sidebar-inner"

				class="flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow-sm"

			>
				{@render children?.()}
			</div>
		</div>
	</div>
{/if}