Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 125 additions & 0 deletions apps/www/src/app/examples/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
Amount,
Avatar,
AvatarGroup,
Breadcrumb,
Button,
Calendar,
Callout,
Expand Down Expand Up @@ -37,6 +38,35 @@ import {
import dayjs from 'dayjs';
import React, { useState } from 'react';

const breadcrumbTrail = (
<>
<Breadcrumb.Item href='/'>Home</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item href='/products'>Products</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item href='/products/electronics'>Electronics</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item href='/products/electronics/laptops'>
Laptops
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item href='/products/electronics/laptops/gaming'>
Gaming
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item href='/products/electronics/laptops/gaming/accessories'>
Accessories
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item
href='/products/electronics/laptops/gaming/accessories'
current
>
Footwear
</Breadcrumb.Item>
Comment on lines +61 to +66
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Inconsistent href for "Footwear" item.

The href for "Footwear" is /products/electronics/laptops/gaming/accessories but the label is "Footwear". This appears to be a copy-paste error—the href should likely be /products/electronics/laptops/gaming/accessories/footwear or similar.

🐛 Suggested fix
     <Breadcrumb.Item
-      href='/products/electronics/laptops/gaming/accessories'
+      href='/products/electronics/laptops/gaming/accessories/footwear'
       current
     >
       Footwear
     </Breadcrumb.Item>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Breadcrumb.Item
href='/products/electronics/laptops/gaming/accessories'
current
>
Footwear
</Breadcrumb.Item>
<Breadcrumb.Item
href='/products/electronics/laptops/gaming/accessories/footwear'
current
>
Footwear
</Breadcrumb.Item>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/www/src/app/examples/page.tsx` around lines 61 - 66, The Breadcrumb.Item
for the "Footwear" label has the wrong href; update the href on the
Breadcrumb.Item (the JSX element with label "Footwear") to the correct path
(e.g. change '/products/electronics/laptops/gaming/accessories' to
'/products/electronics/laptops/gaming/accessories/footwear') so the link matches
the label.

</>
);

const Page = () => {
const [dialogOpen, setDialogOpen] = useState(false);
const [nestedDialogOpen, setNestedDialogOpen] = useState(false);
Expand Down Expand Up @@ -226,6 +256,101 @@ const Page = () => {
</Flex>
</Flex>

{/* Breadcrumb Examples */}
<Text
size='large'
weight='medium'
style={{ marginTop: '32px', marginBottom: '16px' }}
>
Breadcrumb Examples
</Text>
<Flex direction='column' gap={8} style={{ maxWidth: '100%' }}>
<Flex direction='column' gap={2}>
<Text size='small' weight='medium'>
1. (no props) – manual ellipsis
</Text>
<Breadcrumb>
<Breadcrumb.Item href='/'>Home</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Ellipsis />
<Breadcrumb.Separator />
<Breadcrumb.Item
href='/products/electronics/laptops/gaming/accessories'
current
>
Footwear
</Breadcrumb.Item>
</Breadcrumb>
</Flex>
<Flex direction='column' gap={2}>
<Text size='small' weight='medium'>
2. maxItems=8
</Text>
<Breadcrumb maxItems={8}>{breadcrumbTrail}</Breadcrumb>
</Flex>
<Flex direction='column' gap={2}>
<Text size='small' weight='medium'>
3. maxItems=5
</Text>
<Breadcrumb maxItems={5}>{breadcrumbTrail}</Breadcrumb>
</Flex>
<Flex direction='column' gap={2}>
<Text size='small' weight='medium'>
4. maxItems=3
</Text>
<Breadcrumb maxItems={3}>{breadcrumbTrail}</Breadcrumb>
</Flex>
<Flex direction='column' gap={2}>
<Text size='small' weight='medium'>
5. maxItems=5 itemsBeforeCollapse=2
</Text>
<Breadcrumb maxItems={5} itemsBeforeCollapse={2}>
{breadcrumbTrail}
</Breadcrumb>
</Flex>
<Flex direction='column' gap={2}>
<Text size='small' weight='medium'>
6. maxItems=5 itemsBeforeCollapse=5 (4 before + 1 after)
</Text>
<Breadcrumb maxItems={5} itemsBeforeCollapse={5}>
<Breadcrumb.Item href='/'>Home</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item href='/products'>Products</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item href='/products/electronics'>
Electronics
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item href='/products/electronics/laptops'>
Laptops
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item href='/products/electronics/laptops/gaming'>
Gaming
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item href='/products/electronics/laptops/gaming/accessories'>
Accessories
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item
href='/products/electronics/laptops/gaming/accessories'
current
>
Footwear
</Breadcrumb.Item>
</Breadcrumb>
</Flex>
<Flex direction='column' gap={2}>
<Text size='small' weight='medium'>
7. size=small maxItems=4
</Text>
<Breadcrumb size='small' maxItems={4}>
{breadcrumbTrail}
</Breadcrumb>
</Flex>
</Flex>

<Flex direction='column' gap={4} style={{ maxWidth: '550px' }}>
<Search
placeholder='Default large search'
Expand Down
8 changes: 8 additions & 0 deletions apps/www/src/components/demo/demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import {
UploadIcon
} from '@radix-ui/react-icons';
import * as Apsara from '@raystack/apsara';
import {
BellIcon,
FilterIcon,
ShoppingBagFilledIcon
} from '@raystack/apsara/icons';
import dayjs from 'dayjs';
import { Home, Info, Laugh, X } from 'lucide-react';
import NextLink from 'next/link';
Expand All @@ -24,6 +29,9 @@ export default function Demo(props: DemoProps) {
data,
scope = {
...Apsara,
BellIcon,
FilterIcon,
ShoppingBagFilledIcon,
DataTableDemo,
LinearMenuDemo,
PopoverColorPicker,
Expand Down
89 changes: 66 additions & 23 deletions apps/www/src/content/docs/components/breadcrumb/demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,30 @@ export const playground = {

export const sizeDemo = {
type: 'code',
code: `
<Flex gap="medium" direction="column">
<Breadcrumb size="small">
<Breadcrumb.Item href="/">Home</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/products">Products</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/products/shoes" current>Shoes</Breadcrumb.Item>
</Breadcrumb>
<Breadcrumb size="medium">
<Breadcrumb.Item href="/">Home</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/products">Products</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/products/shoes" current>Shoes</Breadcrumb.Item>
</Breadcrumb>
</Flex>`
tabs: [
{
name: 'Small',
code: `
<Breadcrumb size="small">
<Breadcrumb.Item href="/">Home</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/products">Products</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/products/shoes" current>Shoes</Breadcrumb.Item>
</Breadcrumb>`
},
{
name: 'Medium',
code: `
<Breadcrumb size="medium">
<Breadcrumb.Item href="/">Home</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/products">Products</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/products/shoes" current>Shoes</Breadcrumb.Item>
</Breadcrumb>`
}
]
};

export const separatorDemo = {
Expand Down Expand Up @@ -78,6 +85,42 @@ export const ellipsisDemo = {
</Breadcrumb>`
};

export const maxItemsDemo = {
type: 'code',
code: `
<Breadcrumb maxItems={4}>
<Breadcrumb.Item href="/">Home</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/products">Products</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/electronics">Electronics</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/laptops">Laptops</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/gaming" current>Gaming</Breadcrumb.Item>
</Breadcrumb>`
};

export const itemsBeforeCollapseDemo = {
type: 'code',
code: `
<Breadcrumb maxItems={5} itemsBeforeCollapse={2}>
<Breadcrumb.Item href="/">Home</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/products">Products</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/electronics">Electronics</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/laptops">Laptops</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/gaming">Gaming</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/accessories">Accessories</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/footwear" current>Footwear</Breadcrumb.Item>
</Breadcrumb>`
};

export const dropdownDemo = {
type: 'code',
code: `
Expand Down Expand Up @@ -113,22 +156,22 @@ export const iconsDemo = {
name: 'Text with Icon',
code: `
<Breadcrumb>
<Breadcrumb.Item href="/" leadingIcon={<>H</>}>Home</Breadcrumb.Item>
<Breadcrumb.Item href="/" leadingIcon={<BellIcon />}>Home</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/documents" leadingIcon={<>D</>}>Documents</Breadcrumb.Item>
<Breadcrumb.Item href="/documents" leadingIcon={<FilterIcon />}>Documents</Breadcrumb.Item>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/settings" leadingIcon={<>S</>}>Settings</Breadcrumb.Item>
<Breadcrumb.Item href="/settings" leadingIcon={<ShoppingBagFilledIcon />}>Settings</Breadcrumb.Item>
</Breadcrumb>`
},
{
name: 'Only Icon',
code: `
<Breadcrumb>
<Breadcrumb.Item href="/" leadingIcon={<>H</>}/>
<Breadcrumb.Item href="/" leadingIcon={<BellIcon />}/>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/documents" leadingIcon={<>D</>}/>
<Breadcrumb.Item href="/documents" leadingIcon={<FilterIcon />}/>
<Breadcrumb.Separator/>
<Breadcrumb.Item href="/settings" leadingIcon={<>S</>}/>
<Breadcrumb.Item href="/settings" leadingIcon={<ShoppingBagFilledIcon />}/>
</Breadcrumb>`
}
]
Expand Down
20 changes: 17 additions & 3 deletions apps/www/src/content/docs/components/breadcrumb/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
separatorDemo,
iconsDemo,
ellipsisDemo,
maxItemsDemo,
itemsBeforeCollapseDemo,
dropdownDemo,
asDemo,
} from "./demo.ts";
Expand Down Expand Up @@ -42,7 +44,7 @@ Groups all parts of the breadcrumb navigation.

### Item

Renders an individual breadcrumb link.
Renders an individual breadcrumb link. Use the `current` prop on the item that represents the current page so it is styled and exposed to assistive tech (e.g. `aria-current="page"`).

<auto-type-table path="./props.ts" name="BreadcrumbItem" />

Expand Down Expand Up @@ -72,12 +74,24 @@ Customize the separator between breadcrumb items using the `separator` prop.

<Demo data={separatorDemo} />

### Ellipsis
### Ellipsis (manual)

Use the `Breadcrumb.Ellipsis` component to truncate the breadcrumb trail when you need to display a large number of items in a limited space.
Use the `Breadcrumb.Ellipsis` component to manually truncate the breadcrumb trail when you need to display a large number of items in a limited space.

<Demo data={ellipsisDemo} />

### Auto-collapse (maxItems)

Set `maxItems` to automatically collapse the trail when there are more items: the first few and the last items are shown with an ellipsis in between. When collapsed, there is always at least 1 item at the start and 1 at the end—there cannot be fewer than 2 visible items. The number of items before the ellipsis is controlled by `itemsBeforeCollapse` (when not set, it is derived from `maxItems`). The number of items after the ellipsis is always derived (`maxItems` minus before). Values of `maxItems` less than 2 are treated as 2.

<Demo data={maxItemsDemo} />

### itemsBeforeCollapse

Control how many items appear before the ellipsis when collapsed. With `maxItems={5}` and `itemsBeforeCollapse={2}`, you get 2 items before and 3 after (until the cap).

<Demo data={itemsBeforeCollapseDemo} />

### Icons

Breadcrumb items can include icons either alongside text or as standalone elements.
Expand Down
16 changes: 16 additions & 0 deletions apps/www/src/content/docs/components/breadcrumb/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ export interface BreadcrumbItem {
* @default "<a />"
*/
as?: ReactElement;

/** Custom CSS class name applied to the list item wrapper */
className?: string;
}

export interface BreadcrumbProps {
Expand All @@ -45,6 +48,19 @@ export interface BreadcrumbProps {
*/
size?: 'small' | 'medium';

/**
* Maximum number of breadcrumb items to show. When there are more items, the list is collapsed.
* When collapsed: at least 1 item is always shown at the start and 1 at the end (minimum 2 visible items; there cannot be fewer than 2).
* Values less than 2 are treated as 2.
*/
maxItems?: number;

/**
* Number of items to show before the ellipsis when collapsed.
* When not set, derived from maxItems (e.g. maxItems=5 → 2 before, rest after).
*/
itemsBeforeCollapse?: number;

/** Custom CSS class names */
className?: string;
}
Expand Down
Loading