# ബ്രെഡ്‌ക്രമ്പ്

> നിങ്ങളുടെ ആപ്പിൽ ഒരു പേജ് എവിടെ നിൽക്കുന്നു എന്ന് കാണിക്കുന്നു, നീണ്ട ട്രെയിലുകൾ ചുരുക്കുന്നു, നിങ്ങളുടെ റൗട്ടറിന്റെ ലിങ്കുകളുമായി പ്രവർത്തിക്കുന്നു, ഘടനാപരമായ ഡാറ്റ (structured data) പ്രസിദ്ധീകരിക്കാനും കഴിയും.

GramproKit 2.0.0-beta · Navigation · ബീറ്റ (പരീക്ഷണാത്മകം; API-കൾ മാറാം) · ഉറവിടം: https://gramprokit.vercel.app/2.0.0-beta/ml/breadcrumb

## ഇൻസ്റ്റലേഷൻ

```bash
npx gbs-add-block@latest -a Breadcrumb -beta
```

എല്ലാ കമ്പോണന്റുകളും ഇംപോർട്ട് ചെയ്യുന്ന ചെറിയ `shared` ഫോൾഡറിനൊപ്പം, `breadcrumb` ഫോൾഡർ ഈ ബ്ലോക്ക് നിങ്ങളുടെ പ്രോജക്ടിലേക്ക് കോപ്പി ചെയ്യുന്നു. കോഡ് നിങ്ങളുടേതാണ്, സ്വതന്ത്രമായി മാറ്റം വരുത്താം.
React അല്ലാതെ **peer dependencies** ഒന്നും ഇല്ല.

**ആവശ്യകതകൾ**

- React 19-ഉം `@types/react` 19-ഉം
- TypeScript ടാർഗെറ്റ് ES2022 അല്ലെങ്കിൽ അതിനു ശേഷമുള്ളത്, `"jsx": "react-jsx"` എന്നതോടെ
- 2024-നു ശേഷമുള്ള ബ്രൗസറുകൾ (സ്റ്റൈലുകൾ `light-dark()`, `:dir()` ഉപയോഗിക്കുന്നു)

സ്റ്റൈൽഷീറ്റ് ഒരു തവണ ഇംപോർട്ട് ചെയ്യുക, ഉദാഹരണത്തിന് നിങ്ങളുടെ ഗ്ലോബൽ CSS-ൽ:

```css
@import "../components/breadcrumb/styles.css";
```

അല്ലെങ്കിൽ നിങ്ങളുടെ റൂട്ട് ലേഔട്ട് / എൻട്രി ഫയലിൽ:

```ts
import "@/components/breadcrumb/styles.css";
```

നിലവിലെ പേജ് നിങ്ങളുടെ ആപ്പിന്റെ ശ്രേണിയിൽ (hierarchy) എവിടെയാണ് നിൽക്കുന്നത് എന്ന് ബ്രെഡ്‌ക്രമ്പ് കാണിക്കുന്നു, കൂടാതെ ഒറ്റ ക്ലിക്കിൽ മുകളിലേക്ക് പോകാൻ ആളുകളെ അനുവദിക്കുന്നു. നീണ്ട ട്രെയിലുകൾ അവയുടെ അറ്റങ്ങളിൽ ഒരു എലിപ്സിസിന് (ellipsis) പിന്നിൽ ചുരുങ്ങുന്നു. `next/link` പോലുള്ള നിങ്ങളുടെ റൗട്ടറിന്റെ ലിങ്ക് കമ്പോണന്റ് ഉപയോഗിച്ച് ലിങ്കുകൾ വരയ്ക്കാം. തിരയൽ എഞ്ചിനുകൾക്ക് ഫലങ്ങളിൽ ട്രെയിൽ കാണിക്കാൻ കഴിയുന്ന വിധം, ട്രെയിൽ ഘടനാപരമായ ഡാറ്റയായും (structured data) പ്രസിദ്ധീകരിക്കാം.

> **ശ്രദ്ധിക്കുക:** എല്ലാ കമ്പോണന്റുകളും ഒരുമിച്ച് തീം ചെയ്യാൻ :root-ൽ --gbs-* വേരിയബിളുകൾ സെറ്റ് ചെയ്യുക, ഗ്രിഡ് ഉൾപ്പെടെ. ഓരോ കമ്പോണന്റിന്റെയും സ്വന്തം വേരിയബിളുകൾ ഇവയിലേക്കും, പിന്നീട് ബിൽറ്റ്-ഇൻ പാലറ്റിലേക്കും ഫാൾബാക്ക് ചെയ്യുന്നു, അതിനാൽ ഡിഫോൾട്ടായി കമ്പോണന്റുകൾ ഒരേ പോലെ കാണപ്പെടുന്നു.

#### ഡിഫോൾട്ട്

_ഇന്ററാക്ടീവ് ഡെമോ:_ [തത്സമയ ഉദാഹരണം കാണുക](https://gramprokit.vercel.app/2.0.0-beta/ml/breadcrumb)

## ക്വിക്ക് സ്റ്റാർട്ട്

```tsx
"use client";

import Link from "next/link";
import { Breadcrumb } from "@/components/breadcrumb";

export function InvoiceHeader({ invoice }) {
  return (
    <Breadcrumb
      items={[
        { label: "Home", href: "/" },
        { label: "Invoices", href: "/invoices" },
        { label: invoice.number },
      ]}
      renderLink={(props) => <Link {...props} />}
    />
  );
}
```

ഐറ്റങ്ങൾ ഏറ്റവും മുകളിലെ ലെവൽ മുതൽ താഴേക്കാണ് പോകുന്നത്. അവസാനത്തെ ഐറ്റം നിലവിലെ പേജാണ്: അത് ഒരു ലിങ്കല്ല, കൂടാതെ `aria-current="page"` എന്ന് അടയാളപ്പെടുത്തിയിരിക്കുന്നു.

## പ്രോപ്സ് ടേബിൾ

എല്ലാ `<nav>` ആട്രിബ്യൂട്ടുകളും, കൂടാതെ:

| Prop                  | Type                                           | Default            | Description                                                                              |
| --------------------- | ---------------------------------------------- | ------------------ | ---------------------------------------------------------------------------------------- |
| `items`               | `BreadcrumbItem[]`                             | **ആവശ്യമാണ്**      | ട്രെയിൽ, ഏറ്റവും മുകളിലെ ലെവൽ ആദ്യം.                                                     |
| `separator`           | `ReactNode`                                    | ഒരു ഷെവ്റോൺ        | ക്രമ്പുകൾക്കിടയിൽ, ഉദാ. `"/"`.                                                           |
| `maxItems`            | `number`                                       | —                  | ഇതിനേക്കാൾ കൂടുതൽ ക്രമ്പുകൾ ഉള്ളപ്പോൾ മധ്യഭാഗം ചുരുക്കുക.                                |
| `itemsBeforeCollapse` | `number`                                       | `1`                | എലിപ്സിസിന് മുമ്പ് നിലനിർത്തുന്ന ക്രമ്പുകൾ.                                              |
| `itemsAfterCollapse`  | `number`                                       | `1`                | എലിപ്സിസിന് ശേഷം നിലനിർത്തുന്ന ക്രമ്പുകൾ, നിലവിലെ പേജ് ഉൾപ്പെടെ.                         |
| `renderLink`          | `(props: BreadcrumbLinkProps) => ReactElement` | ഒരു `<a>`          | നിങ്ങളുടെ റൗട്ടർ ഉപയോഗിച്ച് ലിങ്കുകൾ വരയ്ക്കുക.                                          |
| `structuredData`      | `boolean` \| `{ baseUrl: string }`             | `false`            | schema.org `BreadcrumbList` JSON-LD ചേർക്കുക. [Structured Data](#structured-data) കാണുക. |
| `size`                | `"sm"` \| `"md"` \| `"lg"`                     | `"md"`             | ഫോണ്ട് സൈസ്.                                                                             |
| `aria-label`          | `string`                                       | `localeText.label` | നാവിഗേഷൻ ലാൻഡ്മാർക്കിന്റെ പേര്.                                                          |
| `className`           | `string`                                       | —                  | `<nav>`-ന് വേണ്ടിയുള്ള ക്ലാസ്.                                                           |
| `classNames`          | `Partial<Record<BreadcrumbSlot, string>>`      | —                  | സ്ലോട്ടുകൾ: `root`, `list`, `item`, `link`, `current`, `separator`, `ellipsis`.          |
| `localeText`          | `Partial<BreadcrumbLocaleText>`                | ഇംഗ്ലീഷ്           | [Locale Text](#locale-text) കാണുക.                                                       |

#### BreadcrumbItem

| Field     | Type         | Description                                                                                                                    |
| --------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------ |
| `label`   | `ReactNode`  | കാണിക്കുന്ന ടെക്സ്റ്റ്. നീണ്ട ലേബലുകൾ ഒരു എലിപ്സിസോടെ മുറിക്കുകയും, മുഴുവൻ ടെക്സ്റ്റും ഒരു ടൂൾടിപ്പിൽ കാണിക്കുകയും ചെയ്യുന്നു. |
| `href`    | `string`     | ലിങ്ക് ടാർഗെറ്റ്. നിലവിലെ പേജിനോ ലിങ്കല്ലാത്ത ക്രമ്പിനോ ഒഴിവാക്കുക.                                                            |
| `icon`    | `ReactNode`  | ലേബലിനു മുമ്പുള്ള ഐക്കൺ, ഉദാ. ഒരു ഹോം ഐക്കൺ.                                                                                   |
| `name`    | `string`     | `label` ഒരു സ്ട്രിംഗ് അല്ലാത്തപ്പോൾ, ഘടനാപരമായ ഡാറ്റയ്ക്കുള്ള പ്ലെയിൻ-ടെക്സ്റ്റ് പേര്.                                         |
| `onClick` | `() => void` | `href` ഉള്ളതോ ഇല്ലാത്തതോ ആയ ക്ലിക്ക് ഹാൻഡ്‌ലർ.                                                                                 |

## നീണ്ട ട്രെയിലുകൾ ചുരുക്കുന്നത്

```tsx
<Breadcrumb
  items={trail}
  maxItems={4}
  itemsBeforeCollapse={1}
  itemsAfterCollapse={2}
/>
```

7 ക്രമ്പുകളുള്ള ഒരു ട്രെയിൽ `Home › … › Invoices › INV-042` ആയി മാറുന്നു. എലിപ്സിസിൽ അമർത്തുന്നത് മുഴുവൻ ട്രെയിലും വെളിപ്പെടുത്തുകയും, മറച്ചുവെച്ച ആദ്യത്തെ ക്രമ്പിലേക്ക് കീബോർഡ് ഫോക്കസ് നീക്കുകയും ചെയ്യുന്നു. `maxItems` എണ്ണത്തിനോ അതിൽ കുറവോ ക്രമ്പുകൾ ഉള്ള ട്രെയിലുകൾ ഒരിക്കലും ചുരുക്കപ്പെടുന്നില്ല.

## റൗട്ടർ ലിങ്കുകൾ

`renderLink`-ന് `href`, `className`, `children`, `onClick` എന്നിവ ലഭിക്കുന്നു. ഇവ നിങ്ങളുടെ ലിങ്കിൽ സ്പ്രെഡ് ചെയ്യുക:

```tsx
import Link from "next/link";

<Breadcrumb
  items={items}
  renderLink={(props) => <Link {...props} prefetch={false} />}
/>;
```

```tsx
// React Router
import { Link } from "react-router";

<Breadcrumb
  items={items}
  renderLink={({ href, ...props }) => <Link to={href} {...props} />}
/>;
```

## ഘടനാപരമായ ഡാറ്റ (Structured Data)

```tsx
<Breadcrumb
  items={items}
  structuredData={{ baseUrl: "https://app.example.com" }}
/>
```

ഇത് schema.org `BreadcrumbList` ഉള്ള ഒരു `<script type="application/ld+json">` ചേർക്കുന്നു. ഫലങ്ങളിൽ പേജ് ടൈറ്റിലിനു താഴെ ട്രെയിൽ കാണിക്കാൻ തിരയൽ എഞ്ചിനുകൾക്ക് ഇത് ഉപയോഗിക്കാം. ആപേക്ഷിക (relative) `href`-കൾ `baseUrl`-നെതിരെ റിസോൾവ് ചെയ്യപ്പെടുന്നു, കാരണം തിരയൽ എഞ്ചിനുകൾ പൂർണ്ണമായ URL-കൾ പ്രതീക്ഷിക്കുന്നു. ബ്രെഡ്‌ക്രമ്പ് സെർവറിൽ റെൻഡർ ചെയ്യുക, ഒരു Next.js പേജ് ചെയ്യുന്നതുപോലെ, അപ്പോൾ ക്രാളറുകൾക്ക് HTML-ൽ ഡാറ്റ കാണാൻ കഴിയും.

## കീബോർഡ്

| Keys      | Action                                                                              |
| --------- | ----------------------------------------------------------------------------------- |
| **Tab**   | ക്രമ്പ് ലിങ്കുകൾക്കും എലിപ്സിസിനും ഇടയിൽ നീങ്ങുക. നിലവിലെ പേജ് ഒരു സ്റ്റോപ്പ് അല്ല. |
| **Enter** | ഫോക്കസ് ചെയ്ത ലിങ്ക് പിന്തുടരുക, അല്ലെങ്കിൽ ചുരുക്കിയ ക്രമ്പുകൾ വെളിപ്പെടുത്തുക.    |

ആക്സസിബിലിറ്റി: ട്രെയിൽ "Breadcrumb" എന്ന് പേരുള്ള ഒരു `<nav>` ലാൻഡ്മാർക്ക് ആണ്, ഇതിൽ ഒരു ഓർഡേർഡ് ലിസ്റ്റ് ഉൾപ്പെടുന്നു. സെപ്പറേറ്ററുകൾ `aria-hidden` ആണ്, അതിനാൽ ക്രമ്പുകൾക്കിടയിൽ സ്ക്രീൻ റീഡറുകൾ "ഷെവ്റോൺ" വായിക്കുന്നില്ല. നിലവിലെ പേജിന് `aria-current="page"` ഉണ്ട്, കൂടാതെ എലിപ്സിസ് അത് എത്ര ക്രമ്പുകൾ വെളിപ്പെടുത്തുന്നു എന്ന് പറയുന്നു ("Show 4 more").

## സ്റ്റൈലിംഗും തീമിംഗും

എല്ലാ റൂളുകളും CSS `components` ലെയറിലാണ്, അതിനാൽ `className` / `classNames` വഴി കടന്നുപോകുന്ന യൂട്ടിലിറ്റി ക്ലാസുകൾ അവയെ ഓവർറൈഡ് ചെയ്യുന്നു.

```tsx
<Breadcrumb
  classNames={{ current: "text-blue-600", separator: "opacity-40" }}
/>
```

#### CSS വേരിയബിളുകൾ

`.bc-root`-ലോ, `:root`-ലോ, അല്ലെങ്കിൽ `style`-ലൂടെയോ ഇവ ഓവർറൈഡ് ചെയ്യുക. ഓരോ വേരിയബിളും അതേ പേരിലുള്ള ഷെയേർഡ് `--gbs-*`-ലേക്ക് ഫാൾബാക്ക് ചെയ്യുന്നു, പിന്നീട് ആ സ്റ്റൈൽഷീറ്റ് ലോഡ് ചെയ്തിട്ടുണ്ടെങ്കിൽ DataGrid-ന്റെ `--dg-*`-ലേക്കും, അവസാനം ബിൽറ്റ്-ഇൻ പാലറ്റിലേക്കും.

| Variable         | Used for                                                  |
| ---------------- | --------------------------------------------------------- |
| `--bc-font-size` | ഫോണ്ട് സൈസ് (`size` സെറ്റ് ചെയ്യുന്നത്).                  |
| `--bc-fg`        | നിലവിലെ പേജും ഹോവർ ചെയ്ത ലിങ്കുകളും.                      |
| `--bc-muted`     | ലിങ്കുകളും സെപ്പറേറ്ററുകളും.                              |
| `--bc-hover`     | എലിപ്സിസ് ഹോവർ ബാക്ക്ഗ്രൗണ്ട്.                            |
| `--bc-focus`     | ഫോക്കസ് റിംഗ്.                                            |
| `--bc-max-label` | മുറിക്കുന്നതിനു മുമ്പുള്ള ഏറ്റവും നീളമുള്ള ലേബൽ (`24ch`). |

#### ഡാറ്റ ആട്രിബ്യൂട്ടുകൾ

| Element                      | Attributes            |
| ---------------------------- | --------------------- |
| Root (`nav.bc-root`)         | `data-size`           |
| Item (`li.bc-item`)          | `data-index`          |
| Current page (`.bc-current`) | `aria-current="page"` |

## ലോക്കൽ ടെക്സ്റ്റ്

```tsx
<Breadcrumb
  localeText={{
    label: "Brotkrumen",
    showMore: (count) => `${count} weitere anzeigen`,
  }}
/>
```

| Key        | Default                          |
| ---------- | -------------------------------- |
| `label`    | `"Breadcrumb"`                   |
| `showMore` | `(count) => "Show {count} more"` |

## ഹെഡ്‌ലെസ് ഉപയോഗം

| Export                                             | Description                                                                     |
| -------------------------------------------------- | ------------------------------------------------------------------------------- |
| `collapseItems(count, maxItems?, before?, after?)` | റെൻഡർ ചെയ്ത ട്രെയിൽ: ക്രമ്പ് ഇൻഡെക്സുകളും മറച്ചുവെച്ചവയോടുകൂടിയ ഒരു എലിപ്സിസും. |
| `toBreadcrumbJsonLd(items, baseUrl?)`              | schema.org `BreadcrumbList` ഒബ്ജക്റ്റ്.                                         |

## Next.js

ബ്രെഡ്‌ക്രമ്പ് ഒരു ക്ലയന്റ് കമ്പോണന്റ് ആണ്, അതിന്റെ ഫയലിന്റെ മുകളിൽ `"use client"` ഉള്ളത്, കൂടാതെ ഘടനാപരമായ ഡാറ്റ ഉൾപ്പെടെ അത് പൂർണ്ണമായി സെർവറിൽ റെൻഡർ ചെയ്യുന്നു.

ഒരു സെർവർ കമ്പോണന്റിന് ഇത് പ്ലെയിൻ `items` (ലേബലുകൾ, `href`-കൾ, ഐക്കണുകൾ) ഉപയോഗിച്ച് നേരിട്ട് റെൻഡർ ചെയ്യാം. `renderLink`-ഉം `onClick`-ഉം ഫംഗ്ഷനുകളാണ്, ഒരു സെർവർ കമ്പോണന്റിൽ നിന്ന് ഒരു ക്ലയന്റ് കമ്പോണന്റിലേക്ക് ഫംഗ്ഷനുകൾ കൈമാറാൻ കഴിയില്ല. അവയെ പകരം ഒരു ചെറിയ ക്ലയന്റ് റാപ്പറിൽ ഇടുക, കൂടാതെ പേജിൽ നിന്ന് ഐറ്റങ്ങൾ അതിലേക്ക് കൈമാറുക:

```tsx
// app/components/AppBreadcrumb.tsx
"use client";

import Link from "next/link";
import { Breadcrumb, type BreadcrumbItem } from "@/components/breadcrumb";

export function AppBreadcrumb({ items }: { items: BreadcrumbItem[] }) {
  return (
    <Breadcrumb items={items} renderLink={(props) => <Link {...props} />} />
  );
}
```

#### കുറിപ്പുകൾ

- വലത്തുനിന്ന്-ഇടത്തോട്ടുള്ള (right-to-left) ലേഔട്ടുകളിൽ, ഷെവ്റോൺ സെപ്പറേറ്റർ സ്വയമേവ മറുവശത്തേക്ക് ചൂണ്ടുന്നു.
- മുമ്പൊരു ബ്രെഡ്‌ക്രമ്പ് കമ്പോണന്റ് ഇല്ലാത്തതിനാൽ, മൈഗ്രേറ്റ് ചെയ്യാൻ ഒന്നുമില്ല.
