@nous-research/ui 0.3.0 → 0.4.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 CHANGED
@@ -6,6 +6,7 @@ export { BlendMode, useBlendMode, withBlendMode } from './ui/components/blend-mo
6
6
  export type { BlendModeProps } from './ui/components/blend-mode';
7
7
  export { Blink } from './ui/components/blink';
8
8
  export { Button } from './ui/components/button';
9
+ export { CommandBlock, CopyButton } from './ui/components/command-block';
9
10
  export { Cursor } from './ui/components/cursor';
10
11
  export { DropdownMenu } from './ui/components/dropdown-menu';
11
12
  export { FitText } from './ui/components/fit-text';
@@ -13,6 +14,7 @@ export { BarChart, LineChart } from './ui/components/graphs';
13
14
  export { Cell, Grid } from './ui/components/grid';
14
15
  export { HoverBg } from './ui/components/hover-bg';
15
16
  export * as Icons from './ui/components/icons';
17
+ export { ImageDistortion } from './ui/components/image-distortion';
16
18
  export { LevaClient } from './ui/components/leva-client';
17
19
  export { Modal } from './ui/components/modal';
18
20
  export { applyLens, LENSES, LENS_0, LENS_5I, toggleLens, $lightMode } from './ui/components/overlays';
@@ -23,6 +25,9 @@ export { SceneCanvas } from './ui/components/scene-canvas';
23
25
  export { Scramble } from './ui/components/scramble';
24
26
  export { SelectionSwitcher } from './ui/components/selection-switcher';
25
27
  export { Stats } from './ui/components/stats';
28
+ export { TerminalDemo } from './ui/components/terminal-demo';
29
+ export type { TerminalDemoStep } from './ui/components/terminal-demo';
30
+ export { ThemeToggle } from './ui/components/theme-toggle';
26
31
  export { TV } from './ui/components/tv';
27
32
  export { Watchlist } from './ui/components/watchlist';
28
33
  export { Typography } from './ui/components/typography';
@@ -42,5 +47,6 @@ export type { PolyComponent, PolyProps, PolyRef } from './utils';
42
47
  export { hexToRgb, rgbToHex, colorDodge, colorMix } from './utils/color';
43
48
  export { useCappedFrame } from './hooks/use-capped-frame';
44
49
  export { useCssVarDims } from './hooks/use-css-var-dims';
50
+ export { $gpuTier, useGpuTier } from './hooks/use-gpu-tier';
45
51
  export { useSmoothControls, getControlAtom, setControlValue } from './hooks/use-smooth-controls';
46
52
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,4 +1,3 @@
1
- // Components
2
1
  export { AnimatedCount, useAnimatedCount } from './ui/components/animated-count';
3
2
  export { AsciiSkeleton, Scramble as AsciiScramble } from './ui/components/ascii';
4
3
  export { Badge } from './ui/components/badge';
@@ -6,6 +5,7 @@ export { NouseGirlBadge } from './ui/components/badges/nous-girl';
6
5
  export { BlendMode, useBlendMode, withBlendMode } from './ui/components/blend-mode';
7
6
  export { Blink } from './ui/components/blink';
8
7
  export { Button } from './ui/components/button';
8
+ export { CommandBlock, CopyButton } from './ui/components/command-block';
9
9
  export { Cursor } from './ui/components/cursor';
10
10
  export { DropdownMenu } from './ui/components/dropdown-menu';
11
11
  export { FitText } from './ui/components/fit-text';
@@ -13,6 +13,7 @@ export { BarChart, LineChart } from './ui/components/graphs';
13
13
  export { Cell, Grid } from './ui/components/grid';
14
14
  export { HoverBg } from './ui/components/hover-bg';
15
15
  export * as Icons from './ui/components/icons';
16
+ export { ImageDistortion } from './ui/components/image-distortion';
16
17
  export { LevaClient } from './ui/components/leva-client';
17
18
  export { Modal } from './ui/components/modal';
18
19
  export { applyLens, LENSES, LENS_0, LENS_5I, toggleLens, $lightMode } from './ui/components/overlays';
@@ -22,27 +23,25 @@ export { SceneCanvas } from './ui/components/scene-canvas';
22
23
  export { Scramble } from './ui/components/scramble';
23
24
  export { SelectionSwitcher } from './ui/components/selection-switcher';
24
25
  export { Stats } from './ui/components/stats';
26
+ export { TerminalDemo } from './ui/components/terminal-demo';
27
+ export { ThemeToggle } from './ui/components/theme-toggle';
25
28
  export { TV } from './ui/components/tv';
26
29
  export { Watchlist } from './ui/components/watchlist';
27
- // Typography
28
30
  export { Typography } from './ui/components/typography';
29
31
  export { H1 } from './ui/components/typography/h1';
30
32
  export { H2 } from './ui/components/typography/h2';
31
33
  export { Legend } from './ui/components/typography/legend';
32
34
  export { Small } from './ui/components/typography/small';
33
- // Layout
34
35
  export { BasicPage } from './ui/basic-page';
35
36
  export { Header } from './ui/header';
36
37
  export { Footer } from './ui/footer';
37
38
  export { LayoutWrapper } from './ui/layout-wrapper';
38
- // Fonts
39
39
  export { FONT_SANS, FONT_MONO, FONT_RULES_COMPRESSED, FONT_RULES_EXPANDED, FONT_MONDWEST } from './fonts';
40
- // Utils
41
40
  export { cn, clamp, smoothstep, hexToVec3, truncate, stripWpStyles } from './utils';
42
41
  export { polyRef } from './utils';
43
42
  export { hexToRgb, rgbToHex, colorDodge, colorMix } from './utils/color';
44
- // Hooks
45
43
  export { useCappedFrame } from './hooks/use-capped-frame';
46
44
  export { useCssVarDims } from './hooks/use-css-var-dims';
45
+ export { $gpuTier, useGpuTier } from './hooks/use-gpu-tier';
47
46
  export { useSmoothControls, getControlAtom, setControlValue } from './hooks/use-smooth-controls';
48
47
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Components\nexport { AnimatedCount, useAnimatedCount } from './ui/components/animated-count'\nexport { AsciiSkeleton, Scramble as AsciiScramble } from './ui/components/ascii'\nexport { Badge } from './ui/components/badge'\nexport { NouseGirlBadge } from './ui/components/badges/nous-girl'\nexport { BlendMode, useBlendMode, withBlendMode } from './ui/components/blend-mode'\nexport type { BlendModeProps } from './ui/components/blend-mode'\nexport { Blink } from './ui/components/blink'\nexport { Button } from './ui/components/button'\nexport { Cursor } from './ui/components/cursor'\nexport { DropdownMenu } from './ui/components/dropdown-menu'\nexport { FitText } from './ui/components/fit-text'\nexport { BarChart, LineChart } from './ui/components/graphs'\nexport { Cell, Grid } from './ui/components/grid'\nexport { HoverBg } from './ui/components/hover-bg'\nexport * as Icons from './ui/components/icons'\nexport { LevaClient } from './ui/components/leva-client'\nexport { Modal } from './ui/components/modal'\nexport {\n applyLens,\n LENSES,\n LENS_0,\n LENS_5I,\n toggleLens,\n $lightMode\n} from './ui/components/overlays'\nexport { Overlays } from './ui/components/overlays'\nexport type { LensPreset } from './ui/components/overlays'\nexport { Progress } from './ui/components/progress'\nexport { SceneCanvas } from './ui/components/scene-canvas'\nexport { Scramble } from './ui/components/scramble'\nexport { SelectionSwitcher } from './ui/components/selection-switcher'\nexport { Stats } from './ui/components/stats'\nexport { TV } from './ui/components/tv'\nexport { Watchlist } from './ui/components/watchlist'\n\n// Typography\nexport { Typography } from './ui/components/typography'\nexport type { TypographyProps } from './ui/components/typography'\nexport { H1 } from './ui/components/typography/h1'\nexport { H2 } from './ui/components/typography/h2'\nexport { Legend } from './ui/components/typography/legend'\nexport { Small } from './ui/components/typography/small'\n\n// Layout\nexport { BasicPage } from './ui/basic-page'\nexport { Header } from './ui/header'\nexport { Footer } from './ui/footer'\nexport { LayoutWrapper } from './ui/layout-wrapper'\n\n// Fonts\nexport {\n FONT_SANS,\n FONT_MONO,\n FONT_RULES_COMPRESSED,\n FONT_RULES_EXPANDED,\n FONT_MONDWEST\n} from './fonts'\n\n// Utils\nexport { cn, clamp, smoothstep, hexToVec3, truncate, stripWpStyles } from './utils'\nexport { polyRef } from './utils'\nexport type { PolyComponent, PolyProps, PolyRef } from './utils'\nexport { hexToRgb, rgbToHex, colorDodge, colorMix } from './utils/color'\n\n// Hooks\nexport { useCappedFrame } from './hooks/use-capped-frame'\nexport { useCssVarDims } from './hooks/use-css-var-dims'\nexport {\n useSmoothControls,\n getControlAtom,\n setControlValue\n} from './hooks/use-smooth-controls'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export { AnimatedCount, useAnimatedCount } from './ui/components/animated-count'\nexport { AsciiSkeleton, Scramble as AsciiScramble } from './ui/components/ascii'\nexport { Badge } from './ui/components/badge'\nexport { NouseGirlBadge } from './ui/components/badges/nous-girl'\nexport { BlendMode, useBlendMode, withBlendMode } from './ui/components/blend-mode'\nexport type { BlendModeProps } from './ui/components/blend-mode'\nexport { Blink } from './ui/components/blink'\nexport { Button } from './ui/components/button'\nexport { CommandBlock, CopyButton } from './ui/components/command-block'\nexport { Cursor } from './ui/components/cursor'\nexport { DropdownMenu } from './ui/components/dropdown-menu'\nexport { FitText } from './ui/components/fit-text'\nexport { BarChart, LineChart } from './ui/components/graphs'\nexport { Cell, Grid } from './ui/components/grid'\nexport { HoverBg } from './ui/components/hover-bg'\nexport * as Icons from './ui/components/icons'\nexport { ImageDistortion } from './ui/components/image-distortion'\nexport { LevaClient } from './ui/components/leva-client'\nexport { Modal } from './ui/components/modal'\nexport {\n applyLens,\n LENSES,\n LENS_0,\n LENS_5I,\n toggleLens,\n $lightMode\n} from './ui/components/overlays'\nexport { Overlays } from './ui/components/overlays'\nexport type { LensPreset } from './ui/components/overlays'\nexport { Progress } from './ui/components/progress'\nexport { SceneCanvas } from './ui/components/scene-canvas'\nexport { Scramble } from './ui/components/scramble'\nexport { SelectionSwitcher } from './ui/components/selection-switcher'\nexport { Stats } from './ui/components/stats'\nexport { TerminalDemo } from './ui/components/terminal-demo'\nexport type { TerminalDemoStep } from './ui/components/terminal-demo'\nexport { ThemeToggle } from './ui/components/theme-toggle'\nexport { TV } from './ui/components/tv'\nexport { Watchlist } from './ui/components/watchlist'\n\nexport { Typography } from './ui/components/typography'\nexport type { TypographyProps } from './ui/components/typography'\nexport { H1 } from './ui/components/typography/h1'\nexport { H2 } from './ui/components/typography/h2'\nexport { Legend } from './ui/components/typography/legend'\nexport { Small } from './ui/components/typography/small'\n\nexport { BasicPage } from './ui/basic-page'\nexport { Header } from './ui/header'\nexport { Footer } from './ui/footer'\nexport { LayoutWrapper } from './ui/layout-wrapper'\n\nexport {\n FONT_SANS,\n FONT_MONO,\n FONT_RULES_COMPRESSED,\n FONT_RULES_EXPANDED,\n FONT_MONDWEST\n} from './fonts'\n\nexport { cn, clamp, smoothstep, hexToVec3, truncate, stripWpStyles } from './utils'\nexport { polyRef } from './utils'\nexport type { PolyComponent, PolyProps, PolyRef } from './utils'\nexport { hexToRgb, rgbToHex, colorDodge, colorMix } from './utils/color'\n\nexport { useCappedFrame } from './hooks/use-capped-frame'\nexport { useCssVarDims } from './hooks/use-css-var-dims'\nexport { $gpuTier, useGpuTier } from './hooks/use-gpu-tier'\nexport {\n useSmoothControls,\n getControlAtom,\n setControlValue\n} from './hooks/use-smooth-controls'\n"]}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * A "copy to clipboard" button that briefly shows a "Copied!" confirmation.
3
+ * Designed to sit alongside a short command string, not as a general button.
4
+ */
5
+ export declare function CopyButton({ children, className, copiedLabel, label, resetDelayMs, text }: CopyButtonProps): import("react/jsx-runtime").JSX.Element;
6
+ /**
7
+ * A labeled, copy-able command (or code) display. Pairs `<CopyButton>` with
8
+ * a monospace code block. Used for install/setup instructions.
9
+ */
10
+ export declare function CommandBlock({ className, code, label }: CommandBlockProps): import("react/jsx-runtime").JSX.Element;
11
+ interface CommandBlockProps {
12
+ className?: string;
13
+ code: string;
14
+ label: string;
15
+ }
16
+ interface CopyButtonProps {
17
+ children?: React.ReactNode;
18
+ className?: string;
19
+ copiedLabel?: string;
20
+ label?: string;
21
+ resetDelayMs?: number;
22
+ text: string;
23
+ }
24
+ export {};
25
+ //# sourceMappingURL=command-block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-block.d.ts","sourceRoot":"","sources":["../../../src/ui/components/command-block.tsx"],"names":[],"mappings":"AAQA;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,WAAuB,EACvB,KAAc,EACd,YAAmB,EACnB,IAAI,EACL,EAAE,eAAe,2CA0BjB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,iBAAiB,2CAmBzE;AAED,UAAU,iBAAiB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd;AAED,UAAU,eAAe;IACvB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,IAAI,EAAE,MAAM,CAAA;CACb"}
@@ -0,0 +1,27 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useCallback, useState } from 'react';
4
+ import { cn } from '../../utils';
5
+ import { Small } from './typography/small';
6
+ /**
7
+ * A "copy to clipboard" button that briefly shows a "Copied!" confirmation.
8
+ * Designed to sit alongside a short command string, not as a general button.
9
+ */
10
+ export function CopyButton({ children, className, copiedLabel = 'Copied!', label = 'Copy', resetDelayMs = 2000, text }) {
11
+ const [copied, setCopied] = useState(false);
12
+ const handleCopy = useCallback(() => {
13
+ void navigator.clipboard.writeText(text).then(() => {
14
+ setCopied(true);
15
+ setTimeout(() => setCopied(false), resetDelayMs);
16
+ });
17
+ }, [resetDelayMs, text]);
18
+ return (_jsx("button", { className: cn('font-courier cursor-pointer border-none bg-transparent text-[0.6875rem]', 'tracking-widest uppercase', 'hover:text-midground tap-highlight-transparent transition-colors', 'flex items-center justify-center', copied ? 'text-midground' : 'text-current opacity-60', className), onClick: handleCopy, type: "button", children: children ?? (copied ? copiedLabel : label) }));
19
+ }
20
+ /**
21
+ * A labeled, copy-able command (or code) display. Pairs `<CopyButton>` with
22
+ * a monospace code block. Used for install/setup instructions.
23
+ */
24
+ export function CommandBlock({ className, code, label }) {
25
+ return (_jsxs("div", { className: cn('flex flex-col gap-1', className), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Small, { className: "opacity-50", children: label }), _jsx(CopyButton, { text: code })] }), _jsx("div", { className: cn('bg-background/40 font-courier border border-current/20', 'px-3 py-2 text-[0.6875rem] leading-relaxed lowercase'), children: _jsx("code", { className: "break-all", children: code }) })] }));
26
+ }
27
+ //# sourceMappingURL=command-block.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-block.js","sourceRoot":"","sources":["../../../src/ui/components/command-block.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAE7C,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAEhC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAE1C;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,WAAW,GAAG,SAAS,EACvB,KAAK,GAAG,MAAM,EACd,YAAY,GAAG,IAAI,EACnB,IAAI,EACY;IAChB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAE3C,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;QAClC,KAAK,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;YACjD,SAAS,CAAC,IAAI,CAAC,CAAA;YACf,UAAU,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC,CAAA;QAClD,CAAC,CAAC,CAAA;IACJ,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,CAAA;IAExB,OAAO,CACL,iBACE,SAAS,EAAE,EAAE,CACX,yEAAyE,EACzE,2BAA2B,EAC3B,kEAAkE,EAClE,kCAAkC,EAClC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,yBAAyB,EACrD,SAAS,CACV,EACD,OAAO,EAAE,UAAU,EACnB,IAAI,EAAC,QAAQ,YAEZ,QAAQ,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,GACpC,CACV,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAqB;IACxE,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,qBAAqB,EAAE,SAAS,CAAC,aAClD,eAAK,SAAS,EAAC,mCAAmC,aAChD,KAAC,KAAK,IAAC,SAAS,EAAC,YAAY,YAAE,KAAK,GAAS,EAE7C,KAAC,UAAU,IAAC,IAAI,EAAE,IAAI,GAAI,IACtB,EAEN,cACE,SAAS,EAAE,EAAE,CACX,wDAAwD,EACxD,sDAAsD,CACvD,YAED,eAAM,SAAS,EAAC,WAAW,YAAE,IAAI,GAAQ,GACrC,IACF,CACP,CAAA;AACH,CAAC","sourcesContent":["'use client'\n\nimport { useCallback, useState } from 'react'\n\nimport { cn } from '../../utils'\n\nimport { Small } from './typography/small'\n\n/**\n * A \"copy to clipboard\" button that briefly shows a \"Copied!\" confirmation.\n * Designed to sit alongside a short command string, not as a general button.\n */\nexport function CopyButton({\n children,\n className,\n copiedLabel = 'Copied!',\n label = 'Copy',\n resetDelayMs = 2000,\n text\n}: CopyButtonProps) {\n const [copied, setCopied] = useState(false)\n\n const handleCopy = useCallback(() => {\n void navigator.clipboard.writeText(text).then(() => {\n setCopied(true)\n setTimeout(() => setCopied(false), resetDelayMs)\n })\n }, [resetDelayMs, text])\n\n return (\n <button\n className={cn(\n 'font-courier cursor-pointer border-none bg-transparent text-[0.6875rem]',\n 'tracking-widest uppercase',\n 'hover:text-midground tap-highlight-transparent transition-colors',\n 'flex items-center justify-center',\n copied ? 'text-midground' : 'text-current opacity-60',\n className\n )}\n onClick={handleCopy}\n type=\"button\"\n >\n {children ?? (copied ? copiedLabel : label)}\n </button>\n )\n}\n\n/**\n * A labeled, copy-able command (or code) display. Pairs `<CopyButton>` with\n * a monospace code block. Used for install/setup instructions.\n */\nexport function CommandBlock({ className, code, label }: CommandBlockProps) {\n return (\n <div className={cn('flex flex-col gap-1', className)}>\n <div className=\"flex items-center justify-between\">\n <Small className=\"opacity-50\">{label}</Small>\n\n <CopyButton text={code} />\n </div>\n\n <div\n className={cn(\n 'bg-background/40 font-courier border border-current/20',\n 'px-3 py-2 text-[0.6875rem] leading-relaxed lowercase'\n )}\n >\n <code className=\"break-all\">{code}</code>\n </div>\n </div>\n )\n}\n\ninterface CommandBlockProps {\n className?: string\n code: string\n label: string\n}\n\ninterface CopyButtonProps {\n children?: React.ReactNode\n className?: string\n copiedLabel?: string\n label?: string\n resetDelayMs?: number\n text: string\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import type { SVGProps } from 'react';
2
+ export declare function HamburgerIcon({ className, open, ...props }: HamburgerIconProps): import("react/jsx-runtime").JSX.Element;
3
+ interface HamburgerIconProps extends SVGProps<SVGSVGElement> {
4
+ open?: boolean;
5
+ }
6
+ export {};
7
+ //# sourceMappingURL=hamburger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hamburger.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/icons/hamburger.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAIrC,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,IAAY,EACZ,GAAG,KAAK,EACT,EAAE,kBAAkB,2CAuCpB;AAED,UAAU,kBAAmB,SAAQ,QAAQ,CAAC,aAAa,CAAC;IAC1D,IAAI,CAAC,EAAE,OAAO,CAAA;CACf"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../../../utils';
3
+ export function HamburgerIcon({ className, open = false, ...props }) {
4
+ return (_jsxs("svg", { className: cn('size-5', className), fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeWidth: 1.5, viewBox: "0 0 24 24", ...props, children: [_jsx("line", { className: "origin-center transition-transform duration-200 ease-out", style: { transform: open ? 'rotate(45deg)' : 'translateY(-4px)' }, x1: 4, x2: 20, y1: 12, y2: 12 }), _jsx("line", { className: "transition-opacity duration-200 ease-out", style: { opacity: open ? 0 : 1 }, x1: 4, x2: 20, y1: 12, y2: 12 }), _jsx("line", { className: "origin-center transition-transform duration-200 ease-out", style: { transform: open ? 'rotate(-45deg)' : 'translateY(4px)' }, x1: 4, x2: 20, y1: 12, y2: 12 })] }));
5
+ }
6
+ //# sourceMappingURL=hamburger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hamburger.js","sourceRoot":"","sources":["../../../../src/ui/components/icons/hamburger.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAA;AAEnC,MAAM,UAAU,aAAa,CAAC,EAC5B,SAAS,EACT,IAAI,GAAG,KAAK,EACZ,GAAG,KAAK,EACW;IACnB,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,EAClC,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,aAAa,EAAC,OAAO,EACrB,WAAW,EAAE,GAAG,EAChB,OAAO,EAAC,WAAW,KACf,KAAK,aAET,eACE,SAAS,EAAC,0DAA0D,EACpE,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,kBAAkB,EAAE,EACjE,EAAE,EAAE,CAAC,EACL,EAAE,EAAE,EAAE,EACN,EAAE,EAAE,EAAE,EACN,EAAE,EAAE,EAAE,GACN,EAEF,eACE,SAAS,EAAC,0CAA0C,EACpD,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAChC,EAAE,EAAE,CAAC,EACL,EAAE,EAAE,EAAE,EACN,EAAE,EAAE,EAAE,EACN,EAAE,EAAE,EAAE,GACN,EAEF,eACE,SAAS,EAAC,0DAA0D,EACpE,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,EAAE,EACjE,EAAE,EAAE,CAAC,EACL,EAAE,EAAE,EAAE,EACN,EAAE,EAAE,EAAE,EACN,EAAE,EAAE,EAAE,GACN,IACE,CACP,CAAA;AACH,CAAC","sourcesContent":["import type { SVGProps } from 'react'\n\nimport { cn } from '../../../utils'\n\nexport function HamburgerIcon({\n className,\n open = false,\n ...props\n}: HamburgerIconProps) {\n return (\n <svg\n className={cn('size-5', className)}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeWidth={1.5}\n viewBox=\"0 0 24 24\"\n {...props}\n >\n <line\n className=\"origin-center transition-transform duration-200 ease-out\"\n style={{ transform: open ? 'rotate(45deg)' : 'translateY(-4px)' }}\n x1={4}\n x2={20}\n y1={12}\n y2={12}\n />\n\n <line\n className=\"transition-opacity duration-200 ease-out\"\n style={{ opacity: open ? 0 : 1 }}\n x1={4}\n x2={20}\n y1={12}\n y2={12}\n />\n\n <line\n className=\"origin-center transition-transform duration-200 ease-out\"\n style={{ transform: open ? 'rotate(-45deg)' : 'translateY(4px)' }}\n x1={4}\n x2={20}\n y1={12}\n y2={12}\n />\n </svg>\n )\n}\n\ninterface HamburgerIconProps extends SVGProps<SVGSVGElement> {\n open?: boolean\n}\n"]}
@@ -2,6 +2,7 @@ export * from './arrow';
2
2
  export * from './chevron';
3
3
  export * from './eye';
4
4
  export * from './gear';
5
+ export * from './hamburger';
5
6
  export * from './heart';
6
7
  export * from './link';
7
8
  export * from './minus';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/icons/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,OAAO,CAAA;AACrB,cAAc,QAAQ,CAAA;AACtB,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/icons/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,OAAO,CAAA;AACrB,cAAc,QAAQ,CAAA;AACtB,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA"}
@@ -2,6 +2,7 @@ export * from './arrow';
2
2
  export * from './chevron';
3
3
  export * from './eye';
4
4
  export * from './gear';
5
+ export * from './hamburger';
5
6
  export * from './heart';
6
7
  export * from './link';
7
8
  export * from './minus';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/ui/components/icons/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,OAAO,CAAA;AACrB,cAAc,QAAQ,CAAA;AACtB,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA","sourcesContent":["export * from './arrow'\nexport * from './chevron'\nexport * from './eye'\nexport * from './gear'\nexport * from './heart'\nexport * from './link'\nexport * from './minus'\nexport * from './search'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/ui/components/icons/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,OAAO,CAAA;AACrB,cAAc,QAAQ,CAAA;AACtB,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA","sourcesContent":["export * from './arrow'\nexport * from './chevron'\nexport * from './eye'\nexport * from './gear'\nexport * from './hamburger'\nexport * from './heart'\nexport * from './link'\nexport * from './minus'\nexport * from './search'\n"]}
@@ -0,0 +1,15 @@
1
+ export declare function ImageDistortion({ active, className, fallbackClassName, src, style, tint, tintStrength }: ImageDistortionProps): import("react/jsx-runtime").JSX.Element;
2
+ interface ImageDistortionProps {
3
+ active?: boolean;
4
+ className?: string;
5
+ fallbackClassName?: string;
6
+ src: string;
7
+ style?: React.CSSProperties;
8
+ tint?: string;
9
+ tintStrength?: {
10
+ active: number;
11
+ inactive: number;
12
+ };
13
+ }
14
+ export {};
15
+ //# sourceMappingURL=image-distortion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-distortion.d.ts","sourceRoot":"","sources":["../../../src/ui/components/image-distortion.tsx"],"names":[],"mappings":"AAoGA,wBAAgB,eAAe,CAAC,EAC9B,MAAa,EACb,SAAS,EACT,iBAAiB,EACjB,GAAG,EACH,KAAK,EACL,IAAI,EACJ,YAAY,EACb,EAAE,oBAAoB,2CA4QtB;AAED,UAAU,oBAAoB;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CACpD"}
@@ -0,0 +1,278 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useEffect, useRef, useState } from 'react';
4
+ import { useGpuTier } from '../../hooks/use-gpu-tier';
5
+ import { cn, hexToRgb } from '../../utils';
6
+ const NUM_BANDS = 12;
7
+ const VERT = `attribute vec2 a;varying vec2 vUv;void main(){vUv=vec2(a.x*.5+.5,.5-a.y*.5);gl_Position=vec4(a,0,1);}`;
8
+ const FRAG = `precision highp float;
9
+ uniform float t;
10
+ uniform vec2 r,imgSize,vel;
11
+ uniform sampler2D tex;
12
+ uniform float bands[${NUM_BANDS}];
13
+ uniform vec3 tint;
14
+ uniform float tintStrength;
15
+ varying vec2 vUv;
16
+
17
+ float h(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}
18
+
19
+ // cover-style UV: crops the image to fill the canvas, centered
20
+ vec2 coverUV(vec2 uv){
21
+ float canvasAspect=r.x/r.y;
22
+ float imgAspect=imgSize.x/imgSize.y;
23
+ vec2 scale=canvasAspect>imgAspect
24
+ ?vec2(1.0,imgAspect/canvasAspect)
25
+ :vec2(canvasAspect/imgAspect,1.0);
26
+ return(uv-0.5)*scale+0.5;
27
+ }
28
+
29
+ void main(){
30
+ vec2 uv=coverUV(vUv);
31
+ float scanY=floor(vUv.y*r.y);
32
+
33
+ float bandF=vUv.y*${NUM_BANDS}.0;
34
+ int bandIdx=int(floor(bandF));
35
+ float bandFrac=fract(bandF);
36
+
37
+ float strength=0.0;
38
+ for(int i=0;i<${NUM_BANDS};i++){
39
+ if(i==bandIdx) strength=bands[i];
40
+ }
41
+
42
+ float neighborStr=0.0;
43
+ int neighborIdx=bandFrac>.5?bandIdx+1:bandIdx-1;
44
+ for(int i=0;i<${NUM_BANDS};i++){
45
+ if(i==neighborIdx) neighborStr=bands[i];
46
+ }
47
+ float edgeBlend=abs(bandFrac-.5)*2.0;
48
+ edgeBlend*=edgeBlend;
49
+ strength=mix(strength,neighborStr,edgeBlend*.3);
50
+
51
+ float speed=length(vel);
52
+ float dirBlend=smoothstep(0.0,0.02,speed);
53
+ vec2 dir=speed>.0001?vel/speed:vec2(0);
54
+ dir*=dirBlend;
55
+
56
+ float rowSeed=h(vec2(scanY,floor(t*3.)+float(bandIdx)*7.));
57
+ float rowVar=mix(.4,1.0,rowSeed);
58
+
59
+ float ySmooth=vUv.y*6.0+t*0.7;
60
+ float yNoise=mix(h(vec2(floor(ySmooth),13.)),h(vec2(floor(ySmooth)+1.0,13.)),smoothstep(0.0,1.0,fract(ySmooth)));
61
+ float colVar=mix(.4,1.0,yNoise);
62
+
63
+ float tearShiftX=dir.x*strength*rowVar*0.15;
64
+ float tearShiftY=dir.y*strength*colVar*0.10;
65
+
66
+ float bandSeed=h(vec2(float(bandIdx),42.));
67
+ tearShiftX+=strength*(.5-bandSeed)*0.05;
68
+
69
+ float yJitter=mix(h(vec2(floor(ySmooth),73.)),h(vec2(floor(ySmooth)+1.0,73.)),smoothstep(0.0,1.0,fract(ySmooth)));
70
+ tearShiftY+=strength*(.5-yJitter)*0.035;
71
+
72
+ uv.x+=tearShiftX;
73
+ uv.y+=tearShiftY;
74
+
75
+ float sortGate=step(.5,strength)*step(.4,rowSeed);
76
+ uv.x+=dir.x*sortGate*strength*0.03;
77
+ uv.y+=dir.y*sortGate*strength*0.02;
78
+
79
+ float caX=abs(tearShiftX)*2.5+sortGate*strength*0.01;
80
+ float caY=abs(tearShiftY)*2.5+sortGate*strength*0.01;
81
+ float cr=texture2D(tex,vec2(uv.x+caX,uv.y+caY)).r;
82
+ float cg=texture2D(tex,uv).g;
83
+ float cb=texture2D(tex,vec2(uv.x-caX,uv.y-caY)).b;
84
+
85
+ vec3 col=vec3(cr,cg,cb);
86
+
87
+ col*=.97+.03*sin(vUv.y*r.y*3.14159);
88
+
89
+ float bandEdge=smoothstep(.02,.0,min(bandFrac,1.0-bandFrac));
90
+ col+=vec3(bandEdge*strength*.1);
91
+
92
+ col=mix(col,col*tint,tintStrength);
93
+
94
+ gl_FragColor=vec4(col,1.0);
95
+ }`;
96
+ export function ImageDistortion({ active = true, className, fallbackClassName, src, style, tint, tintStrength }) {
97
+ const canvasRef = useRef(null);
98
+ const tier = useGpuTier();
99
+ const [loaded, setLoaded] = useState(false);
100
+ const activeRef = useRef(active);
101
+ activeRef.current = active;
102
+ const tintStrengthRef = useRef(tintStrength);
103
+ tintStrengthRef.current = tintStrength;
104
+ const state = useRef({
105
+ bandTargets: new Float32Array(NUM_BANDS),
106
+ bands: new Float32Array(NUM_BANDS),
107
+ hoverTarget: 0,
108
+ imgH: 1,
109
+ imgW: 1,
110
+ mx: 0.5,
111
+ my: 0.5,
112
+ prevMx: 0.5,
113
+ prevMy: 0.5,
114
+ vx: 0,
115
+ vy: 0
116
+ });
117
+ useEffect(() => {
118
+ if (tier === 0) {
119
+ return;
120
+ }
121
+ const c = canvasRef.current;
122
+ if (!c) {
123
+ return;
124
+ }
125
+ const gl = c.getContext('webgl');
126
+ if (!gl) {
127
+ return;
128
+ }
129
+ const compile = (type, source) => {
130
+ const s = gl.createShader(type);
131
+ gl.shaderSource(s, source);
132
+ gl.compileShader(s);
133
+ return s;
134
+ };
135
+ const prog = gl.createProgram();
136
+ gl.attachShader(prog, compile(gl.VERTEX_SHADER, VERT));
137
+ gl.attachShader(prog, compile(gl.FRAGMENT_SHADER, FRAG));
138
+ gl.linkProgram(prog);
139
+ gl.useProgram(prog);
140
+ gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
141
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);
142
+ const a = gl.getAttribLocation(prog, 'a');
143
+ gl.enableVertexAttribArray(a);
144
+ gl.vertexAttribPointer(a, 2, gl.FLOAT, false, 0, 0);
145
+ const uT = gl.getUniformLocation(prog, 't');
146
+ const uR = gl.getUniformLocation(prog, 'r');
147
+ const uImgSize = gl.getUniformLocation(prog, 'imgSize');
148
+ const uVel = gl.getUniformLocation(prog, 'vel');
149
+ const uTex = gl.getUniformLocation(prog, 'tex');
150
+ const uTint = gl.getUniformLocation(prog, 'tint');
151
+ const uTintStrength = gl.getUniformLocation(prog, 'tintStrength');
152
+ const uBands = [];
153
+ for (let i = 0; i < NUM_BANDS; i++) {
154
+ uBands.push(gl.getUniformLocation(prog, `bands[${i}]`));
155
+ }
156
+ const texture = gl.createTexture();
157
+ gl.bindTexture(gl.TEXTURE_2D, texture);
158
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
159
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
160
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
161
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
162
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 0, 255]));
163
+ const img = new Image();
164
+ img.crossOrigin = 'anonymous';
165
+ img.onload = () => {
166
+ state.current.imgW = img.naturalWidth;
167
+ state.current.imgH = img.naturalHeight;
168
+ gl.bindTexture(gl.TEXTURE_2D, texture);
169
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
170
+ setLoaded(true);
171
+ };
172
+ img.src = src;
173
+ gl.activeTexture(gl.TEXTURE0);
174
+ gl.bindTexture(gl.TEXTURE_2D, texture);
175
+ gl.uniform1i(uTex, 0);
176
+ const resize = () => {
177
+ const rect = c.getBoundingClientRect();
178
+ const dpr = Math.min(devicePixelRatio, 2);
179
+ c.width = rect.width * dpr;
180
+ c.height = rect.height * dpr;
181
+ gl.viewport(0, 0, c.width, c.height);
182
+ };
183
+ resize();
184
+ const ro = new ResizeObserver(resize);
185
+ ro.observe(c);
186
+ const onMove = (e) => {
187
+ const rect = c.getBoundingClientRect();
188
+ state.current.mx = (e.clientX - rect.left) / rect.width;
189
+ state.current.my = (e.clientY - rect.top) / rect.height;
190
+ };
191
+ const onEnter = () => {
192
+ state.current.hoverTarget = 1;
193
+ };
194
+ const onLeave = () => {
195
+ state.current.hoverTarget = 0;
196
+ };
197
+ c.addEventListener('pointermove', onMove);
198
+ c.addEventListener('pointerenter', onEnter);
199
+ c.addEventListener('pointerleave', onLeave);
200
+ const bandEaseRates = new Float32Array(NUM_BANDS);
201
+ for (let i = 0; i < NUM_BANDS; i++) {
202
+ bandEaseRates[i] = 0.02 + Math.random() * 0.06;
203
+ }
204
+ const tintVec = tint
205
+ ? (() => {
206
+ const [tr, tg, tb] = hexToRgb(tint);
207
+ return [tr / 255, tg / 255, tb / 255];
208
+ })()
209
+ : [1, 1, 1];
210
+ const t0 = performance.now();
211
+ let raf = 0;
212
+ const loop = () => {
213
+ raf = requestAnimationFrame(loop);
214
+ const s = state.current;
215
+ const dvx = s.mx - s.prevMx;
216
+ const dvy = s.my - s.prevMy;
217
+ s.vx += (dvx * 8 - s.vx) * 0.1;
218
+ s.vy += (dvy * 8 - s.vy) * 0.1;
219
+ s.prevMx = s.mx;
220
+ s.prevMy = s.my;
221
+ const speed = Math.sqrt(s.vx * s.vx + s.vy * s.vy);
222
+ for (let i = 0; i < NUM_BANDS; i++) {
223
+ const bandCenter = (i + 0.5) / NUM_BANDS;
224
+ const dist = Math.abs(s.my - bandCenter);
225
+ const proximity = Math.max(0, 1 - dist / 0.3);
226
+ const activation = s.hoverTarget * proximity * (0.4 + Math.min(speed, 1) * 0.6);
227
+ s.bandTargets[i] = activation;
228
+ }
229
+ for (let i = 0; i < NUM_BANDS; i++) {
230
+ const rate = bandEaseRates[i];
231
+ const current = s.bands[i] ?? 0;
232
+ const target = s.bandTargets[i] ?? 0;
233
+ s.bands[i] = current + (target - current) * rate;
234
+ if (s.bands[i] < 0.001) {
235
+ s.bands[i] = 0;
236
+ }
237
+ }
238
+ gl.uniform1f(uT, (performance.now() - t0) / 1e3);
239
+ gl.uniform2f(uR, c.width, c.height);
240
+ gl.uniform2f(uImgSize, s.imgW, s.imgH);
241
+ gl.uniform2f(uVel, s.vx, s.vy);
242
+ gl.uniform3f(uTint, tintVec[0], tintVec[1], tintVec[2]);
243
+ const ts = tintStrengthRef.current;
244
+ const defaultStrength = tint ? 0.35 : 0;
245
+ const defaultInactive = tint ? 0.15 : 0;
246
+ gl.uniform1f(uTintStrength, activeRef.current
247
+ ? (ts?.active ?? defaultStrength)
248
+ : (ts?.inactive ?? defaultInactive));
249
+ for (let i = 0; i < NUM_BANDS; i++) {
250
+ gl.uniform1f(uBands[i], s.bands[i]);
251
+ }
252
+ gl.bindTexture(gl.TEXTURE_2D, texture);
253
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
254
+ };
255
+ raf = requestAnimationFrame(loop);
256
+ return () => {
257
+ cancelAnimationFrame(raf);
258
+ ro.disconnect();
259
+ c.removeEventListener('pointermove', onMove);
260
+ c.removeEventListener('pointerenter', onEnter);
261
+ c.removeEventListener('pointerleave', onLeave);
262
+ gl.deleteTexture(texture);
263
+ gl.deleteProgram(prog);
264
+ setLoaded(false);
265
+ };
266
+ }, [src, tier, tint]);
267
+ if (tier === 0) {
268
+ return (
269
+ // eslint-disable-next-line @next/next/no-img-element
270
+ _jsx("img", { alt: "", className: cn('absolute inset-0 h-full w-full object-cover', fallbackClassName ?? className), src: src, style: { mixBlendMode: 'overlay', ...style } }));
271
+ }
272
+ return (_jsx("canvas", { className: cn('absolute inset-0 h-full w-full transition-opacity duration-500', className), ref: canvasRef, style: {
273
+ mixBlendMode: 'overlay',
274
+ opacity: loaded ? 1 : 0,
275
+ ...style
276
+ } }));
277
+ }
278
+ //# sourceMappingURL=image-distortion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-distortion.js","sourceRoot":"","sources":["../../../src/ui/components/image-distortion.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport { useEffect, useRef, useState } from 'react'\n\nimport { useGpuTier } from '../../hooks/use-gpu-tier'\nimport { cn, hexToRgb } from '../../utils'\n\nconst NUM_BANDS = 12\n\nconst VERT = `attribute vec2 a;varying vec2 vUv;void main(){vUv=vec2(a.x*.5+.5,.5-a.y*.5);gl_Position=vec4(a,0,1);}`\n\nconst FRAG = `precision highp float;\nuniform float t;\nuniform vec2 r,imgSize,vel;\nuniform sampler2D tex;\nuniform float bands[${NUM_BANDS}];\nuniform vec3 tint;\nuniform float tintStrength;\nvarying vec2 vUv;\n\nfloat h(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}\n\n// cover-style UV: crops the image to fill the canvas, centered\nvec2 coverUV(vec2 uv){\n float canvasAspect=r.x/r.y;\n float imgAspect=imgSize.x/imgSize.y;\n vec2 scale=canvasAspect>imgAspect\n ?vec2(1.0,imgAspect/canvasAspect)\n :vec2(canvasAspect/imgAspect,1.0);\n return(uv-0.5)*scale+0.5;\n}\n\nvoid main(){\n vec2 uv=coverUV(vUv);\n float scanY=floor(vUv.y*r.y);\n\n float bandF=vUv.y*${NUM_BANDS}.0;\n int bandIdx=int(floor(bandF));\n float bandFrac=fract(bandF);\n\n float strength=0.0;\n for(int i=0;i<${NUM_BANDS};i++){\n if(i==bandIdx) strength=bands[i];\n }\n\n float neighborStr=0.0;\n int neighborIdx=bandFrac>.5?bandIdx+1:bandIdx-1;\n for(int i=0;i<${NUM_BANDS};i++){\n if(i==neighborIdx) neighborStr=bands[i];\n }\n float edgeBlend=abs(bandFrac-.5)*2.0;\n edgeBlend*=edgeBlend;\n strength=mix(strength,neighborStr,edgeBlend*.3);\n\n float speed=length(vel);\n float dirBlend=smoothstep(0.0,0.02,speed);\n vec2 dir=speed>.0001?vel/speed:vec2(0);\n dir*=dirBlend;\n\n float rowSeed=h(vec2(scanY,floor(t*3.)+float(bandIdx)*7.));\n float rowVar=mix(.4,1.0,rowSeed);\n\n float ySmooth=vUv.y*6.0+t*0.7;\n float yNoise=mix(h(vec2(floor(ySmooth),13.)),h(vec2(floor(ySmooth)+1.0,13.)),smoothstep(0.0,1.0,fract(ySmooth)));\n float colVar=mix(.4,1.0,yNoise);\n\n float tearShiftX=dir.x*strength*rowVar*0.15;\n float tearShiftY=dir.y*strength*colVar*0.10;\n\n float bandSeed=h(vec2(float(bandIdx),42.));\n tearShiftX+=strength*(.5-bandSeed)*0.05;\n\n float yJitter=mix(h(vec2(floor(ySmooth),73.)),h(vec2(floor(ySmooth)+1.0,73.)),smoothstep(0.0,1.0,fract(ySmooth)));\n tearShiftY+=strength*(.5-yJitter)*0.035;\n\n uv.x+=tearShiftX;\n uv.y+=tearShiftY;\n\n float sortGate=step(.5,strength)*step(.4,rowSeed);\n uv.x+=dir.x*sortGate*strength*0.03;\n uv.y+=dir.y*sortGate*strength*0.02;\n\n float caX=abs(tearShiftX)*2.5+sortGate*strength*0.01;\n float caY=abs(tearShiftY)*2.5+sortGate*strength*0.01;\n float cr=texture2D(tex,vec2(uv.x+caX,uv.y+caY)).r;\n float cg=texture2D(tex,uv).g;\n float cb=texture2D(tex,vec2(uv.x-caX,uv.y-caY)).b;\n\n vec3 col=vec3(cr,cg,cb);\n\n col*=.97+.03*sin(vUv.y*r.y*3.14159);\n\n float bandEdge=smoothstep(.02,.0,min(bandFrac,1.0-bandFrac));\n col+=vec3(bandEdge*strength*.1);\n\n col=mix(col,col*tint,tintStrength);\n\n gl_FragColor=vec4(col,1.0);\n}`\n\nexport function ImageDistortion({\n active = true,\n className,\n fallbackClassName,\n src,\n style,\n tint,\n tintStrength\n}: ImageDistortionProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const tier = useGpuTier()\n const [loaded, setLoaded] = useState(false)\n\n const activeRef = useRef(active)\n activeRef.current = active\n const tintStrengthRef = useRef(tintStrength)\n tintStrengthRef.current = tintStrength\n\n const state = useRef({\n bandTargets: new Float32Array(NUM_BANDS),\n bands: new Float32Array(NUM_BANDS),\n hoverTarget: 0,\n imgH: 1,\n imgW: 1,\n mx: 0.5,\n my: 0.5,\n prevMx: 0.5,\n prevMy: 0.5,\n vx: 0,\n vy: 0\n })\n\n useEffect(() => {\n if (tier === 0) {\n return\n }\n\n const c = canvasRef.current\n\n if (!c) {\n return\n }\n\n const gl = c.getContext('webgl')\n\n if (!gl) {\n return\n }\n\n const compile = (type: number, source: string) => {\n const s = gl.createShader(type)!\n gl.shaderSource(s, source)\n gl.compileShader(s)\n\n return s\n }\n\n const prog = gl.createProgram()!\n gl.attachShader(prog, compile(gl.VERTEX_SHADER, VERT))\n gl.attachShader(prog, compile(gl.FRAGMENT_SHADER, FRAG))\n gl.linkProgram(prog)\n gl.useProgram(prog)\n\n gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer())\n gl.bufferData(\n gl.ARRAY_BUFFER,\n new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n gl.STATIC_DRAW\n )\n\n const a = gl.getAttribLocation(prog, 'a')\n gl.enableVertexAttribArray(a)\n gl.vertexAttribPointer(a, 2, gl.FLOAT, false, 0, 0)\n\n const uT = gl.getUniformLocation(prog, 't')\n const uR = gl.getUniformLocation(prog, 'r')\n const uImgSize = gl.getUniformLocation(prog, 'imgSize')\n const uVel = gl.getUniformLocation(prog, 'vel')\n const uTex = gl.getUniformLocation(prog, 'tex')\n const uTint = gl.getUniformLocation(prog, 'tint')\n const uTintStrength = gl.getUniformLocation(prog, 'tintStrength')\n const uBands: (null | WebGLUniformLocation)[] = []\n\n for (let i = 0; i < NUM_BANDS; i++) {\n uBands.push(gl.getUniformLocation(prog, `bands[${i}]`))\n }\n\n const texture = gl.createTexture()!\n gl.bindTexture(gl.TEXTURE_2D, texture)\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n gl.RGBA,\n 1,\n 1,\n 0,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n new Uint8Array([0, 0, 0, 255])\n )\n\n const img = new Image()\n img.crossOrigin = 'anonymous'\n\n img.onload = () => {\n state.current.imgW = img.naturalWidth\n state.current.imgH = img.naturalHeight\n gl.bindTexture(gl.TEXTURE_2D, texture)\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n gl.RGBA,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n img\n )\n setLoaded(true)\n }\n\n img.src = src\n\n gl.activeTexture(gl.TEXTURE0)\n gl.bindTexture(gl.TEXTURE_2D, texture)\n gl.uniform1i(uTex, 0)\n\n const resize = () => {\n const rect = c.getBoundingClientRect()\n const dpr = Math.min(devicePixelRatio, 2)\n c.width = rect.width * dpr\n c.height = rect.height * dpr\n gl.viewport(0, 0, c.width, c.height)\n }\n\n resize()\n const ro = new ResizeObserver(resize)\n ro.observe(c)\n\n const onMove = (e: PointerEvent) => {\n const rect = c.getBoundingClientRect()\n state.current.mx = (e.clientX - rect.left) / rect.width\n state.current.my = (e.clientY - rect.top) / rect.height\n }\n\n const onEnter = () => {\n state.current.hoverTarget = 1\n }\n\n const onLeave = () => {\n state.current.hoverTarget = 0\n }\n\n c.addEventListener('pointermove', onMove)\n c.addEventListener('pointerenter', onEnter)\n c.addEventListener('pointerleave', onLeave)\n\n const bandEaseRates = new Float32Array(NUM_BANDS)\n\n for (let i = 0; i < NUM_BANDS; i++) {\n bandEaseRates[i] = 0.02 + Math.random() * 0.06\n }\n\n const tintVec: readonly [number, number, number] = tint\n ? (() => {\n const [tr, tg, tb] = hexToRgb(tint)\n\n return [tr / 255, tg / 255, tb / 255] as const\n })()\n : ([1, 1, 1] as const)\n\n const t0 = performance.now()\n let raf = 0\n\n const loop = () => {\n raf = requestAnimationFrame(loop)\n const s = state.current\n\n const dvx = s.mx - s.prevMx\n const dvy = s.my - s.prevMy\n s.vx += (dvx * 8 - s.vx) * 0.1\n s.vy += (dvy * 8 - s.vy) * 0.1\n s.prevMx = s.mx\n s.prevMy = s.my\n\n const speed = Math.sqrt(s.vx * s.vx + s.vy * s.vy)\n\n for (let i = 0; i < NUM_BANDS; i++) {\n const bandCenter = (i + 0.5) / NUM_BANDS\n const dist = Math.abs(s.my - bandCenter)\n const proximity = Math.max(0, 1 - dist / 0.3)\n const activation =\n s.hoverTarget * proximity * (0.4 + Math.min(speed, 1) * 0.6)\n s.bandTargets[i] = activation\n }\n\n for (let i = 0; i < NUM_BANDS; i++) {\n const rate = bandEaseRates[i]!\n const current = s.bands[i] ?? 0\n const target = s.bandTargets[i] ?? 0\n s.bands[i] = current + (target - current) * rate\n\n if (s.bands[i]! < 0.001) {\n s.bands[i] = 0\n }\n }\n\n gl.uniform1f(uT, (performance.now() - t0) / 1e3)\n gl.uniform2f(uR, c.width, c.height)\n gl.uniform2f(uImgSize, s.imgW, s.imgH)\n gl.uniform2f(uVel, s.vx, s.vy)\n gl.uniform3f(uTint, tintVec[0], tintVec[1], tintVec[2])\n\n const ts = tintStrengthRef.current\n const defaultStrength = tint ? 0.35 : 0\n const defaultInactive = tint ? 0.15 : 0\n gl.uniform1f(\n uTintStrength,\n activeRef.current\n ? (ts?.active ?? defaultStrength)\n : (ts?.inactive ?? defaultInactive)\n )\n\n for (let i = 0; i < NUM_BANDS; i++) {\n gl.uniform1f(uBands[i]!, s.bands[i]!)\n }\n\n gl.bindTexture(gl.TEXTURE_2D, texture)\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)\n }\n\n raf = requestAnimationFrame(loop)\n\n return () => {\n cancelAnimationFrame(raf)\n ro.disconnect()\n c.removeEventListener('pointermove', onMove)\n c.removeEventListener('pointerenter', onEnter)\n c.removeEventListener('pointerleave', onLeave)\n gl.deleteTexture(texture)\n gl.deleteProgram(prog)\n setLoaded(false)\n }\n }, [src, tier, tint])\n\n if (tier === 0) {\n return (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n alt=\"\"\n className={cn(\n 'absolute inset-0 h-full w-full object-cover',\n fallbackClassName ?? className\n )}\n src={src}\n style={{ mixBlendMode: 'overlay', ...style }}\n />\n )\n }\n\n return (\n <canvas\n className={cn(\n 'absolute inset-0 h-full w-full transition-opacity duration-500',\n className\n )}\n ref={canvasRef}\n style={{\n mixBlendMode: 'overlay',\n opacity: loaded ? 1 : 0,\n ...style\n }}\n />\n )\n}\n\ninterface ImageDistortionProps {\n active?: boolean\n className?: string\n fallbackClassName?: string\n src: string\n style?: React.CSSProperties\n tint?: string\n tintStrength?: { active: number; inactive: number }\n}\n"]}
@@ -0,0 +1,33 @@
1
+ export declare function TerminalDemo({ ariaLabel, className, height, label, loopDelayMs, outputLineDelayMs, sequence }: TerminalDemoProps): import("react/jsx-runtime").JSX.Element;
2
+ interface ClearStep {
3
+ type: 'clear';
4
+ }
5
+ interface OutputStep {
6
+ lines: string[];
7
+ type: 'output';
8
+ }
9
+ interface PauseStep {
10
+ ms: number;
11
+ type: 'pause';
12
+ }
13
+ interface PromptStep {
14
+ text: string;
15
+ type: 'prompt';
16
+ }
17
+ interface TerminalDemoProps {
18
+ ariaLabel?: string;
19
+ className?: string;
20
+ height?: number | string;
21
+ label?: string;
22
+ loopDelayMs?: number;
23
+ outputLineDelayMs?: number;
24
+ sequence: TerminalDemoStep[];
25
+ }
26
+ export type TerminalDemoStep = ClearStep | OutputStep | PauseStep | PromptStep | TypeStep;
27
+ interface TypeStep {
28
+ delay?: number;
29
+ text: string;
30
+ type: 'type';
31
+ }
32
+ export {};
33
+ //# sourceMappingURL=terminal-demo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-demo.d.ts","sourceRoot":"","sources":["../../../src/ui/components/terminal-demo.tsx"],"names":[],"mappings":"AAUA,wBAAgB,YAAY,CAAC,EAC3B,SAA2B,EAC3B,SAAS,EACT,MAAY,EACZ,KAAkB,EAClB,WAAkB,EAClB,iBAAsB,EACtB,QAAQ,EACT,EAAE,iBAAiB,2CAgInB;AAED,UAAU,SAAS;IACjB,IAAI,EAAE,OAAO,CAAA;CACd;AAED,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,IAAI,EAAE,QAAQ,CAAA;CACf;AAED,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,OAAO,CAAA;CACd;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,QAAQ,CAAA;CACf;AAED,UAAU,iBAAiB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,EAAE,gBAAgB,EAAE,CAAA;CAC7B;AAED,MAAM,MAAM,gBAAgB,GACxB,SAAS,GACT,UAAU,GACV,SAAS,GACT,UAAU,GACV,QAAQ,CAAA;AAEZ,UAAU,QAAQ;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb"}
@@ -0,0 +1,79 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useCallback, useEffect, useRef, useState } from 'react';
4
+ import { cn } from '../../utils';
5
+ function sleep(ms) {
6
+ return new Promise(resolve => setTimeout(resolve, ms));
7
+ }
8
+ export function TerminalDemo({ ariaLabel = 'Terminal Demo', className, height = 320, label = 'Terminal', loopDelayMs = 1000, outputLineDelayMs = 50, sequence }) {
9
+ const bodyRef = useRef(null);
10
+ const startedRef = useRef(false);
11
+ const [html, setHtml] = useState('');
12
+ const runDemo = useCallback(async () => {
13
+ if (startedRef.current) {
14
+ return;
15
+ }
16
+ startedRef.current = true;
17
+ let content = '';
18
+ const render = (h) => {
19
+ content = h;
20
+ setHtml(h);
21
+ };
22
+ for (;;) {
23
+ for (const step of sequence) {
24
+ switch (step.type) {
25
+ case 'clear':
26
+ content = '';
27
+ render('');
28
+ break;
29
+ case 'output':
30
+ for (const line of step.lines) {
31
+ render(content + '\n' + line);
32
+ await sleep(outputLineDelayMs);
33
+ }
34
+ break;
35
+ case 'pause':
36
+ await sleep(step.ms);
37
+ break;
38
+ case 'prompt':
39
+ render(content + `<span class="text-midground">${step.text}</span>`);
40
+ break;
41
+ case 'type':
42
+ for (const char of step.text) {
43
+ render(content + char);
44
+ await sleep(step.delay ?? 30);
45
+ }
46
+ break;
47
+ }
48
+ }
49
+ content = '';
50
+ render('');
51
+ await sleep(loopDelayMs);
52
+ }
53
+ }, [loopDelayMs, outputLineDelayMs, sequence]);
54
+ useEffect(() => {
55
+ const el = bodyRef.current?.closest('[data-demo-root]');
56
+ if (!el) {
57
+ return;
58
+ }
59
+ const observer = new IntersectionObserver(entries => {
60
+ entries.forEach(entry => {
61
+ if (entry.isIntersecting) {
62
+ runDemo();
63
+ }
64
+ });
65
+ }, { threshold: 0.3 });
66
+ observer.observe(el);
67
+ return () => observer.disconnect();
68
+ }, [runDemo]);
69
+ useEffect(() => {
70
+ if (bodyRef.current) {
71
+ bodyRef.current.scrollTop = bodyRef.current.scrollHeight;
72
+ }
73
+ }, [html]);
74
+ return (_jsxs("div", { "aria-label": ariaLabel, className: cn('border-4 border-double border-inherit', className), "data-demo-root": true, role: "img", children: [_jsxs("div", { className: "flex items-center gap-3 border-b border-current/10 px-3 py-2", children: [_jsxs("div", { className: "flex gap-1.5", children: [_jsx("span", { className: "bg-midground size-2 rounded-full", style: { mixBlendMode: 'plus-lighter' } }), _jsx("span", { className: "bg-midground/60 size-2 rounded-full" }), _jsx("span", { className: "bg-midground/30 size-2 rounded-full" })] }), _jsx("span", { className: "font-courier text-[0.625rem] tracking-widest uppercase opacity-50", children: label })] }), _jsx("div", { className: cn('overflow-x-hidden overflow-y-auto whitespace-pre-wrap', 'font-courier p-4 text-[0.75rem] leading-[1.7] normal-case'), dangerouslySetInnerHTML: {
75
+ __html: html +
76
+ '<span class="blink inline-block dither ml-0.5 h-[1em] w-[1ch]"></span>'
77
+ }, ref: bodyRef, style: { height } })] }));
78
+ }
79
+ //# sourceMappingURL=terminal-demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-demo.js","sourceRoot":"","sources":["../../../src/ui/components/terminal-demo.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\n\nimport { cn } from '../../utils'\n\nfunction sleep(ms: number) {\n return new Promise<void>(resolve => setTimeout(resolve, ms))\n}\n\nexport function TerminalDemo({\n ariaLabel = 'Terminal Demo',\n className,\n height = 320,\n label = 'Terminal',\n loopDelayMs = 1000,\n outputLineDelayMs = 50,\n sequence\n}: TerminalDemoProps) {\n const bodyRef = useRef<HTMLDivElement>(null)\n const startedRef = useRef(false)\n const [html, setHtml] = useState('')\n\n const runDemo = useCallback(async () => {\n if (startedRef.current) {\n return\n }\n\n startedRef.current = true\n let content = ''\n\n const render = (h: string) => {\n content = h\n setHtml(h)\n }\n\n for (;;) {\n for (const step of sequence) {\n switch (step.type) {\n case 'clear':\n content = ''\n render('')\n\n break\n\n case 'output':\n for (const line of step.lines) {\n render(content + '\\n' + line)\n await sleep(outputLineDelayMs)\n }\n\n break\n\n case 'pause':\n await sleep(step.ms)\n\n break\n\n case 'prompt':\n render(content + `<span class=\"text-midground\">${step.text}</span>`)\n\n break\n\n case 'type':\n for (const char of step.text) {\n render(content + char)\n await sleep(step.delay ?? 30)\n }\n\n break\n }\n }\n\n content = ''\n render('')\n await sleep(loopDelayMs)\n }\n }, [loopDelayMs, outputLineDelayMs, sequence])\n\n useEffect(() => {\n const el = bodyRef.current?.closest('[data-demo-root]')\n\n if (!el) {\n return\n }\n\n const observer = new IntersectionObserver(\n entries => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n runDemo()\n }\n })\n },\n { threshold: 0.3 }\n )\n\n observer.observe(el)\n\n return () => observer.disconnect()\n }, [runDemo])\n\n useEffect(() => {\n if (bodyRef.current) {\n bodyRef.current.scrollTop = bodyRef.current.scrollHeight\n }\n }, [html])\n\n return (\n <div\n aria-label={ariaLabel}\n className={cn('border-4 border-double border-inherit', className)}\n data-demo-root\n role=\"img\"\n >\n <div className=\"flex items-center gap-3 border-b border-current/10 px-3 py-2\">\n <div className=\"flex gap-1.5\">\n <span\n className=\"bg-midground size-2 rounded-full\"\n style={{ mixBlendMode: 'plus-lighter' }}\n />\n\n <span className=\"bg-midground/60 size-2 rounded-full\" />\n <span className=\"bg-midground/30 size-2 rounded-full\" />\n </div>\n\n <span className=\"font-courier text-[0.625rem] tracking-widest uppercase opacity-50\">\n {label}\n </span>\n </div>\n\n <div\n className={cn(\n 'overflow-x-hidden overflow-y-auto whitespace-pre-wrap',\n 'font-courier p-4 text-[0.75rem] leading-[1.7] normal-case'\n )}\n dangerouslySetInnerHTML={{\n __html:\n html +\n '<span class=\"blink inline-block dither ml-0.5 h-[1em] w-[1ch]\"></span>'\n }}\n ref={bodyRef}\n style={{ height }}\n />\n </div>\n )\n}\n\ninterface ClearStep {\n type: 'clear'\n}\n\ninterface OutputStep {\n lines: string[]\n type: 'output'\n}\n\ninterface PauseStep {\n ms: number\n type: 'pause'\n}\n\ninterface PromptStep {\n text: string\n type: 'prompt'\n}\n\ninterface TerminalDemoProps {\n ariaLabel?: string\n className?: string\n height?: number | string\n label?: string\n loopDelayMs?: number\n outputLineDelayMs?: number\n sequence: TerminalDemoStep[]\n}\n\nexport type TerminalDemoStep =\n | ClearStep\n | OutputStep\n | PauseStep\n | PromptStep\n | TypeStep\n\ninterface TypeStep {\n delay?: number\n text: string\n type: 'type'\n}\n"]}
@@ -0,0 +1,7 @@
1
+ export declare function ThemeToggle({ className, style }: ThemeToggleProps): import("react/jsx-runtime").JSX.Element;
2
+ interface ThemeToggleProps {
3
+ className?: string;
4
+ style?: React.CSSProperties;
5
+ }
6
+ export {};
7
+ //# sourceMappingURL=theme-toggle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-toggle.d.ts","sourceRoot":"","sources":["../../../src/ui/components/theme-toggle.tsx"],"names":[],"mappings":"AAQA,wBAAgB,WAAW,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,gBAAgB,2CAoDjE;AAED,UAAU,gBAAgB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;CAC5B"}
@@ -0,0 +1,10 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useStore } from '@nanostores/react';
4
+ import { cn } from '../../utils';
5
+ import { $lightMode, toggleLens } from './overlays';
6
+ export function ThemeToggle({ className, style }) {
7
+ const light = useStore($lightMode);
8
+ return (_jsxs("button", { "aria-label": light ? 'Switch to dark mode' : 'Switch to light mode', className: cn('relative flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full', 'border border-current/25 bg-current/8 transition-colors', 'hover:bg-current/15', className), onClick: toggleLens, style: style, type: "button", children: [_jsxs("svg", { className: "absolute left-1 size-3.5 opacity-40", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, viewBox: "0 0 24 24", children: [_jsx("circle", { cx: 12, cy: 12, r: 5 }), _jsx("path", { d: "M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" })] }), _jsx("svg", { className: "absolute right-1 size-3.5 opacity-40", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, viewBox: "0 0 24 24", children: _jsx("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }) }), _jsx("span", { "aria-hidden": true, className: cn('bg-midground absolute size-4 rounded-full', 'transition-transform duration-200 ease-out'), style: { transform: `translateX(${light ? 2 : 22}px)` } })] }));
9
+ }
10
+ //# sourceMappingURL=theme-toggle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-toggle.js","sourceRoot":"","sources":["../../../src/ui/components/theme-toggle.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE5C,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAEhC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEnD,MAAM,UAAU,WAAW,CAAC,EAAE,SAAS,EAAE,KAAK,EAAoB;IAChE,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAA;IAElC,OAAO,CACL,gCACc,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,sBAAsB,EAClE,SAAS,EAAE,EAAE,CACX,0EAA0E,EAC1E,yDAAyD,EACzD,qBAAqB,EACrB,SAAS,CACV,EACD,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAC,QAAQ,aAEb,eACE,SAAS,EAAC,qCAAqC,EAC/C,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EACtB,WAAW,EAAE,CAAC,EACd,OAAO,EAAC,WAAW,aAEnB,iBAAQ,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,GAAI,EAEhC,eAAM,CAAC,EAAC,oHAAoH,GAAG,IAC3H,EAEN,cACE,SAAS,EAAC,sCAAsC,EAChD,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EACtB,WAAW,EAAE,CAAC,EACd,OAAO,EAAC,WAAW,YAEnB,eAAM,CAAC,EAAC,iDAAiD,GAAG,GACxD,EAEN,oCAEE,SAAS,EAAE,EAAE,CACX,2CAA2C,EAC3C,4CAA4C,CAC7C,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GACvD,IACK,CACV,CAAA;AACH,CAAC","sourcesContent":["'use client'\n\nimport { useStore } from '@nanostores/react'\n\nimport { cn } from '../../utils'\n\nimport { $lightMode, toggleLens } from './overlays'\n\nexport function ThemeToggle({ className, style }: ThemeToggleProps) {\n const light = useStore($lightMode)\n\n return (\n <button\n aria-label={light ? 'Switch to dark mode' : 'Switch to light mode'}\n className={cn(\n 'relative flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full',\n 'border border-current/25 bg-current/8 transition-colors',\n 'hover:bg-current/15',\n className\n )}\n onClick={toggleLens}\n style={style}\n type=\"button\"\n >\n <svg\n className=\"absolute left-1 size-3.5 opacity-40\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n viewBox=\"0 0 24 24\"\n >\n <circle cx={12} cy={12} r={5} />\n\n <path d=\"M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42\" />\n </svg>\n\n <svg\n className=\"absolute right-1 size-3.5 opacity-40\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n </svg>\n\n <span\n aria-hidden\n className={cn(\n 'bg-midground absolute size-4 rounded-full',\n 'transition-transform duration-200 ease-out'\n )}\n style={{ transform: `translateX(${light ? 2 : 22}px)` }}\n />\n </button>\n )\n}\n\ninterface ThemeToggleProps {\n className?: string\n style?: React.CSSProperties\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nous-research/ui",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "sideEffects": [