aboutsummaryrefslogtreecommitdiffstats
path: root/code/frontend/src/components/ui
diff options
context:
space:
mode:
Diffstat (limited to 'code/frontend/src/components/ui')
-rw-r--r--code/frontend/src/components/ui/button/button.svelte25
-rw-r--r--code/frontend/src/components/ui/button/index.ts48
-rw-r--r--code/frontend/src/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte35
-rw-r--r--code/frontend/src/components/ui/dropdown-menu/dropdown-menu-content.svelte26
-rw-r--r--code/frontend/src/components/ui/dropdown-menu/dropdown-menu-item.svelte31
-rw-r--r--code/frontend/src/components/ui/dropdown-menu/dropdown-menu-label.svelte19
-rw-r--r--code/frontend/src/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte11
-rw-r--r--code/frontend/src/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte35
-rw-r--r--code/frontend/src/components/ui/dropdown-menu/dropdown-menu-separator.svelte11
-rw-r--r--code/frontend/src/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte13
-rw-r--r--code/frontend/src/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte29
-rw-r--r--code/frontend/src/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte32
-rw-r--r--code/frontend/src/components/ui/dropdown-menu/index.ts48
13 files changed, 363 insertions, 0 deletions
diff --git a/code/frontend/src/components/ui/button/button.svelte b/code/frontend/src/components/ui/button/button.svelte
new file mode 100644
index 0000000..196ae77
--- /dev/null
+++ b/code/frontend/src/components/ui/button/button.svelte
@@ -0,0 +1,25 @@
+<script lang="ts">
+ import { Button as ButtonPrimitive } from 'bits-ui'
+ import { type Events, type Props, buttonVariants } from './index.js'
+ import { cn } from '$utils/ui.js'
+
+ type $$Props = Props
+ type $$Events = Events
+
+ let className: $$Props['class'] = undefined
+ export let variant: $$Props['variant'] = 'default'
+ export let size: $$Props['size'] = 'default'
+ export let builders: $$Props['builders'] = []
+ export { className as class }
+</script>
+
+<ButtonPrimitive.Root
+ {builders}
+ class={cn(buttonVariants({ variant, size, className }))}
+ type="button"
+ {...$$restProps}
+ on:click
+ on:keydown
+>
+ <slot />
+</ButtonPrimitive.Root>
diff --git a/code/frontend/src/components/ui/button/index.ts b/code/frontend/src/components/ui/button/index.ts
new file mode 100644
index 0000000..9cfd91c
--- /dev/null
+++ b/code/frontend/src/components/ui/button/index.ts
@@ -0,0 +1,48 @@
+import type { Button as ButtonPrimitive } from 'bits-ui'
+import { type VariantProps, tv } from 'tailwind-variants'
+import Root from './button.svelte'
+
+const buttonVariants = tv({
+ base: 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50',
+ variants: {
+ variant: {
+ default: 'bg-primary text-primary-foreground shadow hover:bg-primary/90',
+ destructive: 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',
+ outline: 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',
+ secondary: 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',
+ ghost: 'hover:bg-accent hover:text-accent-foreground',
+ link: 'text-primary underline-offset-4 hover:underline'
+ },
+ size: {
+ default: 'h-9 px-4 py-2',
+ sm: 'h-8 rounded-md px-3 text-xs',
+ lg: 'h-10 rounded-md px-8',
+ icon: 'h-9 w-9'
+ }
+ },
+ defaultVariants: {
+ variant: 'default',
+ size: 'default'
+ }
+})
+
+type Variant = VariantProps<typeof buttonVariants>['variant']
+type Size = VariantProps<typeof buttonVariants>['size']
+
+type Props = ButtonPrimitive.Props & {
+ variant?: Variant
+ size?: Size
+}
+
+type Events = ButtonPrimitive.Events
+
+export {
+ Root,
+ type Props,
+ type Events,
+ //
+ Root as Button,
+ type Props as ButtonProps,
+ type Events as ButtonEvents,
+ buttonVariants
+}
diff --git a/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte
new file mode 100644
index 0000000..ea02af0
--- /dev/null
+++ b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte
@@ -0,0 +1,35 @@
+<script lang="ts">
+ import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'
+ import Check from 'svelte-radix/Check.svelte'
+ import { cn } from '$utils/ui'
+
+ type $$Props = DropdownMenuPrimitive.CheckboxItemProps
+ type $$Events = DropdownMenuPrimitive.CheckboxItemEvents
+
+ let className: $$Props['class'] = undefined
+ export let checked: $$Props['checked'] = undefined
+ export { className as class }
+</script>
+
+<DropdownMenuPrimitive.CheckboxItem
+ bind:checked
+ class={cn(
+ 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50',
+ className
+ )}
+ {...$$restProps}
+ on:click
+ on:keydown
+ on:focusin
+ on:focusout
+ on:pointerdown
+ on:pointerleave
+ on:pointermove
+>
+ <span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
+ <DropdownMenuPrimitive.CheckboxIndicator>
+ <Check class="h-4 w-4" />
+ </DropdownMenuPrimitive.CheckboxIndicator>
+ </span>
+ <slot />
+</DropdownMenuPrimitive.CheckboxItem>
diff --git a/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-content.svelte b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-content.svelte
new file mode 100644
index 0000000..a2b8da7
--- /dev/null
+++ b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-content.svelte
@@ -0,0 +1,26 @@
+<script lang="ts">
+ import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'
+ import { cn, flyAndScale } from '$utils/ui'
+
+ type $$Props = DropdownMenuPrimitive.ContentProps
+
+ let className: $$Props['class'] = undefined
+ export let sideOffset: $$Props['sideOffset'] = 4
+ export let transition: $$Props['transition'] = flyAndScale
+ export let transitionConfig: $$Props['transitionConfig'] = undefined
+ export { className as class }
+</script>
+
+<DropdownMenuPrimitive.Content
+ {transition}
+ {transitionConfig}
+ {sideOffset}
+ class={cn(
+ 'z-50 min-w-[8rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none',
+ className
+ )}
+ {...$$restProps}
+ on:keydown
+>
+ <slot />
+</DropdownMenuPrimitive.Content>
diff --git a/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-item.svelte b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-item.svelte
new file mode 100644
index 0000000..ed45da7
--- /dev/null
+++ b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-item.svelte
@@ -0,0 +1,31 @@
+<script lang="ts">
+ import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'
+ import { cn } from '$utils/ui'
+
+ type $$Props = DropdownMenuPrimitive.ItemProps & {
+ inset?: boolean
+ }
+ type $$Events = DropdownMenuPrimitive.ItemEvents
+
+ let className: $$Props['class'] = undefined
+ export let inset: $$Props['inset'] = undefined
+ export { className as class }
+</script>
+
+<DropdownMenuPrimitive.Item
+ class={cn(
+ 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50',
+ inset && 'pl-8',
+ className
+ )}
+ on:click
+ on:keydown
+ on:focusin
+ on:focusout
+ on:pointerdown
+ on:pointerleave
+ on:pointermove
+ {...$$restProps}
+>
+ <slot />
+</DropdownMenuPrimitive.Item>
diff --git a/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-label.svelte b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-label.svelte
new file mode 100644
index 0000000..69fddd1
--- /dev/null
+++ b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-label.svelte
@@ -0,0 +1,19 @@
+<script lang="ts">
+ import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'
+ import { cn } from '$utils/ui'
+
+ type $$Props = DropdownMenuPrimitive.LabelProps & {
+ inset?: boolean
+ }
+
+ let className: $$Props['class'] = undefined
+ export let inset: $$Props['inset'] = undefined
+ export { className as class }
+</script>
+
+<DropdownMenuPrimitive.Label
+ class={cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', className)}
+ {...$$restProps}
+>
+ <slot />
+</DropdownMenuPrimitive.Label>
diff --git a/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte
new file mode 100644
index 0000000..c07bd1a
--- /dev/null
+++ b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte
@@ -0,0 +1,11 @@
+<script lang="ts">
+ import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'
+
+ type $$Props = DropdownMenuPrimitive.RadioGroupProps
+
+ export let value: $$Props['value'] = undefined
+</script>
+
+<DropdownMenuPrimitive.RadioGroup {...$$restProps} bind:value>
+ <slot />
+</DropdownMenuPrimitive.RadioGroup>
diff --git a/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte
new file mode 100644
index 0000000..c754953
--- /dev/null
+++ b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte
@@ -0,0 +1,35 @@
+<script lang="ts">
+ import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'
+ import DotFilled from 'svelte-radix/DotFilled.svelte'
+ import { cn } from '$utils/ui'
+
+ type $$Props = DropdownMenuPrimitive.RadioItemProps
+ type $$Events = DropdownMenuPrimitive.RadioItemEvents
+
+ let className: $$Props['class'] = undefined
+ export let value: DropdownMenuPrimitive.RadioItemProps['value']
+ export { className as class }
+</script>
+
+<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 data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50',
+ className
+ )}
+ {value}
+ {...$$restProps}
+ on:click
+ on:keydown
+ on:focusin
+ on:focusout
+ on:pointerdown
+ on:pointerleave
+ on:pointermove
+>
+ <span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
+ <DropdownMenuPrimitive.RadioIndicator>
+ <DotFilled class="h-4 w-4 fill-current" />
+ </DropdownMenuPrimitive.RadioIndicator>
+ </span>
+ <slot />
+</DropdownMenuPrimitive.RadioItem>
diff --git a/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-separator.svelte
new file mode 100644
index 0000000..b6c5798
--- /dev/null
+++ b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-separator.svelte
@@ -0,0 +1,11 @@
+<script lang="ts">
+ import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'
+ import { cn } from '$utils/ui'
+
+ type $$Props = DropdownMenuPrimitive.SeparatorProps
+
+ let className: $$Props['class'] = undefined
+ export { className as class }
+</script>
+
+<DropdownMenuPrimitive.Separator class={cn('-mx-1 my-1 h-px bg-muted', className)} {...$$restProps} />
diff --git a/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte
new file mode 100644
index 0000000..f9e5953
--- /dev/null
+++ b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte
@@ -0,0 +1,13 @@
+<script lang="ts">
+ import type { HTMLAttributes } from 'svelte/elements'
+ import { cn } from '$utils/ui'
+
+ type $$Props = HTMLAttributes<HTMLSpanElement>
+
+ let className: $$Props['class'] = undefined
+ export { className as class }
+</script>
+
+<span class={cn('ml-auto text-xs tracking-widest opacity-60', className)} {...$$restProps}>
+ <slot />
+</span>
diff --git a/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte
new file mode 100644
index 0000000..7c00a1b
--- /dev/null
+++ b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte
@@ -0,0 +1,29 @@
+<script lang="ts">
+ import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'
+ import { cn, flyAndScale } from '$utils/ui'
+
+ type $$Props = DropdownMenuPrimitive.SubContentProps
+
+ let className: $$Props['class'] = undefined
+ export let transition: $$Props['transition'] = flyAndScale
+ export let transitionConfig: $$Props['transitionConfig'] = {
+ x: -10,
+ y: 0
+ }
+ export { className as class }
+</script>
+
+<DropdownMenuPrimitive.SubContent
+ {transition}
+ {transitionConfig}
+ class={cn(
+ 'z-50 min-w-[8rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-lg focus:outline-none',
+ className
+ )}
+ {...$$restProps}
+ on:keydown
+ on:focusout
+ on:pointermove
+>
+ <slot />
+</DropdownMenuPrimitive.SubContent>
diff --git a/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte
new file mode 100644
index 0000000..4967d2b
--- /dev/null
+++ b/code/frontend/src/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte
@@ -0,0 +1,32 @@
+<script lang="ts">
+ import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'
+ import ChevronRight from 'svelte-radix/ChevronRight.svelte'
+ import { cn } from '$utils/ui'
+
+ type $$Props = DropdownMenuPrimitive.SubTriggerProps & {
+ inset?: boolean
+ }
+ type $$Events = DropdownMenuPrimitive.SubTriggerEvents
+
+ let className: $$Props['class'] = undefined
+ export let inset: $$Props['inset'] = undefined
+ export { className as class }
+</script>
+
+<DropdownMenuPrimitive.SubTrigger
+ class={cn(
+ 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[highlighted]:bg-accent data-[state=open]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:text-accent-foreground',
+ inset && 'pl-8',
+ className
+ )}
+ {...$$restProps}
+ on:click
+ on:keydown
+ on:focusin
+ on:focusout
+ on:pointerleave
+ on:pointermove
+>
+ <slot />
+ <ChevronRight class="ml-auto h-4 w-4" />
+</DropdownMenuPrimitive.SubTrigger>
diff --git a/code/frontend/src/components/ui/dropdown-menu/index.ts b/code/frontend/src/components/ui/dropdown-menu/index.ts
new file mode 100644
index 0000000..df959fa
--- /dev/null
+++ b/code/frontend/src/components/ui/dropdown-menu/index.ts
@@ -0,0 +1,48 @@
+import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'
+import Item from './dropdown-menu-item.svelte'
+import Label from './dropdown-menu-label.svelte'
+import Content from './dropdown-menu-content.svelte'
+import Shortcut from './dropdown-menu-shortcut.svelte'
+import RadioItem from './dropdown-menu-radio-item.svelte'
+import Separator from './dropdown-menu-separator.svelte'
+import RadioGroup from './dropdown-menu-radio-group.svelte'
+import SubContent from './dropdown-menu-sub-content.svelte'
+import SubTrigger from './dropdown-menu-sub-trigger.svelte'
+import CheckboxItem from './dropdown-menu-checkbox-item.svelte'
+
+const Sub = DropdownMenuPrimitive.Sub
+const Root = DropdownMenuPrimitive.Root
+const Trigger = DropdownMenuPrimitive.Trigger
+const Group = DropdownMenuPrimitive.Group
+
+export {
+ Sub,
+ Root,
+ Item,
+ Label,
+ Group,
+ Trigger,
+ Content,
+ Shortcut,
+ Separator,
+ RadioItem,
+ SubContent,
+ SubTrigger,
+ RadioGroup,
+ CheckboxItem,
+ //
+ Root as DropdownMenu,
+ Sub as DropdownMenuSub,
+ Item as DropdownMenuItem,
+ Label as DropdownMenuLabel,
+ Group as DropdownMenuGroup,
+ Content as DropdownMenuContent,
+ Trigger as DropdownMenuTrigger,
+ Shortcut as DropdownMenuShortcut,
+ RadioItem as DropdownMenuRadioItem,
+ Separator as DropdownMenuSeparator,
+ RadioGroup as DropdownMenuRadioGroup,
+ SubContent as DropdownMenuSubContent,
+ SubTrigger as DropdownMenuSubTrigger,
+ CheckboxItem as DropdownMenuCheckboxItem
+}