-
-
Notifications
You must be signed in to change notification settings - Fork 516
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added sidebar component * Added sidebar css styling (default colors / needs tweaking) * WIP - Sidebar progress * more cleanup * updated sidebar style * Fixed sidebar styling huntabyte/shadcn-svelte#1496 * Fixed main content area * Workaround open mobile issue. * Removed dead code * Fixed whitespace
- Loading branch information
Showing
43 changed files
with
1,136 additions
and
120 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ | |
"keyof", | ||
"legos", | ||
"lucene", | ||
"lucide", | ||
"nameof", | ||
"navigatetofirstpage", | ||
"oidc", | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
src/Exceptionless.Web/ClientApp/src/lib/features/shared/components/ui/sidebar/constants.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export const SIDEBAR_COOKIE_NAME = "sidebar:state"; | ||
export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7; | ||
export const SIDEBAR_WIDTH = "16rem"; | ||
export const SIDEBAR_WIDTH_MOBILE = "18rem"; | ||
export const SIDEBAR_WIDTH_ICON = "3rem"; | ||
export const SIDEBAR_KEYBOARD_SHORTCUT = "b"; |
81 changes: 81 additions & 0 deletions
81
...ceptionless.Web/ClientApp/src/lib/features/shared/components/ui/sidebar/context.svelte.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { IsMobile } from "$lib/hooks/is-mobile.svelte.js"; | ||
import { getContext, setContext } from "svelte"; | ||
import { SIDEBAR_KEYBOARD_SHORTCUT } from "./constants.js"; | ||
|
||
type Getter<T> = () => T; | ||
|
||
export type SidebarStateProps = { | ||
/** | ||
* A getter function that returns the current open state of the sidebar. | ||
* We use a getter function here to support `bind:open` on the `Sidebar.Provider` | ||
* component. | ||
*/ | ||
open: Getter<boolean>; | ||
|
||
/** | ||
* A function that sets the open state of the sidebar. To support `bind:open`, we need | ||
* a source of truth for changing the open state to ensure it will be synced throughout | ||
* the sub-components and any `bind:` references. | ||
*/ | ||
setOpen: (open: boolean) => void; | ||
}; | ||
|
||
class SidebarState { | ||
readonly props: SidebarStateProps; | ||
open = $derived.by(() => this.props.open()); | ||
openMobile = $state(false); | ||
setOpen: SidebarStateProps["setOpen"]; | ||
#isMobile: IsMobile; | ||
state = $derived.by(() => (this.open ? "expanded" : "collapsed")); | ||
|
||
constructor(props: SidebarStateProps) { | ||
this.setOpen = props.setOpen; | ||
this.#isMobile = new IsMobile(); | ||
this.props = props; | ||
} | ||
|
||
// Convenience getter for checking if the sidebar is mobile | ||
// without this, we would need to use `sidebar.isMobile.current` everywhere | ||
get isMobile() { | ||
return this.#isMobile.current; | ||
} | ||
|
||
// Event handler to apply to the `<svelte:window>` | ||
handleShortcutKeydown = (e: KeyboardEvent) => { | ||
if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) { | ||
e.preventDefault(); | ||
this.toggle(); | ||
} | ||
}; | ||
|
||
setOpenMobile = (value: boolean) => { | ||
this.openMobile = value; | ||
}; | ||
|
||
toggle = () => { | ||
return this.#isMobile.current | ||
? (this.openMobile = !this.openMobile) | ||
: this.setOpen(!this.open); | ||
}; | ||
} | ||
|
||
const SYMBOL_KEY = "scn-sidebar"; | ||
|
||
/** | ||
* Instantiates a new `SidebarState` instance and sets it in the context. | ||
* | ||
* @param props The constructor props for the `SidebarState` class. | ||
* @returns The `SidebarState` instance. | ||
*/ | ||
export function setSidebar(props: SidebarStateProps): SidebarState { | ||
return setContext(Symbol.for(SYMBOL_KEY), new SidebarState(props)); | ||
} | ||
|
||
/** | ||
* Retrieves the `SidebarState` instance from the context. This is a class instance, | ||
* so you cannot destructure it. | ||
* @returns The `SidebarState` instance. | ||
*/ | ||
export function useSidebar(): SidebarState { | ||
return getContext(Symbol.for(SYMBOL_KEY)); | ||
} |
75 changes: 75 additions & 0 deletions
75
src/Exceptionless.Web/ClientApp/src/lib/features/shared/components/ui/sidebar/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { useSidebar } from "./context.svelte.js"; | ||
import Content from "./sidebar-content.svelte"; | ||
import Footer from "./sidebar-footer.svelte"; | ||
import GroupAction from "./sidebar-group-action.svelte"; | ||
import GroupContent from "./sidebar-group-content.svelte"; | ||
import GroupLabel from "./sidebar-group-label.svelte"; | ||
import Group from "./sidebar-group.svelte"; | ||
import Header from "./sidebar-header.svelte"; | ||
import Input from "./sidebar-input.svelte"; | ||
import Inset from "./sidebar-inset.svelte"; | ||
import MenuAction from "./sidebar-menu-action.svelte"; | ||
import MenuBadge from "./sidebar-menu-badge.svelte"; | ||
import MenuButton from "./sidebar-menu-button.svelte"; | ||
import MenuItem from "./sidebar-menu-item.svelte"; | ||
import MenuSkeleton from "./sidebar-menu-skeleton.svelte"; | ||
import MenuSubButton from "./sidebar-menu-sub-button.svelte"; | ||
import MenuSubItem from "./sidebar-menu-sub-item.svelte"; | ||
import MenuSub from "./sidebar-menu-sub.svelte"; | ||
import Menu from "./sidebar-menu.svelte"; | ||
import Provider from "./sidebar-provider.svelte"; | ||
import Rail from "./sidebar-rail.svelte"; | ||
import Separator from "./sidebar-separator.svelte"; | ||
import Trigger from "./sidebar-trigger.svelte"; | ||
import Root from "./sidebar.svelte"; | ||
|
||
export { | ||
Content, | ||
Footer, | ||
Group, | ||
GroupAction, | ||
GroupContent, | ||
GroupLabel, | ||
Header, | ||
Input, | ||
Inset, | ||
Menu, | ||
MenuAction, | ||
MenuBadge, | ||
MenuButton, | ||
MenuItem, | ||
MenuSkeleton, | ||
MenuSub, | ||
MenuSubButton, | ||
MenuSubItem, | ||
Provider, | ||
Rail, | ||
Root, | ||
Separator, | ||
// | ||
Root as Sidebar, | ||
Content as SidebarContent, | ||
Footer as SidebarFooter, | ||
Group as SidebarGroup, | ||
GroupAction as SidebarGroupAction, | ||
GroupContent as SidebarGroupContent, | ||
GroupLabel as SidebarGroupLabel, | ||
Header as SidebarHeader, | ||
Input as SidebarInput, | ||
Inset as SidebarInset, | ||
Menu as SidebarMenu, | ||
MenuAction as SidebarMenuAction, | ||
MenuBadge as SidebarMenuBadge, | ||
MenuButton as SidebarMenuButton, | ||
MenuItem as SidebarMenuItem, | ||
MenuSkeleton as SidebarMenuSkeleton, | ||
MenuSub as SidebarMenuSub, | ||
MenuSubButton as SidebarMenuSubButton, | ||
MenuSubItem as SidebarMenuSubItem, | ||
Provider as SidebarProvider, | ||
Rail as SidebarRail, | ||
Separator as SidebarSeparator, | ||
Trigger as SidebarTrigger, | ||
Trigger, | ||
useSidebar, | ||
}; |
24 changes: 24 additions & 0 deletions
24
...onless.Web/ClientApp/src/lib/features/shared/components/ui/sidebar/sidebar-content.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<script lang="ts"> | ||
import type { HTMLAttributes } from "svelte/elements"; | ||
import type { WithElementRef } from "bits-ui"; | ||
import { cn } from "$lib/utils.js"; | ||
let { | ||
ref = $bindable(null), | ||
class: className, | ||
children, | ||
...restProps | ||
}: WithElementRef<HTMLAttributes<HTMLElement>> = $props(); | ||
</script> | ||
|
||
<div | ||
bind:this={ref} | ||
data-sidebar="content" | ||
class={cn( | ||
"flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden", | ||
className | ||
)} | ||
{...restProps} | ||
> | ||
{@render children?.()} | ||
</div> |
21 changes: 21 additions & 0 deletions
21
...ionless.Web/ClientApp/src/lib/features/shared/components/ui/sidebar/sidebar-footer.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<script lang="ts"> | ||
import type { HTMLAttributes } from "svelte/elements"; | ||
import type { WithElementRef } from "bits-ui"; | ||
import { cn } from "$lib/utils.js"; | ||
let { | ||
ref = $bindable(null), | ||
class: className, | ||
children, | ||
...restProps | ||
}: WithElementRef<HTMLAttributes<HTMLElement>> = $props(); | ||
</script> | ||
|
||
<div | ||
bind:this={ref} | ||
data-sidebar="footer" | ||
class={cn("flex flex-col gap-2 p-2", className)} | ||
{...restProps} | ||
> | ||
{@render children?.()} | ||
</div> |
36 changes: 36 additions & 0 deletions
36
...s.Web/ClientApp/src/lib/features/shared/components/ui/sidebar/sidebar-group-action.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<script lang="ts"> | ||
import { cn } from "$lib/utils.js"; | ||
import type { WithElementRef } from "bits-ui"; | ||
import type { Snippet } from "svelte"; | ||
import type { HTMLButtonAttributes } from "svelte/elements"; | ||
let { | ||
ref = $bindable(null), | ||
class: className, | ||
children, | ||
child, | ||
...restProps | ||
}: WithElementRef<HTMLButtonAttributes> & { | ||
child?: Snippet<[{ props: Record<string, unknown> }]>; | ||
} = $props(); | ||
const propObj = $derived({ | ||
class: cn( | ||
"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-none transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0", | ||
// Increases the hit area of the button on mobile. | ||
"after:absolute after:-inset-2 after:md:hidden", | ||
"group-data-[collapsible=icon]:hidden", | ||
className | ||
), | ||
"data-sidebar": "group-action", | ||
...restProps, | ||
}); | ||
</script> | ||
|
||
{#if child} | ||
{@render child({ props: propObj })} | ||
{:else} | ||
<button bind:this={ref} {...propObj}> | ||
{@render children?.()} | ||
</button> | ||
{/if} |
21 changes: 21 additions & 0 deletions
21
....Web/ClientApp/src/lib/features/shared/components/ui/sidebar/sidebar-group-content.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<script lang="ts"> | ||
import { cn } from "$lib/utils.js"; | ||
import type { WithElementRef } from "bits-ui"; | ||
import type { HTMLAttributes } from "svelte/elements"; | ||
let { | ||
ref = $bindable(null), | ||
class: className, | ||
children, | ||
...restProps | ||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props(); | ||
</script> | ||
|
||
<div | ||
bind:this={ref} | ||
data-sidebar="group-content" | ||
class={cn("w-full text-sm", className)} | ||
{...restProps} | ||
> | ||
{@render children?.()} | ||
</div> |
Oops, something went wrong.