import { CheckIcon } from '@modrinth/assets' import type { Meta, StoryObj } from '@storybook/vue3-vite' import { computed, ref } from 'vue' import MultiSelect from '../../components/base/MultiSelect.vue' const meta = { title: 'Base/MultiSelect', // @ts-ignore - error comes from generically typed component component: MultiSelect, render: (args) => ({ components: { MultiSelect }, setup() { const selected = ref(args.modelValue) return { args, selected } }, template: /*html*/ `
`, }), } satisfies Meta export default meta type Story = StoryObj export const Default: Story = { args: { options: [ { value: 'en', label: 'English' }, { value: 'es', label: 'Spanish' }, { value: 'fr', label: 'French' }, { value: 'de', label: 'German' }, { value: 'zh-CN', label: 'Chinese (Simplified)' }, { value: 'ko', label: 'Korean' }, { value: 'ja', label: 'Japanese' }, { value: 'pt', label: 'Portuguese' }, { value: 'ru', label: 'Russian' }, { value: 'it', label: 'Italian' }, { value: 'ar', label: 'Arabic' }, ], modelValue: ['en', 'es', 'fr', 'zh-CN'], placeholder: 'Select languages', }, } export const WithSearch: Story = { args: { ...Default.args, searchable: true, searchPlaceholder: 'Search versions', }, } export const WithSelectAll: Story = { args: { ...Default.args, searchable: true, includeSelectAllOption: true, searchPlaceholder: 'Search versions', }, } export const WithSelectionActions: Story = { args: { ...Default.args, searchable: true, showSelectionActions: true, searchPlaceholder: 'Search versions', }, } export const WithTopSlot: Story = { args: { ...Default.args, modelValue: [], searchable: true, showSelectionActions: true, searchPlaceholder: 'Search languages', placeholder: 'All languages', }, render: (args) => ({ components: { CheckIcon, MultiSelect }, setup() { const selected = ref(args.modelValue) const isAllLanguagesSelected = computed(() => selected.value.length === 0) const selectAllLanguages = () => { selected.value = [] } return { args, isAllLanguagesSelected, selectAllLanguages, selected } }, template: /*html*/ `
`, }), } export const DropdownMinWidth: Story = { args: { ...Default.args, modelValue: ['en'], dropdownMinWidth: 320, placeholder: 'Languages', }, render: (args) => ({ components: { MultiSelect }, setup() { const selected = ref(args.modelValue) return { args, selected } }, template: /*html*/ `
`, }), } export const ManySelected: Story = { args: { ...Default.args, modelValue: ['en', 'es', 'fr', 'zh-CN', 'ko', 'ja', 'pt', 'ru', 'it', 'ar', 'de'], searchable: true, includeSelectAllOption: true, }, } export const TwoTagRows: Story = { args: { ...ManySelected.args, maxTagRows: 2, }, } export const CustomInputContent: Story = { args: { ...Default.args, modelValue: ['en', 'es'], fitContent: true, showChevron: false, clearable: false, triggerClass: 'h-10 max-w-[16rem] border border-solid border-surface-5 bg-surface-4 px-3 py-1.5 hover:bg-surface-5 hover:brightness-100 active:brightness-100', }, render: (args) => ({ components: { MultiSelect }, setup() { const selected = ref(args.modelValue) const selectedLabel = () => { if (selected.value.length === 0) return 'All languages' if (selected.value.length === 1) { const option = args.options.find((item) => item.value === selected.value[0]) return option?.label ?? '1 selected' } return `${selected.value.length} selected` } return { args, selected, selectedLabel } }, template: /*html*/ `
`, }), } export const WithBottomSlot: Story = { args: { ...Default.args, modelValue: ['en', 'es'], searchable: true, includeSelectAllOption: true, }, render: (args) => ({ components: { MultiSelect }, setup() { const selected = ref(args.modelValue) const minimum = ref('') return { args, selected, minimum } }, template: /*html*/ `
`, }), } export const NoOptions: Story = { args: { ...Default.args, options: [], modelValue: [], searchable: true, noOptionsMessage: 'No options available', }, } export const Empty: Story = { args: { ...Default.args, modelValue: [], }, }