diff --git a/.changeset/cuddly-papayas-rescue.md b/.changeset/cuddly-papayas-rescue.md new file mode 100644 index 0000000..6fa03bb --- /dev/null +++ b/.changeset/cuddly-papayas-rescue.md @@ -0,0 +1,5 @@ +--- +"@blandui/blandui-react": patch +--- + +BreadCrumb added diff --git a/apps/storybook-react/package.json b/apps/storybook-react/package.json index d803533..9c34e93 100644 --- a/apps/storybook-react/package.json +++ b/apps/storybook-react/package.json @@ -11,6 +11,7 @@ "@blandui/blandui-react": "workspace:*", "@tailwindcss/forms": "^0.5.7", "autoprefixer": "^10.4.19", + "lucide-react": "^0.395.0", "postcss": "^8.4.38", "tailwindcss": "^3.4.3", "typescript": "^5.4.5" diff --git a/apps/storybook-react/stories/BreadCrumb.stories.tsx b/apps/storybook-react/stories/BreadCrumb.stories.tsx new file mode 100644 index 0000000..0bd5a1e --- /dev/null +++ b/apps/storybook-react/stories/BreadCrumb.stories.tsx @@ -0,0 +1,45 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { BreadCrumb } from '@blandui/blandui-react'; +import { BreadCrumbItem } from '@blandui/blandui-react/dist/types/components/BreadCrumb/BreadCrumb'; +import { Component, Home, Info, InfoIcon } from 'lucide-react'; + +const meta: Meta = { + title: 'Component/BreadCrumb', + component: BreadCrumb, +}; + +export default meta; +type Story = StoryObj; + + +export const Default: Story = { + render: () => { + const items: BreadCrumbItem[] = [ + { title: 'BlandUI' }, + { title: 'Components' }, + { title: 'BreadCrumb' }, + ]; + + return ( +
+ +
+ ); + }, +}; + +export const WithIcons: Story = { + render: () => { + const items: BreadCrumbItem[] = [ + { title: <>BlandUI }, + { title: <>Components }, + { title: <>BreadCrumb }, + ]; + + return ( +
+ +
+ ); + }, +}; diff --git a/packages/blandui-react/src/components/BreadCrumb/BreadCrumb.tsx b/packages/blandui-react/src/components/BreadCrumb/BreadCrumb.tsx new file mode 100644 index 0000000..fb98cdc --- /dev/null +++ b/packages/blandui-react/src/components/BreadCrumb/BreadCrumb.tsx @@ -0,0 +1,71 @@ +import { + forwardRef, Fragment, MouseEventHandler, ReactNode, +} from 'react'; +import { ChevronRight } from 'lucide-react'; +import cn from '../../utils/cn'; + +export interface BreadCrumbItem { + title: ReactNode; + + onClick?: MouseEventHandler; + href?: string; +} + +export interface BreadCrumbProps { + className?: string; + separator?: ReactNode; + items: BreadCrumbItem[]; +} + +export const BreadCrumb = forwardRef(({ + className, + separator, + items, +}, ref) => { + const breadCrumbCn = cn( + 'flex items-center gap-xs text-link body-md', + className, + ); + + const itemCn = cn( + 'flex gap-sm items-center px-2xs', + 'cursor-pointer', + 'focus:ring-2 focus:ring-offset-0 focus:ring-focused focus:rounded-sm', + ); + + const contentCn = cn( + 'flex items-center gap-sm', + 'hover:underline', + ); + + return ( +
+ {items.map((item, index) => (
+ { item.href && <> + + { item.title } + + } + + { !item.href && <> +
+ { item.title } +
+ } + + { index < items.length - 1 && <> + { separator || } + } +
+ ))} +
+ ); +}); + +BreadCrumb.displayName = 'BreadCrumb'; diff --git a/packages/blandui-react/src/components/BreadCrumb/index.tsx b/packages/blandui-react/src/components/BreadCrumb/index.tsx new file mode 100644 index 0000000..d57760d --- /dev/null +++ b/packages/blandui-react/src/components/BreadCrumb/index.tsx @@ -0,0 +1,2 @@ +export { BreadCrumb } from './BreadCrumb'; +export type { BreadCrumbProps } from './BreadCrumb'; diff --git a/packages/blandui-react/src/index.ts b/packages/blandui-react/src/index.ts index ea6f8cc..780cf23 100644 --- a/packages/blandui-react/src/index.ts +++ b/packages/blandui-react/src/index.ts @@ -1,4 +1,5 @@ export * from './components/Badge'; +export * from './components/BreadCrumb'; export * from './components/Button'; export * from './components/Checkbox'; export * from './components/Chip'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7e47f6d..2d96b02 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,6 +48,9 @@ importers: autoprefixer: specifier: ^10.4.19 version: 10.4.19(postcss@8.4.38) + lucide-react: + specifier: ^0.395.0 + version: 0.395.0(react@18.3.1) postcss: specifier: ^8.4.38 version: 8.4.38