@tollerud/ui 3.0.0 → 3.1.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.
Files changed (86) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +35 -0
  3. package/SKILL.md +5 -4
  4. package/dist/avatar.d.ts +3 -2
  5. package/dist/avatar.js +1 -1
  6. package/dist/bento-dashboard.js +6 -1
  7. package/dist/button.d.ts +1 -1
  8. package/dist/button.js +1 -1
  9. package/dist/{chunk-7TOT5ME3.js → chunk-3LTW224O.js} +6 -6
  10. package/dist/chunk-3LTW224O.js.map +1 -0
  11. package/dist/{chunk-RWJELAS6.js → chunk-ADE22JSR.js} +12 -4
  12. package/dist/chunk-ADE22JSR.js.map +1 -0
  13. package/dist/chunk-AQT3FZRQ.js +23 -0
  14. package/dist/chunk-AQT3FZRQ.js.map +1 -0
  15. package/dist/{chunk-VTRUUT5K.js → chunk-IUPVQWO5.js} +4 -4
  16. package/dist/chunk-IUPVQWO5.js.map +1 -0
  17. package/dist/{chunk-ISHZ6ZPJ.js → chunk-JFOW2DI5.js} +17 -5
  18. package/dist/chunk-JFOW2DI5.js.map +1 -0
  19. package/dist/{chunk-OONIUDST.js → chunk-OLHMMFQ7.js} +3 -8
  20. package/dist/chunk-OLHMMFQ7.js.map +1 -0
  21. package/dist/chunk-ONMTHBZ4.js +54 -0
  22. package/dist/chunk-ONMTHBZ4.js.map +1 -0
  23. package/dist/{chunk-XR5QBVEV.js → chunk-OVSIOZHJ.js} +3 -3
  24. package/dist/{chunk-XR5QBVEV.js.map → chunk-OVSIOZHJ.js.map} +1 -1
  25. package/dist/{chunk-V3P5QLLX.js → chunk-Q54CVE3W.js} +3 -3
  26. package/dist/{chunk-V3P5QLLX.js.map → chunk-Q54CVE3W.js.map} +1 -1
  27. package/dist/chunk-QEIEWGHA.js +62 -0
  28. package/dist/chunk-QEIEWGHA.js.map +1 -0
  29. package/dist/{chunk-CBQ63EBL.js → chunk-QQHBEACI.js} +9 -6
  30. package/dist/chunk-QQHBEACI.js.map +1 -0
  31. package/dist/chunk-T3UQ7G4T.js +58 -0
  32. package/dist/chunk-T3UQ7G4T.js.map +1 -0
  33. package/dist/{chunk-DGCRHVWW.js → chunk-VFS3V3VY.js} +12 -5
  34. package/dist/chunk-VFS3V3VY.js.map +1 -0
  35. package/dist/chunk-VOARBYVQ.js +44 -0
  36. package/dist/chunk-VOARBYVQ.js.map +1 -0
  37. package/dist/{chunk-3TGMGBKM.js → chunk-YPP7QHYT.js} +5 -5
  38. package/dist/{chunk-3TGMGBKM.js.map → chunk-YPP7QHYT.js.map} +1 -1
  39. package/dist/{chunk-O57QMLNI.js → chunk-YTU7BRDW.js} +16 -12
  40. package/dist/chunk-YTU7BRDW.js.map +1 -0
  41. package/dist/{chunk-DFM7UUKB.js → chunk-ZTFOR3AN.js} +4 -4
  42. package/dist/{chunk-DFM7UUKB.js.map → chunk-ZTFOR3AN.js.map} +1 -1
  43. package/dist/cta-band.js +1 -1
  44. package/dist/data-table.js +3 -3
  45. package/dist/date-picker.js +1 -1
  46. package/dist/footer.js +2 -1
  47. package/dist/form-row.d.ts +4 -0
  48. package/dist/form-row.js +1 -1
  49. package/dist/hero-block.js +3 -3
  50. package/dist/index.d.ts +1 -0
  51. package/dist/index.js +22 -21
  52. package/dist/monogram.d.ts +20 -0
  53. package/dist/monogram.js +5 -0
  54. package/dist/monogram.js.map +1 -0
  55. package/dist/noir-glow-background.d.ts +7 -1
  56. package/dist/noir-glow-background.js +1 -1
  57. package/dist/pill.d.ts +5 -2
  58. package/dist/pill.js +1 -1
  59. package/dist/pricing-card.js +2 -2
  60. package/dist/skeleton.d.ts +10 -2
  61. package/dist/skeleton.js +1 -1
  62. package/dist/slider.js +1 -1
  63. package/dist/switch.js +1 -1
  64. package/dist/timeline.js +1 -1
  65. package/globals-layers.css +84 -0
  66. package/package.json +5 -3
  67. package/registry.json +17 -1
  68. package/tokens.css +20 -0
  69. package/tollerud-avatar-full.png +0 -0
  70. package/dist/chunk-7TOT5ME3.js.map +0 -1
  71. package/dist/chunk-CBQ63EBL.js.map +0 -1
  72. package/dist/chunk-DGCRHVWW.js.map +0 -1
  73. package/dist/chunk-FGXOV2QH.js +0 -23
  74. package/dist/chunk-FGXOV2QH.js.map +0 -1
  75. package/dist/chunk-HYQGOC2E.js +0 -79
  76. package/dist/chunk-HYQGOC2E.js.map +0 -1
  77. package/dist/chunk-ISHZ6ZPJ.js.map +0 -1
  78. package/dist/chunk-O57QMLNI.js.map +0 -1
  79. package/dist/chunk-OONIUDST.js.map +0 -1
  80. package/dist/chunk-PLF3BBQI.js +0 -139
  81. package/dist/chunk-PLF3BBQI.js.map +0 -1
  82. package/dist/chunk-Q74VRQEX.js +0 -26
  83. package/dist/chunk-Q74VRQEX.js.map +0 -1
  84. package/dist/chunk-RWJELAS6.js.map +0 -1
  85. package/dist/chunk-VTRUUT5K.js.map +0 -1
  86. /package/{tia-full-figure.svg → tollerud-avatar-full.svg} +0 -0
@@ -0,0 +1,62 @@
1
+ 'use client';
2
+ import { Monogram } from './chunk-VOARBYVQ.js';
3
+ import { cn } from './chunk-WSQNPRGN.js';
4
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
+
6
+ var defaultLabels = {
7
+ tollerudProject: "A Tollerud Project",
8
+ allRightsReserved: "All rights reserved."
9
+ };
10
+ function Footer({
11
+ labels,
12
+ layout = "responsive",
13
+ className,
14
+ style,
15
+ unstyled = false,
16
+ accent = false,
17
+ classNameInner,
18
+ classNameLogo,
19
+ classNameText,
20
+ classNameLink
21
+ }) {
22
+ const t = { ...defaultLabels, ...labels };
23
+ const attribution = t.attribution?.trim();
24
+ const footerSurface = unstyled ? "" : accent ? "border-t border-tollerud-yellow/20 bg-tollerud-yellow/5" : "border-t border-tollerud-border bg-tollerud-noir-900/80";
25
+ const innerLayoutClasses = layout === "row" ? "max-w-7xl mx-auto px-8 flex flex-row items-center justify-between gap-4" : "max-w-7xl mx-auto px-8 flex flex-col md:flex-row items-center justify-center md:justify-between gap-4 md:gap-0";
26
+ const textWrapperClasses = layout === "row" ? "flex-1 text-right ml-4" : "flex-1 text-center md:text-right md:ml-4";
27
+ const textLayoutClasses = layout === "row" ? "text-sm text-tollerud-text-secondary inline-flex flex-row items-center justify-end text-right gap-0" : "text-sm text-tollerud-text-secondary flex flex-col md:flex-row md:inline gap-0";
28
+ return /* @__PURE__ */ jsx("footer", { className: cn("w-full pt-4 pb-4", footerSurface, className), style, children: /* @__PURE__ */ jsxs("div", { className: cn(innerLayoutClasses, classNameInner), children: [
29
+ /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 md:flex-shrink-0", children: /* @__PURE__ */ jsx(Monogram, { color: "yellow", className: cn("h-5 w-auto", classNameLogo) }) }),
30
+ /* @__PURE__ */ jsx("div", { className: textWrapperClasses, children: /* @__PURE__ */ jsxs("p", { className: cn(textLayoutClasses, classNameText), children: [
31
+ /* @__PURE__ */ jsxs("span", { children: [
32
+ /* @__PURE__ */ jsx(
33
+ "a",
34
+ {
35
+ href: "https://tollerud.no",
36
+ target: "_blank",
37
+ rel: "noopener noreferrer",
38
+ className: cn(
39
+ "underline decoration-tollerud-yellow decoration-[3px] underline-offset-[4px] hover:opacity-80 transition-opacity",
40
+ classNameLink
41
+ ),
42
+ style: {
43
+ textDecorationThickness: "3px",
44
+ textUnderlineOffset: "4px"
45
+ },
46
+ children: t.tollerudProject
47
+ }
48
+ ),
49
+ attribution ? /* @__PURE__ */ jsxs(Fragment, { children: [
50
+ " ",
51
+ /* @__PURE__ */ jsx("span", { children: attribution })
52
+ ] }) : null,
53
+ " "
54
+ ] }),
55
+ /* @__PURE__ */ jsx("span", { className: layout === "row" ? "ml-1" : "md:ml-1", children: t.allRightsReserved })
56
+ ] }) })
57
+ ] }) });
58
+ }
59
+
60
+ export { Footer };
61
+ //# sourceMappingURL=chunk-QEIEWGHA.js.map
62
+ //# sourceMappingURL=chunk-QEIEWGHA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Footer.tsx"],"names":[],"mappings":";;;;AAiBA,IAAM,aAAA,GAA8B;AAAA,EAClC,eAAA,EAAiB,oBAAA;AAAA,EACjB,iBAAA,EAAmB;AACrB,CAAA;AAuBO,SAAS,MAAA,CAAO;AAAA,EACrB,MAAA;AAAA,EACA,MAAA,GAAS,YAAA;AAAA,EACT,SAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,MAAA,GAAS,KAAA;AAAA,EACT,cAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAA,EAA8B;AAC5B,EAAA,MAAM,CAAA,GAAI,EAAE,GAAG,aAAA,EAAe,GAAG,MAAA,EAAO;AACxC,EAAA,MAAM,WAAA,GAAc,CAAA,CAAE,WAAA,EAAa,IAAA,EAAK;AAExC,EAAA,MAAM,aAAA,GAAgB,QAAA,GAClB,EAAA,GACA,MAAA,GACE,yDAAA,GACA,yDAAA;AAEN,EAAA,MAAM,kBAAA,GACJ,MAAA,KAAW,KAAA,GACP,yEAAA,GACA,gHAAA;AAEN,EAAA,MAAM,kBAAA,GACJ,MAAA,KAAW,KAAA,GAAQ,wBAAA,GAA2B,0CAAA;AAEhD,EAAA,MAAM,iBAAA,GACJ,MAAA,KAAW,KAAA,GACP,qGAAA,GACA,gFAAA;AAEN,EAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAO,SAAA,EAAW,EAAA,CAAG,oBAAoB,aAAA,EAAe,SAAS,CAAA,EAAG,KAAA,EACnE,+BAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,kBAAA,EAAoB,cAAc,CAAA,EACnD,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EACb,QAAA,kBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,QAAA,EAAS,SAAA,EAAW,EAAA,CAAG,YAAA,EAAc,aAAa,CAAA,EAAG,CAAA,EACvE,CAAA;AAAA,oBAEA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,kBAAA,EACd,QAAA,kBAAA,IAAA,CAAC,OAAE,SAAA,EAAW,EAAA,CAAG,iBAAA,EAAmB,aAAa,CAAA,EAC/C,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,MAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,qBAAA;AAAA,YACL,MAAA,EAAO,QAAA;AAAA,YACP,GAAA,EAAI,qBAAA;AAAA,YACJ,SAAA,EAAW,EAAA;AAAA,cACT,kHAAA;AAAA,cACA;AAAA,aACF;AAAA,YACA,KAAA,EAAO;AAAA,cACL,uBAAA,EAAyB,KAAA;AAAA,cACzB,mBAAA,EAAqB;AAAA,aACvB;AAAA,YAEC,QAAA,EAAA,CAAA,CAAE;AAAA;AAAA,SACL;AAAA,QACC,8BACC,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,UAAA,GAAA;AAAA,0BACD,GAAA,CAAC,UAAM,QAAA,EAAA,WAAA,EAAY;AAAA,SAAA,EACrB,CAAA,GACE,IAAA;AAAA,QAAM;AAAA,OAAA,EACZ,CAAA;AAAA,sBACA,GAAA,CAAC,UAAK,SAAA,EAAW,MAAA,KAAW,QAAQ,MAAA,GAAS,SAAA,EAAY,YAAE,iBAAA,EAAkB;AAAA,KAAA,EAC/E,CAAA,EACF;AAAA,GAAA,EACF,CAAA,EACF,CAAA;AAEJ","file":"chunk-QEIEWGHA.js","sourcesContent":["'use client'\n\nimport type { CSSProperties, ReactElement } from 'react'\nimport { cn } from '@/lib/utils'\nimport { Monogram } from './Monogram'\n\nexport type FooterLabels = {\n /** Text for the tollerud.no link (e.g. \"A Tollerud Project\"). */\n tollerudProject: string\n /**\n * Optional middle segment after the link, before the rights line.\n * Example for Advania: `\"for Advania Norge AS.\"`\n */\n attribution?: string\n allRightsReserved: string\n}\n\nconst defaultLabels: FooterLabels = {\n tollerudProject: 'A Tollerud Project',\n allRightsReserved: 'All rights reserved.',\n}\n\nexport type FooterProps = {\n labels?: Partial<FooterLabels>\n /** Layout behavior: responsive keeps mobile-first stacking, row forces horizontal layout. */\n layout?: 'responsive' | 'row'\n /** Merged onto <footer>. Use for extra layout, padding, etc. */\n className?: string\n /** Merged onto <footer> (wins over conflicting backgroundColor from classes when needed). */\n style?: CSSProperties\n /**\n * When true, skips all default surface styling so className/style fully control the bar\n * (avoids fighting default background/border).\n */\n unstyled?: boolean\n /** When true, uses accent (yellow) surface instead of neutral dark. */\n accent?: boolean\n classNameInner?: string\n classNameLogo?: string\n classNameText?: string\n classNameLink?: string\n}\n\nexport function Footer({\n labels,\n layout = 'responsive',\n className,\n style,\n unstyled = false,\n accent = false,\n classNameInner,\n classNameLogo,\n classNameText,\n classNameLink,\n}: FooterProps): ReactElement {\n const t = { ...defaultLabels, ...labels }\n const attribution = t.attribution?.trim()\n\n const footerSurface = unstyled\n ? ''\n : accent\n ? 'border-t border-tollerud-yellow/20 bg-tollerud-yellow/5'\n : 'border-t border-tollerud-border bg-tollerud-noir-900/80'\n\n const innerLayoutClasses =\n layout === 'row'\n ? 'max-w-7xl mx-auto px-8 flex flex-row items-center justify-between gap-4'\n : 'max-w-7xl mx-auto px-8 flex flex-col md:flex-row items-center justify-center md:justify-between gap-4 md:gap-0'\n\n const textWrapperClasses =\n layout === 'row' ? 'flex-1 text-right ml-4' : 'flex-1 text-center md:text-right md:ml-4'\n\n const textLayoutClasses =\n layout === 'row'\n ? 'text-sm text-tollerud-text-secondary inline-flex flex-row items-center justify-end text-right gap-0'\n : 'text-sm text-tollerud-text-secondary flex flex-col md:flex-row md:inline gap-0'\n\n return (\n <footer className={cn('w-full pt-4 pb-4', footerSurface, className)} style={style}>\n <div className={cn(innerLayoutClasses, classNameInner)}>\n <div className=\"flex-shrink-0 md:flex-shrink-0\">\n <Monogram color=\"yellow\" className={cn('h-5 w-auto', classNameLogo)} />\n </div>\n\n <div className={textWrapperClasses}>\n <p className={cn(textLayoutClasses, classNameText)}>\n <span>\n <a\n href=\"https://tollerud.no\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={cn(\n 'underline decoration-tollerud-yellow decoration-[3px] underline-offset-[4px] hover:opacity-80 transition-opacity',\n classNameLink,\n )}\n style={{\n textDecorationThickness: '3px',\n textUnderlineOffset: '4px',\n }}\n >\n {t.tollerudProject}\n </a>\n {attribution ? (\n <>\n {' '}\n <span>{attribution}</span>\n </>\n ) : null}{' '}\n </span>\n <span className={layout === 'row' ? 'ml-1' : 'md:ml-1'}>{t.allRightsReserved}</span>\n </p>\n </div>\n </div>\n </footer>\n )\n}"]}
@@ -47,7 +47,10 @@ function NoirGlowBackground({
47
47
  preserveCenter = false,
48
48
  noiseOverlay = false,
49
49
  forceCssFallback = false,
50
- inert = true
50
+ inert = true,
51
+ offsetX = 0,
52
+ offsetY = 0,
53
+ scale = 1
51
54
  }) {
52
55
  const wrapperClassName = cx(
53
56
  "tollerud-noir-glow-root absolute inset-0 z-0 overflow-hidden",
@@ -67,9 +70,9 @@ function NoirGlowBackground({
67
70
  intensity: intensityMap[intensity],
68
71
  noise: grainMap[grain],
69
72
  shape,
70
- offsetX: 0,
71
- offsetY: 0,
72
- scale: 1,
73
+ offsetX,
74
+ offsetY,
75
+ scale,
73
76
  rotation: 0,
74
77
  speed: speedMap[speed],
75
78
  colors
@@ -81,5 +84,5 @@ function NoirGlowBackground({
81
84
  }
82
85
 
83
86
  export { NoirGlowBackground };
84
- //# sourceMappingURL=chunk-CBQ63EBL.js.map
85
- //# sourceMappingURL=chunk-CBQ63EBL.js.map
87
+ //# sourceMappingURL=chunk-QQHBEACI.js.map
88
+ //# sourceMappingURL=chunk-QQHBEACI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/NoirGlowBackground.tsx"],"names":[],"mappings":"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","file":"chunk-QQHBEACI.js","sourcesContent":["\"use client\"\n\nimport { lazy, Suspense, type CSSProperties } from \"react\"\n\nconst GrainGradient = lazy(() =>\n import(\"@paper-design/shaders-react\").then((module) => ({\n default: module.GrainGradient,\n }))\n)\n\ntype ShaderShape = \"corners\" | \"wave\" | \"dots\" | \"truchet\" | \"ripple\" | \"blob\" | \"sphere\"\ntype Intensity = \"subtle\" | \"medium\" | \"loud\"\ntype Speed = \"still\" | \"slow\" | \"medium\" | \"fast\"\ntype Grain = \"none\" | \"soft\" | \"high\"\n\nexport interface NoirGlowBackgroundProps {\n /** Extra class names for the outer positioning wrapper. */\n className?: string\n /** Inline style for the outer positioning wrapper. */\n style?: CSSProperties\n /** Canvas/WebGL shape. `corners` matches Tollerud.no. */\n shape?: ShaderShape\n /** Visual strength of the yellow glow. */\n intensity?: Intensity\n /** Ambient animation speed. */\n speed?: Speed\n /** Shader grain/noise amount. */\n grain?: Grain\n /** Softness/falloff of the glow blooms. */\n softness?: number\n /** Background color behind the glow. */\n colorBack?: string\n /** Glow colors. Defaults to the Tollerud/Tia yellow ramp. */\n colors?: string[]\n /** Whether to render a readable center vignette on top of the shader. */\n preserveCenter?: boolean\n /** Add the grain/noise CSS overlay. */\n noiseOverlay?: boolean\n /** Prefer the CSS fallback even if shaders are available. Useful for docs/static contexts. */\n forceCssFallback?: boolean\n /** Disable pointer events so content above remains clickable. */\n inert?: boolean\n /** Horizontal shader offset (-1 to 1). Use for edge-biased layouts. */\n offsetX?: number\n /** Vertical shader offset (-1 to 1). */\n offsetY?: number\n /** Shader scale multiplier. Values > 1 push glow toward edges. */\n scale?: number\n}\n\nconst intensityMap: Record<Intensity, number> = {\n subtle: 0.24,\n medium: 0.45,\n loud: 0.68,\n}\n\nconst speedMap: Record<Speed, number> = {\n still: 0,\n slow: 0.45,\n medium: 1,\n fast: 1.8,\n}\n\nconst grainMap: Record<Grain, number> = {\n none: 0,\n soft: 0.12,\n high: 0.28,\n}\n\nfunction cx(...classes: Array<string | false | null | undefined>) {\n return classes.filter(Boolean).join(\" \")\n}\n\nfunction CssFallback({ preserveCenter = true, noiseOverlay = true }: Pick<NoirGlowBackgroundProps, \"preserveCenter\" | \"noiseOverlay\">) {\n return (\n <>\n <div className=\"tollerud-noir-glow-bg\" aria-hidden=\"true\" />\n {preserveCenter && <div className=\"tollerud-noir-glow-vignette\" aria-hidden=\"true\" />}\n {noiseOverlay && <div className=\"tollerud-noir-noise\" aria-hidden=\"true\" />}\n </>\n )\n}\n\n/**\n * NoirGlowBackground\n *\n * Tia/Tollerud signature background primitive. The defaults replicate\n * MathiasOki/tollerud-landing's `GradientBackground` component.\n *\n * Install dependency in consuming Next.js apps:\n * npm install @paper-design/shaders-react\n *\n * The CSS fallback classes live in `globals.css` and are used during Suspense,\n * reduced-motion contexts, or when `forceCssFallback` is true.\n */\nexport function NoirGlowBackground({\n className,\n style,\n shape = \"corners\",\n intensity = \"medium\",\n speed = \"medium\",\n grain = \"none\",\n softness = 0.76,\n colorBack = \"hsl(0, 0%, 0%)\",\n colors = [\"hsl(54, 85%, 66%)\", \"hsl(56, 100%, 80%)\", \"hsl(56, 100%, 50%)\"],\n preserveCenter = false,\n noiseOverlay = false,\n forceCssFallback = false,\n inert = true,\n offsetX = 0,\n offsetY = 0,\n scale = 1,\n}: NoirGlowBackgroundProps) {\n const wrapperClassName = cx(\n \"tollerud-noir-glow-root absolute inset-0 z-0 overflow-hidden\",\n inert && \"pointer-events-none\",\n className\n )\n\n if (forceCssFallback) {\n return (\n <div className={wrapperClassName} style={style} aria-hidden=\"true\">\n <CssFallback preserveCenter={preserveCenter} noiseOverlay={noiseOverlay} />\n </div>\n )\n }\n\n return (\n <div className={wrapperClassName} style={style} aria-hidden=\"true\">\n <Suspense fallback={<CssFallback preserveCenter={preserveCenter} noiseOverlay={noiseOverlay} />}>\n <GrainGradient\n style={{ height: \"100%\", width: \"100%\" }}\n colorBack={colorBack}\n softness={softness}\n intensity={intensityMap[intensity]}\n noise={grainMap[grain]}\n shape={shape}\n offsetX={offsetX}\n offsetY={offsetY}\n scale={scale}\n rotation={0}\n speed={speedMap[speed]}\n colors={colors}\n />\n </Suspense>\n {preserveCenter && <div className=\"tollerud-noir-glow-vignette\" aria-hidden=\"true\" />}\n {noiseOverlay && <div className=\"tollerud-noir-noise\" aria-hidden=\"true\" />}\n </div>\n )\n}\n"]}
@@ -0,0 +1,58 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import { forwardRef, useId } from 'react';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var FormRow = forwardRef(
7
+ ({
8
+ className,
9
+ label,
10
+ description,
11
+ hint,
12
+ error,
13
+ required,
14
+ htmlFor,
15
+ layout = "settings",
16
+ children,
17
+ ...props
18
+ }, ref) => {
19
+ const autoId = useId();
20
+ const helpText = description ?? hint;
21
+ const descriptionId = helpText ? `${autoId}-description` : void 0;
22
+ const errorId = error ? `${autoId}-error` : void 0;
23
+ if (layout === "settings" && label) {
24
+ return /* @__PURE__ */ jsxs("div", { ref, className: cn("tollerud-formrow", className), ...props, children: [
25
+ /* @__PURE__ */ jsxs("div", { children: [
26
+ /* @__PURE__ */ jsxs("label", { htmlFor, className: "tollerud-formrow__title", children: [
27
+ label,
28
+ required && /* @__PURE__ */ jsx("span", { className: "ml-0.5 text-tollerud-error", children: "*" })
29
+ ] }),
30
+ helpText && /* @__PURE__ */ jsx("p", { id: descriptionId, className: "tollerud-formrow__hint", children: helpText })
31
+ ] }),
32
+ /* @__PURE__ */ jsx(
33
+ "div",
34
+ {
35
+ className: "tollerud-formrow__control",
36
+ "aria-describedby": [descriptionId, errorId].filter(Boolean).join(" ") || void 0,
37
+ children
38
+ }
39
+ ),
40
+ error && /* @__PURE__ */ jsx("p", { id: errorId, className: "col-span-2 text-xs text-tollerud-error", children: error })
41
+ ] });
42
+ }
43
+ return /* @__PURE__ */ jsxs("div", { ref, className: cn("flex flex-col gap-1.5", className), ...props, children: [
44
+ label && /* @__PURE__ */ jsxs("label", { htmlFor, className: "text-sm font-medium text-tollerud-text-primary", children: [
45
+ label,
46
+ required && /* @__PURE__ */ jsx("span", { className: "ml-0.5 text-tollerud-error", children: "*" })
47
+ ] }),
48
+ helpText && /* @__PURE__ */ jsx("p", { id: descriptionId, className: "text-xs text-tollerud-text-muted", children: helpText }),
49
+ /* @__PURE__ */ jsx("div", { "aria-describedby": [descriptionId, errorId].filter(Boolean).join(" ") || void 0, children }),
50
+ error && /* @__PURE__ */ jsx("p", { id: errorId, className: "text-xs text-tollerud-error", children: error })
51
+ ] });
52
+ }
53
+ );
54
+ FormRow.displayName = "FormRow";
55
+
56
+ export { FormRow };
57
+ //# sourceMappingURL=chunk-T3UQ7G4T.js.map
58
+ //# sourceMappingURL=chunk-T3UQ7G4T.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/FormRow.tsx"],"names":[],"mappings":";;;;AAmBA,IAAM,OAAA,GAAU,UAAA;AAAA,EACd,CACE;AAAA,IACE,SAAA;AAAA,IACA,KAAA;AAAA,IACA,WAAA;AAAA,IACA,IAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA,GAAS,UAAA;AAAA,IACT,QAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,SAAS,KAAA,EAAM;AACrB,IAAA,MAAM,WAAW,WAAA,IAAe,IAAA;AAChC,IAAA,MAAM,aAAA,GAAgB,QAAA,GAAW,CAAA,EAAG,MAAM,CAAA,YAAA,CAAA,GAAiB,MAAA;AAC3D,IAAA,MAAM,OAAA,GAAU,KAAA,GAAQ,CAAA,EAAG,MAAM,CAAA,MAAA,CAAA,GAAW,MAAA;AAE5C,IAAA,IAAI,MAAA,KAAW,cAAc,KAAA,EAAO;AAClC,MAAA,uBACE,IAAA,CAAC,SAAI,GAAA,EAAU,SAAA,EAAW,GAAG,kBAAA,EAAoB,SAAS,CAAA,EAAI,GAAG,KAAA,EAC/D,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,OAAA,EAAA,EAAM,OAAA,EAAkB,SAAA,EAAU,yBAAA,EAChC,QAAA,EAAA;AAAA,YAAA,KAAA;AAAA,YACA,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAA6B,QAAA,EAAA,GAAA,EAAC;AAAA,WAAA,EAC7D,CAAA;AAAA,UACC,4BACC,GAAA,CAAC,GAAA,EAAA,EAAE,IAAI,aAAA,EAAe,SAAA,EAAU,0BAC7B,QAAA,EAAA,QAAA,EACH;AAAA,SAAA,EAEJ,CAAA;AAAA,wBACA,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,2BAAA;AAAA,YACV,kBAAA,EAAkB,CAAC,aAAA,EAAe,OAAO,CAAA,CAAE,OAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,IAAK,MAAA;AAAA,YAEvE;AAAA;AAAA,SACH;AAAA,QACC,yBACC,GAAA,CAAC,GAAA,EAAA,EAAE,IAAI,OAAA,EAAS,SAAA,EAAU,0CACvB,QAAA,EAAA,KAAA,EACH;AAAA,OAAA,EAEJ,CAAA;AAAA,IAEJ;AAEA,IAAA,uBACE,IAAA,CAAC,SAAI,GAAA,EAAU,SAAA,EAAW,GAAG,uBAAA,EAAyB,SAAS,CAAA,EAAI,GAAG,KAAA,EACnE,QAAA,EAAA;AAAA,MAAA,KAAA,oBACC,IAAA,CAAC,OAAA,EAAA,EAAM,OAAA,EAAkB,SAAA,EAAU,gDAAA,EAChC,QAAA,EAAA;AAAA,QAAA,KAAA;AAAA,QACA,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAA6B,QAAA,EAAA,GAAA,EAAC;AAAA,OAAA,EAC7D,CAAA;AAAA,MAED,4BACC,GAAA,CAAC,GAAA,EAAA,EAAE,IAAI,aAAA,EAAe,SAAA,EAAU,oCAC7B,QAAA,EAAA,QAAA,EACH,CAAA;AAAA,sBAEF,GAAA,CAAC,KAAA,EAAA,EAAI,kBAAA,EAAkB,CAAC,eAAe,OAAO,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,IAAK,QAAY,QAAA,EAAS,CAAA;AAAA,MACjG,yBACC,GAAA,CAAC,GAAA,EAAA,EAAE,IAAI,OAAA,EAAS,SAAA,EAAU,+BACvB,QAAA,EAAA,KAAA,EACH;AAAA,KAAA,EAEJ,CAAA;AAAA,EAEJ;AACF;AACA,OAAA,CAAQ,WAAA,GAAc,SAAA","file":"chunk-T3UQ7G4T.js","sourcesContent":["'use client'\n\nimport { type HTMLAttributes, forwardRef, useId } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport interface FormRowProps extends HTMLAttributes<HTMLDivElement> {\n label?: React.ReactNode\n /** Hint text rendered below the label */\n description?: React.ReactNode\n /** Alias for `description` — used in docs/settings layouts */\n hint?: React.ReactNode\n error?: React.ReactNode\n required?: boolean\n /** Forwarded to the label's `htmlFor` — should match the control's `id` */\n htmlFor?: string\n /** `settings` = label/hint left, control right; `stack` = vertical field layout */\n layout?: 'settings' | 'stack'\n}\n\nconst FormRow = forwardRef<HTMLDivElement, FormRowProps>(\n (\n {\n className,\n label,\n description,\n hint,\n error,\n required,\n htmlFor,\n layout = 'settings',\n children,\n ...props\n },\n ref\n ) => {\n const autoId = useId()\n const helpText = description ?? hint\n const descriptionId = helpText ? `${autoId}-description` : undefined\n const errorId = error ? `${autoId}-error` : undefined\n\n if (layout === 'settings' && label) {\n return (\n <div ref={ref} className={cn('tollerud-formrow', className)} {...props}>\n <div>\n <label htmlFor={htmlFor} className=\"tollerud-formrow__title\">\n {label}\n {required && <span className=\"ml-0.5 text-tollerud-error\">*</span>}\n </label>\n {helpText && (\n <p id={descriptionId} className=\"tollerud-formrow__hint\">\n {helpText}\n </p>\n )}\n </div>\n <div\n className=\"tollerud-formrow__control\"\n aria-describedby={[descriptionId, errorId].filter(Boolean).join(' ') || undefined}\n >\n {children}\n </div>\n {error && (\n <p id={errorId} className=\"col-span-2 text-xs text-tollerud-error\">\n {error}\n </p>\n )}\n </div>\n )\n }\n\n return (\n <div ref={ref} className={cn('flex flex-col gap-1.5', className)} {...props}>\n {label && (\n <label htmlFor={htmlFor} className=\"text-sm font-medium text-tollerud-text-primary\">\n {label}\n {required && <span className=\"ml-0.5 text-tollerud-error\">*</span>}\n </label>\n )}\n {helpText && (\n <p id={descriptionId} className=\"text-xs text-tollerud-text-muted\">\n {helpText}\n </p>\n )}\n <div aria-describedby={[descriptionId, errorId].filter(Boolean).join(' ') || undefined}>{children}</div>\n {error && (\n <p id={errorId} className=\"text-xs text-tollerud-error\">\n {error}\n </p>\n )}\n </div>\n )\n }\n)\nFormRow.displayName = 'FormRow'\n\nexport { FormRow }\n"]}
@@ -15,9 +15,11 @@ function initialsFrom(name) {
15
15
  return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
16
16
  }
17
17
  var Avatar = forwardRef(
18
- ({ className, src, name, fallback, size = "md", ...props }, ref) => {
18
+ ({ className, src, name, fallback, size = "md", style, ...props }, ref) => {
19
19
  const [errored, setErrored] = useState(false);
20
20
  const showImage = !!src && !errored;
21
+ const isNumeric = typeof size === "number";
22
+ const pixelSize = isNumeric ? size : void 0;
21
23
  return /* @__PURE__ */ jsx(
22
24
  "span",
23
25
  {
@@ -26,9 +28,13 @@ var Avatar = forwardRef(
26
28
  "relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full select-none",
27
29
  "bg-tollerud-surface-raised text-tollerud-text-secondary font-medium",
28
30
  "ring-1 ring-tollerud-border",
29
- avatarSizes[size],
31
+ !isNumeric && avatarSizes[size],
30
32
  className
31
33
  ),
34
+ style: {
35
+ ...pixelSize ? { width: pixelSize, height: pixelSize, fontSize: Math.max(10, Math.round(pixelSize * 0.36)) } : null,
36
+ ...style
37
+ },
32
38
  ...props,
33
39
  children: showImage ? /* @__PURE__ */ jsx(
34
40
  "img",
@@ -64,8 +70,9 @@ var AvatarGroup = forwardRef(
64
70
  "relative inline-flex shrink-0 items-center justify-center rounded-full select-none",
65
71
  "bg-tollerud-surface-raised text-tollerud-text-muted font-medium",
66
72
  "ring-2 ring-tollerud-surface",
67
- avatarSizes[size]
73
+ typeof size !== "number" && avatarSizes[size]
68
74
  ),
75
+ style: typeof size === "number" ? { width: size, height: size, fontSize: Math.max(10, Math.round(size * 0.36)) } : void 0,
69
76
  children: [
70
77
  "+",
71
78
  overflow
@@ -80,5 +87,5 @@ var AvatarGroup = forwardRef(
80
87
  AvatarGroup.displayName = "AvatarGroup";
81
88
 
82
89
  export { Avatar, AvatarGroup };
83
- //# sourceMappingURL=chunk-DGCRHVWW.js.map
84
- //# sourceMappingURL=chunk-DGCRHVWW.js.map
90
+ //# sourceMappingURL=chunk-VFS3V3VY.js.map
91
+ //# sourceMappingURL=chunk-VFS3V3VY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Avatar.tsx"],"names":[],"mappings":"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","file":"chunk-VFS3V3VY.js","sourcesContent":["'use client'\n\nimport { type HTMLAttributes, forwardRef, useState } from 'react'\nimport { cn } from '@/lib/utils'\n\nconst avatarSizes = {\n sm: 'h-6 w-6 text-[10px]',\n md: 'h-8 w-8 text-xs',\n lg: 'h-11 w-11 text-sm',\n} as const\n\nfunction initialsFrom(name: string) {\n const parts = name.trim().split(/\\s+/).filter(Boolean)\n if (parts.length === 0) return ''\n if (parts.length === 1) return parts[0]!.slice(0, 2).toUpperCase()\n return (parts[0]![0] + parts[parts.length - 1]![0]).toUpperCase()\n}\n\nexport interface AvatarProps extends HTMLAttributes<HTMLSpanElement> {\n /** Image source */\n src?: string\n /** Accessible name / used to derive initials fallback */\n name?: string\n /** Explicit fallback content (overrides derived initials) */\n fallback?: React.ReactNode\n /** Named size token or explicit pixel diameter */\n size?: keyof typeof avatarSizes | number\n}\n\nconst Avatar = forwardRef<HTMLSpanElement, AvatarProps>(\n ({ className, src, name, fallback, size = 'md', style, ...props }, ref) => {\n const [errored, setErrored] = useState(false)\n const showImage = !!src && !errored\n const isNumeric = typeof size === 'number'\n const pixelSize = isNumeric ? size : undefined\n\n return (\n <span\n ref={ref}\n className={cn(\n 'relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full select-none',\n 'bg-tollerud-surface-raised text-tollerud-text-secondary font-medium',\n 'ring-1 ring-tollerud-border',\n !isNumeric && avatarSizes[size],\n className\n )}\n style={{\n ...(pixelSize\n ? { width: pixelSize, height: pixelSize, fontSize: Math.max(10, Math.round(pixelSize * 0.36)) }\n : null),\n ...style,\n }}\n {...props}\n >\n {showImage ? (\n <img\n src={src}\n alt={name ?? ''}\n className=\"h-full w-full object-cover\"\n onError={() => setErrored(true)}\n />\n ) : (\n <span aria-hidden={!!name}>{fallback ?? (name ? initialsFrom(name) : null)}</span>\n )}\n </span>\n )\n }\n)\nAvatar.displayName = 'Avatar'\n\nexport interface AvatarGroupProps extends HTMLAttributes<HTMLDivElement> {\n /** Maximum avatars to render before collapsing into a \"+N\" overflow indicator */\n max?: number\n size?: keyof typeof avatarSizes | number\n children: React.ReactNode\n}\n\nconst AvatarGroup = forwardRef<HTMLDivElement, AvatarGroupProps>(\n ({ className, max, size = 'md', children, ...props }, ref) => {\n const items = Array.isArray(children) ? children : [children]\n const visible = max ? items.slice(0, max) : items\n const overflow = max ? items.length - max : 0\n\n return (\n <div\n ref={ref}\n className={cn('flex items-center -space-x-2', className)}\n {...props}\n >\n {visible.map((child, i) => (\n <span key={i} className=\"ring-2 ring-tollerud-surface rounded-full\">\n {child}\n </span>\n ))}\n {overflow > 0 && (\n <span\n className={cn(\n 'relative inline-flex shrink-0 items-center justify-center rounded-full select-none',\n 'bg-tollerud-surface-raised text-tollerud-text-muted font-medium',\n 'ring-2 ring-tollerud-surface',\n typeof size !== 'number' && avatarSizes[size]\n )}\n style={\n typeof size === 'number'\n ? { width: size, height: size, fontSize: Math.max(10, Math.round(size * 0.36)) }\n : undefined\n }\n >\n +{overflow}\n </span>\n )}\n </div>\n )\n }\n)\nAvatarGroup.displayName = 'AvatarGroup'\n\nexport { Avatar, AvatarGroup }\n"]}
@@ -0,0 +1,44 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import { forwardRef } from 'react';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ // components/monogram-geometry.ts
7
+ var MONOGRAM_VIEW_BOX = "0 0 130 143";
8
+ var MONOGRAM_PATH = "M82.4839273,140.272626 L95.1738252,140.272626 L95.1738252,143 L34.8114657,143 L34.8114657,140.272626 L47.5013636,140.272626 L47.5013636,28.2924381 C40.1277806,26.4177752 32.9252955,25.2241422 26.4088393,25.2241422 C12.1757856,25.2241422 4.11617359,34.5982703 4.11617359,39.8821508 C4.11617359,40.9049161 4.63028596,41.5867596 5.65932936,41.5867596 C7.20248513,41.5867596 7.37440169,40.3931266 8.06043062,38.8593855 C10.4615319,33.575505 15.6059302,31.5307881 20.4073141,31.5307881 C29.152955,31.5307881 35.1552988,38.5184637 35.1552988,47.2107482 C35.1552988,56.2447681 28.8107592,62.8907084 18.0070315,62.8907084 C7.5454996,62.891522 0,53.6882617 0,43.8023442 C0,30.8497582 11.3178401,21.986606 26.5799372,21.986606 C51.1026062,21.986606 84.1989996,39.2011209 104.948509,39.2011209 C118.495534,39.2011209 126.384048,31.7016558 126.384048,19.4300996 C126.384048,10.3968933 118.667451,4.60203698 115.580321,4.60203698 C114.552096,4.60203698 113.69415,5.1130128 113.69415,6.13577809 C113.69415,7.49946515 114.552096,7.6695192 115.409223,8.01044097 C115.752237,8.18049502 122.268693,10.5669474 122.268693,19.2592319 C122.268693,28.2924381 115.238125,34.0872945 107.177694,34.0872945 C97.7460244,34.0872945 91.0584702,26.4177752 91.0584702,17.8955448 C91.0584702,6.64675391 99.9760277,0 109.749893,0 C122.268693,0 129.642276,9.88510384 129.642276,19.6001536 C129.642276,34.2581622 119.181563,42.4386572 104.947691,42.4386572 C98.0890388,42.4386572 90.5443579,40.9049161 82.4839273,38.6901451 L82.4839273,140.272626 Z";
9
+ var colorClasses = {
10
+ yellow: "text-tollerud-yellow",
11
+ black: "text-tollerud-noir-950",
12
+ white: "text-white"
13
+ };
14
+ var Monogram = forwardRef(
15
+ ({ color = "yellow", size, className, title = "Tollerud", style, ...props }, ref) => {
16
+ return /* @__PURE__ */ jsxs(
17
+ "svg",
18
+ {
19
+ ref,
20
+ viewBox: MONOGRAM_VIEW_BOX,
21
+ xmlns: "http://www.w3.org/2000/svg",
22
+ role: "img",
23
+ "aria-label": title,
24
+ className: cn(
25
+ "inline-block shrink-0",
26
+ colorClasses[color],
27
+ !size && "h-5 w-auto",
28
+ className
29
+ ),
30
+ style: size ? { height: size, width: "auto", ...style } : style,
31
+ ...props,
32
+ children: [
33
+ /* @__PURE__ */ jsx("title", { children: title }),
34
+ /* @__PURE__ */ jsx("g", { fill: "currentColor", fillRule: "evenodd", children: /* @__PURE__ */ jsx("g", { transform: "translate(-86.000000, -109.000000)", children: /* @__PURE__ */ jsx("g", { transform: "translate(32.000000, 55.000000)", children: /* @__PURE__ */ jsx("g", { transform: "translate(54.000000, 54.000000)", children: /* @__PURE__ */ jsx("path", { d: MONOGRAM_PATH }) }) }) }) })
35
+ ]
36
+ }
37
+ );
38
+ }
39
+ );
40
+ Monogram.displayName = "Monogram";
41
+
42
+ export { Monogram };
43
+ //# sourceMappingURL=chunk-VOARBYVQ.js.map
44
+ //# sourceMappingURL=chunk-VOARBYVQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/monogram-geometry.ts","../components/Monogram.tsx"],"names":[],"mappings":";;;;;AACO,IAAM,iBAAA,GAAoB,aAAA;AAE1B,IAAM,aAAA,GACX,0+CAAA;ACEF,IAAM,YAAA,GAA8C;AAAA,EAClD,MAAA,EAAQ,sBAAA;AAAA,EACR,KAAA,EAAO,wBAAA;AAAA,EACP,KAAA,EAAO;AACT,CAAA;AAgBA,IAAM,QAAA,GAAW,UAAA;AAAA,EACf,CAAC,EAAE,KAAA,GAAQ,QAAA,EAAU,IAAA,EAAM,SAAA,EAAW,KAAA,GAAQ,UAAA,EAAY,KAAA,EAAO,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACnF,IAAA,uBACE,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,OAAA,EAAS,iBAAA;AAAA,QACT,KAAA,EAAM,4BAAA;AAAA,QACN,IAAA,EAAK,KAAA;AAAA,QACL,YAAA,EAAY,KAAA;AAAA,QACZ,SAAA,EAAW,EAAA;AAAA,UACT,uBAAA;AAAA,UACA,aAAa,KAAK,CAAA;AAAA,UAClB,CAAC,IAAA,IAAQ,YAAA;AAAA,UACT;AAAA,SACF;AAAA,QACA,KAAA,EAAO,OAAO,EAAE,MAAA,EAAQ,MAAM,KAAA,EAAO,MAAA,EAAQ,GAAG,KAAA,EAAM,GAAI,KAAA;AAAA,QACzD,GAAG,KAAA;AAAA,QAEJ,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,WAAO,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,0BACd,GAAA,CAAC,GAAA,EAAA,EAAE,IAAA,EAAK,cAAA,EAAe,QAAA,EAAS,WAC9B,QAAA,kBAAA,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,oCAAA,EACX,QAAA,kBAAA,GAAA,CAAC,GAAA,EAAA,EAAE,WAAU,iCAAA,EACX,QAAA,kBAAA,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,iCAAA,EACX,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAG,aAAA,EAAe,CAAA,EAC1B,CAAA,EACF,CAAA,EACF,CAAA,EACF;AAAA;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AACA,QAAA,CAAS,WAAA,GAAc,UAAA","file":"chunk-VOARBYVQ.js","sourcesContent":["/** Shared Tollerud monogram geometry — single continuous T path. */\nexport const MONOGRAM_VIEW_BOX = '0 0 130 143'\n\nexport const MONOGRAM_PATH =\n 'M82.4839273,140.272626 L95.1738252,140.272626 L95.1738252,143 L34.8114657,143 L34.8114657,140.272626 L47.5013636,140.272626 L47.5013636,28.2924381 C40.1277806,26.4177752 32.9252955,25.2241422 26.4088393,25.2241422 C12.1757856,25.2241422 4.11617359,34.5982703 4.11617359,39.8821508 C4.11617359,40.9049161 4.63028596,41.5867596 5.65932936,41.5867596 C7.20248513,41.5867596 7.37440169,40.3931266 8.06043062,38.8593855 C10.4615319,33.575505 15.6059302,31.5307881 20.4073141,31.5307881 C29.152955,31.5307881 35.1552988,38.5184637 35.1552988,47.2107482 C35.1552988,56.2447681 28.8107592,62.8907084 18.0070315,62.8907084 C7.5454996,62.891522 0,53.6882617 0,43.8023442 C0,30.8497582 11.3178401,21.986606 26.5799372,21.986606 C51.1026062,21.986606 84.1989996,39.2011209 104.948509,39.2011209 C118.495534,39.2011209 126.384048,31.7016558 126.384048,19.4300996 C126.384048,10.3968933 118.667451,4.60203698 115.580321,4.60203698 C114.552096,4.60203698 113.69415,5.1130128 113.69415,6.13577809 C113.69415,7.49946515 114.552096,7.6695192 115.409223,8.01044097 C115.752237,8.18049502 122.268693,10.5669474 122.268693,19.2592319 C122.268693,28.2924381 115.238125,34.0872945 107.177694,34.0872945 C97.7460244,34.0872945 91.0584702,26.4177752 91.0584702,17.8955448 C91.0584702,6.64675391 99.9760277,0 109.749893,0 C122.268693,0 129.642276,9.88510384 129.642276,19.6001536 C129.642276,34.2581622 119.181563,42.4386572 104.947691,42.4386572 C98.0890388,42.4386572 90.5443579,40.9049161 82.4839273,38.6901451 L82.4839273,140.272626 Z'\n","import { forwardRef, type SVGAttributes } from 'react'\nimport { cn } from '@/lib/utils'\nimport { MONOGRAM_PATH, MONOGRAM_VIEW_BOX } from './monogram-geometry'\n\nexport type MonogramColor = 'yellow' | 'black' | 'white'\n\nconst colorClasses: Record<MonogramColor, string> = {\n yellow: 'text-tollerud-yellow',\n black: 'text-tollerud-noir-950',\n white: 'text-white',\n}\n\nexport interface MonogramProps extends SVGAttributes<SVGSVGElement> {\n /**\n * Fill color via `currentColor`.\n * - `yellow` — default on dark surfaces (#FFFF00)\n * - `black` — light-mode surfaces (#0A0A0A)\n * - `white` — on tinted or photographic backgrounds\n */\n color?: MonogramColor\n /** Height in px; width scales from the 130×143 viewBox. */\n size?: number\n /** Accessible name — rendered as `<title>` and `aria-label`. */\n title?: string\n}\n\nconst Monogram = forwardRef<SVGSVGElement, MonogramProps>(\n ({ color = 'yellow', size, className, title = 'Tollerud', style, ...props }, ref) => {\n return (\n <svg\n ref={ref}\n viewBox={MONOGRAM_VIEW_BOX}\n xmlns=\"http://www.w3.org/2000/svg\"\n role=\"img\"\n aria-label={title}\n className={cn(\n 'inline-block shrink-0',\n colorClasses[color],\n !size && 'h-5 w-auto',\n className\n )}\n style={size ? { height: size, width: 'auto', ...style } : style}\n {...props}\n >\n <title>{title}</title>\n <g fill=\"currentColor\" fillRule=\"evenodd\">\n <g transform=\"translate(-86.000000, -109.000000)\">\n <g transform=\"translate(32.000000, 55.000000)\">\n <g transform=\"translate(54.000000, 54.000000)\">\n <path d={MONOGRAM_PATH} />\n </g>\n </g>\n </g>\n </g>\n </svg>\n )\n }\n)\nMonogram.displayName = 'Monogram'\n\nexport { Monogram }\n"]}
@@ -1,11 +1,11 @@
1
1
  'use client';
2
+ import { Skeleton } from './chunk-AQT3FZRQ.js';
2
3
  import { Segmented } from './chunk-NSMU66ZX.js';
3
- import { Skeleton } from './chunk-FGXOV2QH.js';
4
4
  import { Pagination } from './chunk-RJTDQOT2.js';
5
5
  import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuSeparator, DropdownMenuLabel, DropdownMenuItem } from './chunk-435JHF7G.js';
6
6
  import { Checkbox } from './chunk-T3TQPOVM.js';
7
7
  import { Badge } from './chunk-QEHTPQHL.js';
8
- import { Button } from './chunk-RWJELAS6.js';
8
+ import { Button } from './chunk-ADE22JSR.js';
9
9
  import { cn } from './chunk-WSQNPRGN.js';
10
10
  import { forwardRef, useMemo, useState } from 'react';
11
11
  import { Search, X, MoreHorizontal, ChevronDown } from 'lucide-react';
@@ -146,7 +146,7 @@ function DataTableInner({
146
146
  "th",
147
147
  {
148
148
  className: cn(
149
- "px-3 py-2.5 text-xs font-semibold text-tollerud-text-muted uppercase tracking-wider",
149
+ "px-3 py-2.5 text-left text-xs font-semibold text-tollerud-text-muted uppercase tracking-wider",
150
150
  col.sortable && "cursor-pointer select-none hover:text-tollerud-text-primary transition-colors",
151
151
  col.align === "right" && "text-right",
152
152
  col.align === "center" && "text-center"
@@ -389,5 +389,5 @@ var DataTable = forwardRef((props, ref) => /* @__PURE__ */ jsx(DataTableInner, {
389
389
  DataTable.displayName = "DataTable";
390
390
 
391
391
  export { DataTable };
392
- //# sourceMappingURL=chunk-3TGMGBKM.js.map
393
- //# sourceMappingURL=chunk-3TGMGBKM.js.map
392
+ //# sourceMappingURL=chunk-YPP7QHYT.js.map
393
+ //# sourceMappingURL=chunk-YPP7QHYT.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../components/DataTable.tsx"],"names":[],"mappings":"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","file":"chunk-3TGMGBKM.js","sourcesContent":["'use client'\n\nimport { useState, useMemo, forwardRef, type ReactNode } from 'react'\nimport { ChevronDown, MoreHorizontal, Search, X } from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { Badge } from './Badge'\nimport { Button } from './Button'\nimport { Checkbox } from './Checkbox'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from './DropdownMenu'\nimport { Pagination } from './Pagination'\nimport { Segmented } from './Segmented'\nimport { Skeleton } from './Skeleton'\n\n/* ──────────────────── Sortable & Filterable Data Table ──────────────────── */\n\nexport interface Column<T> {\n key: string\n label: string\n sortable?: boolean\n filterable?: boolean\n align?: 'left' | 'center' | 'right'\n width?: string\n render?: (value: unknown, row: T) => ReactNode\n}\n\nexport interface DataTableFilter {\n key: string\n options?: string[]\n allLabel?: string\n}\n\nexport interface DataTableBulkAction {\n label: string\n variant?: 'primary' | 'secondary' | 'ghost' | 'destructive' | 'terminal'\n icon?: ReactNode\n onRun: (selectedIds: (string | number)[], clearSelection: () => void) => void\n}\n\nexport interface DataTableRowMenuItem {\n label: string\n onSelect?: () => void\n icon?: ReactNode\n sep?: boolean\n heading?: boolean\n}\n\nexport interface DataTableProps<T extends Record<string, unknown>> {\n columns: Column<T>[]\n /** Row data — use `data` or `rows` (alias). */\n data?: T[]\n rows?: T[]\n /** Row key extractor — defaults to `row.id` or `row.key` */\n rowKey?: keyof T | ((row: T) => string | number)\n onRowClick?: (row: T) => void\n className?: string\n emptyMessage?: string\n /** Global search across `searchKeys` (or all column keys). */\n searchable?: boolean\n searchKeys?: (keyof T | string)[]\n searchPlaceholder?: string\n /** Segmented filter on a single column value. */\n filter?: DataTableFilter\n selectable?: boolean\n pageSize?: number\n bulkActions?: DataTableBulkAction[]\n rowMenu?: (row: T) => DataTableRowMenuItem[]\n toolbarRight?: ReactNode\n emptyState?: ReactNode\n loading?: boolean\n skeletonRows?: number\n}\n\ninterface DataTableInnerProps<T extends Record<string, unknown>> extends DataTableProps<T> {\n forwardedRef?: React.Ref<HTMLDivElement>\n}\n\nfunction DataTableInner<T extends Record<string, unknown>>({\n columns,\n data,\n rows,\n rowKey,\n onRowClick,\n className,\n emptyMessage = 'No data',\n searchable = false,\n searchKeys,\n searchPlaceholder = 'Search…',\n filter,\n selectable = false,\n pageSize,\n bulkActions = [],\n rowMenu,\n toolbarRight,\n emptyState,\n loading = false,\n skeletonRows = 5,\n forwardedRef,\n}: DataTableInnerProps<T>) {\n const tableData = useMemo(() => rows ?? data ?? [], [rows, data])\n\n const isRich =\n searchable ||\n filter ||\n selectable ||\n pageSize !== undefined ||\n !!rowMenu ||\n !!toolbarRight ||\n bulkActions.length > 0 ||\n !!emptyState ||\n loading\n\n const [sortKey, setSortKey] = useState<string | null>(null)\n const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc')\n const [filters, setFilters] = useState<Record<string, string>>({})\n const [query, setQuery] = useState('')\n const [filterValue, setFilterValue] = useState('all')\n const [selected, setSelected] = useState<(string | number)[]>([])\n const [page, setPage] = useState(1)\n\n const getRowKey = (row: T, i: number): string | number => {\n if (typeof rowKey === 'function') return rowKey(row)\n if (rowKey) return row[rowKey] as string | number\n return (row.id ?? row.key ?? i) as string | number\n }\n\n const toggleSort = (key: string) => {\n if (sortKey === key) {\n setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'))\n } else {\n setSortKey(key)\n setSortDir('asc')\n }\n }\n\n const updateFilter = (key: string, value: string) => {\n setFilters((prev) => {\n const next = { ...prev }\n if (value.trim() === '') {\n delete next[key]\n } else {\n next[key] = value\n }\n return next\n })\n }\n\n const searchKeysResolved = searchKeys ?? columns.map((c) => c.key)\n const filterOptions = filter\n ? (filter.options ?? Array.from(new Set(tableData.map((r) => String(r[filter.key] ?? '')))))\n : []\n\n const filtered = useMemo(() => {\n let result = tableData\n\n if (isRich && filter && filterValue !== 'all') {\n result = result.filter((row) => String(row[filter.key] ?? '') === filterValue)\n }\n\n if (isRich && searchable && query.trim()) {\n const q = query.trim().toLowerCase()\n result = result.filter((row) =>\n searchKeysResolved.some((key) => String(row[key as keyof T] ?? '').toLowerCase().includes(q))\n )\n }\n\n if (!isRich) {\n const activeFilters = Object.entries(filters).filter(([, v]) => v.trim() !== '')\n if (activeFilters.length > 0) {\n result = result.filter((row) =>\n activeFilters.every(([key, filterVal]) => {\n const cellValue = String(row[key] ?? '').toLowerCase()\n return cellValue.includes(filterVal.toLowerCase())\n })\n )\n }\n }\n\n return result\n }, [tableData, filters, isRich, filter, filterValue, searchable, query, searchKeysResolved])\n\n const sorted = useMemo(() => {\n if (!sortKey) return filtered\n const col = columns.find((c) => c.key === sortKey)\n if (!col?.sortable) return filtered\n\n return [...filtered].sort((a, b) => {\n const aVal = a[sortKey]\n const bVal = b[sortKey]\n\n if (typeof aVal === 'number' && typeof bVal === 'number') {\n return sortDir === 'asc' ? aVal - bVal : bVal - aVal\n }\n\n const aStr = String(aVal ?? '')\n const bStr = String(bVal ?? '')\n const cmp = aStr.localeCompare(bStr, 'nb', { numeric: true })\n return sortDir === 'asc' ? cmp : -cmp\n })\n }, [filtered, sortKey, sortDir, columns])\n\n const pageCount = pageSize ? Math.max(1, Math.ceil(sorted.length / pageSize)) : 1\n const currentPage = Math.min(page, pageCount)\n const pageRows = pageSize\n ? sorted.slice((currentPage - 1) * pageSize, currentPage * pageSize)\n : sorted\n\n const clearSelection = () => setSelected([])\n const allOnPageSelected =\n pageRows.length > 0 && pageRows.every((row) => selected.includes(getRowKey(row, 0)))\n\n const toggleAllOnPage = () => {\n const pageIds = pageRows.map((row, i) => getRowKey(row, i))\n if (allOnPageSelected) {\n setSelected((prev) => prev.filter((id) => !pageIds.includes(id)))\n } else {\n setSelected((prev) => Array.from(new Set([...prev, ...pageIds])))\n }\n }\n\n const toggleRow = (id: string | number) => {\n setSelected((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]))\n }\n\n const hasActiveFilters = Object.values(filters).some((v) => v.trim() !== '')\n const filterableColumns = columns.filter((c) => c.filterable)\n const colSpan = columns.length + (selectable ? 1 : 0) + (rowMenu ? 1 : 0)\n\n const sortIndicator = (key: string) => {\n const active = sortKey === key\n return (\n <ChevronDown\n size={12}\n className={cn(\n 'shrink-0 transition-transform duration-150',\n active ? 'text-tollerud-yellow opacity-100' : 'opacity-25',\n active && sortDir === 'desc' && 'rotate-180'\n )}\n aria-hidden\n />\n )\n }\n\n const headerCell = (col: Column<T>) => (\n <th\n key={col.key}\n className={cn(\n 'px-3 py-2.5 text-xs font-semibold text-tollerud-text-muted uppercase tracking-wider',\n col.sortable && 'cursor-pointer select-none hover:text-tollerud-text-primary transition-colors',\n col.align === 'right' && 'text-right',\n col.align === 'center' && 'text-center',\n )}\n style={col.width ? { width: col.width } : undefined}\n onClick={() => col.sortable && toggleSort(col.key)}\n >\n <span\n className={cn(\n 'inline-flex items-center gap-1',\n col.align === 'right' && 'justify-end w-full',\n col.align === 'center' && 'justify-center w-full',\n )}\n >\n {col.label}\n {col.sortable && (isRich ? sortIndicator(col.key) : (\n <>\n {sortKey === col.key && (\n <span className=\"text-tollerud-accent\">{sortDir === 'asc' ? '↑' : '↓'}</span>\n )}\n {sortKey !== col.key && <span className=\"text-tollerud-text-muted/30\">↕</span>}\n </>\n ))}\n {!isRich && col.filterable && (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn('opacity-40', filters[col.key] && 'opacity-100 text-tollerud-yellow')}\n aria-hidden\n >\n <path d=\"M4 4h16v2.172a2 2 0 0 1-.586 1.414L15 12v7l-6 2v-8.5L4.52 7.53A2 2 0 0 1 4 6.16V4z\" />\n </svg>\n )}\n </span>\n </th>\n )\n\n const tableBody = () => {\n if (loading) {\n return (\n <tbody>\n {Array.from({ length: skeletonRows }).map((_, i) => (\n <tr key={i} className=\"border-b border-tollerud-border/20\">\n {selectable && (\n <td className=\"px-3 py-2.5 w-10\">\n <Skeleton className=\"h-4 w-4 rounded\" />\n </td>\n )}\n {columns.map((col, j) => (\n <td key={col.key} className={cn('px-3 py-2.5', col.align === 'right' && 'text-right')}>\n <Skeleton className={cn('h-3', j === 0 ? 'w-[70%]' : 'w-[55%]')} />\n </td>\n ))}\n {rowMenu && (\n <td className=\"px-3 py-2.5 w-11\">\n <Skeleton className=\"h-4 w-4 rounded\" />\n </td>\n )}\n </tr>\n ))}\n </tbody>\n )\n }\n\n if (sorted.length === 0) {\n if (isRich && emptyState) {\n return null\n }\n return (\n <tbody>\n <tr>\n <td colSpan={colSpan} className=\"px-3 py-8 text-center text-sm text-tollerud-text-muted\">\n {hasActiveFilters || query || filterValue !== 'all' ? 'No matching rows' : emptyMessage}\n </td>\n </tr>\n </tbody>\n )\n }\n\n return (\n <tbody>\n {pageRows.map((row, i) => {\n const id = getRowKey(row, i)\n const isSelected = selected.includes(id)\n return (\n <tr\n key={id}\n className={cn(\n 'border-b border-tollerud-border/20 transition-colors',\n onRowClick && 'cursor-pointer hover:bg-tollerud-surface-raised/50',\n isSelected && 'bg-tollerud-yellow/[0.05]',\n )}\n onClick={() => onRowClick?.(row)}\n >\n {selectable && (\n <td className=\"px-3 py-2.5 w-10\" onClick={(e) => e.stopPropagation()}>\n <Checkbox checked={isSelected} onChange={() => toggleRow(id)} aria-label={`Select row ${id}`} />\n </td>\n )}\n {columns.map((col) => {\n const value = row[col.key]\n return (\n <td\n key={col.key}\n className={cn(\n 'px-3 py-2.5 text-tollerud-text-secondary',\n col.align === 'right' && 'text-right',\n col.align === 'center' && 'text-center',\n !col.render && 'font-mono text-xs',\n )}\n >\n {col.render ? col.render(value, row) : String(value ?? '—')}\n </td>\n )\n })}\n {rowMenu && (\n <td className=\"px-2 py-2 w-11\" onClick={(e) => e.stopPropagation()}>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n className=\"inline-flex h-7 w-7 items-center justify-center rounded-md text-tollerud-text-muted hover:text-tollerud-text-primary hover:bg-tollerud-surface-raised transition-colors tollerud-focus-ring\"\n aria-label=\"Row actions\"\n >\n <MoreHorizontal size={15} />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {rowMenu(row).map((item, index) => {\n if (item.sep) return <DropdownMenuSeparator key={index} />\n if (item.heading) return <DropdownMenuLabel key={index}>{item.label}</DropdownMenuLabel>\n return (\n <DropdownMenuItem key={index} onSelect={() => item.onSelect?.()}>\n {item.icon ? <span className=\"mr-2 inline-flex\">{item.icon}</span> : null}\n {item.label}\n </DropdownMenuItem>\n )\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n </td>\n )}\n </tr>\n )\n })}\n {isRich &&\n pageSize &&\n pageRows.length < pageSize &&\n Array.from({ length: pageSize - pageRows.length }).map((_, i) => (\n <tr key={`spacer-${i}`} aria-hidden className=\"h-[49px]\">\n <td colSpan={colSpan} />\n </tr>\n ))}\n </tbody>\n )\n }\n\n const table = (\n <table className=\"w-full min-w-[640px] text-sm\">\n <thead>\n <tr className=\"border-b border-tollerud-border/30 bg-tollerud-noir-900\">\n {selectable && (\n <th className=\"px-3 py-2.5 w-10\">\n <Checkbox\n checked={allOnPageSelected}\n onChange={toggleAllOnPage}\n aria-label=\"Select all rows on page\"\n />\n </th>\n )}\n {columns.map((col) => headerCell(col))}\n {rowMenu && <th className=\"w-11\" />}\n </tr>\n {!isRich && filterableColumns.length > 0 && (\n <tr className=\"border-b border-tollerud-border/20\">\n {columns.map((col) => (\n <th\n key={`filter-${col.key}`}\n className={cn('px-1.5 py-1', col.align === 'right' && 'text-right', col.align === 'center' && 'text-center')}\n >\n {col.filterable ? (\n <input\n type=\"text\"\n placeholder={`Filter ${col.label.toLowerCase()}…`}\n value={filters[col.key] ?? ''}\n onChange={(e) => updateFilter(col.key, e.target.value)}\n className={cn(\n 'w-full px-2 py-1 text-xs rounded border transition-colors outline-none',\n 'bg-tollerud-noir-900/50 border-tollerud-border/20 text-tollerud-text-primary placeholder:text-tollerud-text-muted/40',\n 'focus:border-tollerud-yellow/40 focus:ring-1 focus:ring-tollerud-yellow/20',\n )}\n />\n ) : null}\n </th>\n ))}\n </tr>\n )}\n </thead>\n {tableBody()}\n </table>\n )\n\n if (!isRich) {\n return (\n <div ref={forwardedRef} className={cn('overflow-x-auto rounded-lg border border-tollerud-border/30', className)}>\n {table}\n </div>\n )\n }\n\n const showEmpty = !loading && sorted.length === 0\n\n return (\n <div\n ref={forwardedRef}\n className={cn(\n 'overflow-hidden rounded-lg border border-tollerud-border/30 bg-tollerud-noir-900',\n className,\n )}\n >\n {(searchable || filter || toolbarRight) && (\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-b border-tollerud-border/30 px-4 py-3.5\">\n <div className=\"flex flex-wrap items-center gap-2.5\">\n {searchable && (\n <div className=\"flex h-9 w-[230px] max-w-full items-center gap-2 rounded-lg border border-tollerud-border/30 bg-tollerud-noir-950 px-3\">\n <Search size={15} className=\"shrink-0 text-tollerud-text-muted\" aria-hidden />\n <input\n value={query}\n onChange={(e) => {\n setQuery(e.target.value)\n setPage(1)\n }}\n placeholder={searchPlaceholder}\n className=\"min-w-0 flex-1 border-none bg-transparent text-sm text-tollerud-text-primary outline-none placeholder:text-tollerud-text-muted\"\n />\n {query && (\n <button\n type=\"button\"\n onClick={() => setQuery('')}\n className=\"text-tollerud-text-muted hover:text-tollerud-text-primary\"\n aria-label=\"Clear search\"\n >\n <X size={13} />\n </button>\n )}\n </div>\n )}\n {filter && (\n <Segmented\n size=\"sm\"\n value={filterValue}\n onChange={(value) => {\n setFilterValue(value)\n setPage(1)\n }}\n options={[\n { value: 'all', label: filter.allLabel ?? 'All' },\n ...filterOptions.map((opt) => ({ value: opt, label: opt })),\n ]}\n />\n )}\n </div>\n {toolbarRight}\n </div>\n )}\n\n {selectable && selected.length > 0 && (\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-b border-tollerud-border/30 bg-tollerud-yellow/[0.07] px-4 py-2.5\">\n <span className=\"flex items-center gap-2 text-sm text-tollerud-text-primary\">\n <Badge variant=\"accent\">{selected.length}</Badge>\n selected\n </span>\n <div className=\"flex flex-wrap items-center gap-2\">\n {bulkActions.map((action, index) => (\n <Button\n key={index}\n variant={action.variant ?? 'ghost'}\n size=\"sm\"\n onClick={() => action.onRun(selected, clearSelection)}\n >\n {action.icon}\n {action.label}\n </Button>\n ))}\n </div>\n </div>\n )}\n\n {showEmpty ? (\n <div className=\"p-2\">{emptyState ?? <div className=\"py-12 text-center text-sm text-tollerud-text-muted\">No results.</div>}</div>\n ) : (\n <div className=\"overflow-x-auto\">{table}</div>\n )}\n\n {!loading && sorted.length > 0 && (\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-t border-tollerud-border/30 px-4 py-3\">\n <span className=\"text-xs text-tollerud-text-muted\">\n {pageSize\n ? `Showing ${(currentPage - 1) * pageSize + 1}–${(currentPage - 1) * pageSize + pageRows.length} of ${sorted.length}`\n : `${sorted.length} row${sorted.length === 1 ? '' : 's'}`}\n </span>\n {pageSize && pageCount > 1 && (\n <Pagination page={currentPage} pageCount={pageCount} onChange={setPage} siblingCount={1} />\n )}\n </div>\n )}\n </div>\n )\n}\n\nconst DataTable = forwardRef(<T extends Record<string, unknown>>(\n props: DataTableProps<T>,\n ref: React.Ref<HTMLDivElement>\n) => <DataTableInner {...props} forwardedRef={ref} />)\n\nDataTable.displayName = 'DataTable'\n\nexport { DataTable }\n"]}
1
+ {"version":3,"sources":["../components/DataTable.tsx"],"names":[],"mappings":"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","file":"chunk-YPP7QHYT.js","sourcesContent":["'use client'\n\nimport { useState, useMemo, forwardRef, type ReactNode } from 'react'\nimport { ChevronDown, MoreHorizontal, Search, X } from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { Badge } from './Badge'\nimport { Button } from './Button'\nimport { Checkbox } from './Checkbox'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from './DropdownMenu'\nimport { Pagination } from './Pagination'\nimport { Segmented } from './Segmented'\nimport { Skeleton } from './Skeleton'\n\n/* ──────────────────── Sortable & Filterable Data Table ──────────────────── */\n\nexport interface Column<T> {\n key: string\n label: string\n sortable?: boolean\n filterable?: boolean\n align?: 'left' | 'center' | 'right'\n width?: string\n render?: (value: unknown, row: T) => ReactNode\n}\n\nexport interface DataTableFilter {\n key: string\n options?: string[]\n allLabel?: string\n}\n\nexport interface DataTableBulkAction {\n label: string\n variant?: 'primary' | 'secondary' | 'ghost' | 'destructive' | 'terminal'\n icon?: ReactNode\n onRun: (selectedIds: (string | number)[], clearSelection: () => void) => void\n}\n\nexport interface DataTableRowMenuItem {\n label: string\n onSelect?: () => void\n icon?: ReactNode\n sep?: boolean\n heading?: boolean\n}\n\nexport interface DataTableProps<T extends Record<string, unknown>> {\n columns: Column<T>[]\n /** Row data — use `data` or `rows` (alias). */\n data?: T[]\n rows?: T[]\n /** Row key extractor — defaults to `row.id` or `row.key` */\n rowKey?: keyof T | ((row: T) => string | number)\n onRowClick?: (row: T) => void\n className?: string\n emptyMessage?: string\n /** Global search across `searchKeys` (or all column keys). */\n searchable?: boolean\n searchKeys?: (keyof T | string)[]\n searchPlaceholder?: string\n /** Segmented filter on a single column value. */\n filter?: DataTableFilter\n selectable?: boolean\n pageSize?: number\n bulkActions?: DataTableBulkAction[]\n rowMenu?: (row: T) => DataTableRowMenuItem[]\n toolbarRight?: ReactNode\n emptyState?: ReactNode\n loading?: boolean\n skeletonRows?: number\n}\n\ninterface DataTableInnerProps<T extends Record<string, unknown>> extends DataTableProps<T> {\n forwardedRef?: React.Ref<HTMLDivElement>\n}\n\nfunction DataTableInner<T extends Record<string, unknown>>({\n columns,\n data,\n rows,\n rowKey,\n onRowClick,\n className,\n emptyMessage = 'No data',\n searchable = false,\n searchKeys,\n searchPlaceholder = 'Search…',\n filter,\n selectable = false,\n pageSize,\n bulkActions = [],\n rowMenu,\n toolbarRight,\n emptyState,\n loading = false,\n skeletonRows = 5,\n forwardedRef,\n}: DataTableInnerProps<T>) {\n const tableData = useMemo(() => rows ?? data ?? [], [rows, data])\n\n const isRich =\n searchable ||\n filter ||\n selectable ||\n pageSize !== undefined ||\n !!rowMenu ||\n !!toolbarRight ||\n bulkActions.length > 0 ||\n !!emptyState ||\n loading\n\n const [sortKey, setSortKey] = useState<string | null>(null)\n const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc')\n const [filters, setFilters] = useState<Record<string, string>>({})\n const [query, setQuery] = useState('')\n const [filterValue, setFilterValue] = useState('all')\n const [selected, setSelected] = useState<(string | number)[]>([])\n const [page, setPage] = useState(1)\n\n const getRowKey = (row: T, i: number): string | number => {\n if (typeof rowKey === 'function') return rowKey(row)\n if (rowKey) return row[rowKey] as string | number\n return (row.id ?? row.key ?? i) as string | number\n }\n\n const toggleSort = (key: string) => {\n if (sortKey === key) {\n setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'))\n } else {\n setSortKey(key)\n setSortDir('asc')\n }\n }\n\n const updateFilter = (key: string, value: string) => {\n setFilters((prev) => {\n const next = { ...prev }\n if (value.trim() === '') {\n delete next[key]\n } else {\n next[key] = value\n }\n return next\n })\n }\n\n const searchKeysResolved = searchKeys ?? columns.map((c) => c.key)\n const filterOptions = filter\n ? (filter.options ?? Array.from(new Set(tableData.map((r) => String(r[filter.key] ?? '')))))\n : []\n\n const filtered = useMemo(() => {\n let result = tableData\n\n if (isRich && filter && filterValue !== 'all') {\n result = result.filter((row) => String(row[filter.key] ?? '') === filterValue)\n }\n\n if (isRich && searchable && query.trim()) {\n const q = query.trim().toLowerCase()\n result = result.filter((row) =>\n searchKeysResolved.some((key) => String(row[key as keyof T] ?? '').toLowerCase().includes(q))\n )\n }\n\n if (!isRich) {\n const activeFilters = Object.entries(filters).filter(([, v]) => v.trim() !== '')\n if (activeFilters.length > 0) {\n result = result.filter((row) =>\n activeFilters.every(([key, filterVal]) => {\n const cellValue = String(row[key] ?? '').toLowerCase()\n return cellValue.includes(filterVal.toLowerCase())\n })\n )\n }\n }\n\n return result\n }, [tableData, filters, isRich, filter, filterValue, searchable, query, searchKeysResolved])\n\n const sorted = useMemo(() => {\n if (!sortKey) return filtered\n const col = columns.find((c) => c.key === sortKey)\n if (!col?.sortable) return filtered\n\n return [...filtered].sort((a, b) => {\n const aVal = a[sortKey]\n const bVal = b[sortKey]\n\n if (typeof aVal === 'number' && typeof bVal === 'number') {\n return sortDir === 'asc' ? aVal - bVal : bVal - aVal\n }\n\n const aStr = String(aVal ?? '')\n const bStr = String(bVal ?? '')\n const cmp = aStr.localeCompare(bStr, 'nb', { numeric: true })\n return sortDir === 'asc' ? cmp : -cmp\n })\n }, [filtered, sortKey, sortDir, columns])\n\n const pageCount = pageSize ? Math.max(1, Math.ceil(sorted.length / pageSize)) : 1\n const currentPage = Math.min(page, pageCount)\n const pageRows = pageSize\n ? sorted.slice((currentPage - 1) * pageSize, currentPage * pageSize)\n : sorted\n\n const clearSelection = () => setSelected([])\n const allOnPageSelected =\n pageRows.length > 0 && pageRows.every((row) => selected.includes(getRowKey(row, 0)))\n\n const toggleAllOnPage = () => {\n const pageIds = pageRows.map((row, i) => getRowKey(row, i))\n if (allOnPageSelected) {\n setSelected((prev) => prev.filter((id) => !pageIds.includes(id)))\n } else {\n setSelected((prev) => Array.from(new Set([...prev, ...pageIds])))\n }\n }\n\n const toggleRow = (id: string | number) => {\n setSelected((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]))\n }\n\n const hasActiveFilters = Object.values(filters).some((v) => v.trim() !== '')\n const filterableColumns = columns.filter((c) => c.filterable)\n const colSpan = columns.length + (selectable ? 1 : 0) + (rowMenu ? 1 : 0)\n\n const sortIndicator = (key: string) => {\n const active = sortKey === key\n return (\n <ChevronDown\n size={12}\n className={cn(\n 'shrink-0 transition-transform duration-150',\n active ? 'text-tollerud-yellow opacity-100' : 'opacity-25',\n active && sortDir === 'desc' && 'rotate-180'\n )}\n aria-hidden\n />\n )\n }\n\n const headerCell = (col: Column<T>) => (\n <th\n key={col.key}\n className={cn(\n 'px-3 py-2.5 text-left text-xs font-semibold text-tollerud-text-muted uppercase tracking-wider',\n col.sortable && 'cursor-pointer select-none hover:text-tollerud-text-primary transition-colors',\n col.align === 'right' && 'text-right',\n col.align === 'center' && 'text-center',\n )}\n style={col.width ? { width: col.width } : undefined}\n onClick={() => col.sortable && toggleSort(col.key)}\n >\n <span\n className={cn(\n 'inline-flex items-center gap-1',\n col.align === 'right' && 'justify-end w-full',\n col.align === 'center' && 'justify-center w-full',\n )}\n >\n {col.label}\n {col.sortable && (isRich ? sortIndicator(col.key) : (\n <>\n {sortKey === col.key && (\n <span className=\"text-tollerud-accent\">{sortDir === 'asc' ? '↑' : '↓'}</span>\n )}\n {sortKey !== col.key && <span className=\"text-tollerud-text-muted/30\">↕</span>}\n </>\n ))}\n {!isRich && col.filterable && (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn('opacity-40', filters[col.key] && 'opacity-100 text-tollerud-yellow')}\n aria-hidden\n >\n <path d=\"M4 4h16v2.172a2 2 0 0 1-.586 1.414L15 12v7l-6 2v-8.5L4.52 7.53A2 2 0 0 1 4 6.16V4z\" />\n </svg>\n )}\n </span>\n </th>\n )\n\n const tableBody = () => {\n if (loading) {\n return (\n <tbody>\n {Array.from({ length: skeletonRows }).map((_, i) => (\n <tr key={i} className=\"border-b border-tollerud-border/20\">\n {selectable && (\n <td className=\"px-3 py-2.5 w-10\">\n <Skeleton className=\"h-4 w-4 rounded\" />\n </td>\n )}\n {columns.map((col, j) => (\n <td key={col.key} className={cn('px-3 py-2.5', col.align === 'right' && 'text-right')}>\n <Skeleton className={cn('h-3', j === 0 ? 'w-[70%]' : 'w-[55%]')} />\n </td>\n ))}\n {rowMenu && (\n <td className=\"px-3 py-2.5 w-11\">\n <Skeleton className=\"h-4 w-4 rounded\" />\n </td>\n )}\n </tr>\n ))}\n </tbody>\n )\n }\n\n if (sorted.length === 0) {\n if (isRich && emptyState) {\n return null\n }\n return (\n <tbody>\n <tr>\n <td colSpan={colSpan} className=\"px-3 py-8 text-center text-sm text-tollerud-text-muted\">\n {hasActiveFilters || query || filterValue !== 'all' ? 'No matching rows' : emptyMessage}\n </td>\n </tr>\n </tbody>\n )\n }\n\n return (\n <tbody>\n {pageRows.map((row, i) => {\n const id = getRowKey(row, i)\n const isSelected = selected.includes(id)\n return (\n <tr\n key={id}\n className={cn(\n 'border-b border-tollerud-border/20 transition-colors',\n onRowClick && 'cursor-pointer hover:bg-tollerud-surface-raised/50',\n isSelected && 'bg-tollerud-yellow/[0.05]',\n )}\n onClick={() => onRowClick?.(row)}\n >\n {selectable && (\n <td className=\"px-3 py-2.5 w-10\" onClick={(e) => e.stopPropagation()}>\n <Checkbox checked={isSelected} onChange={() => toggleRow(id)} aria-label={`Select row ${id}`} />\n </td>\n )}\n {columns.map((col) => {\n const value = row[col.key]\n return (\n <td\n key={col.key}\n className={cn(\n 'px-3 py-2.5 text-tollerud-text-secondary',\n col.align === 'right' && 'text-right',\n col.align === 'center' && 'text-center',\n !col.render && 'font-mono text-xs',\n )}\n >\n {col.render ? col.render(value, row) : String(value ?? '—')}\n </td>\n )\n })}\n {rowMenu && (\n <td className=\"px-2 py-2 w-11\" onClick={(e) => e.stopPropagation()}>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n className=\"inline-flex h-7 w-7 items-center justify-center rounded-md text-tollerud-text-muted hover:text-tollerud-text-primary hover:bg-tollerud-surface-raised transition-colors tollerud-focus-ring\"\n aria-label=\"Row actions\"\n >\n <MoreHorizontal size={15} />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {rowMenu(row).map((item, index) => {\n if (item.sep) return <DropdownMenuSeparator key={index} />\n if (item.heading) return <DropdownMenuLabel key={index}>{item.label}</DropdownMenuLabel>\n return (\n <DropdownMenuItem key={index} onSelect={() => item.onSelect?.()}>\n {item.icon ? <span className=\"mr-2 inline-flex\">{item.icon}</span> : null}\n {item.label}\n </DropdownMenuItem>\n )\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n </td>\n )}\n </tr>\n )\n })}\n {isRich &&\n pageSize &&\n pageRows.length < pageSize &&\n Array.from({ length: pageSize - pageRows.length }).map((_, i) => (\n <tr key={`spacer-${i}`} aria-hidden className=\"h-[49px]\">\n <td colSpan={colSpan} />\n </tr>\n ))}\n </tbody>\n )\n }\n\n const table = (\n <table className=\"w-full min-w-[640px] text-sm\">\n <thead>\n <tr className=\"border-b border-tollerud-border/30 bg-tollerud-noir-900\">\n {selectable && (\n <th className=\"px-3 py-2.5 w-10\">\n <Checkbox\n checked={allOnPageSelected}\n onChange={toggleAllOnPage}\n aria-label=\"Select all rows on page\"\n />\n </th>\n )}\n {columns.map((col) => headerCell(col))}\n {rowMenu && <th className=\"w-11\" />}\n </tr>\n {!isRich && filterableColumns.length > 0 && (\n <tr className=\"border-b border-tollerud-border/20\">\n {columns.map((col) => (\n <th\n key={`filter-${col.key}`}\n className={cn('px-1.5 py-1', col.align === 'right' && 'text-right', col.align === 'center' && 'text-center')}\n >\n {col.filterable ? (\n <input\n type=\"text\"\n placeholder={`Filter ${col.label.toLowerCase()}…`}\n value={filters[col.key] ?? ''}\n onChange={(e) => updateFilter(col.key, e.target.value)}\n className={cn(\n 'w-full px-2 py-1 text-xs rounded border transition-colors outline-none',\n 'bg-tollerud-noir-900/50 border-tollerud-border/20 text-tollerud-text-primary placeholder:text-tollerud-text-muted/40',\n 'focus:border-tollerud-yellow/40 focus:ring-1 focus:ring-tollerud-yellow/20',\n )}\n />\n ) : null}\n </th>\n ))}\n </tr>\n )}\n </thead>\n {tableBody()}\n </table>\n )\n\n if (!isRich) {\n return (\n <div ref={forwardedRef} className={cn('overflow-x-auto rounded-lg border border-tollerud-border/30', className)}>\n {table}\n </div>\n )\n }\n\n const showEmpty = !loading && sorted.length === 0\n\n return (\n <div\n ref={forwardedRef}\n className={cn(\n 'overflow-hidden rounded-lg border border-tollerud-border/30 bg-tollerud-noir-900',\n className,\n )}\n >\n {(searchable || filter || toolbarRight) && (\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-b border-tollerud-border/30 px-4 py-3.5\">\n <div className=\"flex flex-wrap items-center gap-2.5\">\n {searchable && (\n <div className=\"flex h-9 w-[230px] max-w-full items-center gap-2 rounded-lg border border-tollerud-border/30 bg-tollerud-noir-950 px-3\">\n <Search size={15} className=\"shrink-0 text-tollerud-text-muted\" aria-hidden />\n <input\n value={query}\n onChange={(e) => {\n setQuery(e.target.value)\n setPage(1)\n }}\n placeholder={searchPlaceholder}\n className=\"min-w-0 flex-1 border-none bg-transparent text-sm text-tollerud-text-primary outline-none placeholder:text-tollerud-text-muted\"\n />\n {query && (\n <button\n type=\"button\"\n onClick={() => setQuery('')}\n className=\"text-tollerud-text-muted hover:text-tollerud-text-primary\"\n aria-label=\"Clear search\"\n >\n <X size={13} />\n </button>\n )}\n </div>\n )}\n {filter && (\n <Segmented\n size=\"sm\"\n value={filterValue}\n onChange={(value) => {\n setFilterValue(value)\n setPage(1)\n }}\n options={[\n { value: 'all', label: filter.allLabel ?? 'All' },\n ...filterOptions.map((opt) => ({ value: opt, label: opt })),\n ]}\n />\n )}\n </div>\n {toolbarRight}\n </div>\n )}\n\n {selectable && selected.length > 0 && (\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-b border-tollerud-border/30 bg-tollerud-yellow/[0.07] px-4 py-2.5\">\n <span className=\"flex items-center gap-2 text-sm text-tollerud-text-primary\">\n <Badge variant=\"accent\">{selected.length}</Badge>\n selected\n </span>\n <div className=\"flex flex-wrap items-center gap-2\">\n {bulkActions.map((action, index) => (\n <Button\n key={index}\n variant={action.variant ?? 'ghost'}\n size=\"sm\"\n onClick={() => action.onRun(selected, clearSelection)}\n >\n {action.icon}\n {action.label}\n </Button>\n ))}\n </div>\n </div>\n )}\n\n {showEmpty ? (\n <div className=\"p-2\">{emptyState ?? <div className=\"py-12 text-center text-sm text-tollerud-text-muted\">No results.</div>}</div>\n ) : (\n <div className=\"overflow-x-auto\">{table}</div>\n )}\n\n {!loading && sorted.length > 0 && (\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-t border-tollerud-border/30 px-4 py-3\">\n <span className=\"text-xs text-tollerud-text-muted\">\n {pageSize\n ? `Showing ${(currentPage - 1) * pageSize + 1}–${(currentPage - 1) * pageSize + pageRows.length} of ${sorted.length}`\n : `${sorted.length} row${sorted.length === 1 ? '' : 's'}`}\n </span>\n {pageSize && pageCount > 1 && (\n <Pagination page={currentPage} pageCount={pageCount} onChange={setPage} siblingCount={1} />\n )}\n </div>\n )}\n </div>\n )\n}\n\nconst DataTable = forwardRef(<T extends Record<string, unknown>>(\n props: DataTableProps<T>,\n ref: React.Ref<HTMLDivElement>\n) => <DataTableInner {...props} forwardedRef={ref} />)\n\nDataTable.displayName = 'DataTable'\n\nexport { DataTable }\n"]}
@@ -1,12 +1,15 @@
1
1
  'use client';
2
2
  import { cn } from './chunk-WSQNPRGN.js';
3
- import { forwardRef, useId } from 'react';
3
+ import { forwardRef, useId, useState } from 'react';
4
4
  import { jsxs, jsx } from 'react/jsx-runtime';
5
5
 
6
6
  var Switch = forwardRef(
7
- ({ className, label, id: idProp, checked, ...props }, ref) => {
7
+ ({ className, label, id: idProp, checked, defaultChecked, onChange, ...props }, ref) => {
8
8
  const autoId = useId();
9
9
  const id = idProp ?? autoId;
10
+ const isControlled = checked !== void 0;
11
+ const [internalChecked, setInternalChecked] = useState(!!defaultChecked);
12
+ const isOn = isControlled ? checked : internalChecked;
10
13
  return /* @__PURE__ */ jsxs(
11
14
  "label",
12
15
  {
@@ -24,10 +27,7 @@ var Switch = forwardRef(
24
27
  className: cn(
25
28
  "relative inline-flex items-center h-5 w-9 flex-shrink-0 rounded-full",
26
29
  "transition-colors duration-200 ease-out",
27
- checked ? "bg-tollerud-yellow" : "bg-tollerud-noir-600",
28
- "group-hover:bg-tollerud-noir-500",
29
- checked && "group-hover:bg-tollerud-yellow-warm",
30
- "peer-focus-visible:outline-2 peer-focus-visible:outline-tollerud-yellow peer-focus-visible:outline-offset-2"
30
+ isOn ? "bg-tollerud-yellow group-hover:bg-tollerud-yellow-warm" : "bg-tollerud-noir-600 group-hover:bg-tollerud-noir-500"
31
31
  ),
32
32
  children: [
33
33
  /* @__PURE__ */ jsx(
@@ -37,8 +37,12 @@ var Switch = forwardRef(
37
37
  id,
38
38
  type: "checkbox",
39
39
  role: "switch",
40
- checked,
41
- className: "peer absolute inset-0 opacity-0 w-full h-full cursor-pointer z-10",
40
+ checked: isOn,
41
+ className: "absolute inset-0 opacity-0 w-full h-full cursor-pointer z-10",
42
+ onChange: (e) => {
43
+ if (!isControlled) setInternalChecked(e.target.checked);
44
+ onChange?.(e);
45
+ },
42
46
  ...props
43
47
  }
44
48
  ),
@@ -46,9 +50,9 @@ var Switch = forwardRef(
46
50
  "span",
47
51
  {
48
52
  className: cn(
49
- "block h-3.5 w-3.5 rounded-full shadow-sm",
53
+ "block h-3.5 w-3.5 rounded-full shadow-sm pointer-events-none",
50
54
  "transition-all duration-200 ease-out",
51
- checked ? "translate-x-[18px] bg-tollerud-black" : "translate-x-[3px] bg-tollerud-white"
55
+ isOn ? "translate-x-[18px] bg-tollerud-black" : "translate-x-[3px] bg-tollerud-white"
52
56
  )
53
57
  }
54
58
  )
@@ -64,5 +68,5 @@ var Switch = forwardRef(
64
68
  Switch.displayName = "Switch";
65
69
 
66
70
  export { Switch };
67
- //# sourceMappingURL=chunk-O57QMLNI.js.map
68
- //# sourceMappingURL=chunk-O57QMLNI.js.map
71
+ //# sourceMappingURL=chunk-YTU7BRDW.js.map
72
+ //# sourceMappingURL=chunk-YTU7BRDW.js.map