highsoft-ui 1.0.174 → 1.0.175

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md CHANGED
@@ -964,7 +964,38 @@ A page that has a site `<Header>` already spends the top of a phone screen on th
964
964
  - The grab handle is `aria-hidden` — it's the touch affordance, and the labelled close button is the control. Under `prefers-reduced-motion: reduce` the sheet arrives and leaves instantly; dragging it still tracks the finger, since that's direct manipulation rather than authored motion.
965
965
  - Widening past 760px retires the sheet without moving focus — a resize isn't a dismissal.
966
966
 
967
- ### PrevNextNav
967
+ ### Breadcrumb
968
+ The trail to the current page: linked items are the plain `Button` at size 100, the current page is a label marked `aria-current="page"`, separators are `Icon`s. Everything sits on one 24px row. Pass your router link as `link`.
969
+ ```tsx
970
+ import Link from 'next/link'
971
+ import { Tool02 } from '@untitled-ui/icons-react'
972
+
973
+ <Breadcrumb
974
+ link={Link}
975
+ items={[
976
+ { label: 'Build', icon: Tool02, iconColor: 'brand' }, // a section name, not a link
977
+ { label: 'Charts', href: '/docs/charts' },
978
+ { label: 'Core chart types', href: '/docs/charts/chart-types' },
979
+ { label: '3D pyramid' } // the current page, no href
980
+ ]}
981
+ />
982
+
983
+ // Arrows or slashes instead of chevrons
984
+ <Breadcrumb items={items} separator="arrow" />
985
+ <Breadcrumb items={items} separator="slash" />
986
+ ```
987
+ - **`items`:** `{ label, href?, icon?, iconColor? }`, first to last. An item with `href` is a link; the last item is the current page and never a link; an item without `href` elsewhere (a section name) is a plain label. `icon` is an `@untitled-ui/icons-react` component drawn through `Icon` at 12px; `iconColor="brand"` gives it `--HS-text-brand-default-alt`, the text stays as it is.
988
+ - **`separator`:** `chevron` (default), `arrow`, `slash`. Icons sit in the tertiary tone, 2px from the items.
989
+ - **`link`:** the component for links (Next's `Link`, a router's link); default `"a"`.
990
+ - **`collapse`** (default `true`): with more than three items, the middle ones fold into an ellipsis below 760px (the Sidebar's drawer point) so the first and the last two stay.
991
+ - **`label`:** the `<nav>`'s accessible name (default "Breadcrumb").
992
+ - Labels longer than 28 characters are cut with an ellipsis so a long page title does not push the trail onto three lines.
993
+
994
+ **Accessibility:**
995
+ - A `<nav aria-label="Breadcrumb">` holding an `<ol>`, so a screen reader hears the trail in order and can jump to or skip it as a landmark.
996
+ - Links are real links (the Button as `<a>` or the router's link), keyboard reachable with the Button's shared focus ring. The current page is not a link and carries `aria-current="page"`, so it is announced as where you are.
997
+ - Separators and icons are `aria-hidden`; the folded middle items are `display: none`, so assistive technology gets the full trail only when it is visible. Nothing animates beyond the Button's own hover.
998
+
968
999
  Previous / next footer navigation — two link cards in a three-slot grid (`1fr auto 1fr`) with an optional centered back-to-overview button. For sequential content: docs articles, changelog versions, API option pages.
969
1000
 
970
1001
  ```tsx
@@ -1213,6 +1244,12 @@ All components use the same `iconLeft` / `iconRight` naming:
1213
1244
  - **Do** pass an icon component to `icon` for a custom bullet
1214
1245
  - **Don't** write bullets or numbers into the item text (`•`, `1.`) — the component draws them
1215
1246
 
1247
+ ### Breadcrumb
1248
+ - **Do** end with the current page as a plain item — never link the page you are on
1249
+ - **Don't** put the site root in the trail when the header already links it; start at the section
1250
+ - **Do** pass `link={Link}` in a Next app so the trail routes client-side
1251
+ - **Don't** add icons to every item — one on the section name is enough to mark the band
1252
+
1216
1253
  ### Figure
1217
1254
  - **Do** put the explanation in `caption` and what the image shows in `alt`
1218
1255
  - **Don't** repeat the caption as the alt text, or leave the alt as a file name
@@ -0,0 +1,80 @@
1
+ import { t as e } from "./clsx-BWCAbrjV.js";
2
+ import { Q as t, st as n } from "./esm-DQBytmnt.js";
3
+ import { t as r } from "./Button-DFcjZsF4.js";
4
+ import { t as i } from "./Icon-DJTgdvsG.js";
5
+ import { forwardRef as a } from "react";
6
+ import { jsx as o, jsxs as s } from "react/jsx-runtime";
7
+ var c = {
8
+ brandIcon: "SKL1XW_brandIcon",
9
+ current: "SKL1XW_current",
10
+ ellipsis: "SKL1XW_ellipsis",
11
+ folds: "SKL1XW_folds",
12
+ item: "SKL1XW_item",
13
+ label: "SKL1XW_label",
14
+ list: "SKL1XW_list",
15
+ nav: "SKL1XW_nav",
16
+ sep: "SKL1XW_sep",
17
+ slash: "SKL1XW_slash",
18
+ text: "SKL1XW_text"
19
+ }, l = a(({ items: a, separator: l = "chevron", link: u = "a", collapse: d = !0, label: f = "Breadcrumb", className: p, ...m }, h) => {
20
+ if (a.length === 0) return null;
21
+ let g = a.length - 1, _ = d && a.length > 3, v = l === "slash" ? /* @__PURE__ */ o("span", {
22
+ className: e(c.sep, c.slash),
23
+ "aria-hidden": "true",
24
+ children: "/"
25
+ }) : /* @__PURE__ */ o(i, {
26
+ name: l === "arrow" ? n : t,
27
+ size: 12,
28
+ className: c.sep,
29
+ "aria-hidden": "true"
30
+ });
31
+ return /* @__PURE__ */ o("nav", {
32
+ ref: h,
33
+ className: e("hsui-breadcrumb", c.nav, p),
34
+ "aria-label": f,
35
+ ...m,
36
+ children: /* @__PURE__ */ o("ol", {
37
+ className: c.list,
38
+ children: a.map((t, n) => {
39
+ let a = n === g, l = _ && n > 0 && n < g - 1, d = t.icon ? /* @__PURE__ */ o(i, {
40
+ name: t.icon,
41
+ size: 12,
42
+ className: e(t.iconColor === "brand" && c.brandIcon),
43
+ "aria-hidden": "true"
44
+ }) : null, f = t.href && !a ? /* @__PURE__ */ o(r, {
45
+ as: u,
46
+ href: t.href,
47
+ variant: "plain",
48
+ size: 100,
49
+ iconLeft: d ?? void 0,
50
+ children: t.label
51
+ }) : /* @__PURE__ */ s("span", {
52
+ className: a ? c.current : c.text,
53
+ "aria-current": a ? "page" : void 0,
54
+ children: [d, /* @__PURE__ */ o("span", {
55
+ className: c.label,
56
+ children: t.label
57
+ })]
58
+ });
59
+ return /* @__PURE__ */ s("li", {
60
+ className: e(c.item, l && c.folds),
61
+ children: [
62
+ n > 0 && v,
63
+ f,
64
+ _ && n === 0 && /* @__PURE__ */ s("span", {
65
+ className: c.ellipsis,
66
+ "aria-hidden": "true",
67
+ children: [v, /* @__PURE__ */ o("span", {
68
+ className: c.text,
69
+ children: "…"
70
+ })]
71
+ })
72
+ ]
73
+ }, n);
74
+ })
75
+ })
76
+ });
77
+ });
78
+ l.displayName = "Breadcrumb";
79
+ //#endregion
80
+ export { l as t };
@@ -0,0 +1,2 @@
1
+ import { t as e } from "../../Breadcrumb-CyaMrJfW.js";
2
+ export { e as Breadcrumb };