[READ-ONLY] a fast, modern browser for the npm registry
at main 77 lines 2.3 kB view raw
1<script setup lang="ts"> 2import type { SelectBaseProps } from './Base.vue' 3 4const SELECT_FIELD_SIZES = { 5 sm: 'text-xs py-1.75 ps-2 pe-6 rounded-md', 6 md: 'text-sm py-2.25 ps-3 pe-9 rounded-lg', 7 lg: 'text-base py-4 ps-6 pe-15 rounded-xl', 8} 9const SELECT_FIELD_ICON_SIZES = { 10 sm: 'inset-ie-2 size-[0.75rem]', 11 md: 'inset-ie-3 size-[1rem]', 12 lg: 'inset-ie-5 size-[1.5rem]', 13} 14const SELECT_FIELD_LABEL_SIZES = { 15 sm: 'text-2xs', 16 md: 'text-xs', 17 lg: 'text-sm', 18} 19 20const model = defineModel<string | undefined>({ default: undefined }) 21 22export interface SelectFieldProps extends SelectBaseProps { 23 items: { label: string; value: string; disabled?: boolean }[] 24 size?: keyof typeof SELECT_FIELD_SIZES 25 selectAttrs?: Omit<SelectBaseProps, 'size' | 'id'> & 26 Record<string, string | number | boolean | undefined> 27 label?: string 28 labelAttrs?: Record<string, string | number | boolean | undefined> 29 /** Visually hide label */ 30 hiddenLabel?: boolean 31 id: string 32 /** Render select full width */ 33 block?: boolean 34} 35 36const props = withDefaults(defineProps<SelectFieldProps>(), { 37 size: 'md', 38}) 39</script> 40 41<template> 42 <div class="group/select"> 43 <label 44 v-if="label" 45 :for="id" 46 v-bind="labelAttrs" 47 class="block mb-1 font-mono text-fg-subtle tracking-wide uppercase" 48 :class="[hiddenLabel ? 'sr-only' : '', SELECT_FIELD_LABEL_SIZES[size]]" 49 >{{ label }}</label 50 > 51 <div class="relative" :class="[block ? 'w-full' : 'w-fit']"> 52 <SelectBase 53 :disabled="disabled" 54 size="none" 55 class="appearance-none group-hover/select:border-fg-muted" 56 :class="[SELECT_FIELD_SIZES[size], block ? 'w-full' : 'w-fit']" 57 v-model="model" 58 v-bind="selectAttrs" 59 :id="id" 60 > 61 <option 62 v-for="item in items" 63 :key="item.value" 64 :value="item.value" 65 :disabled="item.disabled" 66 > 67 {{ item.label }} 68 </option> 69 </SelectBase> 70 <span 71 aria-hidden="true" 72 class="block i-lucide:chevron-down absolute top-1/2 -translate-y-1/2 text-fg-subtle pointer-events-none group-hover/select:text-fg group-focus-within/select:text-fg" 73 :class="[SELECT_FIELD_ICON_SIZES[size]]" 74 /> 75 </div> 76 </div> 77</template>