mirror of
https://github.com/pheralb/svgl.git
synced 2025-12-29 08:01:36 +08:00
🎨 Add context-menu UI component
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
<script lang="ts">
|
||||
import { ContextMenu as ContextMenuPrimitive } from "bits-ui";
|
||||
import { cn } from "@/utils/cn";
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
portalProps,
|
||||
class: className,
|
||||
...restProps
|
||||
}: ContextMenuPrimitive.ContentProps & {
|
||||
portalProps?: ContextMenuPrimitive.PortalProps;
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
<ContextMenuPrimitive.Portal {...portalProps}>
|
||||
<ContextMenuPrimitive.Content
|
||||
bind:ref
|
||||
data-slot="context-menu-content"
|
||||
class={cn(
|
||||
"z-50 max-h-(--bits-context-menu-content-available-height) min-w-[8rem] origin-(--bits-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-neutral-200 bg-white p-1 text-neutral-950 shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 dark:border-neutral-800 dark:bg-neutral-900 dark:text-neutral-50",
|
||||
className,
|
||||
)}
|
||||
{...restProps}
|
||||
/>
|
||||
</ContextMenuPrimitive.Portal>
|
||||
@@ -0,0 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { ContextMenu as ContextMenuPrimitive } from "bits-ui";
|
||||
|
||||
let { ref = $bindable(null), ...restProps }: ContextMenuPrimitive.GroupProps =
|
||||
$props();
|
||||
</script>
|
||||
|
||||
<ContextMenuPrimitive.Group
|
||||
bind:ref
|
||||
data-slot="context-menu-group"
|
||||
{...restProps}
|
||||
/>
|
||||
@@ -0,0 +1,27 @@
|
||||
<script lang="ts">
|
||||
import { cn } from "@/utils/cn";
|
||||
import { ContextMenu as ContextMenuPrimitive } from "bits-ui";
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
inset,
|
||||
variant = "default",
|
||||
...restProps
|
||||
}: ContextMenuPrimitive.ItemProps & {
|
||||
inset?: boolean;
|
||||
variant?: "default" | "destructive";
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
<ContextMenuPrimitive.Item
|
||||
bind:ref
|
||||
data-slot="context-menu-item"
|
||||
data-inset={inset}
|
||||
data-variant={variant}
|
||||
class={cn(
|
||||
"relative flex cursor-default items-center gap-2.5 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-highlighted:bg-neutral-200 data-highlighted:text-neutral-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[variant=destructive]:text-neutral-700 data-[variant=destructive]:data-highlighted:bg-neutral-100 data-[variant=destructive]:data-highlighted:text-neutral-700 dark:data-highlighted:bg-neutral-800 dark:data-highlighted:text-neutral-50 dark:data-[variant=destructive]:data-highlighted:bg-neutral-700 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-neutral-500 dark:[&_svg:not([class*='text-'])]:text-neutral-400 data-[variant=destructive]:*:[svg]:text-neutral-700",
|
||||
className,
|
||||
)}
|
||||
{...restProps}
|
||||
/>
|
||||
@@ -0,0 +1,28 @@
|
||||
<script lang="ts">
|
||||
import { cn } from "@/utils/cn";
|
||||
import type { WithElementRef } from "@/types/components";
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
inset,
|
||||
children,
|
||||
...restProps
|
||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
|
||||
inset?: boolean;
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
bind:this={ref}
|
||||
data-slot="context-menu-label"
|
||||
data-inset={inset}
|
||||
class={cn(
|
||||
"px-2 py-1.5 text-sm font-medium text-neutral-900 data-[inset]:pl-8 dark:text-neutral-100",
|
||||
className,
|
||||
)}
|
||||
{...restProps}
|
||||
>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
@@ -0,0 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { cn } from "@/utils/cn";
|
||||
import { ContextMenu as ContextMenuPrimitive } from "bits-ui";
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
...restProps
|
||||
}: ContextMenuPrimitive.SeparatorProps = $props();
|
||||
</script>
|
||||
|
||||
<ContextMenuPrimitive.Separator
|
||||
bind:ref
|
||||
data-slot="context-menu-separator"
|
||||
class={cn("-mx-1 my-1 h-px bg-neutral-200 dark:bg-neutral-800", className)}
|
||||
{...restProps}
|
||||
/>
|
||||
@@ -0,0 +1,24 @@
|
||||
<script lang="ts">
|
||||
import { cn } from "@/utils/cn";
|
||||
import type { WithElementRef } from "bits-ui";
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
children,
|
||||
...restProps
|
||||
}: WithElementRef<HTMLAttributes<HTMLSpanElement>> = $props();
|
||||
</script>
|
||||
|
||||
<span
|
||||
bind:this={ref}
|
||||
data-slot="context-menu-shortcut"
|
||||
class={cn(
|
||||
"ml-auto text-xs tracking-widest text-neutral-400 dark:text-neutral-600",
|
||||
className,
|
||||
)}
|
||||
{...restProps}
|
||||
>
|
||||
{@render children?.()}
|
||||
</span>
|
||||
@@ -0,0 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { ContextMenu as ContextMenuPrimitive } from "bits-ui";
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
...restProps
|
||||
}: ContextMenuPrimitive.TriggerProps = $props();
|
||||
</script>
|
||||
|
||||
<ContextMenuPrimitive.Trigger
|
||||
bind:ref
|
||||
data-slot="context-menu-trigger"
|
||||
{...restProps}
|
||||
/>
|
||||
@@ -0,0 +1,34 @@
|
||||
import { ContextMenu as ContextMenuPrimitive } from "bits-ui";
|
||||
|
||||
import Trigger from "./context-menu-trigger.svelte";
|
||||
import Group from "./context-menu-group.svelte";
|
||||
import Item from "./context-menu-item.svelte";
|
||||
import Content from "./context-menu-content.svelte";
|
||||
import Shortcut from "./context-menu-shortcut.svelte";
|
||||
import Separator from "./context-menu-separator.svelte";
|
||||
import Label from "./context-menu-label.svelte";
|
||||
|
||||
const Sub = ContextMenuPrimitive.Sub;
|
||||
const Root = ContextMenuPrimitive.Root;
|
||||
|
||||
export {
|
||||
Sub,
|
||||
Root,
|
||||
Item,
|
||||
Label,
|
||||
Group,
|
||||
Trigger,
|
||||
Content,
|
||||
Shortcut,
|
||||
Separator,
|
||||
//
|
||||
Root as ContextMenu,
|
||||
Sub as ContextMenuSub,
|
||||
Item as ContextMenuItem,
|
||||
Group as ContextMenuGroup,
|
||||
Content as ContextMenuContent,
|
||||
Trigger as ContextMenuTrigger,
|
||||
Shortcut as ContextMenuShortcut,
|
||||
Separator as ContextMenuSeparator,
|
||||
Label as ContextMenuLabel,
|
||||
};
|
||||
Reference in New Issue
Block a user