@nexub/patterns 2.2.0 → 2.3.1

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/README.md CHANGED
@@ -6,7 +6,10 @@ Composite UI patterns for the Nexub Design System, built on `@nexub/react`.
6
6
  pnpm add @nexub/patterns @nexub/react @nexub/icons @nexub/themes
7
7
  ```
8
8
 
9
- Like `@nexub/react`, the patterns are styled with Tailwind classes your app compiles: add `node_modules/@nexub/patterns/dist/**/*.js` to your Tailwind `content`, use the `@nexub/tokens/tailwind` preset, and import `@nexub/themes/base` plus a palette (e.g. `@nexub/themes/light` and `@nexub/themes/dark`).
9
+ Like `@nexub/react`, the patterns are styled with Tailwind classes your app compiles, on Tailwind 3 or 4. Import `@nexub/themes/base` plus a palette (e.g. `@nexub/themes/light` and `@nexub/themes/dark`), then:
10
+
11
+ - **Tailwind 3:** add `node_modules/@nexub/patterns/dist/**/*.js` to your Tailwind `content` and use the `@nexub/tokens/tailwind` preset.
12
+ - **Tailwind 4:** `@import "@nexub/tokens/tailwind.css";` after `@import "tailwindcss";`, add `@source "../node_modules/@nexub/patterns/dist";`, and import the theme CSS with `layer(base)` so Tailwind's utilities still win over it. See [Getting Started](https://nexub-ds-docs.pages.dev/getting-started) for the full snippet.
10
13
 
11
14
  ## AppHeader
12
15
 
@@ -123,6 +126,8 @@ Search opens with the button, **⌘K / Ctrl+K** anywhere, or **/** when focus is
123
126
  </SettingsLayout>
124
127
  ```
125
128
 
129
+ `navFooter` pins a line to the bottom of the section sidebar and the phone menu while the items scroll, e.g. `navFooter="v1.2.0 · Updated 21 Oct 2026"`. In your own `Sidebar`, use `Sidebar.Footer` for the same.
130
+
126
131
  ### Strict CSP
127
132
 
128
133
  The header injects no `<style>` tags and sets no inline styles of its own: the search palette locks page scroll with a class (`scrollLock="class"`), and the org and account menus are non-modal. One known gap: the colour Nexub mark inside `Logo` still sets `style` on its gradient stops, so under `style-src 'self'` a server-rendered mark loses its colours until that is fixed.
@@ -11,22 +11,26 @@ function SectionNav({
11
11
  activeId,
12
12
  onChoose,
13
13
  label,
14
+ footer,
14
15
  className
15
16
  }) {
16
- return /* @__PURE__ */ jsx(Sidebar.Root, { "aria-label": label, className, children: /* @__PURE__ */ jsx(Sidebar.Group, { children: items.map((item) => /* @__PURE__ */ jsx(
17
- Sidebar.Item,
18
- {
19
- href: item.href,
20
- icon: item.icon,
21
- active: item.id === activeId,
22
- onClick: (e) => onChoose(e, item),
23
- children: item.label
24
- },
25
- item.id
26
- )) }) });
17
+ return /* @__PURE__ */ jsxs(Sidebar.Root, { "aria-label": label, className, children: [
18
+ /* @__PURE__ */ jsx(Sidebar.Group, { children: items.map((item) => /* @__PURE__ */ jsx(
19
+ Sidebar.Item,
20
+ {
21
+ href: item.href,
22
+ icon: item.icon,
23
+ active: item.id === activeId,
24
+ onClick: (e) => onChoose(e, item),
25
+ children: item.label
26
+ },
27
+ item.id
28
+ )) }),
29
+ footer && /* @__PURE__ */ jsx(Sidebar.Footer, { className: "px-5 py-3 text-xs text-[var(--color-on-surface-muted)]", children: footer })
30
+ ] });
27
31
  }
28
32
  var Root = React.forwardRef(
29
- ({ items, activeId, onSelect, logo, actions, header, title, description, navLabel = "Settings", className, children, ...props }, ref) => {
33
+ ({ items, activeId, onSelect, logo, actions, header, title, description, navLabel = "Settings", navFooter, className, children, ...props }, ref) => {
30
34
  const [menuOpen, setMenuOpen] = React.useState(false);
31
35
  const onChoose = (e, item) => {
32
36
  if (!isPlainClick(e)) return;
@@ -51,6 +55,7 @@ var Root = React.forwardRef(
51
55
  activeId,
52
56
  onChoose,
53
57
  label: navLabel,
58
+ footer: navFooter,
54
59
  className: "sticky top-[var(--app-header-height,64px)] hidden h-[calc(100vh-var(--app-header-height,64px))] shrink-0 md:flex"
55
60
  }
56
61
  ),
@@ -66,7 +71,7 @@ var Root = React.forwardRef(
66
71
  /* @__PURE__ */ jsx(Sheet.Overlay, { className: "md:hidden" }),
67
72
  /* @__PURE__ */ jsxs(Sheet.Content, { side: "left", "aria-describedby": void 0, className: "md:hidden", children: [
68
73
  /* @__PURE__ */ jsx(Sheet.Title, { className: "px-5 pb-2 pt-5 text-base", children: navLabel }),
69
- /* @__PURE__ */ jsx(SectionNav, { items, activeId, onChoose, label: navLabel, className: "w-full border-e-0" })
74
+ /* @__PURE__ */ jsx(SectionNav, { items, activeId, onChoose, label: navLabel, footer: navFooter, className: "min-h-0 w-full flex-1 border-e-0" })
70
75
  ] })
71
76
  ] }) })
72
77
  ] });
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  SettingsLayout,
4
4
  SettingsRow
5
- } from "../../chunk-WIHNK7RT.js";
5
+ } from "../../chunk-Z4FCC42C.js";
6
6
  export {
7
7
  SettingsLayout,
8
8
  SettingsRow
package/dist/index.d.ts CHANGED
@@ -199,6 +199,8 @@ interface SettingsLayoutProps extends Omit<React.HTMLAttributes<HTMLDivElement>,
199
199
  description?: React.ReactNode;
200
200
  /** Accessible name of the section navigation. */
201
201
  navLabel?: string;
202
+ /** Pinned to the bottom of the section sidebar (and the phone menu) while the items scroll, e.g. `v1.2.0 · Updated 21 Oct 2026`. */
203
+ navFooter?: React.ReactNode;
202
204
  }
203
205
  interface SettingsLayoutSectionProps extends Omit<React.HTMLAttributes<HTMLElement>, 'title'> {
204
206
  title?: React.ReactNode;
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  import {
19
19
  SettingsLayout,
20
20
  SettingsRow
21
- } from "./chunk-WIHNK7RT.js";
21
+ } from "./chunk-Z4FCC42C.js";
22
22
  import {
23
23
  SettingsPage
24
24
  } from "./chunk-27N33TGN.js";
@@ -31,12 +31,6 @@ import {
31
31
  import {
32
32
  CheckoutPage
33
33
  } from "./chunk-CZR6NZDH.js";
34
- import {
35
- DashboardPage
36
- } from "./chunk-33Z2ZPO7.js";
37
- import {
38
- StatCard
39
- } from "./chunk-INKX2GYA.js";
40
34
  import {
41
35
  ErrorSummary,
42
36
  useFormErrors
@@ -45,14 +39,20 @@ import {
45
39
  FilterBar
46
40
  } from "./chunk-Z6VMCMSW.js";
47
41
  import {
48
- InfoList
49
- } from "./chunk-WPNT5JOU.js";
42
+ DashboardPage
43
+ } from "./chunk-33Z2ZPO7.js";
44
+ import {
45
+ StatCard
46
+ } from "./chunk-INKX2GYA.js";
50
47
  import {
51
48
  ListDetail
52
49
  } from "./chunk-5JU6HUVJ.js";
53
50
  import {
54
51
  NotificationItem
55
52
  } from "./chunk-5IORYY2L.js";
53
+ import {
54
+ InfoList
55
+ } from "./chunk-WPNT5JOU.js";
56
56
  import {
57
57
  ActivityFeed
58
58
  } from "./chunk-HYC5N5MO.js";
@@ -71,10 +71,6 @@ import {
71
71
  import {
72
72
  AuthCard
73
73
  } from "./chunk-HMJRSNJD.js";
74
- import {
75
- BentoGrid,
76
- BentoTile
77
- } from "./chunk-WZTDCJYP.js";
78
74
  import {
79
75
  ChatPage
80
76
  } from "./chunk-64PSI75E.js";
@@ -87,6 +83,10 @@ import {
87
83
  groupByDay,
88
84
  usePageMessages
89
85
  } from "./chunk-7QCJC2DV.js";
86
+ import {
87
+ BentoGrid,
88
+ BentoTile
89
+ } from "./chunk-WZTDCJYP.js";
90
90
  export {
91
91
  ActivityFeed,
92
92
  ActivityPage,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexub/patterns",
3
- "version": "2.2.0",
3
+ "version": "2.3.1",
4
4
  "description": "Composite UI patterns for Nexub Design System — pre-built, production-ready layouts and widgets built on @nexub/react.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -36,9 +36,9 @@
36
36
  "peerDependencies": {
37
37
  "react": ">=18 <20",
38
38
  "react-dom": ">=18 <20",
39
- "@nexub/icons": "^2.2.0",
40
- "@nexub/react": "^2.2.0",
41
- "@nexub/tokens": "^2.2.0"
39
+ "@nexub/icons": "^2.3.1",
40
+ "@nexub/react": "^2.3.1",
41
+ "@nexub/tokens": "^2.3.1"
42
42
  },
43
43
  "peerDependenciesMeta": {
44
44
  "@nexub/icons": {
@@ -59,9 +59,9 @@
59
59
  "typescript": "^5.9.3",
60
60
  "vite": "^7.3.7",
61
61
  "vitest": "^5.0.5",
62
- "@nexub/icons": "2.2.0",
63
- "@nexub/react": "2.2.0",
64
- "@nexub/tokens": "2.2.0"
62
+ "@nexub/icons": "2.3.1",
63
+ "@nexub/react": "2.3.1",
64
+ "@nexub/tokens": "2.3.1"
65
65
  },
66
66
  "scripts": {
67
67
  "build": "tsup",