mirror of
https://github.com/CorentinTh/it-tools.git
synced 2026-02-07 15:45:38 +00:00
287 lines
9.0 KiB
TypeScript
287 lines
9.0 KiB
TypeScript
import type {
|
|
DropdownMenuCheckboxItemProps,
|
|
DropdownMenuContentProps,
|
|
DropdownMenuGroupLabelProps,
|
|
DropdownMenuItemLabelProps,
|
|
DropdownMenuItemProps,
|
|
DropdownMenuRadioItemProps,
|
|
DropdownMenuRootProps,
|
|
DropdownMenuSeparatorProps,
|
|
DropdownMenuSubTriggerProps,
|
|
} from '@kobalte/core/dropdown-menu';
|
|
import type { PolymorphicProps } from '@kobalte/core/polymorphic';
|
|
import type { ComponentProps, ParentProps, ValidComponent } from 'solid-js';
|
|
import { cn } from '@/modules/ui/utils/cn';
|
|
import { DropdownMenu as DropdownMenuPrimitive } from '@kobalte/core/dropdown-menu';
|
|
import { mergeProps, splitProps } from 'solid-js';
|
|
|
|
export const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
export const DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
export const DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
export const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
|
|
export function DropdownMenu(props: DropdownMenuRootProps) {
|
|
const merge = mergeProps<DropdownMenuRootProps[]>({ gutter: 4 }, props);
|
|
|
|
return <DropdownMenuPrimitive {...merge} />;
|
|
}
|
|
|
|
type dropdownMenuContentProps<T extends ValidComponent = 'div'> =
|
|
DropdownMenuContentProps<T> & {
|
|
class?: string;
|
|
};
|
|
|
|
export function DropdownMenuContent<T extends ValidComponent = 'div'>(props: PolymorphicProps<T, dropdownMenuContentProps<T>>) {
|
|
const [local, rest] = splitProps(props as dropdownMenuContentProps, [
|
|
'class',
|
|
]);
|
|
|
|
return (
|
|
<DropdownMenuPrimitive.Portal>
|
|
<DropdownMenuPrimitive.Content
|
|
class={cn(
|
|
'min-w-8rem z-50 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[expanded]:(animate-in fade-in-0 zoom-in-95) data-[closed]:(animate-out fade-out-0 zoom-out-95) focus-visible:(outline-none ring-1.5 ring-ring) transition-shadow',
|
|
local.class,
|
|
)}
|
|
{...rest}
|
|
/>
|
|
</DropdownMenuPrimitive.Portal>
|
|
);
|
|
}
|
|
|
|
type dropdownMenuItemProps<T extends ValidComponent = 'div'> =
|
|
DropdownMenuItemProps<T> & {
|
|
class?: string;
|
|
inset?: boolean;
|
|
};
|
|
|
|
export function DropdownMenuItem<T extends ValidComponent = 'div'>(props: PolymorphicProps<T, dropdownMenuItemProps<T>>) {
|
|
const [local, rest] = splitProps(props as dropdownMenuItemProps, [
|
|
'class',
|
|
'inset',
|
|
]);
|
|
|
|
return (
|
|
<DropdownMenuPrimitive.Item
|
|
class={cn(
|
|
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:(bg-accent text-accent-foreground) data-[disabled]:(pointer-events-none opacity-50)',
|
|
local.inset && 'pl-8',
|
|
local.class,
|
|
)}
|
|
{...rest}
|
|
/>
|
|
);
|
|
}
|
|
|
|
type dropdownMenuGroupLabelProps<T extends ValidComponent = 'span'> =
|
|
DropdownMenuGroupLabelProps<T> & {
|
|
class?: string;
|
|
};
|
|
|
|
export function DropdownMenuGroupLabel<T extends ValidComponent = 'span'>(props: PolymorphicProps<T, dropdownMenuGroupLabelProps<T>>) {
|
|
const [local, rest] = splitProps(props as dropdownMenuGroupLabelProps, [
|
|
'class',
|
|
]);
|
|
|
|
return (
|
|
<DropdownMenuPrimitive.GroupLabel
|
|
as="div"
|
|
class={cn('px-2 py-1.5 text-sm font-semibold', local.class)}
|
|
{...rest}
|
|
/>
|
|
);
|
|
}
|
|
|
|
type dropdownMenuItemLabelProps<T extends ValidComponent = 'div'> =
|
|
DropdownMenuItemLabelProps<T> & {
|
|
class?: string;
|
|
};
|
|
|
|
export function DropdownMenuItemLabel<T extends ValidComponent = 'div'>(props: PolymorphicProps<T, dropdownMenuItemLabelProps<T>>) {
|
|
const [local, rest] = splitProps(props as dropdownMenuItemLabelProps, [
|
|
'class',
|
|
]);
|
|
|
|
return (
|
|
<DropdownMenuPrimitive.ItemLabel
|
|
as="div"
|
|
class={cn('px-2 py-1.5 text-sm font-semibold', local.class)}
|
|
{...rest}
|
|
/>
|
|
);
|
|
}
|
|
|
|
type dropdownMenuSeparatorProps<T extends ValidComponent = 'hr'> =
|
|
DropdownMenuSeparatorProps<T> & {
|
|
class?: string;
|
|
};
|
|
|
|
export function DropdownMenuSeparator<T extends ValidComponent = 'hr'>(props: PolymorphicProps<T, dropdownMenuSeparatorProps<T>>) {
|
|
const [local, rest] = splitProps(props as dropdownMenuSeparatorProps, [
|
|
'class',
|
|
]);
|
|
|
|
return (
|
|
<DropdownMenuPrimitive.Separator
|
|
class={cn('-mx-1 my-1 h-px bg-muted', local.class)}
|
|
{...rest}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export function DropdownMenuShortcut(props: ComponentProps<'span'>) {
|
|
const [local, rest] = splitProps(props, ['class']);
|
|
|
|
return (
|
|
<span
|
|
class={cn('ml-auto text-xs tracking-widest opacity-60', local.class)}
|
|
{...rest}
|
|
/>
|
|
);
|
|
}
|
|
|
|
type dropdownMenuSubTriggerProps<T extends ValidComponent = 'div'> = ParentProps<DropdownMenuSubTriggerProps<T> & { class?: string }>;
|
|
|
|
export function DropdownMenuSubTrigger<T extends ValidComponent = 'div'>(props: PolymorphicProps<T, dropdownMenuSubTriggerProps<T>>) {
|
|
const [local, rest] = splitProps(props as dropdownMenuSubTriggerProps, [
|
|
'class',
|
|
'children',
|
|
]);
|
|
|
|
return (
|
|
<DropdownMenuPrimitive.SubTrigger
|
|
class={cn(
|
|
'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[expanded]:bg-accent',
|
|
local.class,
|
|
)}
|
|
{...rest}
|
|
>
|
|
{local.children}
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="1em"
|
|
height="1em"
|
|
viewBox="0 0 24 24"
|
|
class="ml-auto h-4 w-4"
|
|
>
|
|
<path
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="m9 6l6 6l-6 6"
|
|
/>
|
|
<title>Arrow</title>
|
|
</svg>
|
|
</DropdownMenuPrimitive.SubTrigger>
|
|
);
|
|
}
|
|
|
|
type dropdownMenuSubContentProps<T extends ValidComponent = 'div'> =
|
|
DropdownMenuSubTriggerProps<T> & {
|
|
class?: string;
|
|
};
|
|
|
|
export function DropdownMenuSubContent<T extends ValidComponent = 'div'>(props: PolymorphicProps<T, dropdownMenuSubContentProps<T>>) {
|
|
const [local, rest] = splitProps(props as dropdownMenuSubContentProps, [
|
|
'class',
|
|
]);
|
|
|
|
return (
|
|
<DropdownMenuPrimitive.Portal>
|
|
<DropdownMenuPrimitive.SubContent
|
|
class={cn(
|
|
'min-w-8rem z-50 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[expanded]:(animate-in fade-in-0 zoom-in-95) data-[closed]:(animate-out fade-out-0 zoom-out-95)',
|
|
local.class,
|
|
)}
|
|
{...rest}
|
|
/>
|
|
</DropdownMenuPrimitive.Portal>
|
|
);
|
|
}
|
|
|
|
type dropdownMenuCheckboxItemProps<T extends ValidComponent = 'div'> = ParentProps<DropdownMenuCheckboxItemProps<T> & { class?: string }>;
|
|
|
|
export function DropdownMenuCheckboxItem<T extends ValidComponent = 'div'>(props: PolymorphicProps<T, dropdownMenuCheckboxItemProps<T>>) {
|
|
const [local, rest] = splitProps(props as dropdownMenuCheckboxItemProps, [
|
|
'class',
|
|
'children',
|
|
]);
|
|
|
|
return (
|
|
<DropdownMenuPrimitive.CheckboxItem
|
|
class={cn(
|
|
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:(bg-accent text-accent-foreground) data-[disabled]:(pointer-events-none opacity-50)',
|
|
local.class,
|
|
)}
|
|
{...rest}
|
|
>
|
|
<DropdownMenuPrimitive.ItemIndicator class="absolute left-2 inline-flex h-4 w-4 items-center justify-center">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
viewBox="0 0 24 24"
|
|
class="h-4 w-4"
|
|
>
|
|
<path
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="m5 12l5 5L20 7"
|
|
/>
|
|
<title>Checkbox</title>
|
|
</svg>
|
|
</DropdownMenuPrimitive.ItemIndicator>
|
|
{props.children}
|
|
</DropdownMenuPrimitive.CheckboxItem>
|
|
);
|
|
}
|
|
|
|
type dropdownMenuRadioItemProps<T extends ValidComponent = 'div'> = ParentProps<
|
|
DropdownMenuRadioItemProps<T> & {
|
|
class?: string;
|
|
}
|
|
>;
|
|
|
|
export function DropdownMenuRadioItem<T extends ValidComponent = 'div'>(props: PolymorphicProps<T, dropdownMenuRadioItemProps<T>>) {
|
|
const [local, rest] = splitProps(props as dropdownMenuRadioItemProps, [
|
|
'class',
|
|
'children',
|
|
]);
|
|
|
|
return (
|
|
<DropdownMenuPrimitive.RadioItem
|
|
class={cn(
|
|
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:(bg-accent text-accent-foreground) data-[disabled]:(pointer-events-none opacity-50)',
|
|
local.class,
|
|
)}
|
|
{...rest}
|
|
>
|
|
<DropdownMenuPrimitive.ItemIndicator class="absolute left-2 inline-flex h-4 w-4 items-center justify-center">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
viewBox="0 0 24 24"
|
|
class="h-2 w-2"
|
|
>
|
|
<g
|
|
fill="none"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
>
|
|
<path d="M0 0h24v24H0z" />
|
|
<path
|
|
fill="currentColor"
|
|
d="M7 3.34a10 10 0 1 1-4.995 8.984L2 12l.005-.324A10 10 0 0 1 7 3.34"
|
|
/>
|
|
</g>
|
|
<title>Radio</title>
|
|
</svg>
|
|
</DropdownMenuPrimitive.ItemIndicator>
|
|
{props.children}
|
|
</DropdownMenuPrimitive.RadioItem>
|
|
);
|
|
}
|