@hunterchen/canvas 0.7.0 → 0.9.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/README.md +196 -8
- package/dist/components/canvas/backgrounds.d.ts +4 -4
- package/dist/components/canvas/backgrounds.d.ts.map +1 -1
- package/dist/components/canvas/backgrounds.js +68 -39
- package/dist/components/canvas/backgrounds.js.map +1 -1
- package/dist/components/canvas/canvas.d.ts +3 -1
- package/dist/components/canvas/canvas.d.ts.map +1 -1
- package/dist/components/canvas/canvas.js +451 -387
- package/dist/components/canvas/canvas.js.map +1 -1
- package/dist/components/canvas/component.js +108 -174
- package/dist/components/canvas/component.js.map +1 -1
- package/dist/components/canvas/draggable.js +168 -151
- package/dist/components/canvas/draggable.js.map +1 -1
- package/dist/components/canvas/navbar/index.d.ts +4 -2
- package/dist/components/canvas/navbar/index.d.ts.map +1 -1
- package/dist/components/canvas/navbar/index.js +168 -101
- package/dist/components/canvas/navbar/index.js.map +1 -1
- package/dist/components/canvas/navbar/single-button.d.ts +10 -1
- package/dist/components/canvas/navbar/single-button.d.ts.map +1 -1
- package/dist/components/canvas/navbar/single-button.js +176 -69
- package/dist/components/canvas/navbar/single-button.js.map +1 -1
- package/dist/components/canvas/toolbar.js +121 -82
- package/dist/components/canvas/toolbar.js.map +1 -1
- package/dist/components/canvas/wrapper.js +127 -99
- package/dist/components/canvas/wrapper.js.map +1 -1
- package/dist/contexts/CanvasContext.js +25 -17
- package/dist/contexts/CanvasContext.js.map +1 -1
- package/dist/contexts/PerformanceContext.js +51 -50
- package/dist/contexts/PerformanceContext.js.map +1 -1
- package/dist/hooks/usePerformanceMode.js +36 -37
- package/dist/hooks/usePerformanceMode.js.map +1 -1
- package/dist/hooks/useWindowDimensions.js +22 -18
- package/dist/hooks/useWindowDimensions.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -21
- package/dist/lib/canvas.js +65 -72
- package/dist/lib/canvas.js.map +1 -1
- package/dist/lib/constants.js +78 -92
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/utils.js +10 -5
- package/dist/lib/utils.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/index.d.ts +69 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/performance.js +18 -23
- package/dist/utils/performance.js.map +1 -1
- package/package.json +7 -21
- package/src/components/canvas/backgrounds.tsx +7 -7
- package/src/components/canvas/canvas.tsx +9 -2
- package/src/components/canvas/navbar/index.tsx +91 -15
- package/src/components/canvas/navbar/single-button.tsx +210 -56
- package/src/index.ts +5 -0
- package/src/styles.css +15 -13
- package/src/types/index.ts +91 -0
- package/dist/components/canvas/offest.js +0 -12
- package/dist/components/canvas/offest.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/types/index.js +0 -6
- package/dist/types/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -133,7 +133,35 @@ const navItems: NavItem[] = [
|
|
|
133
133
|
</Canvas>
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
-
When `navItems` is provided, the canvas will render a navbar with buttons to navigate between sections.
|
|
136
|
+
When `navItems` is provided, the canvas will render a navbar with buttons to navigate between sections.
|
|
137
|
+
|
|
138
|
+
#### Using Icons
|
|
139
|
+
|
|
140
|
+
The `icon` property accepts either a Lucide icon name (string) or a custom React component:
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
import { Heart } from 'lucide-react';
|
|
144
|
+
|
|
145
|
+
// Using Lucide icon names (strings)
|
|
146
|
+
const navItems: NavItem[] = [
|
|
147
|
+
{ id: "home", label: "Home", icon: "Home", ...coordinates.home, isHome: true },
|
|
148
|
+
{ id: "about", label: "About", icon: "Info", ...coordinates.about },
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
// Using custom icon components
|
|
152
|
+
const CustomIcon = ({ className }: { className?: string }) => (
|
|
153
|
+
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
|
|
154
|
+
<circle cx="12" cy="12" r="10" />
|
|
155
|
+
</svg>
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
const navItems: NavItem[] = [
|
|
159
|
+
{ id: "home", label: "Home", icon: Heart, ...coordinates.home, isHome: true },
|
|
160
|
+
{ id: "custom", label: "Custom", icon: CustomIcon, ...coordinates.custom },
|
|
161
|
+
];
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
For Lucide icons, use the PascalCase icon name as a string (e.g., `"Home"`, `"Settings"`, `"ChevronRight"`). See the [Lucide icons list](https://lucide.dev/icons) for available icons.
|
|
137
165
|
|
|
138
166
|
### Canvas Dimensions
|
|
139
167
|
|
|
@@ -263,7 +291,7 @@ import { Canvas, DefaultIntroContent } from '@hunterchen/canvas';
|
|
|
263
291
|
|
|
264
292
|
#### Complete Theming Example (Hack Western Style)
|
|
265
293
|
|
|
266
|
-
Here's a complete example showing how to apply a custom theme:
|
|
294
|
+
Here's a complete example showing how to apply a custom theme with warm coral/lilac colors (used by [Hack Western](https://hackwestern.com)):
|
|
267
295
|
|
|
268
296
|
```tsx
|
|
269
297
|
import {
|
|
@@ -275,10 +303,10 @@ import {
|
|
|
275
303
|
canvasHeight,
|
|
276
304
|
} from '@hunterchen/canvas';
|
|
277
305
|
|
|
278
|
-
//
|
|
279
|
-
const CANVAS_GRADIENT = `radial-gradient(ellipse ${canvasWidth}px ${canvasHeight}px at ${canvasWidth / 2}px ${canvasHeight}px,
|
|
280
|
-
const INTRO_GRADIENT = "linear-gradient(to top, #
|
|
281
|
-
const BOX_GRADIENT = "radial-gradient(130.38% 95% at 50.03% 97.25%, #
|
|
306
|
+
// Hack Western theme colors (coral/lilac warm palette)
|
|
307
|
+
const CANVAS_GRADIENT = `radial-gradient(ellipse ${canvasWidth}px ${canvasHeight}px at ${canvasWidth / 2}px ${canvasHeight}px, #f7f1e5 0%, #d9c8e6 41%, #ffb5a7 59%, #f7f1e5 90%)`;
|
|
308
|
+
const INTRO_GRADIENT = "linear-gradient(to top, #ffb5a7 0%, #d9c8e6 50%, #f7f1e5 100%)";
|
|
309
|
+
const BOX_GRADIENT = "radial-gradient(130.38% 95% at 50.03% 97.25%, #ffb5a7 0%, #d9c8e6 48.09%, #f7f1e5 100%)";
|
|
282
310
|
|
|
283
311
|
function App() {
|
|
284
312
|
return (
|
|
@@ -291,19 +319,26 @@ function App() {
|
|
|
291
319
|
<DefaultIntroContent
|
|
292
320
|
logoSrc="/logo.svg"
|
|
293
321
|
logoAlt="Logo"
|
|
294
|
-
title="
|
|
322
|
+
title="HACK WESTERN"
|
|
323
|
+
titleClassName="text-[#513b7a]"
|
|
295
324
|
/>
|
|
296
325
|
}
|
|
297
326
|
loadingText="LOADING..."
|
|
298
327
|
canvasBackground={
|
|
299
328
|
<DefaultCanvasBackground
|
|
300
329
|
gradientStyle={CANVAS_GRADIENT}
|
|
301
|
-
dotColor="#
|
|
330
|
+
dotColor="#c9a7db"
|
|
302
331
|
/>
|
|
303
332
|
}
|
|
304
333
|
wrapperBackground={
|
|
305
334
|
<DefaultWrapperBackground gradient={INTRO_GRADIENT} />
|
|
306
335
|
}
|
|
336
|
+
navbarConfig={{
|
|
337
|
+
buttonConfig: {
|
|
338
|
+
activeClassName: "bg-[#f5f2f7]",
|
|
339
|
+
hoverClassName: "bg-[#f5f2f7]",
|
|
340
|
+
},
|
|
341
|
+
}}
|
|
307
342
|
>
|
|
308
343
|
{/* Your canvas content */}
|
|
309
344
|
</Canvas>
|
|
@@ -311,6 +346,31 @@ function App() {
|
|
|
311
346
|
}
|
|
312
347
|
```
|
|
313
348
|
|
|
349
|
+
#### Customizing CSS Variables
|
|
350
|
+
|
|
351
|
+
The library uses CSS variables for theming. You can override them in your CSS to customize colors globally:
|
|
352
|
+
|
|
353
|
+
```css
|
|
354
|
+
:root {
|
|
355
|
+
/* Text colors */
|
|
356
|
+
--canvas-heavy: #3c204c; /* Darkest text */
|
|
357
|
+
--canvas-emphasis: #513b7a; /* Emphasized text */
|
|
358
|
+
--canvas-active: #8f57ad; /* Active/selected state */
|
|
359
|
+
--canvas-medium: #776780; /* Medium text */
|
|
360
|
+
--canvas-light: #c3b8cb; /* Light text */
|
|
361
|
+
|
|
362
|
+
/* Background colors */
|
|
363
|
+
--canvas-beige: #f7f1e5; /* Warm beige */
|
|
364
|
+
--canvas-coral: #ffb5a7; /* Coral accent */
|
|
365
|
+
--canvas-lilac: #d9c8e6; /* Lilac accent */
|
|
366
|
+
--canvas-salmon: #ffa585; /* Salmon accent */
|
|
367
|
+
--canvas-tinted: #c9a7db; /* Tinted purple */
|
|
368
|
+
--canvas-faint-lilac: #f5f2f7; /* Very light lilac */
|
|
369
|
+
--canvas-offwhite: #fdfcfd; /* Off-white */
|
|
370
|
+
--canvas-highlight: #f5f2f7; /* Highlight/hover */
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
314
374
|
### Toolbar Customization
|
|
315
375
|
|
|
316
376
|
The toolbar displays the current canvas coordinates and zoom level. You can customize its position, appearance, and behavior using the `toolbarConfig` prop.
|
|
@@ -398,6 +458,113 @@ The toolbar displays the current canvas coordinates and zoom level. You can cust
|
|
|
398
458
|
<Canvas toolbarConfig={{ hidden: true }} />
|
|
399
459
|
```
|
|
400
460
|
|
|
461
|
+
### Navbar Customization
|
|
462
|
+
|
|
463
|
+
The navbar provides navigation buttons to jump between canvas sections. You can customize its position, display mode, button styling, and tooltips using the `navbarConfig` prop.
|
|
464
|
+
|
|
465
|
+
```tsx
|
|
466
|
+
<Canvas
|
|
467
|
+
homeCoordinates={homeCoordinates}
|
|
468
|
+
navItems={navItems}
|
|
469
|
+
navbarConfig={{
|
|
470
|
+
position: "top",
|
|
471
|
+
display: "icons-labels",
|
|
472
|
+
}}
|
|
473
|
+
>
|
|
474
|
+
{/* ... */}
|
|
475
|
+
</Canvas>
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
**NavbarConfig options:**
|
|
479
|
+
|
|
480
|
+
| Prop | Type | Default | Description |
|
|
481
|
+
|------|------|---------|-------------|
|
|
482
|
+
| `hidden` | `boolean` | `false` | Hide the navbar entirely |
|
|
483
|
+
| `display` | `'icons' \| 'labels' \| 'icons-labels' \| 'compact'` | `'icons'` | Display mode for items |
|
|
484
|
+
| `position` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'bottom'` | Navbar position |
|
|
485
|
+
| `className` | `string` | - | Additional CSS classes for container |
|
|
486
|
+
| `style` | `CSSProperties` | - | Inline styles for container |
|
|
487
|
+
| `buttonConfig` | `NavbarButtonConfig` | - | Button styling options (see below) |
|
|
488
|
+
| `tooltipConfig` | `NavbarTooltipConfig` | - | Tooltip options (see below) |
|
|
489
|
+
| `gap` | `number` | `4` | Gap between buttons in pixels |
|
|
490
|
+
| `padding` | `number` | `4` | Padding inside navbar in pixels |
|
|
491
|
+
|
|
492
|
+
**NavbarButtonConfig options:**
|
|
493
|
+
|
|
494
|
+
| Prop | Type | Description |
|
|
495
|
+
|------|------|-------------|
|
|
496
|
+
| `className` | `string` | Additional classes for all buttons |
|
|
497
|
+
| `style` | `CSSProperties` | Inline styles for all buttons |
|
|
498
|
+
| `activeClassName` | `string` | Classes for active/pushed state |
|
|
499
|
+
| `activeStyle` | `CSSProperties` | Styles for active state |
|
|
500
|
+
| `hoverClassName` | `string` | Classes for hover state |
|
|
501
|
+
| `hoverStyle` | `CSSProperties` | Styles for hover state |
|
|
502
|
+
| `iconClassName` | `string` | Classes for icons |
|
|
503
|
+
| `iconSize` | `number` | Icon size in pixels (default: 20) |
|
|
504
|
+
| `labelClassName` | `string` | Classes for labels |
|
|
505
|
+
| `labelStyle` | `CSSProperties` | Styles for labels |
|
|
506
|
+
|
|
507
|
+
**NavbarTooltipConfig options:**
|
|
508
|
+
|
|
509
|
+
| Prop | Type | Default | Description |
|
|
510
|
+
|------|------|---------|-------------|
|
|
511
|
+
| `disabled` | `boolean` | `false` | Disable tooltips entirely |
|
|
512
|
+
| `className` | `string` | - | Additional classes for tooltip |
|
|
513
|
+
| `style` | `CSSProperties` | - | Inline styles for tooltip |
|
|
514
|
+
| `delay` | `number` | `100` | Delay before showing tooltip (ms) |
|
|
515
|
+
|
|
516
|
+
#### Display Modes
|
|
517
|
+
|
|
518
|
+
- **`icons`** (default): Shows icons only, expands to show label when active, tooltip on hover
|
|
519
|
+
- **`labels`**: Shows labels only, no icons
|
|
520
|
+
- **`icons-labels`**: Always shows both icon and label for all items
|
|
521
|
+
- **`compact`**: Icons only, no expansion on active, just highlights
|
|
522
|
+
|
|
523
|
+
#### Navbar Examples
|
|
524
|
+
|
|
525
|
+
```tsx
|
|
526
|
+
// Position at top
|
|
527
|
+
<Canvas navbarConfig={{ position: "top" }} />
|
|
528
|
+
|
|
529
|
+
// Labels only (no icons)
|
|
530
|
+
<Canvas navbarConfig={{ display: "labels" }} />
|
|
531
|
+
|
|
532
|
+
// Always show icons + labels
|
|
533
|
+
<Canvas navbarConfig={{ display: "icons-labels" }} />
|
|
534
|
+
|
|
535
|
+
// Compact mode (icons only, no expansion)
|
|
536
|
+
<Canvas navbarConfig={{ display: "compact" }} />
|
|
537
|
+
|
|
538
|
+
// Custom container styling
|
|
539
|
+
<Canvas
|
|
540
|
+
navbarConfig={{
|
|
541
|
+
className: "bg-black/80 backdrop-blur-md",
|
|
542
|
+
style: { borderRadius: "20px" },
|
|
543
|
+
}}
|
|
544
|
+
/>
|
|
545
|
+
|
|
546
|
+
// Custom button styling
|
|
547
|
+
<Canvas
|
|
548
|
+
navbarConfig={{
|
|
549
|
+
buttonConfig: {
|
|
550
|
+
activeClassName: "bg-blue-500",
|
|
551
|
+
activeStyle: { color: "white" },
|
|
552
|
+
hoverClassName: "bg-gray-100",
|
|
553
|
+
iconSize: 24,
|
|
554
|
+
},
|
|
555
|
+
}}
|
|
556
|
+
/>
|
|
557
|
+
|
|
558
|
+
// Disable tooltips
|
|
559
|
+
<Canvas navbarConfig={{ tooltipConfig: { disabled: true } }} />
|
|
560
|
+
|
|
561
|
+
// Vertical sidebar layout
|
|
562
|
+
<Canvas navbarConfig={{ position: "left" }} />
|
|
563
|
+
|
|
564
|
+
// Hide navbar entirely
|
|
565
|
+
<Canvas navbarConfig={{ hidden: true }} />
|
|
566
|
+
```
|
|
567
|
+
|
|
401
568
|
### Exported Constants
|
|
402
569
|
|
|
403
570
|
The library exports default gradient values you can use as a starting point:
|
|
@@ -499,6 +666,11 @@ npm run type-check
|
|
|
499
666
|
- `ToolbarConfig` - Toolbar customization options
|
|
500
667
|
- `ToolbarPosition` - Preset toolbar positions
|
|
501
668
|
- `ToolbarDisplayMode` - Toolbar display modes
|
|
669
|
+
- `NavbarConfig` - Navbar customization options
|
|
670
|
+
- `NavbarPosition` - Preset navbar positions
|
|
671
|
+
- `NavbarDisplayMode` - Navbar display modes
|
|
672
|
+
- `NavbarButtonConfig` - Navbar button styling options
|
|
673
|
+
- `NavbarTooltipConfig` - Navbar tooltip options
|
|
502
674
|
- `NavItem` - Navigation item configuration
|
|
503
675
|
- `SectionCoordinates` - Section coordinate definition
|
|
504
676
|
|
|
@@ -525,6 +697,22 @@ The `Canvas` component accepts the following props:
|
|
|
525
697
|
| `canvasBackground` | `ReactNode` | No | `<DefaultCanvasBackground />` | Custom canvas background |
|
|
526
698
|
| `wrapperBackground` | `ReactNode` | No | - | Custom wrapper/intro background |
|
|
527
699
|
| `toolbarConfig` | `ToolbarConfig` | No | - | Toolbar customization options |
|
|
700
|
+
| `navbarConfig` | `NavbarConfig` | No | - | Navbar customization options |
|
|
701
|
+
|
|
702
|
+
### NavItem Props
|
|
703
|
+
|
|
704
|
+
Each item in the `navItems` array has the following properties:
|
|
705
|
+
|
|
706
|
+
| Prop | Type | Required | Description |
|
|
707
|
+
|------|------|----------|-------------|
|
|
708
|
+
| `id` | `string` | Yes | Unique identifier for this section |
|
|
709
|
+
| `label` | `string` | Yes | Display label shown in the navbar |
|
|
710
|
+
| `icon` | `string \| React.ComponentType` | Yes | Lucide icon name or custom component |
|
|
711
|
+
| `x` | `number` | Yes | X coordinate on the canvas |
|
|
712
|
+
| `y` | `number` | Yes | Y coordinate on the canvas |
|
|
713
|
+
| `width` | `number` | Yes | Section viewport width |
|
|
714
|
+
| `height` | `number` | Yes | Section viewport height |
|
|
715
|
+
| `isHome` | `boolean` | No | If true, clicking triggers reset/home behavior |
|
|
528
716
|
|
|
529
717
|
### Draggable Props
|
|
530
718
|
|
|
@@ -25,8 +25,8 @@ export interface DefaultCanvasBackgroundProps {
|
|
|
25
25
|
/** Additional children to render in the background */
|
|
26
26
|
children?: ReactNode;
|
|
27
27
|
}
|
|
28
|
-
/** The default canvas gradient (neutral gray) */
|
|
29
|
-
export declare const DEFAULT_CANVAS_GRADIENT = "radial-gradient(ellipse 6000px 4000px at 3000px 4000px, #
|
|
28
|
+
/** The default canvas gradient (neutral light gray) */
|
|
29
|
+
export declare const DEFAULT_CANVAS_GRADIENT = "radial-gradient(ellipse 6000px 4000px at 3000px 4000px, #fafafa 0%, #f5f5f5 41%, #e5e5e5 59%, #fafafa 90%)";
|
|
30
30
|
/**
|
|
31
31
|
* Default canvas background with gradient, dots, and noise filter.
|
|
32
32
|
* All aspects are customizable via props.
|
|
@@ -65,6 +65,6 @@ export interface DefaultIntroContentProps {
|
|
|
65
65
|
* Can be customized or replaced entirely.
|
|
66
66
|
*/
|
|
67
67
|
export declare const DefaultIntroContent: React.FC<DefaultIntroContentProps>;
|
|
68
|
-
export declare const DEFAULT_INTRO_GRADIENT = "linear-gradient(to top, #
|
|
69
|
-
export declare const DEFAULT_CANVAS_BOX_GRADIENT = "radial-gradient(130.38% 95% at 50.03% 97.25%, #
|
|
68
|
+
export declare const DEFAULT_INTRO_GRADIENT = "linear-gradient(to top, #f5f5f5 0%, #fafafa 50%, #ffffff 100%)";
|
|
69
|
+
export declare const DEFAULT_CANVAS_BOX_GRADIENT = "radial-gradient(130.38% 95% at 50.03% 97.25%, #f5f5f5 0%, #fafafa 48.09%, #ffffff 100%)";
|
|
70
70
|
//# sourceMappingURL=backgrounds.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backgrounds.d.ts","sourceRoot":"","sources":["../../../src/components/canvas/backgrounds.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAO9C,MAAM,WAAW,4BAA4B;IAC3C,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kDAAkD;IAClD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8CAA8C;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,
|
|
1
|
+
{"version":3,"file":"backgrounds.d.ts","sourceRoot":"","sources":["../../../src/components/canvas/backgrounds.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAO9C,MAAM,WAAW,4BAA4B;IAC3C,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kDAAkD;IAClD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8CAA8C;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,uDAAuD;AACvD,eAAO,MAAM,uBAAuB,+GAA6J,CAAC;AAElM;;;GAGG;AACH,eAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC,EAAE,CAAC,4BAA4B,CA6D1E,CAAC;AAIF,MAAM,WAAW,6BAA6B;IAC5C,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAE,KAAK,CAAC,EAAE,CAAC,6BAA6B,CAc5E,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CA0ClE,CAAC;AAGF,eAAO,MAAM,sBAAsB,mEAC+B,CAAC;AAEnE,eAAO,MAAM,2BAA2B,4FACmD,CAAC"}
|
|
@@ -1,47 +1,76 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { canvasHeight, canvasWidth } from "../../lib/canvas.js";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
2
3
|
import { motion } from "framer-motion";
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import React from "react";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
|
|
7
|
+
//#region src/components/canvas/backgrounds.tsx
|
|
8
|
+
/** The default canvas gradient (neutral light gray) */
|
|
9
|
+
const DEFAULT_CANVAS_GRADIENT = `radial-gradient(ellipse ${canvasWidth}px ${canvasHeight}px at ${canvasWidth / 2}px ${canvasHeight}px, #fafafa 0%, #f5f5f5 41%, #e5e5e5 59%, #fafafa 90%)`;
|
|
7
10
|
/**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
* Default canvas background with gradient, dots, and noise filter.
|
|
12
|
+
* All aspects are customizable via props.
|
|
13
|
+
*/
|
|
14
|
+
const DefaultCanvasBackground = ({ gradientStyle, showDots = true, dotColor = "#a3a3a3", dotSize = 1.5, dotSpacing = 22, dotOpacity = .35, showFilter = true, filterOpacity = .6, gradientClassName, dotsClassName, filterClassName, children }) => {
|
|
15
|
+
const gradientImage = gradientStyle ?? DEFAULT_CANVAS_GRADIENT;
|
|
16
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
17
|
+
/* @__PURE__ */ jsx("div", {
|
|
18
|
+
className: cn("pointer-events-none absolute inset-0 h-full w-full", gradientClassName),
|
|
19
|
+
style: { backgroundImage: gradientImage }
|
|
20
|
+
}),
|
|
21
|
+
showDots && /* @__PURE__ */ jsx("div", {
|
|
22
|
+
className: cn("pointer-events-none absolute inset-0 h-full w-full", dotsClassName),
|
|
23
|
+
style: {
|
|
24
|
+
backgroundImage: `radial-gradient(${dotColor} ${dotSize}px, transparent ${dotSize}px)`,
|
|
25
|
+
backgroundSize: `${dotSpacing}px ${dotSpacing}px`,
|
|
26
|
+
opacity: dotOpacity
|
|
27
|
+
}
|
|
28
|
+
}),
|
|
29
|
+
showFilter && /* @__PURE__ */ jsx("div", {
|
|
30
|
+
className: cn("pointer-events-none absolute inset-0 hidden h-full w-full bg-none filter md:inline md:bg-noise", filterClassName),
|
|
31
|
+
style: {
|
|
32
|
+
opacity: filterOpacity,
|
|
33
|
+
filter: "contrast(0.6)"
|
|
34
|
+
}
|
|
35
|
+
}),
|
|
36
|
+
children
|
|
37
|
+
] });
|
|
23
38
|
};
|
|
24
39
|
/**
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
40
|
+
* Default wrapper/intro background gradient.
|
|
41
|
+
*/
|
|
42
|
+
const DefaultWrapperBackground = ({ gradient = "linear-gradient(to top, #f5f5f5 0%, #fafafa 50%, #ffffff 100%)", className, style }) => {
|
|
43
|
+
return /* @__PURE__ */ jsx("div", {
|
|
44
|
+
className: cn("absolute inset-0 h-full w-full", className),
|
|
45
|
+
style: {
|
|
46
|
+
backgroundImage: gradient,
|
|
47
|
+
...style
|
|
48
|
+
}
|
|
49
|
+
});
|
|
32
50
|
};
|
|
33
51
|
/**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
52
|
+
* Default intro content shown during loading.
|
|
53
|
+
* Can be customized or replaced entirely.
|
|
54
|
+
*/
|
|
55
|
+
const DefaultIntroContent = ({ logoSrc, logoAlt = "Logo", logoWidth = 64, logoHeight = 64, title, className, titleClassName }) => {
|
|
56
|
+
if (!logoSrc && !title) return null;
|
|
57
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
58
|
+
className: cn("absolute left-1/2 top-24 flex -translate-x-1/2 flex-col items-center text-center", className),
|
|
59
|
+
children: [logoSrc && /* @__PURE__ */ jsx(motion.img, {
|
|
60
|
+
src: logoSrc,
|
|
61
|
+
alt: logoAlt,
|
|
62
|
+
width: logoWidth,
|
|
63
|
+
height: logoHeight,
|
|
64
|
+
className: "mb-4"
|
|
65
|
+
}), title && /* @__PURE__ */ jsx("div", {
|
|
66
|
+
className: cn("font-sans font-semibold text-neutral-600", titleClassName),
|
|
67
|
+
children: title
|
|
68
|
+
})]
|
|
69
|
+
});
|
|
43
70
|
};
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
71
|
+
const DEFAULT_INTRO_GRADIENT = "linear-gradient(to top, #f5f5f5 0%, #fafafa 50%, #ffffff 100%)";
|
|
72
|
+
const DEFAULT_CANVAS_BOX_GRADIENT = "radial-gradient(130.38% 95% at 50.03% 97.25%, #f5f5f5 0%, #fafafa 48.09%, #ffffff 100%)";
|
|
73
|
+
|
|
74
|
+
//#endregion
|
|
75
|
+
export { DEFAULT_CANVAS_BOX_GRADIENT, DEFAULT_CANVAS_GRADIENT, DEFAULT_INTRO_GRADIENT, DefaultCanvasBackground, DefaultIntroContent, DefaultWrapperBackground };
|
|
47
76
|
//# sourceMappingURL=backgrounds.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backgrounds.js","
|
|
1
|
+
{"version":3,"file":"backgrounds.js","names":[],"sources":["../../../src/components/canvas/backgrounds.tsx"],"sourcesContent":["import React, { type ReactNode } from \"react\";\nimport { motion } from \"framer-motion\";\nimport { canvasWidth, canvasHeight } from \"../../lib/canvas\";\nimport { cn } from \"../../lib/utils\";\n\n// ============== Canvas Background ==============\n\nexport interface DefaultCanvasBackgroundProps {\n /** Custom gradient CSS string. If not provided, uses the default radial gradient. */\n gradientStyle?: string;\n /** Whether to show the dot pattern. Default: true */\n showDots?: boolean;\n /** Dot pattern color. Default: #888888 */\n dotColor?: string;\n /** Dot pattern size in pixels. Default: 1.5 */\n dotSize?: number;\n /** Dot pattern spacing in pixels. Default: 22 */\n dotSpacing?: number;\n /** Dot pattern opacity (0-1). Default: 0.35 */\n dotOpacity?: number;\n /** Whether to show the noise filter. Default: true */\n showFilter?: boolean;\n /** Filter opacity (0-1). Default: 0.6 */\n filterOpacity?: number;\n /** Additional className for the gradient layer */\n gradientClassName?: string;\n /** Additional className for the dots layer */\n dotsClassName?: string;\n /** Additional className for the filter layer */\n filterClassName?: string;\n /** Additional children to render in the background */\n children?: ReactNode;\n}\n\n/** The default canvas gradient (neutral light gray) */\nexport const DEFAULT_CANVAS_GRADIENT = `radial-gradient(ellipse ${canvasWidth}px ${canvasHeight}px at ${canvasWidth / 2}px ${canvasHeight}px, #fafafa 0%, #f5f5f5 41%, #e5e5e5 59%, #fafafa 90%)`;\n\n/**\n * Default canvas background with gradient, dots, and noise filter.\n * All aspects are customizable via props.\n */\nexport const DefaultCanvasBackground: React.FC<DefaultCanvasBackgroundProps> = ({\n gradientStyle,\n showDots = true,\n dotColor = \"#a3a3a3\",\n dotSize = 1.5,\n dotSpacing = 22,\n dotOpacity = 0.35,\n showFilter = true,\n filterOpacity = 0.6,\n gradientClassName,\n dotsClassName,\n filterClassName,\n children,\n}) => {\n const gradientImage = gradientStyle ?? DEFAULT_CANVAS_GRADIENT;\n\n return (\n <>\n {/* Gradient layer */}\n <div\n className={cn(\n \"pointer-events-none absolute inset-0 h-full w-full\",\n gradientClassName\n )}\n style={{\n backgroundImage: gradientImage,\n }}\n />\n\n {/* Dots layer */}\n {showDots && (\n <div\n className={cn(\n \"pointer-events-none absolute inset-0 h-full w-full\",\n dotsClassName\n )}\n style={{\n backgroundImage: `radial-gradient(${dotColor} ${dotSize}px, transparent ${dotSize}px)`,\n backgroundSize: `${dotSpacing}px ${dotSpacing}px`,\n opacity: dotOpacity,\n }}\n />\n )}\n\n {/* Filter/noise layer */}\n {showFilter && (\n <div\n className={cn(\n \"pointer-events-none absolute inset-0 hidden h-full w-full bg-none filter md:inline md:bg-noise\",\n filterClassName\n )}\n style={{\n opacity: filterOpacity,\n filter: \"contrast(0.6)\",\n }}\n />\n )}\n\n {children}\n </>\n );\n};\n\n// ============== Wrapper/Intro Background ==============\n\nexport interface DefaultWrapperBackgroundProps {\n /** Background gradient for the intro screen */\n gradient?: string;\n /** Additional className */\n className?: string;\n /** Additional inline styles */\n style?: React.CSSProperties;\n}\n\n/**\n * Default wrapper/intro background gradient.\n */\nexport const DefaultWrapperBackground: React.FC<DefaultWrapperBackgroundProps> = ({\n gradient = \"linear-gradient(to top, #f5f5f5 0%, #fafafa 50%, #ffffff 100%)\",\n className,\n style,\n}) => {\n return (\n <div\n className={cn(\"absolute inset-0 h-full w-full\", className)}\n style={{\n backgroundImage: gradient,\n ...style,\n }}\n />\n );\n};\n\nexport interface DefaultIntroContentProps {\n /** Logo image source */\n logoSrc?: string;\n /** Logo alt text */\n logoAlt?: string;\n /** Logo width */\n logoWidth?: number;\n /** Logo height */\n logoHeight?: number;\n /** Title text */\n title?: string;\n /** Additional className for the container */\n className?: string;\n /** Additional className for the title */\n titleClassName?: string;\n}\n\n/**\n * Default intro content shown during loading.\n * Can be customized or replaced entirely.\n */\nexport const DefaultIntroContent: React.FC<DefaultIntroContentProps> = ({\n logoSrc,\n logoAlt = \"Logo\",\n logoWidth = 64,\n logoHeight = 64,\n title,\n className,\n titleClassName,\n}) => {\n // If no logo or title provided, render nothing\n if (!logoSrc && !title) {\n return null;\n }\n\n return (\n <div\n className={cn(\n \"absolute left-1/2 top-24 flex -translate-x-1/2 flex-col items-center text-center\",\n className\n )}\n >\n {logoSrc && (\n <motion.img\n src={logoSrc}\n alt={logoAlt}\n width={logoWidth}\n height={logoHeight}\n className=\"mb-4\"\n />\n )}\n {title && (\n <div\n className={cn(\n \"font-sans font-semibold text-neutral-600\",\n titleClassName\n )}\n >\n {title}\n </div>\n )}\n </div>\n );\n};\n\n// Default gradient values for export (neutral light grays)\nexport const DEFAULT_INTRO_GRADIENT =\n \"linear-gradient(to top, #f5f5f5 0%, #fafafa 50%, #ffffff 100%)\";\n\nexport const DEFAULT_CANVAS_BOX_GRADIENT =\n \"radial-gradient(130.38% 95% at 50.03% 97.25%, #f5f5f5 0%, #fafafa 48.09%, #ffffff 100%)\";\n"],"mappings":";;;;;;;;AAmCA,MAAa,0BAA0B,2BAA2B,YAAY,KAAK,aAAa,QAAQ,cAAc,EAAE,KAAK,aAAa;;;;;AAM1I,MAAa,2BAAmE,EAC9E,eACA,WAAW,MACX,WAAW,WACX,UAAU,KACV,aAAa,IACb,aAAa,KACb,aAAa,MACb,gBAAgB,IAChB,mBACA,eACA,iBACA,eACI;CACJ,MAAM,gBAAgB,iBAAiB;AAEvC,QACE;EAEE,oBAAC;GACC,WAAW,GACT,sDACA,kBACD;GACD,OAAO,EACL,iBAAiB,eAClB;IACD;EAGD,YACC,oBAAC;GACC,WAAW,GACT,sDACA,cACD;GACD,OAAO;IACL,iBAAiB,mBAAmB,SAAS,GAAG,QAAQ,kBAAkB,QAAQ;IAClF,gBAAgB,GAAG,WAAW,KAAK,WAAW;IAC9C,SAAS;IACV;IACD;EAIH,cACC,oBAAC;GACC,WAAW,GACT,kGACA,gBACD;GACD,OAAO;IACL,SAAS;IACT,QAAQ;IACT;IACD;EAGH;KACA;;;;;AAkBP,MAAa,4BAAqE,EAChF,WAAW,kEACX,WACA,YACI;AACJ,QACE,oBAAC;EACC,WAAW,GAAG,kCAAkC,UAAU;EAC1D,OAAO;GACL,iBAAiB;GACjB,GAAG;GACJ;GACD;;;;;;AAyBN,MAAa,uBAA2D,EACtE,SACA,UAAU,QACV,YAAY,IACZ,aAAa,IACb,OACA,WACA,qBACI;AAEJ,KAAI,CAAC,WAAW,CAAC,MACf,QAAO;AAGT,QACE,qBAAC;EACC,WAAW,GACT,oFACA,UACD;aAEA,WACC,oBAAC,OAAO;GACN,KAAK;GACL,KAAK;GACL,OAAO;GACP,QAAQ;GACR,WAAU;IACV,EAEH,SACC,oBAAC;GACC,WAAW,GACT,4CACA,eACD;aAEA;IACG;GAEJ;;AAKV,MAAa,yBACX;AAEF,MAAa,8BACX"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Transition } from "framer-motion";
|
|
2
2
|
import React, { type FC } from "react";
|
|
3
|
-
import type { NavItem, SectionCoordinates, ToolbarConfig } from "../../types";
|
|
3
|
+
import type { NavItem, NavbarConfig, SectionCoordinates, ToolbarConfig } from "../../types";
|
|
4
4
|
import type { ReactNode } from "react";
|
|
5
5
|
interface Props {
|
|
6
6
|
homeCoordinates: SectionCoordinates;
|
|
@@ -29,6 +29,8 @@ interface Props {
|
|
|
29
29
|
wrapperBackground?: ReactNode;
|
|
30
30
|
/** Toolbar customization options */
|
|
31
31
|
toolbarConfig?: ToolbarConfig;
|
|
32
|
+
/** Navbar customization options */
|
|
33
|
+
navbarConfig?: NavbarConfig;
|
|
32
34
|
}
|
|
33
35
|
declare const Canvas: FC<Props>;
|
|
34
36
|
export default Canvas;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvas.d.ts","sourceRoot":"","sources":["../../../src/components/canvas/canvas.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,UAAU,EAChB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,EAIZ,KAAK,EAAE,EAIR,MAAM,OAAO,CAAC;AA0Bf,OAAO,KAAK,EAEV,OAAO,EACP,kBAAkB,EAClB,aAAa,EACd,MAAM,aAAa,CAAC;AAGrB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,UAAU,KAAK;IACb,eAAe,EAAE,kBAAkB,CAAC;IACpC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAG1B,WAAW,CAAC,EAAC,MAAM,CAAC;IACpB,YAAY,CAAC,EAAC,MAAM,CAAC;IAGrB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IAGrB,uCAAuC;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,0BAA0B;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,0BAA0B;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,6BAA6B;IAC7B,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,6BAA6B;IAC7B,cAAc,CAAC,EAAE,UAAU,CAAC;IAG5B,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAG9B,oCAAoC;IACpC,aAAa,CAAC,EAAE,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"canvas.d.ts","sourceRoot":"","sources":["../../../src/components/canvas/canvas.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,UAAU,EAChB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,EAIZ,KAAK,EAAE,EAIR,MAAM,OAAO,CAAC;AA0Bf,OAAO,KAAK,EAEV,OAAO,EACP,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACd,MAAM,aAAa,CAAC;AAGrB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,UAAU,KAAK;IACb,eAAe,EAAE,kBAAkB,CAAC;IACpC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAG1B,WAAW,CAAC,EAAC,MAAM,CAAC;IACpB,YAAY,CAAC,EAAC,MAAM,CAAC;IAGrB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IAGrB,uCAAuC;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,0BAA0B;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,0BAA0B;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,6BAA6B;IAC7B,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,6BAA6B;IAC7B,cAAc,CAAC,EAAE,UAAU,CAAC;IAG5B,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAG9B,oCAAoC;IACpC,aAAa,CAAC,EAAE,aAAa,CAAC;IAG9B,mCAAmC;IACnC,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAYD,QAAA,MAAM,MAAM,EAAE,EAAE,CAAC,KAAK,CAkmBrB,CAAC;AAEF,eAAe,MAAM,CAAC"}
|