streaming, markdown, model selecting, and lots more

This commit is contained in:
Zoe
2026-02-02 23:16:06 -06:00
parent 8c28946703
commit d5a5945c03
114 changed files with 6109 additions and 2938 deletions
+30 -35
View File
@@ -2,71 +2,66 @@
import type { DropdownItem } from '~/types/dropdown';
interface Props {
items: DropdownItem[];
modelValue?: boolean;
items?: DropdownItem[];
placement?: 'right' | 'left' | 'center';
verticality?: 'asscending' | 'descending';
width?: string;
}
const props = withDefaults(defineProps<Props>(), {
modelValue: false,
placement: 'right',
verticality: 'descending',
width: 'auto'
})
width: 'auto',
});
const emit = defineEmits<{
(e: 'update:modelValue', value: boolean): void;
(e: 'select', item: DropdownItem): void;
}>()
const emit = defineEmits<(e: 'select', item: DropdownItem) => void>();
const triggerRef = ref<HTMLElement | null>(null)
const isOpen = defineModel<boolean>({ required: true })
const triggerRef = ref<HTMLElement | null>(null);
const isOpen = defineModel<boolean>({ required: false });
const toggle = () => {
isOpen.value = !isOpen.value
}
isOpen.value = !isOpen.value;
};
const select = (item: DropdownItem) => {
if (item.disabled || item.divider) return
emit('select', item)
isOpen.value = false
}
if (item.disabled || item.divider) return;
emit('select', item);
isOpen.value = false;
};
const placementClasses = computed(() => {
let classes = ''
let classes = '';
switch (props.placement) {
case 'right':
classes += 'right-0 '
break
classes += 'right-0 ';
break;
case 'left':
classes += 'left-0 '
break
classes += 'left-0 ';
break;
case 'center':
classes += 'left-1/2 -translate-x-1/2 '
break
classes += 'left-1/2 -translate-x-1/2 ';
break;
default:
classes += 'left-0 '
break
classes += 'left-0 ';
break;
}
switch (props.verticality) {
case 'asscending':
classes += 'bottom-full mb-1.5'
break
classes += 'bottom-full mb-1.5';
break;
case 'descending':
classes += 'top-full mt-1.5'
break
classes += 'top-full mt-1.5';
break;
}
return classes
})
return classes;
});
useClickOutside(triggerRef, () => {
isOpen.value = false
})
isOpen.value = false;
});
</script>
<template>
@@ -88,7 +83,7 @@ useClickOutside(triggerRef, () => {
:class="[
item.disabled
? 'opacity-50 cursor-not-allowed'
: 'hover:bg-[var(--color-highlight)] cursor-pointer'
: 'hover:bg-[var(--color-highlight)] focus-visible:bg-[var(--color-highlight)] cursor-pointer'
]">
<Icon v-if="item.icon" :name="item.icon" class="w-4 h-4 flex-shrink-0" />
<span class="text-sm whitespace-nowrap">{{ item.label }}</span>