Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
94a3fd0
refactor: swap out dropdown with radix components
Mar 18, 2025
b061416
refactor: add, popover, stories, update Dropdown menu to use unraid u…
Mar 19, 2025
5fda057
refactor: add all changes files from refactor
Mar 19, 2025
2a69007
refactor: add hardcoded width to dropdown menu
Mar 19, 2025
dc8a809
chore: update width to 350px
Mar 19, 2025
1a33f0d
chore: add missing imports
Mar 19, 2025
cb9ec2d
chore: remove unused import
Mar 19, 2025
f467258
fix: update BrandLoading to use type indexes
Mar 19, 2025
9935ed8
chore: run prettier on newly installed dropdown components
Mar 20, 2025
c869b29
refactor: create seperate arrow component for dropdown menu and fix d…
Mar 20, 2025
8ada6cd
feat: add DropdownMenuArrow component
Mar 20, 2025
6242560
refactor: remove promo related file and refrences, store from Dropdow…
Mar 20, 2025
733849a
chore: remove unused import
Mar 20, 2025
c3b9038
fix: add modal true to DropdownMenu and switch select component impor…
Mar 21, 2025
88189f7
refactor: update shadcn select to latest and use teleport in select s…
Mar 21, 2025
2d0c144
style: adjust DropdownMenu width for better responsiveness
zackspear Mar 21, 2025
590ca3c
style: format and clean up code in DropdownConnectStatus.vue for cons…
zackspear Mar 21, 2025
6f2bab9
refactor: fix unraid-ui typescript errors, amd move usePortal to unra…
Mar 24, 2025
e7e05ad
fix: leave modal prop at default for dropdownMenu to fix trigger issue
Mar 24, 2025
8ea4d8f
fix: config provider around dropdown
elibosley Mar 24, 2025
0d29e71
refactor: remove element from useTeleport
Mar 24, 2025
cfc6aa3
chore: config provider
elibosley Mar 24, 2025
4fed857
chore: fix dropdown config
elibosley Mar 24, 2025
ae35610
chore: fix modals div
elibosley Mar 24, 2025
5161d10
chore: remove casting on teleport in DropdownMenuContent
Mar 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 108 additions & 104 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions unraid-ui/.storybook/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ const preview: Preview = {
},
},
},
// Add decorator to include modals container in every story
decorators: [
(story) => ({
components: { story },
template: `
<div>
<div id="modals"></div>
<story />
</div>
`,
}),
],
};

export default preview;
13 changes: 7 additions & 6 deletions unraid-ui/components.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@
"$schema": "https://shadcn-vue.com/schema.json",
"style": "default",
"typescript": true,
"tsConfigPath": "./tsconfig.json",
"tailwind": {
"config": "./tailwind.config.ts",
"css": "./src/styles/globals.css",
"config": "tailwind.config.ts",
"css": "src/styles/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"framework": "vite",
"aliases": {
"components": "@/components/common",
"utils": "@/lib/utils"
}
"composables": "@/composables",
"utils": "@/lib/utils",
"lib": "@/lib"
},
"iconLibrary": "lucide"
}
2 changes: 1 addition & 1 deletion unraid-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
"kebab-case": "^2.0.1",
"lucide-vue-next": "^0.483.0",
"radix-vue": "^1.9.13",
"reka-ui": "^2.0.2",
"shadcn-vue": "^1.0.0",
"reka-ui": "^2.1.0",
"tailwind-merge": "^2.6.0",
"vue-sonner": "^1.3.0"
},
Expand Down
12 changes: 8 additions & 4 deletions unraid-ui/src/components/brand/BrandLoading.ce.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
<script setup lang="ts">
import { cn } from '@/lib/utils';
import { computed } from 'vue';
import { brandLoadingVariants, markAnimations } from './brand-loading.variants';
import {
brandLoadingVariants,
markAnimations,
type BrandLoadingVariants,
} from './brand-loading.variants';

export interface Props {
variant?: 'default' | 'black' | 'white';
size?: 'sm' | 'md' | 'lg' | 'full';
variant?: BrandLoadingVariants['variant'];
size?: BrandLoadingVariants['size'];
class?: string;
title?: string;
}
Expand All @@ -22,7 +26,7 @@ const GRADIENT_COLORS = {
default: { start: '#e32929', stop: '#ff8d30' },
} as const;

const gradientColors = computed(() => GRADIENT_COLORS[props.variant]);
const gradientColors = computed(() => GRADIENT_COLORS[props.variant as keyof typeof GRADIENT_COLORS]);

const classes = computed(() => {
return cn(brandLoadingVariants({ variant: props.variant, size: props.size }), props.class);
Expand Down
40 changes: 23 additions & 17 deletions unraid-ui/src/components/brand/brand-loading.variants.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
import { cva } from 'class-variance-authority';
import { cva, type VariantProps } from 'class-variance-authority';

export const brandLoadingVariants = cva('inline-flex items-center justify-center w-full h-full aspect-[7/4]', {
variants: {
variant: {
default: '',
black: 'text-black fill-black',
white: 'text-white fill-white',
export const brandLoadingVariants = cva(
'inline-flex items-center justify-center w-full h-full aspect-[7/4]',
{
variants: {
variant: {
default: '',
black: 'text-black fill-black',
white: 'text-white fill-white',
},
size: {
sm: 'w-12',
md: 'w-16',
lg: 'w-20',
full: 'w-full',
custom: '',
},
},
size: {
sm: 'w-12',
md: 'w-16',
lg: 'w-20',
full: 'w-full',
defaultVariants: {
variant: 'default',
},
},
defaultVariants: {
variant: 'default',
},
});
}
);

export const markAnimations = {
mark_2_4: 'animate-mark-2',
mark_3: 'animate-mark-3',
mark_6_8: 'animate-mark-6',
mark_7: 'animate-mark-7',
};

export type BrandLoadingVariants = VariantProps<typeof brandLoadingVariants>;
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<script setup lang="ts">
import {
DropdownMenuRoot,
useForwardPropsEmits,
type DropdownMenuRootEmits,
type DropdownMenuRootProps,
useForwardPropsEmits,
} from "radix-vue";
} from 'reka-ui';

const props = defineProps<DropdownMenuRootProps>();
const emits = defineEmits<DropdownMenuRootEmits>();

const forwarded = useForwardPropsEmits(props, emits);
const forwarded = useForwardPropsEmits<DropdownMenuRootProps, 'update:open'>(props, emits);
</script>

<template>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script setup lang="ts">
import { cn } from '@/lib/utils';
import {
DropdownMenuArrow as RekaDropdownMenuArrow,
useForwardProps,
type DropdownMenuArrowProps,
} from 'reka-ui';
import { computed, type HTMLAttributes } from 'vue';

const props = defineProps<DropdownMenuArrowProps & { class?: HTMLAttributes['class'] }>();

const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;
return delegated;
});

const forwardedProps = useForwardProps(delegatedProps);
</script>

<template>
<RekaDropdownMenuArrow
v-bind="forwardedProps"
:class="
cn(
'fill-popover data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
props.class
)
"
/>
</template>
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from "vue";
import { cn } from '@/lib/utils';
import { Check } from 'lucide-vue-next';
import {
DropdownMenuCheckboxItem,
type DropdownMenuCheckboxItemEmits,
type DropdownMenuCheckboxItemProps,
DropdownMenuItemIndicator,
useForwardPropsEmits,
} from "radix-vue";
import { Check } from "lucide-vue-next";
import { cn } from "@/lib/utils";
type DropdownMenuCheckboxItemEmits,
type DropdownMenuCheckboxItemProps,
} from 'reka-ui';
import { computed, type HTMLAttributes } from 'vue';

const props = defineProps<
DropdownMenuCheckboxItemProps & { class?: HTMLAttributes["class"] }
>();
const props = defineProps<DropdownMenuCheckboxItemProps & { class?: HTMLAttributes['class'] }>();
const emits = defineEmits<DropdownMenuCheckboxItemEmits>();

const delegatedProps = computed(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,48 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from "vue";
import useTeleport from '@/composables/useTeleport';
import { cn } from '@/lib/utils';
import {
DropdownMenuContent,
type DropdownMenuContentEmits,
type DropdownMenuContentProps,
DropdownMenuPortal,
useForwardPropsEmits,
} from "radix-vue";
import { cn } from "@/lib/utils";
type DropdownMenuContentEmits,
type DropdownMenuContentProps,
} from 'reka-ui';
import { computed, type HTMLAttributes } from 'vue';

const { teleportTarget } = useTeleport();

const props = withDefaults(
defineProps<DropdownMenuContentProps & { class?: HTMLAttributes["class"] }>(),
defineProps<DropdownMenuContentProps & { class?: HTMLAttributes['class'] }>(),
{
sideOffset: 4,
class: undefined,
}
);
const emits = defineEmits<DropdownMenuContentEmits>();

const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;

return delegated;
});

const forwarded = useForwardPropsEmits(delegatedProps, emits);
</script>

<template>
<DropdownMenuPortal>
<DropdownMenuPortal :to="teleportTarget">
<DropdownMenuContent
v-bind="forwarded"
side="bottom"
:class="
cn(
'z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 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',
'z-50 min-w-32 rounded-lg bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 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',
props.class
)
"
>
<slot />
<div class="overflow-hidden">
<slot />
</div>
</DropdownMenuContent>
</DropdownMenuPortal>
</template>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { DropdownMenuGroup, type DropdownMenuGroupProps } from "radix-vue";
import { DropdownMenuGroup, type DropdownMenuGroupProps } from 'reka-ui';

const props = defineProps<DropdownMenuGroupProps>();
</script>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from "vue";
import {
DropdownMenuItem,
type DropdownMenuItemProps,
useForwardProps,
} from "radix-vue";
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils';
import { DropdownMenuItem, useForwardProps, type DropdownMenuItemProps } from 'reka-ui';
import { computed, type HTMLAttributes } from 'vue';

const props = defineProps<
DropdownMenuItemProps & { class?: HTMLAttributes["class"]; inset?: boolean }
DropdownMenuItemProps & { class?: HTMLAttributes['class']; inset?: boolean }
>();

const delegatedProps = computed(() => {
Expand All @@ -25,7 +21,7 @@ const forwardedProps = useForwardProps(delegatedProps);
v-bind="forwardedProps"
: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 focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
'relative flex cursor-default select-none items-center rounded-sm gap-2 px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0',
inset && 'pl-8',
props.class
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from "vue";
import {
DropdownMenuLabel,
type DropdownMenuLabelProps,
useForwardProps,
} from "radix-vue";
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils';
import { DropdownMenuLabel, useForwardProps, type DropdownMenuLabelProps } from 'reka-ui';
import { computed, type HTMLAttributes } from 'vue';

const props = defineProps<
DropdownMenuLabelProps & { class?: HTMLAttributes["class"]; inset?: boolean }
DropdownMenuLabelProps & { class?: HTMLAttributes['class']; inset?: boolean }
>();

const delegatedProps = computed(() => {
Expand All @@ -23,9 +19,7 @@ const forwardedProps = useForwardProps(delegatedProps);
<template>
<DropdownMenuLabel
v-bind="forwardedProps"
:class="
cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', props.class)
"
:class="cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', props.class)"
>
<slot />
</DropdownMenuLabel>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<script setup lang="ts">
import {
DropdownMenuRadioGroup,
useForwardPropsEmits,
type DropdownMenuRadioGroupEmits,
type DropdownMenuRadioGroupProps,
useForwardPropsEmits,
} from "radix-vue";
} from 'reka-ui';

const props = defineProps<DropdownMenuRadioGroupProps>();
const emits = defineEmits<DropdownMenuRadioGroupEmits>();

const forwarded = useForwardPropsEmits(props, emits);
const forwarded = useForwardPropsEmits<DropdownMenuRadioGroupProps, 'update:modelValue'>(props, emits);
</script>

<template>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from "vue";
import { cn } from '@/lib/utils';
import { Circle } from 'lucide-vue-next';
import {
DropdownMenuItemIndicator,
DropdownMenuRadioItem,
useForwardPropsEmits,
type DropdownMenuRadioItemEmits,
type DropdownMenuRadioItemProps,
useForwardPropsEmits,
} from "radix-vue";
import { Circle } from "lucide-vue-next";
import { cn } from "@/lib/utils";
} from 'reka-ui';
import { computed, type HTMLAttributes } from 'vue';

const props = defineProps<
DropdownMenuRadioItemProps & { class?: HTMLAttributes["class"] }
>();
const props = defineProps<DropdownMenuRadioItemProps & { class?: HTMLAttributes['class'] }>();

const emits = defineEmits<DropdownMenuRadioItemEmits>();

Expand Down
Loading
Loading