@nous-research/ui 0.10.0 → 0.11.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/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/ui/components/icons/discord.d.ts +3 -0
- package/dist/ui/components/icons/discord.d.ts.map +1 -0
- package/dist/ui/components/icons/discord.js +6 -0
- package/dist/ui/components/icons/discord.js.map +1 -0
- package/dist/ui/components/icons/github.d.ts +3 -0
- package/dist/ui/components/icons/github.d.ts.map +1 -0
- package/dist/ui/components/icons/github.js +6 -0
- package/dist/ui/components/icons/github.js.map +1 -0
- package/dist/ui/components/icons/index.d.ts +2 -0
- package/dist/ui/components/icons/index.d.ts.map +1 -1
- package/dist/ui/components/icons/index.js +2 -0
- package/dist/ui/components/icons/index.js.map +1 -1
- package/dist/ui/components/overlays/blend-modes.d.ts +2 -0
- package/dist/ui/components/overlays/blend-modes.d.ts.map +1 -0
- package/dist/ui/components/overlays/blend-modes.js +14 -0
- package/dist/ui/components/overlays/blend-modes.js.map +1 -0
- package/dist/ui/components/overlays/glitch.js +1 -1
- package/dist/ui/components/overlays/glitch.js.map +1 -1
- package/dist/ui/components/overlays/greys.js +1 -1
- package/dist/ui/components/overlays/greys.js.map +1 -1
- package/dist/ui/components/overlays/index.d.ts +9 -53
- package/dist/ui/components/overlays/index.d.ts.map +1 -1
- package/dist/ui/components/overlays/index.js +9 -135
- package/dist/ui/components/overlays/index.js.map +1 -1
- package/dist/ui/components/overlays/lens-layers.d.ts +15 -0
- package/dist/ui/components/overlays/lens-layers.d.ts.map +1 -0
- package/dist/ui/components/overlays/lens-layers.js +68 -0
- package/dist/ui/components/overlays/lens-layers.js.map +1 -0
- package/dist/ui/components/overlays/lens.d.ts +45 -0
- package/dist/ui/components/overlays/lens.d.ts.map +1 -0
- package/dist/ui/components/overlays/lens.js +65 -0
- package/dist/ui/components/overlays/lens.js.map +1 -0
- package/dist/ui/components/overlays/noise.js +1 -1
- package/dist/ui/components/overlays/noise.js.map +1 -1
- package/dist/ui/components/overlays/vignette.js +1 -1
- package/dist/ui/components/overlays/vignette.js.map +1 -1
- package/dist/ui/components/socials.d.ts +21 -0
- package/dist/ui/components/socials.d.ts.map +1 -0
- package/dist/ui/components/socials.js +9 -0
- package/dist/ui/components/socials.js.map +1 -0
- package/dist/ui/footer.d.ts +18 -3
- package/dist/ui/footer.d.ts.map +1 -1
- package/dist/ui/footer.js +13 -3
- package/dist/ui/footer.js.map +1 -1
- package/dist/ui/header.d.ts +39 -3
- package/dist/ui/header.d.ts.map +1 -1
- package/dist/ui/header.js +58 -5
- package/dist/ui/header.js.map +1 -1
- package/package.json +3 -1
package/dist/ui/footer.js
CHANGED
|
@@ -3,16 +3,26 @@ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useRef } from 'react';
|
|
4
4
|
import { useCssVarDims } from '../hooks/use-css-var-dims';
|
|
5
5
|
import { Cell, Grid } from './components/grid';
|
|
6
|
+
import { Socials } from './components/socials';
|
|
7
|
+
import { ThemeToggle } from './components/theme-toggle';
|
|
6
8
|
import { Small } from './components/typography/small';
|
|
7
|
-
const
|
|
9
|
+
const DEFAULT_GROUPS = [
|
|
8
10
|
{ label: 'Product', links: ['Overview', 'Features', 'Pricing'] },
|
|
9
11
|
{ label: 'Resources', links: ['Docs', 'Blog', 'Support'] },
|
|
10
12
|
{ label: 'Company', links: ['About', 'Careers', 'Contact'] },
|
|
11
13
|
{ label: 'Legal', links: ['Privacy', 'Terms', 'License'] }
|
|
12
14
|
];
|
|
13
|
-
export function Footer({ LinkComponent = 'a' }) {
|
|
15
|
+
export function Footer({ className, groups = DEFAULT_GROUPS, LinkComponent = 'a', socials, socialsLabel = 'Socials', style, themeLabel = 'Theme', themeToggle = false }) {
|
|
14
16
|
const ref = useRef(null);
|
|
15
17
|
useCssVarDims('footer', ref);
|
|
16
|
-
|
|
18
|
+
const hasSocials = (socials?.length ?? 0) > 0;
|
|
19
|
+
const hasChrome = hasSocials || themeToggle;
|
|
20
|
+
return (_jsxs("footer", { className: className, ref: ref, style: style, children: [_jsxs(Grid, { children: [_jsx(Cell, { children: _jsxs(Small, { className: "opacity-50", children: ["\u00A9", new Date().getFullYear()] }) }), groups.map(({ label, links }) => (_jsxs(Cell, { children: [_jsx(Small, { className: "opacity-50", children: label }), _jsx("nav", { className: "mt-3 flex flex-col gap-2", children: links.map(link => {
|
|
21
|
+
const href = typeof link === 'string'
|
|
22
|
+
? `/${link.toLowerCase()}`
|
|
23
|
+
: link.href;
|
|
24
|
+
const label = typeof link === 'string' ? link : link.label;
|
|
25
|
+
return (_jsx(Small, { as: LinkComponent, className: "underline", href: href, children: label }, label));
|
|
26
|
+
}) })] }, label)))] }), hasChrome && (_jsxs(Grid, { children: [hasSocials && (_jsxs(Cell, { className: "flex items-start justify-between", children: [_jsx(Small, { className: "opacity-50", children: socialsLabel }), _jsx(Socials, { items: socials })] })), themeToggle && (_jsxs(Cell, { className: "flex items-start justify-between", children: [_jsx(Small, { className: "opacity-50", children: themeLabel }), _jsx(ThemeToggle, {})] }))] }))] }));
|
|
17
27
|
}
|
|
18
28
|
//# sourceMappingURL=footer.js.map
|
package/dist/ui/footer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"footer.js","sourceRoot":"","sources":["../../src/ui/footer.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAA;AAErD,MAAM,
|
|
1
|
+
{"version":3,"file":"footer.js","sourceRoot":"","sources":["../../src/ui/footer.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport { useRef } from 'react'\n\nimport { useCssVarDims } from '../hooks/use-css-var-dims'\nimport { Cell, Grid } from './components/grid'\nimport { Socials, type SocialLink } from './components/socials'\nimport { ThemeToggle } from './components/theme-toggle'\nimport { Small } from './components/typography/small'\n\nconst DEFAULT_GROUPS: FooterGroup[] = [\n { label: 'Product', links: ['Overview', 'Features', 'Pricing'] },\n { label: 'Resources', links: ['Docs', 'Blog', 'Support'] },\n { label: 'Company', links: ['About', 'Careers', 'Contact'] },\n { label: 'Legal', links: ['Privacy', 'Terms', 'License'] }\n]\n\nexport function Footer({\n className,\n groups = DEFAULT_GROUPS,\n LinkComponent = 'a',\n socials,\n socialsLabel = 'Socials',\n style,\n themeLabel = 'Theme',\n themeToggle = false\n}: FooterProps) {\n const ref = useRef<HTMLElement>(null)\n useCssVarDims('footer', ref)\n\n const hasSocials = (socials?.length ?? 0) > 0\n const hasChrome = hasSocials || themeToggle\n\n return (\n <footer className={className} ref={ref} style={style}>\n <Grid>\n <Cell>\n <Small className=\"opacity-50\">©{new Date().getFullYear()}</Small>\n </Cell>\n\n {groups.map(({ label, links }) => (\n <Cell key={label}>\n <Small className=\"opacity-50\">{label}</Small>\n\n <nav className=\"mt-3 flex flex-col gap-2\">\n {links.map(link => {\n const href = typeof link === 'string'\n ? `/${link.toLowerCase()}`\n : link.href\n\n const label = typeof link === 'string' ? link : link.label\n\n return (\n <Small\n as={LinkComponent}\n className=\"underline\"\n href={href}\n key={label}\n >\n {label}\n </Small>\n )\n })}\n </nav>\n </Cell>\n ))}\n </Grid>\n\n {hasChrome && (\n <Grid>\n {hasSocials && (\n <Cell className=\"flex items-start justify-between\">\n <Small className=\"opacity-50\">{socialsLabel}</Small>\n\n <Socials items={socials!} />\n </Cell>\n )}\n\n {themeToggle && (\n <Cell className=\"flex items-start justify-between\">\n <Small className=\"opacity-50\">{themeLabel}</Small>\n\n <ThemeToggle />\n </Cell>\n )}\n </Grid>\n )}\n </footer>\n )\n}\n\nexport interface FooterGroup {\n label: string\n links: (FooterLink | string)[]\n}\n\nexport interface FooterLink {\n href: string\n label: string\n}\n\nexport interface FooterProps {\n className?: string\n groups?: FooterGroup[]\n LinkComponent?: React.ElementType\n socials?: SocialLink[]\n socialsLabel?: string\n style?: React.CSSProperties\n themeLabel?: string\n themeToggle?: boolean\n}\n"]}
|
package/dist/ui/header.d.ts
CHANGED
|
@@ -1,6 +1,42 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { type SocialLink } from './components/socials';
|
|
2
|
+
export declare function Header({ brand, brandHref, className, desktopGridStyle, links, LinkComponent, scramble: scrambleProp, socials, socialsLabel, style, themeLabel, themeToggle }: HeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export interface HeaderLink {
|
|
4
|
+
external?: boolean;
|
|
5
|
+
href: string;
|
|
6
|
+
label: string;
|
|
7
|
+
onClick?: React.MouseEventHandler;
|
|
8
|
+
}
|
|
9
|
+
export interface HeaderProps {
|
|
10
|
+
brand?: React.ReactNode;
|
|
11
|
+
brandHref?: string;
|
|
12
|
+
className?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Inline `style` for the desktop `Grid` only — useful for overriding
|
|
15
|
+
* `grid-template-columns` (e.g. to align with a sidebar track) without
|
|
16
|
+
* affecting the mobile bar or drawer.
|
|
17
|
+
*/
|
|
18
|
+
desktopGridStyle?: React.CSSProperties;
|
|
19
|
+
links?: HeaderLink[];
|
|
3
20
|
LinkComponent?: React.ElementType;
|
|
21
|
+
/**
|
|
22
|
+
* Apply the hover-Scramble effect to nav link labels. Defaults to `true`,
|
|
23
|
+
* automatically suppressed on tier-0 GPUs and when the user has
|
|
24
|
+
* `prefers-reduced-motion: reduce`.
|
|
25
|
+
*/
|
|
26
|
+
scramble?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Optional socials shown in a trailing chrome cell on desktop and in the
|
|
29
|
+
* mobile drawer's chrome row. For nav-heavy products (≥ 5 links) prefer
|
|
30
|
+
* passing socials to `<Footer>` instead — the desktop `Grid` only ships
|
|
31
|
+
* column rules through `grid-cols-6`, so brand + many links + chrome can
|
|
32
|
+
* overflow.
|
|
33
|
+
*/
|
|
34
|
+
socials?: SocialLink[];
|
|
35
|
+
socialsLabel?: string;
|
|
36
|
+
style?: React.CSSProperties;
|
|
37
|
+
themeLabel?: string;
|
|
38
|
+
themeToggle?: boolean;
|
|
4
39
|
}
|
|
5
|
-
|
|
40
|
+
/** @deprecated Use `SocialLink` from `@nous-research/ui`. Same shape. */
|
|
41
|
+
export type HeaderSocial = SocialLink;
|
|
6
42
|
//# sourceMappingURL=header.d.ts.map
|
package/dist/ui/header.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"header.d.ts","sourceRoot":"","sources":["../../src/ui/header.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"header.d.ts","sourceRoot":"","sources":["../../src/ui/header.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAW,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAoB/D,wBAAgB,MAAM,CAAC,EACrB,KAAqB,EACrB,SAAe,EACf,SAAS,EACT,gBAAgB,EAChB,KAAqB,EACrB,aAAmB,EACnB,QAAQ,EAAE,YAAmB,EAC7B,OAAO,EACP,YAAwB,EACxB,KAAK,EACL,UAAoB,EACpB,WAAmB,EACpB,EAAE,WAAW,2CAmJb;AAsJD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAA;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;IACtC,KAAK,CAAC,EAAE,UAAU,EAAE,CAAA;IACpB,aAAa,CAAC,EAAE,KAAK,CAAC,WAAW,CAAA;IACjC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,UAAU,EAAE,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,yEAAyE;AACzE,MAAM,MAAM,YAAY,GAAG,UAAU,CAAA"}
|
package/dist/ui/header.js
CHANGED
|
@@ -1,21 +1,74 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { AnimatePresence, motion } from 'motion/react';
|
|
4
|
+
import { createElement, useCallback, useRef, useState } from 'react';
|
|
4
5
|
import { useCssVarDims } from '../hooks/use-css-var-dims';
|
|
6
|
+
import { useGpuTier } from '../hooks/use-gpu-tier';
|
|
7
|
+
import { cn } from '../utils';
|
|
5
8
|
import { Blink } from './components/blink';
|
|
6
9
|
import { Cell, Grid } from './components/grid';
|
|
7
10
|
import { HoverBg } from './components/hover-bg';
|
|
11
|
+
import { HamburgerIcon } from './components/icons/hamburger';
|
|
12
|
+
import { Scramble } from './components/scramble';
|
|
13
|
+
import { Socials } from './components/socials';
|
|
14
|
+
import { ThemeToggle } from './components/theme-toggle';
|
|
8
15
|
import { H2 } from './components/typography/h2';
|
|
9
16
|
import { Small } from './components/typography/small';
|
|
10
|
-
const
|
|
17
|
+
const DEFAULT_BRAND = (_jsxs("hgroup", { className: "flex flex-col gap-2", children: [_jsx(Small, { children: "Nous" }), _jsx(H2, { children: "Research" })] }));
|
|
18
|
+
const DEFAULT_LINKS = [
|
|
11
19
|
{ href: '/projects', label: 'Projects' },
|
|
12
20
|
{ href: '/participants', label: 'Participants' },
|
|
13
21
|
{ href: '/provenance', label: 'Provenance' },
|
|
14
22
|
{ href: '/contribute', label: 'Contribute' }
|
|
15
23
|
];
|
|
16
|
-
export function Header({ LinkComponent = 'a' }) {
|
|
24
|
+
export function Header({ brand = DEFAULT_BRAND, brandHref = '/', className, desktopGridStyle, links = DEFAULT_LINKS, LinkComponent = 'a', scramble: scrambleProp = true, socials, socialsLabel = 'Socials', style, themeLabel = 'Theme', themeToggle = false }) {
|
|
17
25
|
const ref = useRef(null);
|
|
18
26
|
useCssVarDims('header', ref);
|
|
19
|
-
|
|
27
|
+
// Skip the hover-Scramble rAF loop on tier-0 devices (no GPU / software
|
|
28
|
+
// renderer / `prefers-reduced-motion: reduce`) regardless of the prop.
|
|
29
|
+
const gpuTier = useGpuTier();
|
|
30
|
+
const scramble = scrambleProp && gpuTier > 0;
|
|
31
|
+
const [open, setOpen] = useState(false);
|
|
32
|
+
const close = useCallback(() => setOpen(false), []);
|
|
33
|
+
const hasSocials = (socials?.length ?? 0) > 0;
|
|
34
|
+
const hasMobileChrome = themeToggle || hasSocials;
|
|
35
|
+
return (_jsxs("header", { className: className, ref: ref, style: style, children: [_jsxs(Grid, { className: "hidden border-t border-b lg:grid", style: desktopGridStyle, children: [_jsx(BrandCell, { brand: brand, href: brandHref, LinkComponent: LinkComponent }), links.map(link => (_jsx(NavCell, { link: link, LinkComponent: LinkComponent, scramble: scramble }, link.href))), hasSocials && (_jsxs(Cell, { className: "flex items-start justify-between", children: [_jsx(Small, { className: "opacity-50", children: socialsLabel }), _jsx(Socials, { items: socials })] })), themeToggle && (_jsxs(Cell, { className: "flex items-start justify-between", children: [_jsx(Small, { className: "opacity-50", children: themeLabel }), _jsx(ThemeToggle, {})] }))] }), _jsxs("div", { className: cn('flex items-center justify-between border border-current/20 p-4', 'lg:hidden'), children: [_jsx(BrandLink, { brand: brand, href: brandHref, LinkComponent: LinkComponent }), _jsxs("div", { className: "flex items-center gap-3", children: [themeToggle && _jsx(ThemeToggle, {}), _jsx("button", { "aria-label": open ? 'Close menu' : 'Open menu', className: "relative z-50 cursor-pointer bg-transparent p-2", onClick: () => setOpen(v => !v), type: "button", children: _jsx(HamburgerIcon, { open: open }) })] })] }), _jsx(AnimatePresence, { children: open && (_jsx(motion.div, { animate: { opacity: 1 }, className: cn('bg-background/95 fixed inset-0 z-50 flex flex-col backdrop-blur-sm', 'p-8 lg:hidden'), exit: { opacity: 0 }, initial: { opacity: 0 }, transition: { duration: 0.2 }, children: _jsxs("div", { className: "flex flex-col border border-current/20", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-current/20 p-4", children: [_jsx(BrandLink, { brand: brand, href: brandHref, LinkComponent: LinkComponent, onClick: close }), _jsx("button", { "aria-label": "Close menu", className: "cursor-pointer bg-transparent p-2", onClick: close, type: "button", children: _jsx(HamburgerIcon, { open: true }) })] }), links.map(link => (_jsx(MobileNavLink, { link: link, LinkComponent: LinkComponent, onNavigate: close, scramble: scramble }, link.href))), hasMobileChrome && (_jsxs("div", { className: "flex items-center gap-3 border-b border-current/20 p-4", children: [hasSocials && (_jsxs(_Fragment, { children: [_jsx(Small, { className: "opacity-50", children: socialsLabel }), _jsx(Socials, { items: socials, onNavigate: close })] })), themeToggle && hasSocials && _jsx("span", { className: "flex-1" }), themeToggle && (_jsxs(_Fragment, { children: [_jsx(Small, { className: "opacity-50", children: themeLabel }), _jsx(ThemeToggle, {})] }))] }))] }) })) })] }));
|
|
20
36
|
}
|
|
37
|
+
function BrandCell({ brand, href, LinkComponent }) {
|
|
38
|
+
return isExternal(href) ? (_jsx(Cell, { href: href, ...EXTERNAL_REL, as: "a", children: brand })) : (_jsx(Cell, { as: LinkComponent, href: href, children: brand }));
|
|
39
|
+
}
|
|
40
|
+
function BrandLink({ brand, href, LinkComponent, onClick }) {
|
|
41
|
+
if (isExternal(href)) {
|
|
42
|
+
return (_jsx("a", { href: href, onClick: onClick, ...EXTERNAL_REL, children: brand }));
|
|
43
|
+
}
|
|
44
|
+
return createElement(LinkComponent, { href, onClick }, brand);
|
|
45
|
+
}
|
|
46
|
+
function NavCell({ link, LinkComponent, scramble }) {
|
|
47
|
+
const ref = useRef(null);
|
|
48
|
+
const isExt = link.external ?? isExternal(link.href);
|
|
49
|
+
const inner = (_jsxs(_Fragment, { children: [_jsxs(Small, { children: [scramble ? (_jsx(Scramble, { target: ref, children: link.label })) : (link.label), _jsx(Blink, {})] }), _jsx(HoverBg, {})] }));
|
|
50
|
+
if (isExt) {
|
|
51
|
+
return (_jsx(Cell, { as: "a", className: "group relative cursor-pointer", href: link.href, onClick: link.onClick, ref: ref, ...EXTERNAL_REL, children: inner }));
|
|
52
|
+
}
|
|
53
|
+
return (_jsx(Cell, { as: LinkComponent, className: "group relative cursor-pointer", href: link.href, onClick: link.onClick, ref: ref, children: inner }));
|
|
54
|
+
}
|
|
55
|
+
function MobileNavLink({ link, LinkComponent, onNavigate, scramble }) {
|
|
56
|
+
const ref = useRef(null);
|
|
57
|
+
const isExt = link.external ?? isExternal(link.href);
|
|
58
|
+
const className = cn('group relative flex cursor-pointer items-center border-b border-current/20 p-4');
|
|
59
|
+
const onClick = (e) => {
|
|
60
|
+
link.onClick?.(e);
|
|
61
|
+
onNavigate();
|
|
62
|
+
};
|
|
63
|
+
const children = (_jsxs(_Fragment, { children: [_jsxs(Small, { children: [scramble ? (_jsx(Scramble, { target: ref, children: link.label })) : (link.label), _jsx(Blink, {})] }), _jsx(HoverBg, {})] }));
|
|
64
|
+
if (isExt) {
|
|
65
|
+
return (_jsx("a", { className: className, href: link.href, onClick: onClick, ref: ref, ...EXTERNAL_REL, children: children }));
|
|
66
|
+
}
|
|
67
|
+
return createElement(LinkComponent, { className, href: link.href, onClick, ref }, children);
|
|
68
|
+
}
|
|
69
|
+
const EXTERNAL_REL = {
|
|
70
|
+
rel: 'noopener noreferrer',
|
|
71
|
+
target: '_blank'
|
|
72
|
+
};
|
|
73
|
+
const isExternal = (href) => /^(https?:|mailto:|tel:)/i.test(href);
|
|
21
74
|
//# sourceMappingURL=header.js.map
|
package/dist/ui/header.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"header.js","sourceRoot":"","sources":["../../src/ui/header.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAC/C,OAAO,EAAE,EAAE,EAAE,MAAM,4BAA4B,CAAA;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAA;AAErD,MAAM,GAAG,GAAG;IACV,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE;IACxC,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE;IAChD,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE;IAC5C,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE;CAC7C,CAAA;AAED,MAAM,UAAU,MAAM,CAAC,EAAE,aAAa,GAAG,GAAG,EAAe;IACzD,MAAM,GAAG,GAAG,MAAM,CAAc,IAAI,CAAC,CAAA;IACrC,aAAa,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;IAE5B,OAAO,CACL,MAAC,IAAI,IAAC,EAAE,EAAC,QAAQ,EAAO,GAAG,aACzB,KAAC,IAAI,IAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAC,GAAG,YAC/B,kBAAQ,SAAS,EAAC,qBAAqB,aACrC,KAAC,KAAK,uBAAa,EACnB,KAAC,EAAE,yBAAY,IACR,GACJ,EAEN,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAC5B,MAAC,IAAI,IACH,EAAE,EAAE,aAAa,EACjB,SAAS,EAAC,gBAAgB,EAEpB,IAAI,EAAE,OAAO,aAEnB,MAAC,KAAK,eACH,KAAK,EACN,KAAC,KAAK,KAAG,IACH,EAER,KAAC,OAAO,KAAG,KARN,IAAI,CASJ,CACR,CAAC,IACG,CACR,CAAA;AACH,CAAC","sourcesContent":["'use client'\n\nimport { useRef } from 'react'\n\nimport { useCssVarDims } from '../hooks/use-css-var-dims'\nimport { Blink } from './components/blink'\nimport { Cell, Grid } from './components/grid'\nimport { HoverBg } from './components/hover-bg'\nimport { H2 } from './components/typography/h2'\nimport { Small } from './components/typography/small'\n\nconst NAV = [\n { href: '/projects', label: 'Projects' },\n { href: '/participants', label: 'Participants' },\n { href: '/provenance', label: 'Provenance' },\n { href: '/contribute', label: 'Contribute' }\n]\n\nexport function Header({ LinkComponent = 'a' }: HeaderProps) {\n const ref = useRef<HTMLElement>(null)\n useCssVarDims('header', ref)\n\n return (\n <Grid as=\"header\" {...{ ref }}>\n <Cell as={LinkComponent} href=\"/\">\n <hgroup className=\"flex flex-col gap-2\">\n <Small>Nous</Small>\n <H2>Psyche</H2>\n </hgroup>\n </Cell>\n\n {NAV.map(({ href, label }) => (\n <Cell\n as={LinkComponent}\n className=\"group relative\"\n key={href}\n {...{ href: '/runs' }}\n >\n <Small>\n {label}\n <Blink />\n </Small>\n\n <HoverBg />\n </Cell>\n ))}\n </Grid>\n )\n}\n\ninterface HeaderProps {\n LinkComponent?: React.ElementType\n}\n"]}
|
|
1
|
+
{"version":3,"file":"header.js","sourceRoot":"","sources":["../../src/ui/header.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport { AnimatePresence, motion } from 'motion/react'\nimport { createElement, useCallback, useRef, useState } from 'react'\n\nimport { useCssVarDims } from '../hooks/use-css-var-dims'\nimport { useGpuTier } from '../hooks/use-gpu-tier'\nimport { cn } from '../utils'\n\nimport { Blink } from './components/blink'\nimport { Cell, Grid } from './components/grid'\nimport { HoverBg } from './components/hover-bg'\nimport { HamburgerIcon } from './components/icons/hamburger'\nimport { Scramble } from './components/scramble'\nimport { Socials, type SocialLink } from './components/socials'\nimport { ThemeToggle } from './components/theme-toggle'\nimport { H2 } from './components/typography/h2'\nimport { Small } from './components/typography/small'\n\nconst DEFAULT_BRAND = (\n <hgroup className=\"flex flex-col gap-2\">\n <Small>Nous</Small>\n\n <H2>Research</H2>\n </hgroup>\n)\n\nconst DEFAULT_LINKS: HeaderLink[] = [\n { href: '/projects', label: 'Projects' },\n { href: '/participants', label: 'Participants' },\n { href: '/provenance', label: 'Provenance' },\n { href: '/contribute', label: 'Contribute' }\n]\n\nexport function Header({\n brand = DEFAULT_BRAND,\n brandHref = '/',\n className,\n desktopGridStyle,\n links = DEFAULT_LINKS,\n LinkComponent = 'a',\n scramble: scrambleProp = true,\n socials,\n socialsLabel = 'Socials',\n style,\n themeLabel = 'Theme',\n themeToggle = false\n}: HeaderProps) {\n const ref = useRef<HTMLElement>(null)\n useCssVarDims('header', ref)\n\n // Skip the hover-Scramble rAF loop on tier-0 devices (no GPU / software\n // renderer / `prefers-reduced-motion: reduce`) regardless of the prop.\n const gpuTier = useGpuTier()\n const scramble = scrambleProp && gpuTier > 0\n\n const [open, setOpen] = useState(false)\n const close = useCallback(() => setOpen(false), [])\n\n const hasSocials = (socials?.length ?? 0) > 0\n const hasMobileChrome = themeToggle || hasSocials\n\n return (\n <header className={className} ref={ref} style={style}>\n <Grid\n className=\"hidden border-t border-b lg:grid\"\n style={desktopGridStyle}\n >\n <BrandCell\n brand={brand}\n href={brandHref}\n LinkComponent={LinkComponent}\n />\n\n {links.map(link => (\n <NavCell\n key={link.href}\n link={link}\n LinkComponent={LinkComponent}\n scramble={scramble}\n />\n ))}\n\n {hasSocials && (\n <Cell className=\"flex items-start justify-between\">\n <Small className=\"opacity-50\">{socialsLabel}</Small>\n\n <Socials items={socials!} />\n </Cell>\n )}\n\n {themeToggle && (\n <Cell className=\"flex items-start justify-between\">\n <Small className=\"opacity-50\">{themeLabel}</Small>\n\n <ThemeToggle />\n </Cell>\n )}\n </Grid>\n\n <div\n className={cn(\n 'flex items-center justify-between border border-current/20 p-4',\n 'lg:hidden'\n )}\n >\n <BrandLink\n brand={brand}\n href={brandHref}\n LinkComponent={LinkComponent}\n />\n\n <div className=\"flex items-center gap-3\">\n {themeToggle && <ThemeToggle />}\n\n <button\n aria-label={open ? 'Close menu' : 'Open menu'}\n className=\"relative z-50 cursor-pointer bg-transparent p-2\"\n onClick={() => setOpen(v => !v)}\n type=\"button\"\n >\n <HamburgerIcon open={open} />\n </button>\n </div>\n </div>\n\n <AnimatePresence>\n {open && (\n <motion.div\n animate={{ opacity: 1 }}\n className={cn(\n 'bg-background/95 fixed inset-0 z-50 flex flex-col backdrop-blur-sm',\n 'p-8 lg:hidden'\n )}\n exit={{ opacity: 0 }}\n initial={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n >\n <div className=\"flex flex-col border border-current/20\">\n <div className=\"flex items-center justify-between border-b border-current/20 p-4\">\n <BrandLink\n brand={brand}\n href={brandHref}\n LinkComponent={LinkComponent}\n onClick={close}\n />\n\n <button\n aria-label=\"Close menu\"\n className=\"cursor-pointer bg-transparent p-2\"\n onClick={close}\n type=\"button\"\n >\n <HamburgerIcon open />\n </button>\n </div>\n\n {links.map(link => (\n <MobileNavLink\n key={link.href}\n link={link}\n LinkComponent={LinkComponent}\n onNavigate={close}\n scramble={scramble}\n />\n ))}\n\n {hasMobileChrome && (\n <div className=\"flex items-center gap-3 border-b border-current/20 p-4\">\n {hasSocials && (\n <>\n <Small className=\"opacity-50\">{socialsLabel}</Small>\n\n <Socials items={socials!} onNavigate={close} />\n </>\n )}\n\n {themeToggle && hasSocials && <span className=\"flex-1\" />}\n\n {themeToggle && (\n <>\n <Small className=\"opacity-50\">{themeLabel}</Small>\n\n <ThemeToggle />\n </>\n )}\n </div>\n )}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </header>\n )\n}\n\nfunction BrandCell({ brand, href, LinkComponent }: BrandSlotProps) {\n return isExternal(href) ? (\n <Cell href={href} {...EXTERNAL_REL} as=\"a\">\n {brand}\n </Cell>\n ) : (\n <Cell as={LinkComponent} href={href}>\n {brand}\n </Cell>\n )\n}\n\nfunction BrandLink({ brand, href, LinkComponent, onClick }: BrandLinkProps) {\n if (isExternal(href)) {\n return (\n <a href={href} onClick={onClick} {...EXTERNAL_REL}>\n {brand}\n </a>\n )\n }\n\n return createElement(\n LinkComponent,\n { href, onClick } as Record<string, unknown>,\n brand\n )\n}\n\nfunction NavCell({ link, LinkComponent, scramble }: NavCellProps) {\n const ref = useRef<HTMLAnchorElement>(null)\n const isExt = link.external ?? isExternal(link.href)\n\n const inner = (\n <>\n <Small>\n {scramble ? (\n <Scramble target={ref}>{link.label}</Scramble>\n ) : (\n link.label\n )}\n\n <Blink />\n </Small>\n\n <HoverBg />\n </>\n )\n\n if (isExt) {\n return (\n <Cell\n as=\"a\"\n className=\"group relative cursor-pointer\"\n href={link.href}\n onClick={link.onClick}\n ref={ref}\n {...EXTERNAL_REL}\n >\n {inner}\n </Cell>\n )\n }\n\n return (\n <Cell\n as={LinkComponent}\n className=\"group relative cursor-pointer\"\n href={link.href}\n onClick={link.onClick}\n ref={ref}\n >\n {inner}\n </Cell>\n )\n}\n\nfunction MobileNavLink({\n link,\n LinkComponent,\n onNavigate,\n scramble\n}: MobileNavLinkProps) {\n const ref = useRef<HTMLAnchorElement>(null)\n const isExt = link.external ?? isExternal(link.href)\n\n const className = cn(\n 'group relative flex cursor-pointer items-center border-b border-current/20 p-4'\n )\n\n const onClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n link.onClick?.(e)\n onNavigate()\n }\n\n const children = (\n <>\n <Small>\n {scramble ? (\n <Scramble target={ref}>{link.label}</Scramble>\n ) : (\n link.label\n )}\n\n <Blink />\n </Small>\n\n <HoverBg />\n </>\n )\n\n if (isExt) {\n return (\n <a\n className={className}\n href={link.href}\n onClick={onClick}\n ref={ref}\n {...EXTERNAL_REL}\n >\n {children}\n </a>\n )\n }\n\n return createElement(\n LinkComponent,\n { className, href: link.href, onClick, ref } as Record<string, unknown>,\n children\n )\n}\n\nconst EXTERNAL_REL = {\n rel: 'noopener noreferrer',\n target: '_blank'\n} as const\n\nconst isExternal = (href: string) => /^(https?:|mailto:|tel:)/i.test(href)\n\ninterface BrandLinkProps extends BrandSlotProps {\n onClick?: React.MouseEventHandler\n}\n\ninterface BrandSlotProps {\n brand: React.ReactNode\n href: string\n LinkComponent: React.ElementType\n}\n\nexport interface HeaderLink {\n external?: boolean\n href: string\n label: string\n onClick?: React.MouseEventHandler\n}\n\nexport interface HeaderProps {\n brand?: React.ReactNode\n brandHref?: string\n className?: string\n /**\n * Inline `style` for the desktop `Grid` only — useful for overriding\n * `grid-template-columns` (e.g. to align with a sidebar track) without\n * affecting the mobile bar or drawer.\n */\n desktopGridStyle?: React.CSSProperties\n links?: HeaderLink[]\n LinkComponent?: React.ElementType\n /**\n * Apply the hover-Scramble effect to nav link labels. Defaults to `true`,\n * automatically suppressed on tier-0 GPUs and when the user has\n * `prefers-reduced-motion: reduce`.\n */\n scramble?: boolean\n /**\n * Optional socials shown in a trailing chrome cell on desktop and in the\n * mobile drawer's chrome row. For nav-heavy products (≥ 5 links) prefer\n * passing socials to `<Footer>` instead — the desktop `Grid` only ships\n * column rules through `grid-cols-6`, so brand + many links + chrome can\n * overflow.\n */\n socials?: SocialLink[]\n socialsLabel?: string\n style?: React.CSSProperties\n themeLabel?: string\n themeToggle?: boolean\n}\n\n/** @deprecated Use `SocialLink` from `@nous-research/ui`. Same shape. */\nexport type HeaderSocial = SocialLink\n\ninterface MobileNavLinkProps {\n link: HeaderLink\n LinkComponent: React.ElementType\n onNavigate: () => void\n scramble: boolean\n}\n\ninterface NavCellProps {\n link: HeaderLink\n LinkComponent: React.ElementType\n scramble: boolean\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nous-research/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"sideEffects": [
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"@vitejs/plugin-react": "^5.0.0",
|
|
63
63
|
"gsap": "^3.13.0",
|
|
64
64
|
"leva": "^0.10.1",
|
|
65
|
+
"motion": "^12.38.0",
|
|
65
66
|
"storybook": "^10.3.1",
|
|
66
67
|
"tailwindcss": "^4",
|
|
67
68
|
"three": "^0.180.0",
|
|
@@ -73,6 +74,7 @@
|
|
|
73
74
|
"@react-three/fiber": "^9.4.0",
|
|
74
75
|
"gsap": "^3.13.0",
|
|
75
76
|
"leva": "^0.10.1",
|
|
77
|
+
"motion": "^12.38.0",
|
|
76
78
|
"react": "^19.0.0",
|
|
77
79
|
"react-dom": "^19.0.0",
|
|
78
80
|
"three": "^0.180.0"
|