157 lines
3.7 KiB
TypeScript
157 lines
3.7 KiB
TypeScript
import type { Meta, StoryObj } from '@storybook/react'
|
|
import { useState } from 'react'
|
|
import type { Selection } from 'react-stately'
|
|
import { Tree, type TreeItemType } from './Tree'
|
|
|
|
const meta = {
|
|
title: 'Components/Tree',
|
|
component: Tree,
|
|
args: {
|
|
items: [],
|
|
},
|
|
argTypes: {
|
|
selectionMode: {
|
|
control: 'select',
|
|
options: ['single', 'multiple', 'none'],
|
|
},
|
|
enableDragAndDrop: {
|
|
control: 'boolean',
|
|
},
|
|
},
|
|
} satisfies Meta<typeof Tree>
|
|
|
|
export default meta
|
|
type Story = StoryObj<typeof meta>
|
|
|
|
const sampleItems: TreeItemType[] = [
|
|
{
|
|
id: 1,
|
|
title: '프로젝트 A',
|
|
type: 'directory',
|
|
children: [
|
|
{ id: 11, title: '문서 1', type: 'file' },
|
|
{ id: 12, title: '문서 2', type: 'file' },
|
|
{ id: 13, title: '문서 3', type: 'file' },
|
|
],
|
|
},
|
|
{
|
|
id: 2,
|
|
title: '프로젝트 B',
|
|
type: 'directory',
|
|
children: [
|
|
{ id: 21, title: '파일 1', type: 'file' },
|
|
{ id: 22, title: '파일 2', type: 'file' },
|
|
],
|
|
},
|
|
{
|
|
id: 3,
|
|
title: '프로젝트 C',
|
|
type: 'directory',
|
|
children: [
|
|
{ id: 31, title: '항목 1', type: 'file' },
|
|
{ id: 32, title: '항목 2', type: 'file' },
|
|
{ id: 33, title: '항목 3', type: 'file' },
|
|
{ id: 34, title: '항목 4', type: 'file' },
|
|
],
|
|
},
|
|
]
|
|
|
|
export const Default: Story = {
|
|
args: {
|
|
items: sampleItems,
|
|
selectionMode: 'single',
|
|
},
|
|
}
|
|
|
|
export const SingleSelection: Story = {
|
|
render: function Render() {
|
|
const [selectedKeys, setSelectedKeys] = useState<Selection>(new Set())
|
|
return (
|
|
<div className="w-80 border border-gray-200">
|
|
<Tree
|
|
items={sampleItems}
|
|
selectionMode="single"
|
|
selectedKeys={selectedKeys as Set<number | string>}
|
|
onSelectionChange={setSelectedKeys}
|
|
/>
|
|
</div>
|
|
)
|
|
},
|
|
}
|
|
|
|
export const MultipleSelection: Story = {
|
|
render: function Render() {
|
|
const [selectedKeys, setSelectedKeys] = useState<Selection>(new Set())
|
|
return (
|
|
<div className="w-80 border border-gray-200">
|
|
<Tree
|
|
items={sampleItems}
|
|
selectionMode="multiple"
|
|
selectedKeys={selectedKeys as Set<number | string>}
|
|
onSelectionChange={setSelectedKeys}
|
|
/>
|
|
</div>
|
|
)
|
|
},
|
|
}
|
|
|
|
export const WithDragAndDrop: Story = {
|
|
render: function Render() {
|
|
const [selectedKeys, setSelectedKeys] = useState<Selection>(new Set())
|
|
return (
|
|
<div className="w-80 border border-gray-200">
|
|
<Tree
|
|
items={sampleItems}
|
|
selectionMode="single"
|
|
selectedKeys={selectedKeys as Set<number | string>}
|
|
onSelectionChange={setSelectedKeys}
|
|
enableDragAndDrop={true}
|
|
onReorder={(sourceKey, targetKey, dropPosition, parentKey) => {
|
|
console.log('Reorder:', { sourceKey, targetKey, dropPosition, parentKey })
|
|
}}
|
|
/>
|
|
</div>
|
|
)
|
|
},
|
|
}
|
|
|
|
export const WithoutDragAndDrop: Story = {
|
|
args: {
|
|
items: sampleItems,
|
|
selectionMode: 'single',
|
|
enableDragAndDrop: false,
|
|
},
|
|
}
|
|
|
|
export const NestedTree: Story = {
|
|
args: {
|
|
items: [
|
|
{
|
|
id: 1,
|
|
title: '루트 폴더',
|
|
type: 'directory',
|
|
children: [
|
|
{
|
|
id: 11,
|
|
title: '하위 폴더 1',
|
|
type: 'directory',
|
|
children: [
|
|
{ id: 111, title: '파일 A', type: 'file' },
|
|
{ id: 112, title: '파일 B', type: 'file' },
|
|
],
|
|
},
|
|
{
|
|
id: 12,
|
|
title: '하위 폴더 2',
|
|
type: 'directory',
|
|
children: [
|
|
{ id: 121, title: '파일 C', type: 'file' },
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
selectionMode: 'single',
|
|
},
|
|
}
|