mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 12:32:30 +08:00
### What problem does this PR solve? Feat: Replace the collapse icon #9869 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -3,6 +3,7 @@ import path from 'path';
|
||||
|
||||
const config: StorybookConfig = {
|
||||
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
|
||||
staticDirs: ['../public'],
|
||||
addons: [
|
||||
'@storybook/addon-webpack5-compiler-swc',
|
||||
'@storybook/addon-docs',
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import '@/locales/config';
|
||||
import type { Preview } from '@storybook/react-webpack5';
|
||||
import { createElement } from 'react';
|
||||
import '../public/iconfont.js';
|
||||
import { TooltipProvider } from '../src/components/ui/tooltip';
|
||||
|
||||
import '../tailwind.css';
|
||||
|
||||
@ -59,6 +59,10 @@
|
||||
`<symbol id="icon-GitHub" viewBox="0 0 1024 1024">
|
||||
<path d="M512 42.666667C252.714667 42.666667 42.666667 252.714667 42.666667 512c0 207.658667 134.357333 383.104 320.896 445.269333 23.466667 4.096 32.256-9.941333 32.256-22.272 0-11.178667-0.554667-48.128-0.554667-87.424-117.930667 21.717333-148.437333-28.757333-157.824-55.125333-5.290667-13.525333-28.16-55.168-48.085333-66.304-16.426667-8.832-39.936-30.506667-0.597334-31.104 36.949333-0.597333 63.36 34.005333 72.149334 48.128 42.24 70.954667 109.696 51.029333 136.704 38.698667 4.096-30.506667 16.426667-51.029333 29.909333-62.762667-104.448-11.733333-213.546667-52.224-213.546667-231.765333 0-51.029333 18.176-93.269333 48.128-126.122667-4.736-11.733333-21.162667-59.818667 4.693334-124.373333 0 0 39.296-12.288 129.024 48.128a434.901333 434.901333 0 0 1 117.333333-15.829334c39.936 0 79.829333 5.248 117.333333 15.829334 89.770667-61.013333 129.066667-48.128 129.066667-48.128 25.813333 64.554667 9.429333 112.64 4.736 124.373333 29.909333 32.853333 48.085333 74.538667 48.085333 126.122667 0 180.138667-109.696 220.032-214.144 231.765333 17.024 14.677333 31.701333 42.837333 31.701334 86.826667 0 62.762667-0.597333 113.237333-0.597334 129.066666 0 12.330667 8.789333 26.965333 32.256 22.272C846.976 895.104 981.333333 719.104 981.333333 512c0-259.285333-210.005333-469.333333-469.333333-469.333333z"></path>
|
||||
</symbol>` +
|
||||
`<symbol id="icon-more" viewBox="0 0 1024 1024">
|
||||
<path d="M0 0h1024v1024H0z" opacity=".01"></path>
|
||||
<path d="M867.072 141.184H156.032a32 32 0 0 0 0 64h711.04a32 32 0 0 0 0-64z m0.832 226.368H403.2a32 32 0 0 0 0 64h464.704a32 32 0 0 0 0-64zM403.2 573.888h464.704a32 32 0 0 1 0 64H403.2a32 32 0 0 1 0-64z m464.704 226.368H156.864a32 32 0 0 0 0 64h711.04a32 32 0 0 0 0-64zM137.472 367.552v270.336l174.528-122.24-174.528-148.096z" ></path>
|
||||
</symbol>` +
|
||||
'</svg>'),
|
||||
((h) => {
|
||||
var a = (l = (l = document.getElementsByTagName('script'))[
|
||||
|
||||
@ -3,9 +3,16 @@ import {
|
||||
CollapsibleContent,
|
||||
CollapsibleTrigger,
|
||||
} from '@/components/ui/collapsible';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { CollapsibleProps } from '@radix-ui/react-collapsible';
|
||||
import { ListCollapse } from 'lucide-react';
|
||||
import { PropsWithChildren, ReactNode } from 'react';
|
||||
import {
|
||||
PropsWithChildren,
|
||||
ReactNode,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { IconFontFill } from './icon-font';
|
||||
|
||||
type CollapseProps = Omit<CollapsibleProps, 'title'> & {
|
||||
title?: ReactNode;
|
||||
@ -16,22 +23,42 @@ export function Collapse({
|
||||
title,
|
||||
children,
|
||||
rightContent,
|
||||
open,
|
||||
open = true,
|
||||
defaultOpen = false,
|
||||
onOpenChange,
|
||||
disabled,
|
||||
}: CollapseProps) {
|
||||
const [currentOpen, setCurrentOpen] = useState(open);
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentOpen(open);
|
||||
}, [open]);
|
||||
|
||||
const handleOpenChange = useCallback(
|
||||
(open: boolean) => {
|
||||
setCurrentOpen(open);
|
||||
onOpenChange?.(open);
|
||||
},
|
||||
[onOpenChange],
|
||||
);
|
||||
|
||||
return (
|
||||
<Collapsible
|
||||
defaultOpen={defaultOpen}
|
||||
open={open}
|
||||
onOpenChange={onOpenChange}
|
||||
open={currentOpen}
|
||||
onOpenChange={handleOpenChange}
|
||||
disabled={disabled}
|
||||
>
|
||||
<CollapsibleTrigger className="w-full">
|
||||
<section className="flex justify-between items-center pb-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<ListCollapse className="size-4" /> {title}
|
||||
<IconFontFill
|
||||
name={`more`}
|
||||
className={cn('size-4', {
|
||||
'rotate-90': !currentOpen,
|
||||
})}
|
||||
></IconFontFill>
|
||||
{title}
|
||||
</div>
|
||||
<div>{rightContent}</div>
|
||||
</section>
|
||||
|
||||
153
web/src/stories/collapse.stories.tsx
Normal file
153
web/src/stories/collapse.stories.tsx
Normal file
@ -0,0 +1,153 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react-webpack5';
|
||||
|
||||
import { fn } from 'storybook/test';
|
||||
|
||||
import { Collapse } from '@/components/collapse';
|
||||
import { Button } from '@/components/ui/button';
|
||||
|
||||
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
|
||||
const meta = {
|
||||
title: 'Example/Collapse',
|
||||
component: Collapse,
|
||||
parameters: {
|
||||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
|
||||
layout: 'centered',
|
||||
docs: {
|
||||
description: {
|
||||
component: `
|
||||
## Component Description
|
||||
|
||||
Collapse is a component that allows you to show or hide content with a smooth animation. It can be controlled or uncontrolled and supports custom titles and right-aligned content.
|
||||
|
||||
The component uses a trigger element (typically with an icon) to toggle the visibility of its content. It's built on top of Radix UI's Collapsible primitive.
|
||||
`,
|
||||
},
|
||||
},
|
||||
},
|
||||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
|
||||
// More on argTypes: https://storybook.js.org/docs/api/argtypes
|
||||
argTypes: {
|
||||
title: {
|
||||
control: 'text',
|
||||
description: 'The title text or element to display in the trigger',
|
||||
},
|
||||
open: {
|
||||
control: 'boolean',
|
||||
description: 'Controlled open state of the collapse',
|
||||
},
|
||||
defaultOpen: {
|
||||
control: 'boolean',
|
||||
description: 'Initial open state of the collapse',
|
||||
},
|
||||
disabled: {
|
||||
control: 'boolean',
|
||||
description: 'Whether the collapse is disabled',
|
||||
},
|
||||
rightContent: {
|
||||
control: 'text',
|
||||
description: 'Content to display on the right side of the trigger',
|
||||
},
|
||||
onOpenChange: {
|
||||
action: 'onOpenChange',
|
||||
description: 'Callback function when the open state changes',
|
||||
},
|
||||
},
|
||||
// Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args
|
||||
args: { onOpenChange: fn() },
|
||||
} satisfies Meta<typeof Collapse>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
title: 'Collapse Title',
|
||||
children: (
|
||||
<div className="p-4 border border-gray-200 rounded-md">
|
||||
<p>This is the collapsible content. It can be any React node.</p>
|
||||
<p>You can put any content here, including other components.</p>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: `
|
||||
### Usage Examples
|
||||
|
||||
\`\`\`tsx
|
||||
import { Collapse } from '@/components/collapse';
|
||||
|
||||
<Collapse title="Collapse Title">
|
||||
<div className="p-4 border border-gray-200 rounded-md">
|
||||
<p>This is the collapsible content.</p>
|
||||
</div>
|
||||
</Collapse>
|
||||
\`\`\`
|
||||
`,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const WithRightContent: Story = {
|
||||
args: {
|
||||
title: 'Collapse with Right Content',
|
||||
rightContent: <Button size="sm">Action</Button>,
|
||||
children: (
|
||||
<div className="p-4 border border-gray-200 rounded-md">
|
||||
<p>
|
||||
This collapse has additional content on the right side of the trigger.
|
||||
</p>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: `
|
||||
### Usage Examples
|
||||
|
||||
\`\`\`tsx
|
||||
import { Collapse } from '@/components/collapse';
|
||||
import { Button } from '@/components/ui/button';
|
||||
|
||||
<Collapse
|
||||
title="Collapse Title"
|
||||
rightContent={<Button size="sm">Action</Button>}
|
||||
>
|
||||
<div className="p-4 border border-gray-200 rounded-md">
|
||||
<p>Content with right-aligned action button.</p>
|
||||
</div>
|
||||
</Collapse>
|
||||
\`\`\`
|
||||
`,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const InitiallyClosed: Story = {
|
||||
args: {
|
||||
title: 'Initially Closed Collapse',
|
||||
defaultOpen: false,
|
||||
children: (
|
||||
<div className="p-4 border border-gray-200 rounded-md">
|
||||
<p>This collapse is initially closed.</p>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
export const Disabled: Story = {
|
||||
args: {
|
||||
title: 'Disabled Collapse',
|
||||
disabled: true,
|
||||
children: (
|
||||
<div className="p-4 border border-gray-200 rounded-md">
|
||||
<p>This collapse is disabled and cannot be toggled.</p>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user