219 lines
5.3 KiB
TypeScript
219 lines
5.3 KiB
TypeScript
//@ts-ignore
|
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
|
|
import { useState } from 'react';
|
|
|
|
import type { BoxerItem } from '../Boxer.types';
|
|
|
|
import { Boxer } from '../Boxer';
|
|
|
|
const meta: Meta<typeof Boxer> = {
|
|
component: Boxer,
|
|
parameters: {
|
|
layout: 'centered',
|
|
},
|
|
tags: ['autodocs'],
|
|
title: 'Components/Boxer',
|
|
};
|
|
|
|
export default meta;
|
|
type Story = StoryObj<typeof Boxer>;
|
|
|
|
// Sample data
|
|
const sampleData: Array<BoxerItem> = [
|
|
{ label: 'Apple', value: 'apple' },
|
|
{ label: 'Banana', value: 'banana' },
|
|
{ label: 'Cherry', value: 'cherry' },
|
|
{ label: 'Date', value: 'date' },
|
|
{ label: 'Elderberry', value: 'elderberry' },
|
|
{ label: 'Fig', value: 'fig' },
|
|
{ label: 'Grape', value: 'grape' },
|
|
{ label: 'Honeydew', value: 'honeydew' },
|
|
{ label: 'Kiwi', value: 'kiwi' },
|
|
{ label: 'Lemon', value: 'lemon' },
|
|
{ label: 'Mango', value: 'mango' },
|
|
{ label: 'Nectarine', value: 'nectarine' },
|
|
{ label: 'Orange', value: 'orange' },
|
|
{ label: 'Papaya', value: 'papaya' },
|
|
{ label: 'Quince', value: 'quince' },
|
|
{ label: 'Raspberry', value: 'raspberry' },
|
|
{ label: 'Strawberry', value: 'strawberry' },
|
|
{ label: 'Tangerine', value: 'tangerine' },
|
|
{ label: 'Ugli Fruit', value: 'ugli' },
|
|
{ label: 'Watermelon', value: 'watermelon' },
|
|
];
|
|
|
|
// Local Data Example
|
|
export const LocalData: Story = {
|
|
render: () => {
|
|
const [value, setValue] = useState<null | string>(null);
|
|
|
|
return (
|
|
<div style={{ width: 300 }}>
|
|
<Boxer
|
|
clearable
|
|
data={sampleData}
|
|
dataSource="local"
|
|
label="Favorite Fruit"
|
|
onChange={setValue}
|
|
placeholder="Select a fruit"
|
|
searchable
|
|
value={value}
|
|
/>
|
|
<div style={{ marginTop: 20 }}>
|
|
<strong>Selected Value:</strong> {value ?? 'None'}
|
|
</div>
|
|
</div>
|
|
);
|
|
},
|
|
};
|
|
|
|
// Multi-Select Example
|
|
export const MultiSelect: Story = {
|
|
render: () => {
|
|
const [value, setValue] = useState<Array<string>>([]);
|
|
|
|
return (
|
|
<div style={{ width: 300 }}>
|
|
<Boxer
|
|
clearable
|
|
data={sampleData}
|
|
dataSource="local"
|
|
label="Favorite Fruits"
|
|
multiSelect
|
|
onChange={setValue}
|
|
placeholder="Select fruits"
|
|
searchable
|
|
value={value}
|
|
/>
|
|
<div style={{ marginTop: 20 }}>
|
|
<strong>Selected Values:</strong>{' '}
|
|
{value.length > 0 ? value.join(', ') : 'None'}
|
|
</div>
|
|
</div>
|
|
);
|
|
},
|
|
};
|
|
|
|
// Server-Side Example (Simulated)
|
|
export const ServerSide: Story = {
|
|
render: () => {
|
|
const [value, setValue] = useState<null | string>(null);
|
|
|
|
// Simulate server-side API call
|
|
const handleAPICall = async (params: {
|
|
page: number;
|
|
pageSize: number;
|
|
search?: string;
|
|
}): Promise<{ data: Array<BoxerItem>; total: number }> => {
|
|
// Simulate network delay
|
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
|
|
// Filter based on search
|
|
let filteredData = [...sampleData];
|
|
if (params.search) {
|
|
filteredData = filteredData.filter((item) =>
|
|
item.label.toLowerCase().includes(params.search!.toLowerCase())
|
|
);
|
|
}
|
|
|
|
// Paginate
|
|
const start = params.page * params.pageSize;
|
|
const end = start + params.pageSize;
|
|
const paginatedData = filteredData.slice(start, end);
|
|
|
|
return {
|
|
data: paginatedData,
|
|
total: filteredData.length,
|
|
};
|
|
};
|
|
|
|
return (
|
|
<div style={{ width: 300 }}>
|
|
<Boxer
|
|
clearable
|
|
dataSource="server"
|
|
label="Favorite Fruit (Server-side)"
|
|
onAPICall={handleAPICall}
|
|
onChange={setValue}
|
|
pageSize={10}
|
|
placeholder="Select a fruit (Server-side)"
|
|
searchable
|
|
value={value}
|
|
/>
|
|
<div style={{ marginTop: 20 }}>
|
|
<strong>Selected Value:</strong> {value ?? 'None'}
|
|
</div>
|
|
</div>
|
|
);
|
|
},
|
|
};
|
|
|
|
// Select First Example
|
|
export const SelectFirst: Story = {
|
|
render: () => {
|
|
const [value, setValue] = useState<null | string>(null);
|
|
|
|
return (
|
|
<div style={{ width: 300 }}>
|
|
<Boxer
|
|
clearable
|
|
data={sampleData}
|
|
dataSource="local"
|
|
label="Auto-select First"
|
|
onChange={setValue}
|
|
placeholder="Select a fruit"
|
|
searchable
|
|
selectFirst
|
|
value={value}
|
|
/>
|
|
<div style={{ marginTop: 20 }}>
|
|
<strong>Selected Value:</strong> {value ?? 'None'}
|
|
</div>
|
|
</div>
|
|
);
|
|
},
|
|
};
|
|
|
|
// With Error
|
|
export const WithError: Story = {
|
|
render: () => {
|
|
const [value, setValue] = useState<null | string>(null);
|
|
|
|
return (
|
|
<div style={{ width: 300 }}>
|
|
<Boxer
|
|
clearable
|
|
data={sampleData}
|
|
dataSource="local"
|
|
error="Please select a fruit"
|
|
label="With Error"
|
|
onChange={setValue}
|
|
placeholder="Select a fruit"
|
|
searchable
|
|
value={value}
|
|
/>
|
|
</div>
|
|
);
|
|
},
|
|
};
|
|
|
|
// Disabled
|
|
export const Disabled: Story = {
|
|
render: () => {
|
|
return (
|
|
<div style={{ width: 300 }}>
|
|
<Boxer
|
|
data={sampleData}
|
|
dataSource="local"
|
|
disabled
|
|
label="Disabled"
|
|
onChange={() => {}}
|
|
placeholder="Select a fruit"
|
|
value="apple"
|
|
/>
|
|
</div>
|
|
);
|
|
},
|
|
};
|