@knkcs/anker 2.0.10 → 2.2.0

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-ANKER.md CHANGED
@@ -77,9 +77,10 @@ Available templates:
77
77
 
78
78
  | Template | Use for |
79
79
  |---|---|
80
- | `<AppShell>` | Authenticated chrome (sidebar · main · rail). Provides `usePageActions(node)` and `usePageRail(node)` hooks. |
80
+ | `<AppShell>` | Authenticated chrome (sidebar · main · rail). Provides `usePageActions(node)`, `usePageHeader(node)`, and `usePageRail(node)` hooks. Page templates register their `<PageHeader>` via `usePageHeader`, which renders it as a band spanning main + rail. |
81
+ | `<PageHeader>` | Three-row page header band (breadcrumb · detail · tabs). Props: `breadcrumbs`, `title`, `subtitle`, `eyebrow`, `actions`, `avatar`, `badges`, `meta`, `tabs`. Each row is independently optional except title. See `docs/page-patterns.md` §Page header anatomy. |
81
82
  | `<IndexPageTemplate>` | List pages — header + optional tabs + toolbar + DataTable |
82
- | `<DetailPageTemplate>` | Single-entity pages — header + optional tabs + body |
83
+ | `<DetailPageTemplate>` | Single-entity pages — registers a three-row header band via `usePageHeader`. New props: `avatar`, `badges`, `meta`, `tabs`. `subheader` and `bodyTabs` were removed in v2.2.0 — migrate to the slot props on PageHeader. |
83
84
  | `<SettingsPageTemplate>` | Tabbed settings pages with form Cards |
84
85
  | `<DashboardPageTemplate>` | Widget-grid overview pages |
85
86
  | `<AuthPageTemplate>` | Login, register, MFA, verify — centered card, no shell |
@@ -106,7 +106,11 @@ var PageHeader = ({
106
106
  title,
107
107
  subtitle,
108
108
  actions,
109
- eyebrow
109
+ avatar,
110
+ badges,
111
+ eyebrow,
112
+ meta,
113
+ tabs
110
114
  }) => {
111
115
  const hasCrumbs = !!breadcrumbs && breadcrumbs.length > 0;
112
116
  const hasActions = !!actions;
@@ -169,19 +173,23 @@ var PageHeader = ({
169
173
  })
170
174
  }
171
175
  ),
172
- /* @__PURE__ */ jsxs(Flex, { align: "center", justify: "space-between", gap: "4", children: [
176
+ /* @__PURE__ */ jsxs(Flex, { align: "flex-start", justify: "space-between", gap: "4", children: [
177
+ avatar && /* @__PURE__ */ jsx(Box, { "data-testid": "page-header-avatar", flexShrink: 0, children: avatar }),
173
178
  /* @__PURE__ */ jsxs(Box, { flex: "1", minW: "0", children: [
174
- /* @__PURE__ */ jsx(
175
- Heading,
176
- {
177
- as: "h1",
178
- fontSize: "2xl",
179
- fontWeight: "semibold",
180
- color: "default",
181
- letterSpacing: "-0.02em",
182
- children: title
183
- }
184
- ),
179
+ /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "2", wrap: "wrap", children: [
180
+ /* @__PURE__ */ jsx(
181
+ Heading,
182
+ {
183
+ as: "h1",
184
+ fontSize: "2xl",
185
+ fontWeight: "semibold",
186
+ color: "default",
187
+ letterSpacing: "-0.02em",
188
+ children: title
189
+ }
190
+ ),
191
+ badges && /* @__PURE__ */ jsx(Flex, { "data-testid": "page-header-badges", align: "center", gap: "2", children: badges })
192
+ ] }),
185
193
  subtitle && /* @__PURE__ */ jsx(
186
194
  Text,
187
195
  {
@@ -191,10 +199,12 @@ var PageHeader = ({
191
199
  mt: "1",
192
200
  children: subtitle
193
201
  }
194
- )
202
+ ),
203
+ meta && /* @__PURE__ */ jsx(Box, { "data-testid": "page-header-meta", mt: "2", children: meta })
195
204
  ] }),
196
205
  hasActions && /* @__PURE__ */ jsx(Flex, { align: "center", gap: "2", flexShrink: 0, children: actions })
197
- ] })
206
+ ] }),
207
+ tabs && /* @__PURE__ */ jsx(Box, { "data-testid": "page-header-tabs", mt: "4", mx: "-8", children: tabs })
198
208
  ]
199
209
  }
200
210
  );
@@ -202,5 +212,5 @@ var PageHeader = ({
202
212
  PageHeader.displayName = "PageHeader";
203
213
 
204
214
  export { AuthCard, PageHeader };
205
- //# sourceMappingURL=chunk-D5ICTOCW.js.map
206
- //# sourceMappingURL=chunk-D5ICTOCW.js.map
215
+ //# sourceMappingURL=chunk-IHX7KQRU.js.map
216
+ //# sourceMappingURL=chunk-IHX7KQRU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/auth-card.tsx","../src/components/page-header.tsx"],"names":["jsxs","jsx"],"mappings":"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","file":"chunk-IHX7KQRU.js","sourcesContent":["// src/components/auth-card.tsx\nimport type React from \"react\";\nimport { Box, Flex } from \"../primitives/layout\";\nimport { Heading, Text } from \"../primitives/typography\";\n\nexport interface AuthCardProps {\n\t/** Logo or wordmark, far-left of the topbar. */\n\tlogo?: React.ReactNode;\n\t/** Right-side topbar content (help link, locale switcher, etc.). */\n\ttopBarRight?: React.ReactNode;\n\t/** Hide the topbar entirely (rare — e.g. embedded preview). */\n\thideTopBar?: boolean;\n\t/** Hide the dot-grid background (rare — e.g. printable). */\n\thideBackground?: boolean;\n\t/** Small uppercase eyebrow above the title. */\n\teyebrow?: React.ReactNode;\n\t/**\n\t * Card title. Accepts a string or inline element — the component wraps\n\t * it in an `<h3>` (semantic heading, 24px, semibold, default color).\n\t * Avoid passing block elements (e.g. `<div>`) or pre-built headings.\n\t */\n\ttitle?: React.ReactNode;\n\t/** Subtitle below title (14px, muted color, centered). */\n\tsubtitle?: React.ReactNode;\n\t/** Card width preset. md = 440px (default), lg = 480px. */\n\tsize?: \"md\" | \"lg\";\n\t/** Card footer slot. Bottom-bordered inside the card. */\n\tfooter?: React.ReactNode;\n\t/** Page content inside the card body. */\n\tchildren: React.ReactNode;\n}\n\nconst SIZE_TO_WIDTH: Record<NonNullable<AuthCardProps[\"size\"]>, string> = {\n\tmd: \"440px\",\n\tlg: \"480px\",\n};\n\nconst DOT_PATTERN_BG =\n\t\"radial-gradient(var(--chakra-colors-primary-200) 1px, transparent 1px)\";\n\nexport const AuthCard = ({\n\tlogo,\n\ttopBarRight,\n\thideTopBar = false,\n\thideBackground = false,\n\teyebrow,\n\ttitle,\n\tsubtitle,\n\tsize = \"md\",\n\tfooter,\n\tchildren,\n}: AuthCardProps) => {\n\treturn (\n\t\t<Box data-testid=\"auth-card\" data-size={size} minH=\"100vh\" bg=\"bg-canvas\">\n\t\t\t<Box\n\t\t\t\tdata-testid=\"auth-card-canvas\"\n\t\t\t\tdata-background={hideBackground ? \"hidden\" : \"visible\"}\n\t\t\t\tminH=\"100vh\"\n\t\t\t\tbgImage={hideBackground ? undefined : DOT_PATTERN_BG}\n\t\t\t\tbgSize=\"24px 24px\"\n\t\t\t>\n\t\t\t\t{!hideTopBar && (\n\t\t\t\t\t<Flex\n\t\t\t\t\t\talign=\"center\"\n\t\t\t\t\t\tjustify=\"space-between\"\n\t\t\t\t\t\tpx=\"8\"\n\t\t\t\t\t\tpy=\"4\"\n\t\t\t\t\t\tbg=\"bg-surface/85\"\n\t\t\t\t\t\tbackdropFilter=\"blur(4px)\"\n\t\t\t\t\t\tborderBottom=\"1px solid\"\n\t\t\t\t\t\tborderColor=\"border\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<Box>{logo}</Box>\n\t\t\t\t\t\t<Flex gap=\"4\" fontSize=\"xs\" color=\"muted\">\n\t\t\t\t\t\t\t{topBarRight}\n\t\t\t\t\t\t</Flex>\n\t\t\t\t\t</Flex>\n\t\t\t\t)}\n\n\t\t\t\t<Flex justify=\"center\" pt=\"16\" px=\"4\">\n\t\t\t\t\t<Box\n\t\t\t\t\t\tw=\"full\"\n\t\t\t\t\t\tmaxW={SIZE_TO_WIDTH[size]}\n\t\t\t\t\t\tbg=\"bg-surface\"\n\t\t\t\t\t\tborderRadius=\"lg\"\n\t\t\t\t\t\tshadow=\"md\"\n\t\t\t\t\t\tp=\"8\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{eyebrow && (\n\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\ttextStyle=\"overline\"\n\t\t\t\t\t\t\t\tcolor=\"muted\"\n\t\t\t\t\t\t\t\ttextAlign=\"center\"\n\t\t\t\t\t\t\t\tmb=\"2\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{eyebrow}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{title && (\n\t\t\t\t\t\t\t<Heading\n\t\t\t\t\t\t\t\tas=\"h3\"\n\t\t\t\t\t\t\t\tsize=\"2xl\"\n\t\t\t\t\t\t\t\tfontWeight=\"semibold\"\n\t\t\t\t\t\t\t\tcolor=\"default\"\n\t\t\t\t\t\t\t\ttextAlign=\"center\"\n\t\t\t\t\t\t\t\tmb=\"2\"\n\t\t\t\t\t\t\t\tletterSpacing=\"-0.02em\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{title}\n\t\t\t\t\t\t\t</Heading>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{subtitle && (\n\t\t\t\t\t\t\t<Text color=\"muted\" textAlign=\"center\" fontSize=\"sm\" mb=\"6\">\n\t\t\t\t\t\t\t\t{subtitle}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{children}\n\n\t\t\t\t\t\t{footer && (\n\t\t\t\t\t\t\t<Box\n\t\t\t\t\t\t\t\tdata-testid=\"auth-card-footer\"\n\t\t\t\t\t\t\t\tmt=\"6\"\n\t\t\t\t\t\t\t\tpt=\"4\"\n\t\t\t\t\t\t\t\tborderTop=\"1px solid\"\n\t\t\t\t\t\t\t\tborderColor=\"border\"\n\t\t\t\t\t\t\t\ttextAlign=\"center\"\n\t\t\t\t\t\t\t\tfontSize=\"xs\"\n\t\t\t\t\t\t\t\tcolor=\"emphasized\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{footer}\n\t\t\t\t\t\t\t</Box>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Box>\n\t\t\t\t</Flex>\n\t\t\t</Box>\n\t\t</Box>\n\t);\n};\nAuthCard.displayName = \"AuthCard\";\n","// src/components/page-header.tsx\nimport type React from \"react\";\nimport { Box, Flex } from \"../primitives/layout\";\nimport { Heading, Link, Text } from \"../primitives/typography\";\n\nexport interface PageHeaderBreadcrumb {\n\tlabel: string;\n\tto?: string;\n}\n\nexport interface PageHeaderProps {\n\tbreadcrumbs?: PageHeaderBreadcrumb[];\n\ttitle: React.ReactNode;\n\tsubtitle?: React.ReactNode;\n\tactions?: React.ReactNode;\n\tavatar?: React.ReactNode;\n\tbadges?: React.ReactNode;\n\teyebrow?: React.ReactNode;\n\tmeta?: React.ReactNode;\n\ttabs?: React.ReactNode;\n}\n\nexport const PageHeader = ({\n\tbreadcrumbs,\n\ttitle,\n\tsubtitle,\n\tactions,\n\tavatar,\n\tbadges,\n\teyebrow,\n\tmeta,\n\ttabs,\n}: PageHeaderProps) => {\n\tconst hasCrumbs = !!breadcrumbs && breadcrumbs.length > 0;\n\tconst hasActions = !!actions;\n\n\treturn (\n\t\t<Box\n\t\t\tpy=\"4\"\n\t\t\tpx=\"8\"\n\t\t\tborderBottomWidth=\"1px\"\n\t\t\tborderBottomColor=\"border\"\n\t\t\tbg=\"bg-surface\"\n\t\t>\n\t\t\t{eyebrow && (\n\t\t\t\t<Text\n\t\t\t\t\tfontSize=\"2xs\"\n\t\t\t\t\tfontWeight=\"semibold\"\n\t\t\t\t\tletterSpacing=\"wider\"\n\t\t\t\t\ttextTransform=\"uppercase\"\n\t\t\t\t\tcolor=\"muted\"\n\t\t\t\t\tmb=\"1\"\n\t\t\t\t>\n\t\t\t\t\t{eyebrow}\n\t\t\t\t</Text>\n\t\t\t)}\n\n\t\t\t{hasCrumbs && (\n\t\t\t\t<Flex\n\t\t\t\t\tdata-testid=\"page-header-breadcrumbs\"\n\t\t\t\t\talign=\"center\"\n\t\t\t\t\tgap=\"1\"\n\t\t\t\t\tmb=\"1\"\n\t\t\t\t\tfontSize=\"xs\"\n\t\t\t\t\tcolor=\"muted\"\n\t\t\t\t>\n\t\t\t\t\t{breadcrumbs.map((c, idx) => {\n\t\t\t\t\t\tconst isLast = idx === breadcrumbs.length - 1;\n\t\t\t\t\t\tconst sep = !isLast ? <span aria-hidden> › </span> : null;\n\t\t\t\t\t\tconst node = c.to ? (\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tkey={`crumb-link-${c.label}`}\n\t\t\t\t\t\t\t\thref={c.to}\n\t\t\t\t\t\t\t\tcolor=\"muted\"\n\t\t\t\t\t\t\t\t_hover={{ color: \"default\" }}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{c.label}\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\tkey={`crumb-text-${c.label}`}\n\t\t\t\t\t\t\t\tas=\"span\"\n\t\t\t\t\t\t\t\tcolor={isLast ? \"default\" : \"muted\"}\n\t\t\t\t\t\t\t\tfontWeight={isLast ? \"medium\" : \"normal\"}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{c.label}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<Flex key={`crumb-wrap-${c.label}`} align=\"center\" gap=\"1\">\n\t\t\t\t\t\t\t\t{node}\n\t\t\t\t\t\t\t\t{sep}\n\t\t\t\t\t\t\t</Flex>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</Flex>\n\t\t\t)}\n\n\t\t\t<Flex align=\"flex-start\" justify=\"space-between\" gap=\"4\">\n\t\t\t\t{avatar && (\n\t\t\t\t\t<Box data-testid=\"page-header-avatar\" flexShrink={0}>\n\t\t\t\t\t\t{avatar}\n\t\t\t\t\t</Box>\n\t\t\t\t)}\n\t\t\t\t<Box flex=\"1\" minW=\"0\">\n\t\t\t\t\t<Flex align=\"center\" gap=\"2\" wrap=\"wrap\">\n\t\t\t\t\t\t<Heading\n\t\t\t\t\t\t\tas=\"h1\"\n\t\t\t\t\t\t\tfontSize=\"2xl\"\n\t\t\t\t\t\t\tfontWeight=\"semibold\"\n\t\t\t\t\t\t\tcolor=\"default\"\n\t\t\t\t\t\t\tletterSpacing=\"-0.02em\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{title}\n\t\t\t\t\t\t</Heading>\n\t\t\t\t\t\t{badges && (\n\t\t\t\t\t\t\t<Flex data-testid=\"page-header-badges\" align=\"center\" gap=\"2\">\n\t\t\t\t\t\t\t\t{badges}\n\t\t\t\t\t\t\t</Flex>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Flex>\n\t\t\t\t\t{subtitle && (\n\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\tdata-testid=\"page-header-subtitle\"\n\t\t\t\t\t\t\tfontSize=\"sm\"\n\t\t\t\t\t\t\tcolor=\"muted\"\n\t\t\t\t\t\t\tmt=\"1\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{subtitle}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t)}\n\t\t\t\t\t{meta && (\n\t\t\t\t\t\t<Box data-testid=\"page-header-meta\" mt=\"2\">\n\t\t\t\t\t\t\t{meta}\n\t\t\t\t\t\t</Box>\n\t\t\t\t\t)}\n\t\t\t\t</Box>\n\t\t\t\t{hasActions && (\n\t\t\t\t\t<Flex align=\"center\" gap=\"2\" flexShrink={0}>\n\t\t\t\t\t\t{actions}\n\t\t\t\t\t</Flex>\n\t\t\t\t)}\n\t\t\t</Flex>\n\t\t\t{tabs && (\n\t\t\t\t<Box data-testid=\"page-header-tabs\" mt=\"4\" mx=\"-8\">\n\t\t\t\t\t{tabs}\n\t\t\t\t</Box>\n\t\t\t)}\n\t\t</Box>\n\t);\n};\nPageHeader.displayName = \"PageHeader\";\n"]}
@@ -1,4 +1,4 @@
1
- export { A as AuthCard, a as AuthCardProps, P as PageHeader, b as PageHeaderBreadcrumb, c as PageHeaderProps } from '../page-header-D-kxNn-f.js';
1
+ export { A as AuthCard, a as AuthCardProps, P as PageHeader, b as PageHeaderBreadcrumb, c as PageHeaderProps } from '../page-header-DQZjQA5u.js';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import * as React$1 from 'react';
4
4
  import React__default, { ReactNode, MouseEventHandler } from 'react';
@@ -4,7 +4,7 @@ import { MenuItem, MenuRoot, MenuTrigger, MenuContent, Tooltip, Badge, Avatar, T
4
4
  import { Popover, PopoverTrigger, PopoverContent, PopoverBody, Switch } from '../chunk-WQIEF5N3.js';
5
5
  import { text_input_default } from '../chunk-OU6H3KU4.js';
6
6
  import { Button, IconButton } from '../chunk-JS7ZEZV3.js';
7
- export { AuthCard, PageHeader } from '../chunk-D5ICTOCW.js';
7
+ export { AuthCard, PageHeader } from '../chunk-IHX7KQRU.js';
8
8
  import { Box, Flex, Heading, Text, HStack, Grid, GridItem, Code, VStack, Link, Spacer, Stack } from '../chunk-G4QMIXLC.js';
9
9
  import { PanelRightOpen, PanelRightClose, ChevronRight, PanelLeftOpen, PanelLeftClose, Search, X, Ellipsis, Plus, ChevronLeft, ArrowUp, ArrowDown, ArrowUpDown, ChevronDown, Check, Upload } from 'lucide-react';
10
10
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
@@ -428,7 +428,7 @@ var ContextRailRoot = ({ storageKey, children }) => {
428
428
  window.localStorage.setItem(storageKey, String(collapsed));
429
429
  }
430
430
  }, [collapsed, storageKey]);
431
- return /* @__PURE__ */ jsx(RailRootContext.Provider, { value: true, children: /* @__PURE__ */ jsx(
431
+ return /* @__PURE__ */ jsx(RailRootContext.Provider, { value: true, children: /* @__PURE__ */ jsxs(
432
432
  Box,
433
433
  {
434
434
  "data-testid": "context-rail",
@@ -436,32 +436,33 @@ var ContextRailRoot = ({ storageKey, children }) => {
436
436
  w: collapsed ? COLLAPSED_WIDTH : EXPANDED_WIDTH,
437
437
  minH: "100vh",
438
438
  transition: "width 250ms ease-out",
439
- overflow: "hidden",
440
439
  position: "relative",
441
- children: collapsed ? /* @__PURE__ */ jsx(Flex, { direction: "column", align: "center", pt: "3", gap: "3", children: /* @__PURE__ */ jsx(
442
- IconButton,
443
- {
444
- "data-testid": "context-rail-toggle",
445
- "aria-label": "Expand context rail",
446
- variant: "ghost",
447
- size: "sm",
448
- onClick: () => setCollapsed(false),
449
- children: /* @__PURE__ */ jsx(PanelRightOpen, { size: 16 })
450
- }
451
- ) }) : /* @__PURE__ */ jsxs(Flex, { direction: "column", h: "full", children: [
452
- /* @__PURE__ */ jsx(Flex, { justify: "flex-end", px: "3", pt: "3", children: /* @__PURE__ */ jsx(
440
+ children: [
441
+ /* @__PURE__ */ jsx(
453
442
  IconButton,
454
443
  {
455
444
  "data-testid": "context-rail-toggle",
456
- "aria-label": "Collapse context rail",
457
- variant: "ghost",
458
- size: "sm",
459
- onClick: () => setCollapsed(true),
460
- children: /* @__PURE__ */ jsx(PanelRightClose, { size: 16 })
445
+ "aria-label": collapsed ? "Expand context rail" : "Collapse context rail",
446
+ onClick: () => setCollapsed((c) => !c),
447
+ variant: "outline",
448
+ size: "xs",
449
+ position: "absolute",
450
+ top: "6",
451
+ left: "-3.5",
452
+ width: "7",
453
+ height: "7",
454
+ minW: "7",
455
+ borderRadius: "full",
456
+ bg: "bg-surface",
457
+ borderColor: "border",
458
+ boxShadow: "sm",
459
+ zIndex: 1,
460
+ _hover: { bg: "bg-muted" },
461
+ children: collapsed ? /* @__PURE__ */ jsx(PanelRightOpen, { size: 14 }) : /* @__PURE__ */ jsx(PanelRightClose, { size: 14 })
461
462
  }
462
- ) }),
463
- /* @__PURE__ */ jsx(Box, { flex: "1", overflowY: "auto", px: "4", pb: "4", children })
464
- ] })
463
+ ),
464
+ collapsed ? null : /* @__PURE__ */ jsx(Box, { h: "full", overflowY: "auto", px: "4", pt: "4", pb: "4", children })
465
+ ]
465
466
  }
466
467
  ) });
467
468
  };