import type { Meta, StoryObj } from '@storybook/vue3' import { ref } from 'vue' import TitanInlineSelectRenderer from './TitanInlineSelectRenderer.vue' import type { SelectOption } from '@/types/components' const meta = { component: TitanInlineSelectRenderer, title: 'UI/Internal/TitanInlineSelectRenderer', tags: ['autodocs'], argTypes: { options: { control: 'object', description: 'Array of SelectOption objects to display as pills' }, label: { control: 'text', description: 'Label text displayed above the options' }, showCheckmark: { control: 'boolean', description: 'Show checkmark on selected options' }, error: { control: 'boolean', description: 'Show error state' }, errorMessage: { control: 'text', description: 'Error message to display' }, disabled: { control: 'boolean', description: 'Disable all options' }, multiple: { control: 'boolean', description: 'Allow multiple selections' } } } satisfies Meta export default meta type Story = StoryObj /** * Default inline renderer with basic options */ export const Default: Story = { render: (args) => ({ components: { TitanInlineSelectRenderer }, setup() { const selected = ref('option1') const isSelected = (option: SelectOption) => selected.value === option.value const handleSelect = (option: SelectOption) => { selected.value = option.value } const getStateClasses = (option: SelectOption) => ({ base: 'px-4 py-1.5 rounded-2xl text-sm font-medium transition-colors', state: isSelected(option) ? 'bg-titan-purple-500 text-white border-titan-purple-500 shadow-sm' : 'bg-titan-green-800/10 text-titan-green-800 border-titan-green-800/20 hover:bg-titan-green-800/15', disabled: option.disabled ? 'opacity-50 cursor-not-allowed' : '' }) const getOptionAriaAttributes = (option: SelectOption) => ({ role: 'radio', 'aria-checked': isSelected(option), 'aria-disabled': option.disabled }) return { args, isSelected, handleSelect, getStateClasses, getOptionAriaAttributes } }, template: ` ` }), args: { options: [ { value: 'option1', label: 'Option 1' }, { value: 'option2', label: 'Option 2' }, { value: 'option3', label: 'Option 3' } ], label: 'SELECT AN OPTION' } } /** * Multiple selection with checkmarks */ export const MultipleSelection: Story = { render: (args) => ({ components: { TitanInlineSelectRenderer }, setup() { const selected = ref(['option1', 'option3']) const isSelected = (option: SelectOption) => selected.value.includes(option.value as string) const handleSelect = (option: SelectOption) => { const index = selected.value.indexOf(option.value as string) if (index > -1) { selected.value.splice(index, 1) } else { selected.value.push(option.value as string) } } const getStateClasses = (option: SelectOption) => ({ base: 'px-4 py-1.5 rounded-2xl text-sm font-medium transition-colors', state: isSelected(option) ? 'bg-titan-purple-500 text-white border-titan-purple-500 shadow-sm' : 'bg-titan-green-800/10 text-titan-green-800 border-titan-green-800/20 hover:bg-titan-green-800/15', disabled: option.disabled ? 'opacity-50 cursor-not-allowed' : '' }) const getOptionAriaAttributes = (option: SelectOption) => ({ role: 'checkbox', 'aria-checked': isSelected(option), 'aria-disabled': option.disabled }) return { args, isSelected, handleSelect, getStateClasses, getOptionAriaAttributes } }, template: ` ` }), args: { options: [ { value: 'option1', label: 'Option 1' }, { value: 'option2', label: 'Option 2' }, { value: 'option3', label: 'Option 3' }, { value: 'option4', label: 'Option 4' } ], label: 'SELECT ALL THAT APPLY', showCheckmark: true, multiple: true } } /** * With disabled options */ export const WithDisabledOptions: Story = { render: (args) => ({ components: { TitanInlineSelectRenderer }, setup() { const selected = ref('option1') const isSelected = (option: SelectOption) => selected.value === option.value const handleSelect = (option: SelectOption) => { if (!option.disabled) { selected.value = option.value } } const getStateClasses = (option: SelectOption) => ({ base: 'px-4 py-1.5 rounded-2xl text-sm font-medium transition-colors', state: isSelected(option) ? 'bg-titan-purple-500 text-white border-titan-purple-500 shadow-sm' : 'bg-titan-green-800/10 text-titan-green-800 border-titan-green-800/20 hover:bg-titan-green-800/15', disabled: option.disabled ? 'opacity-50 cursor-not-allowed' : '' }) const getOptionAriaAttributes = (option: SelectOption) => ({ role: 'radio', 'aria-checked': isSelected(option), 'aria-disabled': option.disabled }) return { args, isSelected, handleSelect, getStateClasses, getOptionAriaAttributes } }, template: ` ` }), args: { options: [ { value: 'option1', label: 'Option 1' }, { value: 'option2', label: 'Option 2', disabled: true }, { value: 'option3', label: 'Option 3' } ], label: 'SELECT AN OPTION' } } /** * Error state with message */ export const ErrorState: Story = { render: (args) => ({ components: { TitanInlineSelectRenderer }, setup() { const selected = ref('') const isSelected = (option: SelectOption) => selected.value === option.value const handleSelect = (option: SelectOption) => { selected.value = option.value } const getStateClasses = (option: SelectOption) => ({ base: 'px-4 py-1.5 rounded-2xl text-sm font-medium transition-colors', state: isSelected(option) ? 'bg-titan-purple-500 text-white border-titan-purple-500 shadow-sm' : 'bg-titan-green-800/10 text-titan-green-800 border-titan-green-800/20 hover:bg-titan-green-800/15', disabled: option.disabled ? 'opacity-50 cursor-not-allowed' : '' }) const getOptionAriaAttributes = (option: SelectOption) => ({ role: 'radio', 'aria-checked': isSelected(option), 'aria-disabled': option.disabled }) return { args, isSelected, handleSelect, getStateClasses, getOptionAriaAttributes } }, template: ` ` }), args: { options: [ { value: 'option1', label: 'Option 1' }, { value: 'option2', label: 'Option 2' }, { value: 'option3', label: 'Option 3' } ], label: 'SELECT AN OPTION', error: true, errorMessage: 'Please select at least one option' } } /** * No label variant */ export const NoLabel: Story = { render: (args) => ({ components: { TitanInlineSelectRenderer }, setup() { const selected = ref('option2') const isSelected = (option: SelectOption) => selected.value === option.value const handleSelect = (option: SelectOption) => { selected.value = option.value } const getStateClasses = (option: SelectOption) => ({ base: 'px-4 py-1.5 rounded-2xl text-sm font-medium transition-colors', state: isSelected(option) ? 'bg-titan-purple-500 text-white border-titan-purple-500 shadow-sm' : 'bg-titan-green-800/10 text-titan-green-800 border-titan-green-800/20 hover:bg-titan-green-800/15', disabled: option.disabled ? 'opacity-50 cursor-not-allowed' : '' }) const getOptionAriaAttributes = (option: SelectOption) => ({ role: 'radio', 'aria-checked': isSelected(option), 'aria-disabled': option.disabled }) return { args, isSelected, handleSelect, getStateClasses, getOptionAriaAttributes } }, template: ` ` }), args: { options: [ { value: 'option1', label: 'Option 1' }, { value: 'option2', label: 'Option 2' }, { value: 'option3', label: 'Option 3' } ] } }